", "").Replace("
", "").Replace("=", "_").Replace(">", "_").Replace("|", "_").Replace("!", "_").Replace("<", "_").Replace("/", "_")) - Return ReportFile - Else - Return Nothing - End If - Else - Return Nothing - End If - End Function - Public Function getFDSDoc(ByRef file As Byte(), reportid As String, type As String) As IO.FileInfo - Dim pl As New List(Of SqlClient.SqlParameter) From {SQL_VarChar("@type", type), SQL_VarChar("@reportid", reportid)} - Dim sqldt As SQLDataTable = System.Threading.Tasks.Task.Run(Async Function() Await getSQLDatatable_async("EXECUTE [dbo].[fds__getFDSDocument] @type, @reportid;", FDSConnectionString, SqlParameterList:=pl, options:=New fds_SQLOptions())).Result() - If sqldt.Count > 0 Then - Dim irow As DataRow = sqldt.FirstRow() - Dim fl As Byte() = irow.no("file", Nothing), fln As String = irow.nz("DocumentName") - If IsNothing(fl) = False Then - file = fl - Dim ReportFile As New IO.FileInfo(IO.Path.GetTempPath & fln.Replace("=", "_").Replace(">", "_").Replace("|", "_").Replace("!", "_").Replace("?", "_")) - Return ReportFile - Else - Return Nothing - End If - Else - Return Nothing - End If - End Function - - Public Function DATEV(header As DATEV_HEADER, tbl As DataTable) As String - - Return header.toHeaderstring() & ControlChars.CrLf & tbl.ToCsv(includeHeaders:=True, quoteStrings:=False, fieldDelimiter:=";", cultureinfo:=New Globalization.CultureInfo("de-DE"), quoteHeader:=False) - End Function - Public Class DATEV_HEADER - - 'c.f. https://developer.datev.de/portal/de/dtvf/formate/header - - Public Kennzeichen As DATEV_Kennzeichen = DATEV_Kennzeichen.EXTF - Public Versionsnummer As Integer = 700 - Public Formatkategorie As DATEV_Formatkategorie = DATEV_Formatkategorie.Debitoren__Kreditoren - Public Formatversion As DATEV_Formatversion = DATEV_Formatversion.Debitoren__Kreditoren - Public Beraternummer As Integer - Public Mandantennummer As Integer - Public WJBeginn As Date - Public Sachkontenlänge As Integer - Public Datum_von As Date - Public Datum_bis As Date - Public Bezeichnung As String - Public Buchungstyp As DATEV_Buchungstyp = DATEV_Buchungstyp.Finanzbuchführung - Public Rechnungsslegungszweck As DATEV_Rechnungslegungszweck = DATEV_Rechnungslegungszweck.unabhängig - Public Festschreibung As Boolean = 1 - Public WKZ As String = "EUR" - - - Public created As Date = Now() - Public ReadOnly Property Formatname As String - Get - Return [Enum].GetName(GetType(DATEV_Formatkategorie), Me.Formatkategorie).Replace("__", "/").Replace("_", " ") - End Get - End Property - - Dim EmptyDblQuote As String = Microsoft.VisualBasic.ChrW(34) & Microsoft.VisualBasic.ChrW(34) - - Public ReadOnly Property toHeaderstring As String - Get - Dim sb As New List(Of String) - sb.Add(Microsoft.VisualBasic.ChrW(34) & [Enum].GetName(GetType(DATEV_Kennzeichen), Me.Kennzeichen) & Microsoft.VisualBasic.ChrW(34)) - sb.Add(Me.Versionsnummer.ToString) - sb.Add(CInt(Me.Formatkategorie).ToString) - sb.Add(Microsoft.VisualBasic.ChrW(34) & Me.Formatname & Microsoft.VisualBasic.ChrW(34)) - sb.Add(CInt(Me.Formatversion).ToString) - sb.Add(created.ToString("yyyyMMddHHmmssfff")) - sb.Add("") '7 Leerfeld - sb.Add(EmptyDblQuote) '8 Leerfeld - sb.Add(EmptyDblQuote) '9 Leerfeld - sb.Add(EmptyDblQuote) '10 Leerfeld - sb.Add(Me.Beraternummer.ToString) '11 Beraternummer - sb.Add(Me.Mandantennummer.ToString) '12 Mandantennummer - sb.Add(Me.WJBeginn.ToString("yyyyMMdd")) - sb.Add(Me.Sachkontenlänge.ToString) - sb.Add(Me.Datum_von.ToString("yyyyMMdd")) - sb.Add(Me.Datum_bis.ToString("yyyyMMdd")) - sb.Add(Microsoft.VisualBasic.ChrW(34) & Me.Bezeichnung & Microsoft.VisualBasic.ChrW(34)) - sb.Add(EmptyDblQuote) '18 Diktatkürzel - sb.Add(CInt(Me.Buchungstyp).ToString) - sb.Add(CInt(Me.Rechnungsslegungszweck).ToString) - sb.Add(If(Me.Festschreibung = False, 0, 1)) - sb.Add(Microsoft.VisualBasic.ChrW(34) & Me.WKZ & Microsoft.VisualBasic.ChrW(34)) - sb.Add("") '23 Leerfeld - sb.Add("") '24 Leerfeld - sb.Add("") '25 Leerfeld - sb.Add("") '26 Leerfeld - sb.Add("") '27 Sachkontenrahmen - sb.Add("") '28 ID der Branchenlösung - sb.Add("") '29 Leerfeld - sb.Add("") '30 Leerfeld - sb.Add("") '31 Verarbeitungskennzeichen - Return vbs.Join(sb.ToArray, ";") - End Get - End Property - - - End Class - - - - Public Enum DATEV_Rechnungslegungszweck - unabhängig = 0 - Steuerrecht = 30 - Kalkulatorik = 40 - Handelsrecht = 50 - IFRS = 64 - End Enum - - Public Enum DATEV_Buchungstyp - Finanzbuchführung = 1 - Jahresabschluss = 2 - End Enum - - Public Enum DATEV_Kennzeichen - EXTF - DTVF - End Enum - - Public Enum DATEV_Formatkategorie - [Debitoren__Kreditoren] = 16 - [Sachkontenbeschriftungen] = 20 - [Buchungsstapel] = 21 - [Zahlungsbedingungen] = 46 - [Diverse_Adressen] = 48 - [Wiederkehrende_Buchungen] = 65 - End Enum - Public Enum DATEV_Formatversion - [Debitoren__Kreditoren] = 5 - [Sachkontenbeschriftungen] = 3 - [Buchungsstapel_9] = 9 - [Buchungsstapel] = 12 - [Zahlungsbedingungen] = 2 - [Wiederkehrende_Buchungen] = 4 - [Diverse_Adressen] = 2 - End Enum - - Public Class DATEV_Document - Public guid As String - Public type As Integer = 2 - Public processID As Integer = 2 - Public Filename As String - Public KeyWords As String - Public Repository As String - Public Register As String - Public Sub New(guid As String, filename As String, keywords As String, Repository As String, Register As String) - Me.guid = guid - Me.Filename = filename - Me.KeyWords = keywords - Me.Repository = Repository - Me.Register = Register - End Sub - End Class - - - Public Function getDatevZip(ByRef stream As IO.Stream, ByVal tgtdate As Date, mode As String, ByVal AuthUser As String, ByVal includeFiles As Boolean, Optional DebugDetails As Boolean = False) As IO.FileInfo - - Using mfr As New fds_MFR_Client - Try - Dim DSet As SQLDataSet = System.Threading.Tasks.Task.Run(Async Function() Await getSQLDataSet_async("EXECUTE [dbo].[fds__getDatevExports] @tgtdate, @mode, @files, @authuser;", FDSConnectionString, SqlParameterList:=New List(Of SqlClient.SqlParameter) From {SQL_date("@tgtdate", tgtdate), SQL_VarChar("@mode", mode), SQL_bit("@files", includeFiles), SQL_VarChar("@authuser", AuthUser)}, tablenames:=New String() {"admin", "inv", "buchungen", "debitoren"}, options:=New fds_SQLOptions())).Result() - - Dim bedi_files As New List(Of DATEV_Document) - - If DSet.Count >= 4 Then - Dim admin As Dictionary(Of String, Object) = DSet.Tables("admin").Rows(0).toObjectDictionary() - Dim startdate As Date = admin("startdate"), enddate As Date = admin("enddate") - Dim Datev_Level3_Register As String = tgtdate.ToString("yyyy\/MM") & If(mode.ToLower = "w", "_w" & tgtdate.ToString("dd"), "") - Dim fls As New Dictionary(Of String, Byte()) - Dim header As New DATEV_HEADER With { - .Formatkategorie = DATEV_Formatkategorie.Buchungsstapel, - .Formatversion = DATEV_Formatversion.Buchungsstapel_9, - .Beraternummer = admin("beraternummer"), - .Mandantennummer = admin("mandantennummer"), - .WJBeginn = admin("WJ-Beginn"), - .Sachkontenlänge = admin("Sachkontenlänge"), - .Datum_von = startdate, - .Datum_bis = enddate, - .Bezeichnung = "fds_" & mode & tgtdate.ToString("yyMMdd") - } - fls.Add("EXTF_PCW_Buchungen_0_" & startdate.ToString("yyMMdd HHmmss") & ".csv", DATEV(header, DSet.Tables("buchungen")).ToByteArray(encoding:=Encoding.GetEncoding("ISO-8859-1"))) - - ''only for debug - 'Using fsw As New IO.StreamWriter("C:\Users\sailo\Desktop\Fuchs\DatevUpload_AR 202107_w___DATEVNEU\EXTF_PCW_Buchungen_0_" & startdate.ToString("yyMMdd HHmmss") & ".csv", False, Encoding.GetEncoding("ISO-8859-1")) - ' fsw.Write(value:=DATEV(header, DSet.Tables("buchungen"))) - ' fsw.Close() - 'End Using - - - With header - .Formatkategorie = DATEV_Formatkategorie.Debitoren__Kreditoren - .Formatversion = DATEV_Formatversion.Debitoren__Kreditoren - End With - fls.Add("EXTF_PCW_Debitoren_0_" & startdate.ToString("yyMMdd HHmmss") & ".csv", DATEV(header, DSet.Tables("debitoren")).ToByteArray(encoding:=Encoding.GetEncoding("ISO-8859-1"))) - - - ''only for debug - 'Using fsw As New IO.StreamWriter("C:\Users\sailo\Desktop\Fuchs\DatevUpload_AR 202107_w___DATEVNEU\EXTF_PCW_Debitoren_0_" & startdate.ToString("yyMMdd HHmmss") & ".csv", False, Encoding.GetEncoding("ISO-8859-1")) - ' fsw.Write(value:=DATEV(header, DSet.Tables("debitoren"))) - ' fsw.Close() - 'End Using - - - 'add csv files to bedi list - For Each fl As String In fls.Keys - bedi_files.Add(New DATEV_Document(Guid.NewGuid().ToString.ToLower, filename:=fl, keywords:="", Repository:="Processweb_Daten", Register:=Datev_Level3_Register)) - Next - - If includeFiles = True Then - For Each irow As DataRow In DSet.Tables("inv").Rows - Dim fl As Byte() = Nothing, fln As String = irow.nz("DocumentName") - Try - If fln <> "" AndAlso irow.no("fds", True) = False Then - fl = mfr.GetFile(irow.nz("URI")) - Else - fl = irow.no("file", Nothing) - End If - Catch ex As Exception - - End Try - If IsNothing(fl) = False AndAlso fln <> "" Then - fls.Add(fln, fl) - bedi_files.Add(New DATEV_Document(irow("file_guid"), filename:=fln, keywords:="RgNr: " & irow.nz("InvoiceId") & " RgDatum: " & irow.ndt_string("DateOfCreation", "dd.MM.yyyy"), Repository:="ProcessWeb_Belege", Register:=Datev_Level3_Register)) - End If - 'If fls.Count > 7 Then Exit For - Next - - fls.Add("document.xml", createDATEV_document_xml(bedi_files).ToByteArray()) - End If - - If fls.Count > 0 Then - Dim ArchiveFile As New IO.FileInfo(IO.Path.GetTempPath & "DatevUpload_AR " & startdate.ToString("yyyyMM") & "_" & admin("mode").ToString & ".zip") - Try - Using Archive As New fds.Archive(ArchiveFile, Type:=SevenZip.OutArchiveFormat.Zip) - If Archive.CompressToStream(fls, targetstream:=stream) = True Then - Diagnostics.Debug.Print("ok") - 'Archive.WriteArchiveStreamToDisk() - stream.Position = 0 - Return ArchiveFile - Else - Return Nothing - End If - End Using - Catch aex As Exception - End Try - - End If - - End If - - Catch ex As Exception - Call DebugLog("getDatevZip - mfr", exc:=ex) - If DebugDetails = True Then Call DebugToFile("getDatevZip - mfr", exc:=ex, data:="", filename:="DebugDetail.txt") - End Try - End Using - Return Nothing - End Function -#Enable Warning BC42358 - - Public Function createDATEV_document_xml(files As List(Of DATEV_Document)) As String - Dim xmldoc As New Xml.XmlDocument - - 'Write down the XML declaration - Dim XmlDeclaration As Xml.XmlDeclaration = xmldoc.CreateXmlDeclaration("1.0", "UTF-8", Nothing) - xmldoc.InsertBefore(XmlDeclaration, xmldoc.DocumentElement) - - 'create root - Dim RootNode As Xml.XmlElement = xmldoc.CreateElement("archive", "http://xml.datev.de/bedi/tps/document/v04.0") - xmldoc.AppendChild(RootNode) - - With RootNode - Dim schemaLocation As Xml.XmlAttribute = xmldoc.CreateAttribute("xsi", "schemaLocation", "http://www.w3.org/2001/XMLSchema-instance") - schemaLocation.Value = "http://xml.datev.de/bedi/tps/document/v04.0 document_v040.xsd" - .Attributes.Append(schemaLocation) - .SetAttribute("generatingSystem", "ProcessWeb") - .SetAttribute("version", "4.0") - End With - - Dim header As Xml.XmlElement = xmldoc.CreateElement("header") - xmldoc.DocumentElement.PrependChild(header) - Dim headerelement As Xml.XmlElement = xmldoc.CreateElement("date") - headerelement.InnerText = Now().ToString("yyyy-MM-ddTHH:mm:ss") - header.AppendChild(headerelement) - headerelement = xmldoc.CreateElement("description") - headerelement.InnerText = "DATEV Schnittstelle ProcessWeb" - header.AppendChild(headerelement) - - Dim content As Xml.XmlElement = xmldoc.CreateElement("content") - xmldoc.DocumentElement.AppendChild(content) - For Each fl As DATEV_Document In files - Dim docelement As Xml.XmlElement = xmldoc.CreateElement("document") - docelement.SetAttribute("guid", fl.guid) - docelement.SetAttribute("type", fl.type) - docelement.SetAttribute("processID", fl.processID) - - If If(fl.KeyWords, "") <> "" Then - Dim keyword As Xml.XmlElement = xmldoc.CreateElement("keywords") - keyword.InnerText = fl.KeyWords - docelement.AppendChild(keyword) - End If - - Dim extension As Xml.XmlElement = xmldoc.CreateElement("extension") - Dim ext_attr As Xml.XmlAttribute = xmldoc.CreateAttribute("xsi", "type", "http://www.w3.org/2001/XMLSchema-instance") - ext_attr.Value = "File" - extension.Attributes.Append(ext_attr) - extension.SetAttribute("name", fl.Filename) - docelement.AppendChild(extension) - - Dim repository As Xml.XmlElement = xmldoc.CreateElement("repository") - Dim level As Xml.XmlElement - level = xmldoc.CreateElement("level") - level.SetAttribute("id", "1") 'Kategorie - level.SetAttribute("name", "ProcessWeb") - repository.AppendChild(level) - level = xmldoc.CreateElement("level") - level.SetAttribute("id", "2") 'Ordner - level.SetAttribute("name", fl.Repository) - repository.AppendChild(level) - level = xmldoc.CreateElement("level") - level.SetAttribute("id", "3") 'Register e.g. 2020/12 - level.SetAttribute("name", fl.Register) - repository.AppendChild(level) - docelement.AppendChild(repository) - - content.AppendChild(docelement) - Next - - Dim xmlasstring As String = "" - Using sw As New IO.StringWriter - Using tw As Xml.XmlWriter = Xml.XmlWriter.Create(sw) - xmldoc.WriteTo(tw) - tw.Flush() - xmlasstring = sw.GetStringBuilder().ToString() - End Using - End Using - Return xmlasstring - End Function - - - Public Function UpdateNeedValue(need As String) As UpdateNeed - Return [Enum].Parse(GetType(UpdateNeed), need) - End Function - - - - End Module - - - - - - Public Class fds_MFR_Client - Implements IDisposable - - - Dim MFRClient As Global.MFR_RESTClient.MFRClient - - Private Shared Function DefaultCredentials() - Return New MFRClientCredentials(My.Settings.MFR_UserName, My.Settings.MFR_Password) - End Function - - Public Sub New(Credentials As MFRClientCredentials) - Dim config As New MFRClientConfig(My.Settings.MFR_host) - Me.MFRClient = New MFRClient(config, credentials:=Credentials) - End Sub - Public Sub New() - Me.New(fds_MFR_Client.DefaultCredentials()) - End Sub - - Public Property IsReadonly() As Boolean - Get - Return Me.MFRClient.IsReadonly - End Get - Set(value As Boolean) - Me.MFRClient.IsReadonly = value - End Set - End Property - - Public ReadOnly Property clientConfig As MFRClientConfig - Get - Return Me.MFRClient.clientConfig - End Get - End Property - - Public Async Function ReadAnything(address As String, Optional throwerror_if_nOK As Boolean = True) As Task(Of String) - Return Await Me.MFRClient.ReadAnything(address:=address, throwerror_if_nOK:=throwerror_if_nOK) - End Function - Public Function GetFile(address As String, Optional throwerror_if_nOK As Boolean = True) As Byte() - Return Me.MFRClient.GetFile(address:=address, throwerror_if_nOK:=throwerror_if_nOK) - End Function - Public Async Function ReadOData(address As String, Optional throwerror_if_nOK As Boolean = True) As Task(Of ODataEnvelope) - Return Await Me.MFRClient.ReadOData(address:=address, throwerror_if_nOK:=throwerror_if_nOK) - End Function - Public Async Function getEntities(Optional throwerror_if_nOK As Boolean = True) As Task(Of String) - Return Await Me.MFRClient.getEntities(throwerror_if_nOK:=throwerror_if_nOK) - End Function - - Public Class DatabaseSchema - Private _et As EntityTypes - - Public ReadOnly Property isValid As Boolean = False - Public ReadOnly Property hasEntity As Boolean = False - - Public ReadOnly Property ThisEntityName As String - Get - Return EntityName(Me._et) - End Get - End Property - - Public ReadOnly Property EntityConfig As Dictionary(Of String, String) - Public ReadOnly Property Entitytablename As String - Public ReadOnly Property Complextypes As New Dictionary(Of String, Dictionary(Of String, String)) - Public ReadOnly Property NavProperties As New Dictionary(Of String, Dictionary(Of String, String)) - - Private _tableset As DataSet - - - - Public Sub New(et As EntityTypes) - Me._et = et - Dim DSet As SQLDataSet = System.Threading.Tasks.Task.Run(Async Function() - Return Await getSQLDataSet_async("EXECUTE [dbo].[mfr__getSchema] 'table', @tgttype;", FDSConnectionString, SqlParameterList:=New List(Of SqlClient.SqlParameter) From {New SqlClient.SqlParameter("@tgttype", ThisEntityName)}, tablenames:=New String() {"entity", "complex_types", "navigation_properties", "tables"}, options:=New fds_SQLOptions()) - End Function).Result() - - Me._isValid = DSet.Count > 0 - Me._hasEntity = DSet.Tables("entity").Rows.Count = 1 - - Me._EntityConfig = If(DSet.Tables("entity").Rows.Count > 0, DSet.Tables("entity").Rows(0).toStringDictionary(), New Dictionary(Of String, String)) - Me._Entitytablename = If(Me.EntityConfig.ContainsKey("tablename"), Me.EntityConfig("tablename"), "") - - For Each ctrw As DataRow In DSet.Tables("complex_types").Rows() - Me._Complextypes.Add(ctrw.nz("name").ToLower, ctrw.toStringDictionary()) - Next - For Each nprw As DataRow In DSet.Tables("navigation_properties").Rows() - Me._NavProperties.Add(nprw.nz("name").ToLower, nprw.toStringDictionary()) - Next - Dim sql As New List(Of String) From {newDatatable_SQL(Me.Entitytablename)} 'The target entitytype's table MUST be the first - Dim tablenames As New List(Of String) From {Me.Entitytablename} - - For Each ttrw As DataRow In DSet.Tables("tables").Rows - sql.Add(newDatatable_SQL(ttrw.nz("tablename"))) - tablenames.Add(ttrw.nz("tablename")) - Next - Me._tableset = System.Threading.Tasks.Task.Run(Async Function() - Return Await getSQLDataSet_async(vbs.Join(sql.ToArray(), vbNewLine), FDSConnectionString, tablenames:=tablenames.ToArray, options:=New fds_SQLOptions()) - End Function).Result().DataSet - End Sub - - Public Function tgtDataset(SetID As String) As DataSet - Dim dset As New DataSet - For Each tbl As DataTable In Me._tableset.Tables - Dim t As DataTable = tbl.Clone - If t.Columns.Contains("setid") Then t.Columns("setid").DefaultValue = SetID - dset.Tables.Add(t) - Next - Return dset - End Function - - End Class - - -#Disable Warning BC42356 ' This async method lacks 'Await' operators and so will run synchronously - Public Async Function Update__entitytable(et As EntityTypes, UpdateNeed As fds.fds_mfr.UpdateNeed, EntityID As Long(), Optional DebugDetails As Boolean = False, Optional SchemaDic As Dictionary(Of String, DatabaseSchema) = Nothing, Optional AdditionalCommandAfter As String = "") As Threading.Tasks.Task(Of Boolean) - If et = EntityTypes.none Then Return False - EntityID = If(EntityID, New Long() {}) ''make sure is not nothing - If UpdateNeed = UpdateNeed.None AndAlso If(EntityID, New Long() {}).Length = 0 Then Return True - - Dim StartTime As DateTime = Now() - Diagnostics.Debug.Print(StartTime.ToLongTimeString() & " - " & "Start before Schema " & et.ToString) - Dim SetID As String = RandomString(5) 'generate a unique ID to identify the submitted data and prevent mixup. A table can be accessed by several batch processes in parallel. - Dim ThisEntityName As String = EntityName(et) - - - Dim DtF As New Action(Of String, String, String)(Sub(note As String, info As String, data As String) - If DebugDetails = True Then Call DebugToFile("Update__entitytable - " & note & " For " & ThisEntityName & "(" & SetID & ")" & If(If(info, "") <> "", ": " & info, ""), filename:="DebugDetail.txt") - End Sub) - Dim Dlg As New Action(Of String, String, String)(Sub(note As String, info As String, data As String) - Dim str As String = "Update__entitytable - " & note & " for " & ThisEntityName & "(" & SetID & ")" & If(If(info, "") <> "", ": " & info, "") - Call DebugLog(str, data:=If(data, "")) - If DebugDetails = True Then Call DebugToFile(str, filename:="DebugDetail.txt") - Diagnostics.Debug.Print(str) - End Sub) - - - - 'check if update processes not already in progress and set lock - Dim params As New List(Of SqlClient.SqlParameter) From { - New SqlClient.SqlParameter("@tbl", ThisEntityName), - New SqlClient.SqlParameter("@state", True), - New SqlClient.SqlParameter("@override", False), - New SqlClient.SqlParameter("@setid", SetID) - } - Dim lockstate As Object = True 'getSQLValue("EXECUTE [dbo].[ctm__admin_getTableLock] @tbl, @state, @override, @setid;", con, SqlParameterList:=params, options:=New fds_SQLOptions()) - If DebugDetails = True AndAlso lockstate.GetType() = GetType(System.Boolean) Then Call DebugToFile("Update__entitytable - lock received for " & ThisEntityName & "(" & SetID & ") - " & lockstate.ToString, filename:="DebugDetail.txt") - 'true means lock was successful - If lockstate.GetType() = GetType(System.Boolean) AndAlso DirectCast(lockstate, Boolean) = True Then - Try - 'get Schema - Dim Schema As DatabaseSchema = If(IsNothing(SchemaDic) = False AndAlso SchemaDic.ContainsKey(ThisEntityName), SchemaDic(ThisEntityName), New DatabaseSchema(et)) - If Schema.isValid = False Then - Dlg("Schema not found", "", Nothing) - ElseIf Schema.hasEntity = True Then - Dim tgtDataset As DataSet = Schema.tgtDataset(SetID:=SetID) - - Dim lastDate As SQLObject, Filter As New List(Of String), EntityIDFilter As String = "", isProcessed As Boolean = False - If If(EntityID, New Long() {}).Length = 1 Then - EntityIDFilter = "(" & EntityID(0).ToString() & "L)" - Filter.Add("") - UpdateNeed = UpdateNeed.Reset - ElseIf If(EntityID, New Long() {}).Length > 1 Then - EntityIDFilter = "" - For idx As Integer = 0 To EntityID.Length - 1 Step 50 - Filter.Add("$filter=" & EntityID.Skip(idx).Take(50).Convert(Of String)(Function(l As Long) "Id eq " & l.ToString() & "L").Join(" or ")) - Next - UpdateNeed = UpdateNeed.Reset - ElseIf UpdateNeed > UpdateNeed.Short Then - EntityIDFilter = "" - Filter.Add("") - ElseIf Schema.EntityConfig.ContainsKey("DateColumn") AndAlso If(Schema.EntityConfig("DateColumn"), "") <> "" Then - lastDate = Await getSQLValue_async(Schema.EntityConfig.nz("DateSQL").ne("SELECT MAX([" & Schema.EntityConfig("DateColumn") & "]) FROM [dbo].[" & Schema.Entitytablename & "];"), FDSConnectionString, options:=New fds_SQLOptions()) - Filter.Add(If(UpdateNeed = fds.fds_mfr.UpdateNeed.Short AndAlso IsNothing(lastDate.Result) = False AndAlso lastDate.Result.GetType() = GetType(System.DateTime), "$filter=" & Schema.EntityConfig("DateColumn") & " gt DateTime'" & DirectCast(lastDate.Result, System.DateTime).ToString(format:="yyyy\-MM\-dd") & "T00:00:00'", "")) - End If - For Each iFilter As String In Filter - If (Schema.EntityConfig.ContainsKey("url") AndAlso Schema.EntityConfig("url") <> "") AndAlso (UpdateNeed = UpdateNeed.Short AndAlso iFilter <> "") OrElse (UpdateNeed > UpdateNeed.Short) Then - isProcessed = True - Diagnostics.Debug.Print(Now.ToLongTimeString() & " - " & "Start MFR " & Schema.Entitytablename) - Dim MFR_Response As ODataEnvelope = Await ReadOData(Me.MFRClient.clientConfig.BaseUrl & Schema.EntityConfig("url").Replace("?", EntityIDFilter & "?") & If(iFilter <> "" AndAlso Schema.EntityConfig("url").Contains("?") = False, "?", If(iFilter <> "", "&", "")) & iFilter) - Diagnostics.Debug.Print(Now.ToLongTimeString() & " - " & "End MFR " & Schema.Entitytablename) - Do Until IsNothing(MFR_Response) = True - If MFR_Response.value.GetType() = GetType(JObject) Then - MFR_Response.ConvertToArray() - End If - Try - - If MFR_Response.value.GetType() = GetType(JArray) AndAlso IsNothing(DirectCast(MFR_Response.value, Newtonsoft.Json.Linq.JContainer).First) = False AndAlso DirectCast(DirectCast(DirectCast(MFR_Response.value, Newtonsoft.Json.Linq.JContainer).First, Newtonsoft.Json.Linq.JContainer).First, Newtonsoft.Json.Linq.JProperty).Name = "odata.error" AndAlso DirectCast(MFR_Response.value, Newtonsoft.Json.Linq.JContainer).First.ToString().IndexOf("Sequence contains no elements", 0, StringComparison.InvariantCultureIgnoreCase) > -1 Then - MFR_Response.value = New JArray() - End If - Catch jbex As Exception - End Try - If MFR_Response.value.GetType() = GetType(JArray) Then - Diagnostics.Debug.Print(Now.ToLongTimeString() & " - " & DirectCast(MFR_Response.value, JArray).Count & ":" & tgtDataset.Tables(Schema.Entitytablename).Rows.Count & "- this " & Strings.Right(MFR_Response.url, 10)) - For Each vi As JObject In MFR_Response.value - Dim vdic As Dictionary(Of String, Object) = vi.ToObject(Of Dictionary(Of String, Object)) - Dim etrow As DataRow = tgtDataset.Tables(Schema.Entitytablename).NewRow - etrow.Item("setid") = SetID - etrow.Item("Id") = vdic("Id") - For Each vkey As String In vdic.Keys - If IsNothing(vdic(vkey)) = False Then - If Schema.Complextypes.ContainsKey(vkey.ToLower) AndAlso Schema.Complextypes(vkey.ToLower)("name") <> "CustomValues" Then - Call StoreCP(tgtDataset, etrow, Schema.Complextypes, CP:=vdic(vkey), EntityProperty:=ThisEntityName & ":" & vkey, vkey:=vkey, setid:=SetID, vdic:=vdic) - ElseIf Schema.Complextypes.ContainsKey(vkey.ToLower) AndAlso Schema.Complextypes(vkey.ToLower)("name") = "CustomValues" Then - If etrow.Table.Columns.Contains(vkey) Then etrow.Item(vkey) = json.SerializeObject(vdic(vkey)) - ElseIf Schema.NavProperties.ContainsKey(vkey.ToLower) Then - Call StoreNP(tgtDataset, Schema.Complextypes, Schema.NavProperties(vkey.ToLower), NP:=vdic(vkey), EntityProperty:=ThisEntityName & ":" & vkey, setid:=SetID, vdic:=vdic) - Else - If etrow.Table.Columns.Contains(vkey) Then - If vdic(vkey).GetType() = GetType(System.DateTime) Then - If Year(vdic(vkey)) > 1900 Then etrow.Item(vkey) = vdic(vkey) - ElseIf vdic(vkey).GetType = etrow.Table.Columns(vkey).DataType Then - etrow.Item(vkey) = vdic(vkey) - ElseIf vdic(vkey).GetType = GetType(String) And vdic(vkey).GetType() <> etrow.Table.Columns(vkey).DataType Then - Try - etrow.Item(vkey) = DirectCast(vdic(vkey), System.String).TryConvert(etrow.Table.Columns(vkey).DataType) - Catch cgvex As Exception - Try - etrow.Item(vkey) = vdic(vkey) - Catch cvex As Exception - Diagnostics.Debug.Print(Now.ToLongTimeString() & " - " & "cvex inner " & cvex.Message) - End Try - End Try - Else - Try - etrow.Item(vkey) = vdic(vkey) - Catch cvex As Exception - Diagnostics.Debug.Print(Now.ToLongTimeString() & " - " & "cvex outer " & cvex.Message) - End Try - End If - End If - End If - End If - Next - tgtDataset.Tables(Schema.Entitytablename).Rows.Add(etrow) - tgtDataset.Tables(Schema.Entitytablename).AcceptChanges() - Next - Else - Diagnostics.Debug.Print(Now.ToLongTimeString() & " - " & " MFR_Response not jArray") - End If - If IsNothing(MFR_Response.nextlink) = False AndAlso MFR_Response.nextlink.ToString <> "" Then - MFR_Response = Await ReadOData(MFR_Response.nextlink.ToString) - Else - MFR_Response = Nothing - End If - - Loop - End If - Next iFilter - - Diagnostics.Debug.Print(Now.ToLongTimeString() & " - " & "Start SQL " & Schema.Entitytablename) - If isProcessed = True Then - For Each tbl As DataTable In tgtDataset.Tables - Dim trc As Integer = tbl.Rows.Count - If trc > 0 OrElse If(EntityID, New Long() {}).Length > 0 Then - Try - tbl.AcceptChanges() - Dim dtwa As New DatatableWriterAsync(tbl, FDSConnectionString) - dtwa.CommandAfterError = New SqlClient.SqlCommand("SELECT * INTO [t_" & SetID.ToLower & "_" & tbl.TableName & "] FROM " & dtwa.DestinationTableName & ";") - - dtwa.CommandAfter = New SqlClient.SqlCommand('"SELECT * INTO [t_" & SetID.ToLower & "_" & tbl.TableName & "] FROM " & dtwa.DestinationTableName & ";" & - "EXECUTE [dbo].[" & (tbl.TableName).Replace("__", "__updt__") & "] @tblname, @referencetable, @tgtid;" & - "EXECUTE [dbo].[fds__setStatus] @table,@action,@setid,@info;" & If(AdditionalCommandAfter, "")) - dtwa.CommandAfter.Parameters.AddRange(New SqlClient.SqlParameter() { - New SqlClient.SqlParameter("@tblname", dtwa.DestinationTableName), - New SqlClient.SqlParameter("@table", tbl.TableName), - New SqlClient.SqlParameter("@action", If(tbl.TableName.ToLower = Schema.Entitytablename.ToLower, "update_", "imdu_") & UpdateNeed.ToString().ToLower()), - New SqlClient.SqlParameter("@setid", SetID.ToLower), - New SqlClient.SqlParameter("@entityname", Schema.ThisEntityName), - New SqlClient.SqlParameter("@info", json.SerializeObject(New With {.count = trc, .reference = Schema.Entitytablename, .id = If(If(EntityID, New Long() {}).Length > 0, vbs.Join(EntityID.Convert(Of String)(Function(x As Long) x.ToString).ToArray, ","), Nothing)})), - New SqlClient.SqlParameter("@referencetable", Schema.Entitytablename), - New SqlClient.SqlParameter("@tgtid", If(If(EntityID, New Long() {}).Length > 0, EntityID(0).ToString, DBNull.Value)) - }) - Diagnostics.Debug.Print("tbs:" & tbl.TableName & " - " & dtwa.DestinationTableName & " - " & SetID.ToLower) - dtwa.DoSubmit() - Catch dsex As Exception - Dlg("Submission issue", dsex.Message, "table: " & tbl.TableName) - End Try - Diagnostics.Debug.Print("OK") - End If - Next - Diagnostics.Debug.Print(Now.ToLongTimeString() & " - " & "End SQL " & Schema.Entitytablename) - End If - End If - Catch ex As Exception - Dlg(ex.Message, "", ex.StackTrace) - Finally - 'release lock - params = New List(Of SqlClient.SqlParameter) From { - New SqlClient.SqlParameter("@tbl", ThisEntityName), - New SqlClient.SqlParameter("@state", False), - New SqlClient.SqlParameter("@override", False), - New SqlClient.SqlParameter("@setid", SetID) - } - Dim Exceptionmessages_gtl As String = "" - 'setSQLValue("EXECUTE [dbo].[ctm__admin_getTableLock] @tbl, @state, @override, @setid;", connectionstring:=FDSConnectionString, SqlParameterList:=params, ExceptionMessage:=Exceptionmessages_gtl) - If DebugDetails = True Then Call DebugToFile("Update__entitytable - locked released for " & ThisEntityName & "(" & SetID & ")", filename:="DebugDetail.txt") - End Try - Else - 'abort action if locked = true - Debug.Print("Updates already locked for " & ThisEntityName & "(" & SetID & ")") - If DebugDetails = True Then Call DebugToFile("Update__entitytable - Updates already locked For " & ThisEntityName & "(" & SetID & ")", filename:="DebugDetail.txt") - End If - Return True - End Function - - - - Private Function StoreCP(ByRef TgtDataset As DataSet, ByRef etrow As DataRow, Complextypes As Dictionary(Of String, Dictionary(Of String, String)), ByVal CP As Object, ByVal EntityProperty As String, ByVal vkey As String, ByVal setid As String, ByVal vdic As Dictionary(Of String, Object)) As Boolean - If CP.GetType = GetType(JArray) Then - For Each vitm As JObject In vdic(vkey) - Call StoreCP(TgtDataset, etrow, Complextypes, CP:=vitm, EntityProperty:=EntityProperty, vkey:=vkey, setid:=setid, vdic:=vdic) - Next - ElseIf CP.GetType = GetType(JObject) Then - Dim CxType As Dictionary(Of String, String) = Complextypes(vkey.ToLower) - Dim cto As Dictionary(Of String, Object) = CP.ToObject(Of Dictionary(Of String, Object)) - Dim cnr As DataRow = TgtDataset.Tables(CxType("tablename")).NewRow - cnr.Item("setid") = setid - For Each cky As String In cto.Keys - If IsNothing(cto(cky)) = False AndAlso cnr.Table.Columns.Contains(cky) Then - 'cnr.Item(cky) = cto(cky) - If cto(cky).GetType() = GetType(System.DateTime) Then - If Year(cto(cky)) > 1900 Then cnr.Item(cky) = cto(cky) - ElseIf cto(cky).GetType = cnr.Table.Columns(cky).DataType Then - cnr.Item(cky) = cto(cky) - ElseIf cto(cky).GetType = GetType(String) And cto(cky).GetType() <> cnr.Table.Columns(cky).DataType Then - Try - cnr.Item(cky) = DirectCast(cto(cky), System.String).TryConvert(cnr.Table.Columns(cky).DataType) - Catch cgvex As Exception - Try - cnr.Item(cky) = cto(cky) - Catch cvex As Exception - End Try - End Try - Else - Try - cnr.Item(cky) = cto(cky) - Catch cvex As Exception - End Try - End If - End If - Next - If cnr.Table.Columns.Contains("EntityId") Then cnr.Item("EntityId") = vdic("Id") - If cnr.Table.Columns.Contains("Property") Then cnr.Item("Property") = EntityProperty - TgtDataset.Tables(CxType("tablename")).Rows.Add(cnr) - If etrow.Table.Columns.Contains(vkey & "#ID") AndAlso cto.ContainsKey("id") Then etrow.Item(vkey & "#ID") = vdic("Id") - End If - - Return True - End Function - - Private Function StoreNP(ByRef TgtDataset As DataSet, Complextypes As Dictionary(Of String, Dictionary(Of String, String)), NavProp As Dictionary(Of String, String), ByVal NP As Object, ByVal EntityProperty As String, ByVal setid As String, ByVal vdic As Dictionary(Of String, Object)) As Boolean - If NP.GetType() = GetType(JArray) Then - For Each vitm As JObject In NP - Call StoreNP(TgtDataset:=TgtDataset, Complextypes:=Complextypes, NavProp:=NavProp, NP:=vitm, EntityProperty:=EntityProperty, setid:=setid, vdic:=vdic) - Next - ElseIf NP.GetType() = GetType(JObject) Then - Dim nto As Dictionary(Of String, Object) = NP.ToObject(Of Dictionary(Of String, Object)) - If nto.ContainsKey("Id") Then - Dim nnr As DataRow = TgtDataset.Tables(NavProp("countertable")).NewRow - Dim ncr As DataRow = TgtDataset.Tables(NavProp("tablename")).NewRow - nnr.Item("setid") = setid - For Each cky As String In nto.Keys - If IsNothing(nto(cky)) = False Then - If Complextypes.ContainsKey(cky.ToLower) AndAlso Complextypes(cky.ToLower)("name") <> "CustomValues" Then - Call StoreCP(TgtDataset:=TgtDataset, etrow:=nnr, Complextypes:=Complextypes, CP:=nto(cky), EntityProperty:=Complextypes(cky.ToLower)("EntityType") & ":" & cky, vkey:=cky, setid:=setid, vdic:=vdic) - Else - If IsNothing(nto(cky)) = False AndAlso nnr.Table.Columns.Contains(cky) Then - 'nnr.Item(cky) = nto(cky) - If nto(cky).GetType() = GetType(System.DateTime) Then - If Year(nto(cky)) > 1900 Then nnr.Item(cky) = nto(cky) - ElseIf nto(cky).GetType = nnr.Table.Columns(cky).DataType Then - nnr.Item(cky) = nto(cky) - ElseIf nto(cky).GetType = GetType(String) And nto(cky).GetType() <> nnr.Table.Columns(cky).DataType Then - Try - nnr.Item(cky) = DirectCast(nto(cky), System.String).TryConvert(nnr.Table.Columns(cky).DataType) - Catch cgvex As Exception - Try - nnr.Item(cky) = nto(cky) - Catch cvex As Exception - End Try - End Try - Else - Try - nnr.Item(cky) = nto(cky) - Catch cvex As Exception - End Try - End If - End If - End If - End If - Next - ncr.Item("EntityId") = vdic("Id") - ncr.Item("PartnerType") = NavProp("countertype") - ncr.Item("PartnerId") = nto("Id") - ncr.Item("Property") = EntityProperty - TgtDataset.Tables(NavProp("tablename")).Rows.Add(ncr) - TgtDataset.Tables(NavProp("countertable")).Rows.Add(nnr) - End If - End If - Return True - End Function - - Private Shared Function newDatatable_SQL(tablename As String) As String - Return System.String.Format("Select TOP(0) [setid] = CAST('' as varchar(50)), * FROM [dbo].[{0}];", tablename) - End Function - Private Async Function newDatatable(tablename As String, setid As String) As Task(Of DataTable) - Dim sqldt As SQLDataTable = Await getSQLDatatable_async(newDatatable_SQL(tablename:=tablename), SqlConnectionString:=FDSConnectionString, options:=New fds_SQLOptions()) - Dim dt As DataTable = sqldt.DataTable.Clone - dt.TableName = tablename - If dt.Columns.Contains("setid") = False Then dt.Columns.Add(New DataColumn("setid", GetType(System.String)) With {.MaxLength = 5}) - dt.Columns("setid").DefaultValue = setid - Return dt - End Function -#Enable Warning BC42356 ' This async method lacks 'Await' operators and so will run synchronously - - Public Async Function Update__Entitytables(Optional DebugDetails As Boolean = False, Optional tgtEntityType As Nullable(Of EntityTypes) = Nothing) As Threading.Tasks.Task - Dim UpdateTasks As New List(Of Threading.Tasks.Task) - - Dim DtF As New Action(Of String, String, String, Exception)(Sub(note As String, info As String, data As String, ex As Exception) - If DebugDetails = True Then Call DebugToFile("Update__AllEntitytables - " & note & If(If(info, "") <> "", ": " & info, ""), filename:="DebugDetail.txt", exc:=ex, data:=data) - End Sub) - Dim Dlg As New Action(Of String, String, String, Exception)(Sub(note As String, info As String, data As String, ex As Exception) - Dim str As String = "Update__AllEntitytables - " & note & If(If(info, "") <> "", ": " & info, "") - Call DebugLog(str, data:=If(data, ""), exc:=ex) - If DebugDetails = True Then Call DebugToFile(str, filename:="DebugDetail.txt", exc:=ex, data:=data) - Debug.Print(str) - End Sub) - - Try - 'get updateable tables - 'the SQL query returns all tables that have corresponding temp tables and update procedures - 'a lock status is included to determine if update processes are running - Dim UpdateableTables As SQLDataTable = Await getSQLDatatable_async("SELECT * FROM [dbo].[fds__getUpdateableTables]()" & If(tgtEntityType.HasValue, " WHERE [entity_name] = '" & tgtEntityType.Value.ToString & "'", "") & ";", FDSConnectionString, options:=New fds_SQLOptions()) - Call DtF("UpdateableTables ", UpdateableTables.Exception, "(" & If(UpdateableTables.Count > 0, UpdateableTables.DataTable.Rows.Count.ToString, " no") & " Rows)", Nothing) - - If UpdateableTables.Count > 0 AndAlso UpdateableTables.DataTable.Columns.Contains("updateneed") = True Then 'just to avoid exceptions in next steps - For Each UpdateableTable_rw As DataRow In UpdateableTables.Select("updateneed > 0", "updateneed DESC") - Dim etname As String = UpdateableTable_rw.nz("entity_name", "") - Try 'create capsule for each cycle to prevent everything fails if anything fails - If etname = "" Then - Call DtF("no entity_name received", "", json.SerializeObject(UpdateableTable_rw), Nothing) - ElseIf UpdateableTable_rw.nbool("locked", True) = False Then - Dim Tbl_UpdateNeed As UpdateNeed = UpdateableTable_rw.nint("updateneed", 0) - Dim et As generic.EntityTypes = _generic.EntityValue(etname) - If Not et = EntityTypes.none Then - Call DtF("updating: " & etname, "", json.SerializeObject(UpdateableTable_rw), Nothing) - - Await Update__entitytable(et, UpdateNeed:=Tbl_UpdateNeed, EntityID:=Nothing, DebugDetails:=DebugDetails) - Call DtF("updating task completed", "", "", Nothing) - Else - Call DtF("entitytype not known", "", json.SerializeObject(New With {.etname = etname}), Nothing) - End If - Else - Call DtF("Table update locked" & etname, "", json.SerializeObject(UpdateableTable_rw), Nothing) - End If - Catch tableupdate_ex As Exception - Call Dlg("updatepart failed - " & etname, "", json.SerializeObject(UpdateableTable_rw), tableupdate_ex) - End Try - Next UpdateableTable_rw - End If - Catch exa As Exception - Call Dlg("outer frame", "", "", Nothing) - End Try - End Function - Public Async Function Update__EntityRequests(Optional DebugDetails As Boolean = False) As Threading.Tasks.Task - Dim UpdateTasks As New List(Of Threading.Tasks.Task) - - Dim DtF As New Action(Of String, String, String, Exception)(Sub(note As String, info As String, data As String, ex As Exception) - If DebugDetails = True Then Call DebugToFile("Update__EntityRequests - " & note & If(If(info, "") <> "", ": " & info, ""), filename:="DebugDetail.txt", exc:=ex, data:=data) - End Sub) - Dim Dlg As New Action(Of String, String, String, Exception)(Sub(note As String, info As String, data As String, ex As Exception) - Dim str As String = "Update__EntityRequests - " & note & If(If(info, "") <> "", ": " & info, "") - Call DebugLog(str, data:=If(data, ""), exc:=ex) - If DebugDetails = True Then Call DebugToFile(str, filename:="DebugDetail.txt", exc:=ex, data:=data) - Debug.Print(str) - End Sub) - - Try - 'get updateable tables - 'the SQL query returns all tables that have corresponding temp tables and update procedures - 'a lock status is included to determine if update processes are running - Dim UpdateableRequests As SQLDataTable = Await getSQLDatatable_async("SELECT * FROM [dbo].[fds__getUpdateableRequests]();", FDSConnectionString, options:=New fds_SQLOptions()) - Call DtF("UpdateableRequests ", UpdateableRequests.Exception, "(" & If(UpdateableRequests.Count > 0, UpdateableRequests.DataTable.Rows.Count.ToString, " no") & " Rows)", Nothing) - - If UpdateableRequests.Count > 0 Then 'just to avoid exceptions in next steps - For Each UpdateableRequest_rw As DataRow In UpdateableRequests.Select("", "order") - Dim etname As String = UpdateableRequest_rw.nz("entity_name", "") - Dim tgtid As Long = UpdateableRequest_rw.nint("Id", -1) - If tgtid > -1 AndAlso etname.IsNullOrWhiteSpace = False Then - Try 'create capsule for each cycle to prevent everything fails if anything fails - Dim et As generic.EntityTypes = _generic.EntityValue(etname) - Await Update__entitytable(et, UpdateNeed:=UpdateNeed.Reset, EntityID:=New Long() {tgtid}, DebugDetails:=DebugDetails, AdditionalCommandAfter:="DELETE FROM [dbo].[fds__mfr_updaterequests] WHERE LOWER([entity_name]) = LOWER(ISNULL(@entityname,'')) AND CAST(ISNULL([Id],'') as varchar(1000)) = @tgtid;") - - Catch tableupdate_ex As Exception - Call Dlg("Update__EntityRequest single failed - " & etname, "", json.SerializeObject(UpdateableRequest_rw), tableupdate_ex) - End Try - End If - Next UpdateableRequest_rw - End If - Catch exa As Exception - Call Dlg("outer frame", "", "", Nothing) - End Try - End Function - - Public Enum PostSubmissionActionMode - full - incremental - reset - End Enum - - - - Public Sub Dispose() Implements IDisposable.Dispose - ''Me.MFRClient.Logout() - DirectCast(Me.MFRClient, IDisposable).Dispose() - End Sub - - - - - End Class - -End Namespace \ No newline at end of file diff --git a/DataService_Legacy/fds_shared.vb b/DataService_Legacy/fds_shared.vb deleted file mode 100644 index c12d49e..0000000 --- a/DataService_Legacy/fds_shared.vb +++ /dev/null @@ -1,226 +0,0 @@ - - -Friend Module fds_shared - - Friend Function SQLConnectionString() As String - Return Configuration.ConfigurationManager.ConnectionStrings("fuchs_ConnectionString").ConnectionString - End Function - Friend Function FDSConnectionString() As String - Return Configuration.ConfigurationManager.ConnectionStrings("fuchs_fds_ConnectionString").ConnectionString - End Function - Friend Function SqlCon() As SqlClient.SqlConnection - Return New SqlClient.SqlConnection(Configuration.ConfigurationManager.ConnectionStrings("fuchs_ConnectionString").ConnectionString) - End Function - - - - Public Function RandomString(rs_length As Byte) As String - Dim r As New Random() - Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" - Dim sb As New Text.StringBuilder - For i As Byte = 1 To rs_length - Dim idx As Integer = r.Next(0, s.Length) - sb.Append(s.Substring(idx, 1)) - Next - Return sb.ToString() - End Function - - - ''''…
`, `
and ILoggerFactory are supplied by the ASP.NET Core DI container
builder.Services.AddSingleton();
+ // In-process MFR ERP sync — formerly the standalone Fuchs_DataService Windows Service
+ // (Topshelf), now hosted here as a BackgroundService. Gated by Fds:SyncEnabled so
+ // developer machines (appsettings.Development.json sets it false) never poll the ERP;
+ // interval and debug verbosity come from the Fds config section.
+ if (builder.Configuration.GetValue("Fds:SyncEnabled", false))
+ {
+ builder.Services.AddHostedService(sp =>
+ {
+ var mfr = sp.GetRequiredService();
+ var interval = TimeSpan.FromMinutes(
+ builder.Configuration.GetValue("Fds:ExecutionFrequency_Minutes", 15d));
+ bool debug = builder.Configuration.GetValue("Fds:DebugDetails", false);
+ var jobs = new[]
+ {
+ new PeriodicJobDefinition("MfrSync", interval, async ct =>
+ {
+ await mfr.UpdateIfNecessary_async(debug, ct);
+ await mfr.UpdateRequested_async(debug, ct);
+ await mfr.GetInvoiceFiles_async(debug, ct);
+ })
+ };
+ return new PeriodicHostedService(jobs, sp.GetRequiredService>());
+ });
+ }
+
// MVC with Razor view support
builder.Services.AddControllersWithViews();
builder.Services.AddSignalR();
diff --git a/Fuchs/Properties/PublishProfiles/FolderProfile.pubxml b/Fuchs/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 0000000..57fab78
--- /dev/null
+++ b/Fuchs/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,20 @@
+
+
+
+
+ true
+ false
+ true
+ Release
+ x64
+ FileSystem
+ Q:\PWProjects\Fuchs_Intranet
+ FileSystem
+ <_TargetId>Folder
+
+ net10.0
+ win-x64
+ 2856176d-cda6-1be2-0ce0-d72c26fb4f35
+ false
+
+
\ No newline at end of file
diff --git a/Fuchs/Services/InvoiceDraftEditService.cs b/Fuchs/Services/InvoiceDraftEditService.cs
index c4ba38e..b1be176 100644
--- a/Fuchs/Services/InvoiceDraftEditService.cs
+++ b/Fuchs/Services/InvoiceDraftEditService.cs
@@ -116,6 +116,9 @@ public sealed class InvoiceDraftEditService : IInvoiceDraftService
case "block.replace": return ReplaceBlock(s, d, ref oldValue, ref newValue);
case "block.remove": return RemoveBlock(s, d, ref oldValue, ref newValue);
case "block.order": return ReorderBlocks(s, d, ref oldValue, ref newValue);
+ case "item.setprice": return ApplyItemSetPrice(s, d, ref oldValue, ref newValue);
+ case "block.setprice": return ApplyBlockSetPricing(s, removeMembers: false, ref oldValue, ref newValue);
+ case "block.setonly": return ApplyBlockSetPricing(s, removeMembers: true, ref oldValue, ref newValue);
default: return false;
}
}
@@ -185,6 +188,183 @@ public sealed class InvoiceDraftEditService : IInvoiceDraftService
return true;
}
+ ///
+ /// "Auf Setpreis umstellen" (backend-authoritative, ADR 0006): irreversibly converts a Set
+ /// header item (Ref = the header's item id) from individually-priced members to a
+ /// single set price. Sums the net /net_val /vat_val /svcnet_val /
+ /// svcvat_val of every member line in the same block whose SetItmId equals the
+ /// header id (the grouping fds__prepInvoice computes, anchored on the still-unconverted,
+ /// zero-priced Set header — see the [SetItmID] window function there), writes that sum
+ /// onto the header line and zeroes each member's price fields — matching the visual
+ /// SetPrice display mode ( ), but as an actual, irreversible
+ /// data change rather than a display toggle. The user can still change the resulting header price
+ /// manually afterwards (ordinary item edit), which is why this is one-way.
+ ///
+ /// The header row's own SetItmId now self-references its own id (rather than being
+ /// null ) once fds__prepInvoice stopped special-casing it, so membership is
+ /// determined by id == Ref first (captured as below and
+ /// continue d past) — a header is never mistaken for its own member.
+ ///
+ ///
+ private static bool ApplyItemSetPrice(InvoiceDraftSession s, InvoiceDraftDelta d, ref string oldValue, ref string newValue)
+ {
+ if (string.IsNullOrEmpty(d.Ref)) return false;
+ foreach (var blockTok in s.Req)
+ {
+ if (blockTok is not JObject block || block["itm"] is not JArray lines) continue;
+ JObject? header = null;
+ var members = new List();
+ foreach (var lineTok in lines)
+ {
+ if (lineTok is not JObject co) continue;
+ if (Str(co["id"]) == d.Ref) { header = co; continue; } // the header itself is never a member, even if its SetItmId self-references
+ if (Str(co["SetItmId"]) == d.Ref) members.Add(co);
+ }
+ if (header == null) continue;
+ if (!string.Equals(Str(header["typ"]), "set", StringComparison.OrdinalIgnoreCase)) return false;
+
+ oldValue = InvoiceDraftCalculator.Dec(header["vt"]).ToString(CultureInfo.InvariantCulture);
+ decimal sumNet = 0, sumVat = 0, sumSvcNet = 0, sumSvcVat = 0;
+ foreach (var m in members)
+ {
+ sumNet += InvoiceDraftCalculator.Dec(m["vt"]);
+ sumVat += InvoiceDraftCalculator.Dec(m["vv"]);
+ sumSvcNet += InvoiceDraftCalculator.Dec(m["vs"]);
+ sumSvcVat += InvoiceDraftCalculator.Dec(m["vsv"]);
+ NullLinePrice(m); // ADR 0009: null (empty cell), not 0 — excluded from the sum, distinct from a real 0,00 €
+ }
+ header["v"] = sumNet; header["vt"] = sumNet; header["vv"] = sumVat; header["vs"] = sumSvcNet; header["vsv"] = sumSvcVat;
+ newValue = sumNet.ToString(CultureInfo.InvariantCulture);
+
+ // Mirror the conversion onto the "items" contract shape (InvoiceSetPricing/BuildSetDisplay
+ // read total_net from here, not from "itm") so the online editor's set-display immediately
+ // reflects that the set is now converted, instead of waiting for a reload.
+ if (block["items"] is JArray items)
+ {
+ foreach (var itemTok in items)
+ {
+ if (itemTok is not JObject io) continue;
+ string id = Str(io["id"]);
+ if (id == d.Ref) { io["total_net"] = sumNet; }
+ else if (members.Any(m => Str(m["id"]) == id)) { NullItemPrice(io); }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// The two menu set-price modes (ADR 0009), grouped by service-request block
+ /// (not SetItmId ) and applied server-side as an irreversible mutation of the
+ /// cached session — never a display flag. For every block that carries any priced line:
+ /// a dedicated, emphasised set row (typ == "set" ) is inserted at the top carrying the
+ /// block's aggregated value (net + VAT + service-net/-VAT splits); then the block's original
+ /// items are either price-nulled ( = false → "Set mit
+ /// Preis": empty price cells, kept) or removed ( = true →
+ /// "Nur Set mit Preis"). null (not 0 ) marks "no price" — an empty cell excluded
+ /// from the sum, distinct from a genuine 0,00 €. Any pre-existing set membership is neutralised
+ /// (existing set rows demoted, setId /SetItmId cleared) so the block becomes one
+ /// flat set and the two groupings (this vs. the SetItmId -based item switch) never collide.
+ /// The invoice total is conserved: the set row's value equals the sum of the members it blanks
+ /// or removes.
+ ///
+ private static bool ApplyBlockSetPricing(InvoiceDraftSession s, bool removeMembers, ref string oldValue, ref string newValue)
+ {
+ bool mutated = false;
+ int converted = 0;
+ foreach (var blockTok in s.Req)
+ {
+ if (blockTok is not JObject block || block["itm"] is not JArray lines || lines.Count == 0) continue;
+
+ // Aggregate the block from its current line values (nulled/absent = 0 contribution).
+ decimal net = 0, vat = 0, svcNet = 0, svcVat = 0;
+ string rate = "";
+ foreach (var lineTok in lines)
+ {
+ if (lineTok is not JObject co) continue;
+ net += InvoiceDraftCalculator.Dec(co["vt"]);
+ vat += InvoiceDraftCalculator.Dec(co["vv"]);
+ svcNet += InvoiceDraftCalculator.Dec(co["vs"]);
+ svcVat += InvoiceDraftCalculator.Dec(co["vsv"]);
+ string r = InvoiceDraftCalculator.NormalizeRate(Str(co["vat"]));
+ if (r.Length > 0) rate = r; // collapsed set line carries the block's (highest/last) rate
+ }
+ if (net == 0 && vat == 0 && svcNet == 0 && svcVat == 0) continue; // nothing priced -> skip block
+
+ string blockId = Str(block["Id"]);
+ string setId = "bset_" + (blockId.Length > 0 ? blockId : Guid.NewGuid().ToString("N")[..8]);
+ const string title = "Gesamtumfang pauschal"; // neutral label for the block set row (ADR 0009) — not the service-request title
+
+ // The dedicated, emphasised set row, in both line shapes (itm = editor co; items = contract).
+ var setItm = new JObject
+ {
+ ["id"] = setId, ["typ"] = "set", ["p"] = "", ["q"] = "", ["t"] = title, ["tt"] = "",
+ ["v"] = JValue.CreateNull(), ["vt"] = net, ["vv"] = vat, ["vs"] = svcNet, ["vsv"] = svcVat,
+ ["vat"] = rate, ["det"] = false
+ };
+ var setItem = new JObject
+ {
+ ["id"] = setId, ["type"] = "set", ["title"] = title, ["desc"] = "", ["qty"] = "",
+ ["price_net"] = net, ["total_net"] = net, ["vat"] = rate, ["setId"] = JValue.CreateNull()
+ };
+
+ // Mutate the itm array in place (avoids Newtonsoft re-parenting): drop members (setonly)
+ // or null their prices + neutralise set membership (setprice), then prepend the set row.
+ if (removeMembers) lines.Clear();
+ else
+ foreach (var lineTok in lines)
+ {
+ if (lineTok is not JObject co) continue;
+ DemoteSet(co, "typ"); co["SetItmId"] = JValue.CreateNull();
+ NullLinePrice(co);
+ }
+ lines.Insert(0, setItm);
+
+ if (block["items"] is JArray items)
+ {
+ if (removeMembers) items.Clear();
+ else
+ foreach (var itemTok in items)
+ {
+ if (itemTok is not JObject io) continue;
+ DemoteSet(io, "type"); io["setId"] = JValue.CreateNull();
+ NullItemPrice(io);
+ }
+ items.Insert(0, setItem);
+ }
+ else
+ {
+ block["items"] = new JArray { setItem };
+ }
+
+ mutated = true; converted++;
+ }
+ oldValue = "";
+ newValue = (removeMembers ? "setonly" : "setprice") + ":" + converted;
+ return mutated;
+ }
+
+ /// Demotes a pre-existing set row to a plain line so only the freshly inserted block set row stays "set".
+ private static void DemoteSet(JObject line, string typeKey)
+ {
+ if (line[typeKey] is { } t && string.Equals(Str(t), "set", StringComparison.OrdinalIgnoreCase))
+ line[typeKey] = "other";
+ }
+
+ /// Sets the editor co price fields to JSON null (empty cell, excluded from sums — ADR 0009).
+ private static void NullLinePrice(JObject co)
+ {
+ co["v"] = JValue.CreateNull(); co["vt"] = JValue.CreateNull(); co["vv"] = JValue.CreateNull();
+ co["vs"] = JValue.CreateNull(); co["vsv"] = JValue.CreateNull();
+ }
+
+ /// Sets the items-contract price fields to JSON null (empty cell — ADR 0009).
+ private static void NullItemPrice(JObject io)
+ {
+ io["price_net"] = JValue.CreateNull(); io["total_net"] = JValue.CreateNull();
+ }
+
///
/// Reorders the service-request blocks to the id sequence the editor posts after a section
/// drag (Value = ["id",…]). Named ids move into the given order; any not named are kept
@@ -269,7 +449,9 @@ public sealed class InvoiceDraftEditService : IInvoiceDraftService
{
if (blockTok is not JObject block || block["items"] is not JArray itemsArr) continue;
List>? items = itemsArr.ToObject>>();
- if (items == null || !InvoiceSetPricing.ContainsSets(items)) continue;
+ // Only function-1 (SetItmId-linked) sets get display flags; block-mode sets (ADR 0009)
+ // clear setId and render flat, so BuildSetDisplay must not sweep them into Build here.
+ if (items == null || !InvoiceSetPricing.HasSetMembers(items)) continue;
foreach (var line in InvoiceSetPricing.Build(items, mode))
{
@@ -331,6 +513,7 @@ public sealed class InvoiceDraftEditService : IInvoiceDraftService
// ── Internals ──────────────────────────────────────────────────────────────
private static void Refresh(InvoiceDraftSession session)
{
+ InvoiceDraftCalculator.RecomputeLineValues(session);
InvoiceDraftCalculator.RecomputeTotals(session);
InvoiceDraftCalculator.RecomputePositions(session);
InvoiceDraftCalculator.Validate(session);
@@ -430,7 +613,7 @@ public sealed class InvoiceDraftEditService : IInvoiceDraftService
string setmode = Str(session.Admin["setmode"]).Trim().ToLowerInvariant();
// Mirrors FdsInvoiceData.BuildInvoiceOptions: persist any explicitly-chosen mode
// (including the default "setprice") so it is distinguishable from "never touched".
- if (setmode is "setprice" or "itemprices" or "setonly") tokens.Add("setmode:" + setmode);
+ if (setmode is "setprice" or "setonly") tokens.Add("setmode:" + setmode);
return string.Join(",", tokens);
}
diff --git a/Fuchs_DataService/PeriodicHostedService.cs b/Fuchs/Services/PeriodicHostedService.cs
similarity index 86%
rename from Fuchs_DataService/PeriodicHostedService.cs
rename to Fuchs/Services/PeriodicHostedService.cs
index 445588f..2a35d31 100644
--- a/Fuchs_DataService/PeriodicHostedService.cs
+++ b/Fuchs/Services/PeriodicHostedService.cs
@@ -1,7 +1,7 @@
-using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
-namespace fds;
+namespace Fuchs.Services;
///
/// Defines a named job with its own execution schedule for use with .
@@ -13,6 +13,8 @@ public sealed record PeriodicJobDefinition(
///
/// A that runs multiple independent jobs, each on its own .
+/// Hosts the MFR ERP sync that formerly ran as the standalone Fuchs_DataService Windows Service
+/// (Topshelf); it is now registered in-process from Program.cs , gated by Fds:SyncEnabled .
///
public sealed class PeriodicHostedService : BackgroundService
{
diff --git a/Fuchs/Views/Shared/_Layout.cshtml b/Fuchs/Views/Shared/_Layout.cshtml
index 754296b..8be0e95 100644
--- a/Fuchs/Views/Shared/_Layout.cshtml
+++ b/Fuchs/Views/Shared/_Layout.cshtml
@@ -19,6 +19,10 @@
string appName = ViewData["AppName"] as string ?? "Fuchs Intranet";
string fullName = ViewData["FullName"] as string ?? "";
string pageTitle = ViewData["Title"] as string ?? "Intranet";
+ // When the deployment is flagged as a test/staging instance (Fuchs:IsTestDeployment = true),
+ // a distinctive green background is injected below so a test instance is never mistaken for
+ // production. Defaults to false (production) in appsettings.json.
+ bool isTestDeployment = Configuration.GetValue("Fuchs:IsTestDeployment");
string? debugDbTarget = null;
if (HostEnvironment.IsDevelopment())
{
@@ -56,6 +60,15 @@
@await RenderSectionAsync("CustomHeader", required: false)
+ @if (isTestDeployment)
+ {
+
+ }
+
diff --git a/Fuchs/appsettings.Development.json b/Fuchs/appsettings.Development.json
index 05befc1..cbc124c 100644
--- a/Fuchs/appsettings.Development.json
+++ b/Fuchs/appsettings.Development.json
@@ -39,6 +39,9 @@
}
},
"Fds": {
+ "SyncEnabled": false,
+ "ExecutionFrequency_Minutes": 15,
+ "DebugDetails": true,
"MFR_host": "portal.mobilefieldreport.com",
"MFR_UserName": "system@sebastian-fuchs---bad-und-heizung-gmbh-und-co-kg.com",
"MFR_Password": "0oT4G3H2"
diff --git a/Fuchs/appsettings.json b/Fuchs/appsettings.json
index d158d8b..1efe820 100644
--- a/Fuchs/appsettings.json
+++ b/Fuchs/appsettings.json
@@ -32,6 +32,7 @@
"AzureBlobStorage_ConnectionString": "MANAGED_BY_KEYVAULT"
},
"Fuchs": {
+ "IsTestDeployment": true,
"ocms_guid": "00094b8f-a822-4e9c-b627-87802f93fca8",
"ocms_valid_locales_csv": "de,en",
"ocms_default_locale": "de",
@@ -48,7 +49,7 @@
"Enabled": false
},
"Email": {
- "OverrideRecipient": ""
+ "OverrideRecipient": "info@processweb.de"
},
"StartupChecks": {
"Enabled": false,
@@ -60,9 +61,9 @@
"StartupEmailRecipientName": "Startup Monitor"
},
"AzureStorage": {
- "Enabled": false,
- "InvoiceContainer": "fuchs-invoices",
- "ReminderContainer": "fuchs-reminders",
+ "Enabled": true,
+ "InvoiceContainer": "dev-fuchs-invoices",
+ "ReminderContainer": "dev-fuchs-reminders",
"MetadataFields": [ "Id", "Version", "InvoiceId", "InvoiceTitle", "InvId", "DocumentName", "file_guid" ]
},
"Telemetry": {
@@ -71,6 +72,9 @@
}
},
"Fds": {
+ "SyncEnabled": true,
+ "ExecutionFrequency_Minutes": 15,
+ "DebugDetails": false,
"MFR_host": "portal.mobilefieldreport.com",
"MFR_UserName": "MANAGED_BY_KEYVAULT",
"MFR_Password": "MANAGED_BY_KEYVAULT"
diff --git a/Fuchs/code/7z.dll b/Fuchs/code/7z.dll
deleted file mode 100644
index b32d7bf..0000000
Binary files a/Fuchs/code/7z.dll and /dev/null differ
diff --git a/Fuchs/code/FdsInvoiceData.cs b/Fuchs/code/FdsInvoiceData.cs
index b7c1bc9..30cbc49 100644
--- a/Fuchs/code/FdsInvoiceData.cs
+++ b/Fuchs/code/FdsInvoiceData.cs
@@ -175,7 +175,7 @@ public class FdsInvoiceData
// explicit user choice of the default is indistinguishable from an invoice that was never
// switched to set-pricing at all (needed so the editor can hide the "Set-Preisanzeige"
// menu entry once a mode has been chosen; see InvoiceDraftEditService.BuildInvoiceOptions).
- if (setmode is "setprice" or "itemprices" or "setonly") tokens.Add("setmode:" + setmode);
+ if (setmode is "setprice" or "setonly") tokens.Add("setmode:" + setmode);
return string.Join(",", tokens);
}
diff --git a/Fuchs/code/FuchsPdf.cs b/Fuchs/code/FuchsPdf.cs
index a2121e9..d42d29c 100644
--- a/Fuchs/code/FuchsPdf.cs
+++ b/Fuchs/code/FuchsPdf.cs
@@ -168,6 +168,9 @@ public static class FuchsPdf
bool isText = type is "text" or "title";
ParseDec(i.no("price_net", 0), out decimal price);
ParseDec(i.no("total_net", 0), out decimal total);
+ // ADR 0009: a null/absent total_net means "no price" — render an empty cell (not 0,00 €),
+ // distinct from a genuine 0. This is how block-mode (Set mit Preis) nulled members print.
+ bool hasPrice = i.TryGetValue("total_net", out var tv) && tv != null;
return new InvoiceSetLine
{
Title = i.nz("title", ""),
@@ -175,7 +178,8 @@ public static class FuchsPdf
Qty = i.nz("qty", ""),
PriceNet = price,
TotalNet = total,
- ShowPrice = !isText,
+ ShowPrice = !isText && hasPrice,
+ Numbered = !isText, // numbered like the editor: every line except free-text/heading, even price-blanked set members
IsSetHeader = type == "set"
};
}
@@ -764,8 +768,8 @@ public static class FuchsPdf
// Each section prints its heading; positions are numbered the same way the editor numbers
// them (every line except free-text/heading lines, including a set header). The chosen
// set-display mode (see INVOICE_SET_PRICING.md) governs how "set" items and their members
- // are shown: SetPrice (default) prices the set, blanks members; ItemPrices prices the
- // members, blanks the set heading; SetOnly prices the set and drops the members entirely.
+ // are shown: SetPrice (default) prices the set, blanks members; SetOnly prices the set
+ // and drops the members entirely.
// Blocks without any set items are unaffected and always render flat.
var setMode = InvoiceSetPricing.ModeFromInvoiceOptions(inv.InvoiceRegistration?.getString("InvoiceOptions"));
int pos = 0;
@@ -779,13 +783,16 @@ public static class FuchsPdf
hr.Cells[1].AddParagraph().WithStyle("TblCell_RTitle").AddFormattedText(block.Heading, TextFormat.Bold);
}
- var lines = InvoiceSetPricing.ContainsSets(block.Items)
+ // Function-1 (SetItmId-linked) sets still collapse via Build; block-mode sets (ADR 0009)
+ // and plain blocks render flat — their set row is emphasised on its own and nulled
+ // members map to blank cells (see MapItemToLine).
+ var lines = InvoiceSetPricing.HasSetMembers(block.Items)
? InvoiceSetPricing.Build(block.Items, setMode)
- : block.Items.Select(MapItemToLine).ToList(); // no sets: flat, faithful mirror of the editor
+ : block.Items.Select(MapItemToLine).ToList();
foreach (var line in lines)
{
- bool numbered = line.IsSetHeader || line.ShowPrice; // free-text/heading lines carry no number
+ bool numbered = line.Numbered; // every line except free-text/heading (mirrors the editor's RecomputePositions), even price-blanked set members
var row = tbl.AddRow();
row.HeightRule = RowHeightRule.Auto;
row.Cells[0].AddParagraph(numbered ? (++pos).ToString() : "").Style = "TblCell_Base";
diff --git a/Fuchs/code/InvoiceDraftCalculator.cs b/Fuchs/code/InvoiceDraftCalculator.cs
index 357928b..9cdc653 100644
--- a/Fuchs/code/InvoiceDraftCalculator.cs
+++ b/Fuchs/code/InvoiceDraftCalculator.cs
@@ -1,4 +1,4 @@
-using System.Globalization;
+using System.Globalization;
using Newtonsoft.Json.Linq;
namespace Fuchs.intranet;
@@ -16,6 +16,45 @@ namespace Fuchs.intranet;
///
public static class InvoiceDraftCalculator
{
+ ///
+ /// Recomputes every line's own net/VAT/service values from its raw quantity (qn ),
+ /// unit price (v ) and VAT rate (vat ) — the authoritative, server-side port of
+ /// the former client-side quantChange /setVat multiplication (ADR 0006/0008: the
+ /// online editor performs no arithmetic at all, not even a single line's net = qty × price).
+ /// Only lines that actually carry a raw quantity and a positive unit price are recomputed
+ /// (mirrors quantChange 's own guard); lines without both (headings, free text,
+ /// combined-sum rows, and set members that have been zeroed by
+ /// 's "Auf Setpreis umstellen" conversion)
+ /// keep whatever value they already carry, so a set header's synthesised sum is never
+ /// clobbered by a subsequent recompute.
+ ///
+ public static void RecomputeLineValues(InvoiceDraftSession session)
+ {
+ foreach (var blockTok in session.Req)
+ {
+ if (blockTok is not JObject block || block["itm"] is not JArray lines) continue;
+ foreach (var lineTok in lines)
+ {
+ if (lineTok is not JObject co) continue;
+ decimal qty = Dec(co["qn"]);
+ decimal price = Dec(co["v"]);
+ if (qty <= 0 || price <= 0) continue; // no raw qty/price posted -> leave the value as delivered
+
+ string rate = NormalizeRate(Str(co["vat"]));
+ decimal vatFactor = rate.Length > 0 && decimal.TryParse(rate, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal r)
+ ? r / 100m : 0m;
+ decimal netVal = Math.Round(qty * price, 2, MidpointRounding.AwayFromZero);
+ decimal vatVal = Math.Round(netVal * vatFactor, 2, MidpointRounding.AwayFromZero);
+
+ co["vt"] = netVal;
+ co["vv"] = vatVal;
+ bool isService = string.Equals(Str(co["typ"]), "Service", StringComparison.OrdinalIgnoreCase);
+ co["vs"] = isService ? netVal : 0;
+ co["vsv"] = isService ? vatVal : 0;
+ }
+ }
+ }
+
///
/// Aggregates every block's line values into the draft's totals — the port of
/// invSumUpdate 's csms accumulation plus §13b (VAT suppressed → gross = net).
diff --git a/Fuchs/code/InvoiceSetPricing.cs b/Fuchs/code/InvoiceSetPricing.cs
index c8d993f..fd3e345 100644
--- a/Fuchs/code/InvoiceSetPricing.cs
+++ b/Fuchs/code/InvoiceSetPricing.cs
@@ -13,8 +13,6 @@ public enum SetDisplayMode
{
/// Default: show the set as one priced line; member items listed without price.
SetPrice,
- /// Show each member item with its own price; the set line is a header without price.
- ItemPrices,
/// Show only the set as one priced line; member items are removed entirely.
SetOnly
}
@@ -32,6 +30,14 @@ public sealed class InvoiceSetLine
public decimal TotalNet { get; init; }
/// When false, the price/total cells are rendered blank (e.g. set members in SetPrice mode).
public bool ShowPrice { get; init; } = true;
+ ///
+ /// Whether this line carries a position number. Mirrors the editor's numbering
+ /// (InvoiceDraftCalculator.RecomputePositions ): every line is numbered except
+ /// free-text/heading lines — independent of whether a price is shown, so a price-blanked set
+ /// member (SetPrice mode / block-mode nulled member) is still numbered exactly like in the
+ /// online editor.
+ ///
+ public bool Numbered { get; init; } = true;
/// True for the set header line (rendered emphasised).
public bool IsSetHeader { get; init; }
}
@@ -43,17 +49,24 @@ public sealed class InvoiceSetLine
/// header's id . Items that belong to no set pass through unchanged.
///
/// The invoice total is taken from the registration balance, not from these
-/// lines, so switching modes is purely presentational and never changes the
-/// invoice sum — set price always equals the sum of its members.
+/// lines, so calling is a pure, non-mutating transformation
+/// of the items it is given and never changes the invoice sum. A set header
+/// only adopts the chosen once it has actually been
+/// converted (its own total_net is non-zero, via the one-way set-item
+/// switch, InvoiceDraftEditService.ApplyItemSetPrice ) — until then the
+/// header renders blank and each member keeps its own individual price, exactly
+/// like a non-set item. (The choice of which mode to apply is itself a
+/// persisted, effectively one-way decision on the draft session — see
+/// Fuchs/Docs/INVOICE_SET_PRICING.md — but that persistence lives outside
+/// this class.)
///
public static class InvoiceSetPricing
{
public static SetDisplayMode ParseMode(string? raw) =>
(raw ?? "").Trim().ToLowerInvariant() switch
{
- "itemprices" or "items" or "item" => SetDisplayMode.ItemPrices,
- "setonly" or "set_only" => SetDisplayMode.SetOnly,
- _ => SetDisplayMode.SetPrice
+ "setonly" or "set_only" => SetDisplayMode.SetOnly,
+ _ => SetDisplayMode.SetPrice
};
/// Reads the set mode from an InvoiceOptions CSV token like "setmode:itemprices".
@@ -71,9 +84,21 @@ public static class InvoiceSetPricing
public static bool ContainsSets(IEnumerable> items) =>
items.Any(IsSetHeader) || items.Any(i => !string.IsNullOrEmpty(SetIdOf(i)));
+ ///
+ /// True if the block carries a SetItmId -linked set (a member points at a header via
+ /// setId ) — i.e. the function-1 "set-item switch" grouping. This is the only case that
+ /// still routes through ; the two menu modes (ADR 0009) clear setId
+ /// and render flat (their inserted set row is emphasised on its own, members null out to blank).
+ ///
+ public static bool HasSetMembers(IEnumerable> items) =>
+ items.Any(i => !string.IsNullOrEmpty(SetIdOf(i)));
+
///
/// Produces the ordered display lines for the given items and mode.
- /// Standalone items are always shown with their price.
+ /// Standalone items are always shown with their price. A set header whose
+ /// own total_net is still zero (not yet converted via the set-item
+ /// switch) is rendered blank with its members individually priced,
+ /// regardless of .
///
public static List Build(IReadOnlyList> items, SetDisplayMode mode)
{
@@ -90,22 +115,29 @@ public static class InvoiceSetPricing
{
if (IsSetHeader(item))
{
- string setId = HeaderIdOf(item);
- var members = membersBySet.TryGetValue(setId, out var m) ? m : new List>();
- decimal setTot = HeaderTotal(item, members);
+ string setId = HeaderIdOf(item);
+ var members = membersBySet.TryGetValue(setId, out var m) ? m : new List>();
+ FuchsPdf.ParseDec(item.no("total_net", 0), out decimal headerOwnTotal);
+
+ if (headerOwnTotal == 0)
+ {
+ // Not yet converted (the set-item switch, ApplyItemSetPrice, hasn't run): the
+ // header still carries its as-delivered zero price, so the chosen display mode
+ // does not apply yet — show the header blank and each member with its own,
+ // individual price, exactly as if there were no set grouping at all.
+ result.Add(HeaderLine(item, 0, showPrice: false));
+ foreach (var mem in members) result.Add(MemberLine(mem, showPrice: true));
+ continue;
+ }
switch (mode)
{
case SetDisplayMode.SetPrice:
- result.Add(HeaderLine(item, setTot, showPrice: true));
+ result.Add(HeaderLine(item, headerOwnTotal, showPrice: true));
foreach (var mem in members) result.Add(MemberLine(mem, showPrice: false));
break;
- case SetDisplayMode.ItemPrices:
- result.Add(HeaderLine(item, setTot, showPrice: false)); // grouping title, no price (avoid double count)
- foreach (var mem in members) result.Add(MemberLine(mem, showPrice: true));
- break;
case SetDisplayMode.SetOnly:
- result.Add(HeaderLine(item, setTot, showPrice: true));
+ result.Add(HeaderLine(item, headerOwnTotal, showPrice: true));
break;
}
}
@@ -148,15 +180,6 @@ public static class InvoiceSetPricing
return string.IsNullOrEmpty(s) ? i.nz("id", "") : s;
}
- private static decimal HeaderTotal(Dictionary header, List> members)
- {
- FuchsPdf.ParseDec(header.no("total_net", 0), out decimal headerTot);
- if (headerTot != 0) return headerTot;
- decimal sum = 0;
- foreach (var m in members) { FuchsPdf.ParseDec(m.no("total_net", 0), out decimal t); sum += t; }
- return sum;
- }
-
private static InvoiceSetLine HeaderLine(Dictionary i, decimal setTotal, bool showPrice) => new()
{
Id = i.nz("id", ""),
@@ -166,6 +189,7 @@ public static class InvoiceSetPricing
PriceNet = setTotal,
TotalNet = setTotal,
ShowPrice = showPrice,
+ Numbered = true, // a set header is always numbered
IsSetHeader = true
};
@@ -182,6 +206,7 @@ public static class InvoiceSetPricing
PriceNet = price,
TotalNet = total,
ShowPrice = showPrice && !IsNoPriceLine(i), // headings/free text print no price
+ Numbered = !IsNoPriceLine(i), // …but are still numbered unless heading/free-text
IsSetHeader = false
};
}
diff --git a/Fuchs/dotnet-tools.json b/Fuchs/dotnet-tools.json
new file mode 100644
index 0000000..cce89d8
--- /dev/null
+++ b/Fuchs/dotnet-tools.json
@@ -0,0 +1,13 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-ef": {
+ "version": "10.0.10",
+ "commands": [
+ "dotnet-ef"
+ ],
+ "rollForward": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/Fuchs/js/intranet/modules/fis.inv_shared.js b/Fuchs/js/intranet/modules/fis.inv_shared.js
index b278842..5b1e744 100644
--- a/Fuchs/js/intranet/modules/fis.inv_shared.js
+++ b/Fuchs/js/intranet/modules/fis.inv_shared.js
@@ -130,10 +130,13 @@ $inv.d = {
return h;
},
/* Seed the authoritative server session from the assembled editor payload. Called
- once from invSumUpdate on open; thereafter the backend is the source of truth. */
+ once from invSumUpdate on open; thereafter the backend is the source of truth.
+ The in-flight ajax promise is stashed on 'dseedpromise' so a delta sent (e.g. via
+ a context-menu action) before seeding has actually completed can wait for the token
+ instead of silently no-op'ing (see $inv.d.sync). */
seed: function (payload) {
let l = $inv.d.layout(); l.aC('freeze');
- $ocms.postXT({
+ let p = $ocms.postXT({
url: $ocms.url('inv/dopen'), data: { payload: JSON.stringify(payload) }, success: (r) => {
$inv.d.tbl().data('dtoken', r.token).data('dver', r.version).data('dhashes', $inv.d.hashes()).data('dorder', $inv.d.order());
$fis.draft.bind(r.token, {
@@ -142,8 +145,10 @@ $inv.d = {
onClosed: (reason) => $inv.d.closed(reason)
});
$inv.d.refresh();
- }, error: () => { l.rC('freeze'); }, complete: () => { $inv.d.tbl().removeData('dseeding'); }
+ }, error: () => { l.rC('freeze'); }, complete: () => { $inv.d.tbl().removeData('dseeding').removeData('dseedpromise'); }
});
+ $inv.d.tbl().data('dseedpromise', p);
+ return p;
},
/* Re-fetch the authoritative state and render the totals footer + validation from it. */
refresh: function (cb) {
@@ -157,11 +162,21 @@ $inv.d = {
},
applyState: function (state) {
let tbl = $inv.d.tbl(); if (tbl.length < 1) { return; }
+ /* Concurrent refreshes (one per flushed block plus one for a follow-up delta such as
+ item.setprice, and SignalR draftReady on top) can have their dstate responses arrive
+ out of order. Applying a response older than the version already rendered would
+ silently roll back a just-applied server-side mutation (e.g. a set-price conversion
+ reverting to its pre-conversion 0/individually-priced state) — so stale responses are
+ dropped here instead of rendered. */
+ let curVer = tbl.data('dver');
+ if (typeof curVer === 'number' && typeof state.version === 'number' && state.version < curVer) {
+ return;
+ }
tbl.data('dver', state.version).data('serverSums', state.sums);
$inv.d.footer(tbl, state.sums || {}, state.admin || {});
$inv.d.notes(state.notes || []);
$inv.d.validation(state.validation || []);
- $inv.d.applyPositions(tbl, state.req || []);
+ $inv.d.applyItems(tbl, state.req || []);
$inv.d.applySetDisplay(tbl, state.setDisplay || {});
/* Keep the menu's "Set-Preisanzeige" entry in sync with the authoritative admin.setmode:
hides it right after a mode switch, and restores it if a discard reverted the draft to
@@ -181,19 +196,60 @@ $inv.d = {
/* Push the server's authoritative position numbers back onto the rendered rows so the online
editor and the PDF preview always agree (the server numbers priced lines continuously; the
browser must not keep its own numbering). Only the position cell is touched — no re-render. */
- applyPositions: function (tbl, req) {
- (req || []).forEach((b) => (b && b.itm || []).forEach((co) => {
- if (!co || (co.id || '') === '') { return; }
- let cell = tbl.find('#itm' + co.id + ' td.keep').first();
- if (cell.length) { cell.text(co.p != null ? co.p : ''); }
- }));
+ /* Reconciles each block's rendered rows against the authoritative server line list
+ (`req[].itm`, the co shape). The server may not only change a line's values but also
+ ADD lines (the block set row inserted by "Set mit Preis"/block.setprice) and REMOVE lines
+ ("Nur Set mit Preis"/block.setonly), and reorder them — the browser never computes any of
+ that (ADR 0006/0008/0009), it just mirrors the server. For each server line: patch/insert
+ the matching row, preserving null price fields verbatim (ADR 0009: null = empty cell, kept
+ distinct from 0). Rows the server no longer lists are removed; order follows the server.
+ Position numbers, net/VAT and the set-row emphasis all come from rrw off the mirrored data. */
+ applyItems: function (tbl, req) {
+ let val = (x) => (x === undefined ? null : x); // JSON null stays null; absent -> null
+ (req || []).forEach((b) => {
+ if (!b) { return; }
+ let bid = (b.Id || '').toString(); if (bid === '') { return; }
+ let bdy = tbl.children('tbody').filter((i, e) => (($(e).data() || {}).Id || '').toString() === bid).first();
+ if (bdy.length < 1) { return; }
+ let itms = b.itm || [], serverIds = {};
+ let title = bdy.find('tr.title').first();
+ let prev = title.length ? title : null;
+ itms.forEach((co) => {
+ let id = (co.id || '').toString(); if (id === '') { return; }
+ serverIds[id] = true;
+ let rw = bdy.find('#itm' + id).first(), isNew = rw.length < 1;
+ if (isNew) { rw = $$.tr(bdy, { id: 'itm' + id, class: 'itm' }); }
+ let dta = rw.data() || {};
+ let changed = isNew || (dta.Type || '') !== (co.typ || '')
+ || dta.net !== val(co.v) || dta.net_val !== val(co.vt) || dta.vat_val !== val(co.vv)
+ || dta.svcnet_val !== val(co.vs) || dta.svcvat_val !== val(co.vsv)
+ || (dta.position || '') !== (co.p != null ? co.p : '');
+ $.extend(dta, {
+ Id: id, Type: co.typ,
+ net: val(co.v), net_val: val(co.vt), vat_val: val(co.vv),
+ svcnet_val: val(co.vs), svcvat_val: val(co.vsv),
+ vat: co.vat, position: (co.p != null ? co.p : ''),
+ SetItmId: (co.SetItmId != null ? co.SetItmId : null)
+ });
+ if (isNew) { $.extend(dta, { htmltext: co.t, quantity: co.q }); } // text only for server-created rows (e.g. the set row)
+ rw.data(dta);
+ if (prev) { if (rw.prev()[0] !== prev[0]) { rw.insertAfter(prev); } } // keep server order, but don't churn already-ordered rows
+ else if (bdy.children().first()[0] !== rw[0]) { bdy.prepend(rw); }
+ prev = rw;
+ if (changed) { $inv.rrw.call(rw); }
+ });
+ bdy.find('tr.itm').each((i, tr) => {
+ let id = (($(tr).data() || {}).Id || '').toString();
+ if (id !== '' && !serverIds[id]) { $(tr).remove(); } // dropped server-side (block.setonly)
+ });
+ });
},
/* Applies the backend-authoritative set-pricing display flags (see BuildSetDisplay /
InvoiceSetPricing) onto the rendered rows: blanks the price/total cells for lines the
- server says should show no price (set members in SetPrice mode, the set header in
- ItemPrices mode), and emphasises the set header line — so the online editor always
- shows exactly what the PDF will print, without duplicating the pricing rules client-side.
- Rows not present in the map (no set in that block, or standalone items) are left untouched. */
+ server says should show no price (set members in SetPrice/SetOnly mode), and emphasises
+ the set header line — so the online editor always shows exactly what the PDF will print,
+ without duplicating the pricing rules client-side. Rows not present in the map (no set in
+ that block, or standalone items) are left untouched. */
applySetDisplay: function (tbl, setDisplay) {
tbl.find('tr.itm').each((i, tr) => {
let rw = $(tr), dta = rw.data() || {}, id = (dta.Id || '').toString();
@@ -205,11 +261,23 @@ $inv.d = {
}
});
},
- /* Send one change to the server; the draftReady signal and this success both refresh. */
+ /* Send one change to the server; the draftReady signal and this success both refresh.
+ Returns the underlying ajax promise so callers that must not race a follow-up delta
+ against this one (e.g. $inv.toSetPrice after a flush) can chain on it.
+ If the initial seeding (inv/dopen) is still in flight (no token yet, but a
+ 'dseedpromise' is pending), the delta previously vanished silently — the user saw no
+ network activity at all when clicking a context-menu action right after opening the
+ editor. Now the delta waits for the seed to finish and retries against the freshly
+ issued token instead of being dropped. */
sync: function (delta) {
- let t = $inv.d.token(); if (t === '') { return; }
+ let t = $inv.d.token();
+ if (t === '') {
+ let seeding = $inv.d.tbl().data('dseedpromise');
+ if (seeding) { return $.when(seeding).then(() => $inv.d.sync(delta)); }
+ return $.when();
+ }
$inv.d.layout().aC('freeze');
- $ocms.postXT({
+ return $ocms.postXT({
url: $ocms.url('inv/dpatch'), data: { token: t, delta: JSON.stringify(delta) },
success: () => { $inv.d.refresh(); },
error: (xhr) => { $inv.d.layout().rC('freeze'); if (xhr && xhr.status === 410) { $inv.d.closed('expired'); } }
@@ -220,22 +288,29 @@ $inv.d = {
/* Diff the freshly-rebuilt blocks against the last-synced state and send only the
changed/removed blocks as granular block.replace / block.remove deltas. A pure section
reorder (same blocks, new sequence) changes no block hash, so it is sent separately as a
- block.order delta; the server reorders the cache, renumbers positions and pushes them back. */
+ block.order delta; the server reorders the cache, renumbers positions and pushes them back.
+ No early return on an empty token here: sync() itself waits for an in-flight seed
+ (dseedpromise) instead of silently dropping the delta, so edits made in the brief window
+ before seeding completes are not lost. */
syncChanged: function (tbl) {
- if (($inv.d.token()) === '') { return; }
- let bai = tbl.data('bai') || [], prev = tbl.data('dhashes') || {}, next = {}, changed = [], removed = [];
+ let bai = tbl.data('bai') || [], prev = tbl.data('dhashes') || {}, next = {}, changed = [], removed = [], pending = [];
$.each(bai, (i, b) => { let id = (b.Id || '').toString(), h = JSON.stringify(b); next[id] = h; if (prev[id] !== h) { changed.push(b); } });
$.each(prev, (id) => { if (next[id] === undefined) { removed.push(id); } });
let order = $inv.d.order(), prevOrder = tbl.data('dorder') || [];
tbl.data('dhashes', next).data('dorder', order);
- changed.forEach((b) => $inv.d.sync({ Target: 'block.replace', Ref: (b.Id || '').toString(), Value: b }));
- removed.forEach((id) => $inv.d.sync({ Target: 'block.remove', Ref: id }));
+ changed.forEach((b) => pending.push($inv.d.sync({ Target: 'block.replace', Ref: (b.Id || '').toString(), Value: b })));
+ removed.forEach((id) => pending.push($inv.d.sync({ Target: 'block.remove', Ref: id })));
let sameSet = prevOrder.length === order.length && prevOrder.slice().sort().join(',') === order.slice().sort().join(',');
- if (sameSet && prevOrder.join(',') !== order.join(',')) { $inv.d.sync({ Target: 'block.order', Value: order }); }
+ if (sameSet && prevOrder.join(',') !== order.join(',')) { pending.push($inv.d.sync({ Target: 'block.order', Value: order })); }
+ /* $.when(...pending) so a caller (e.g. toSetPrice) can wait until every flushed block
+ has actually reached the server before sending a further delta that depends on it —
+ otherwise a delayed block.replace carrying pre-conversion values can land after and
+ silently overwrite a just-applied server-side mutation (e.g. item.setprice). */
+ return $.when.apply($, pending).promise();
},
- /* Map an inline recipient field to its delta target and send it. */
+ /* Map an inline recipient field to its delta target and send it. No token-guard here for the
+ same reason as syncChanged: sync() waits for an in-flight seed instead of dropping the edit. */
syncField: function (nme, val) {
- if ($inv.d.token() === '') { return; }
let map = { invoicetitle: 'title', invoiceaddress: 'address', invoiceemail: 'email', loc: 'provisionlocation', provisionlocation: 'provisionlocation', provisionperiod: 'provisionperiod' };
let target = map[nme]; if (!target) { return; }
$inv.d.sync({ Target: target, Value: val });
@@ -390,6 +465,12 @@ $inv.rd = {
},
applyState: function (state) {
let tbl = $inv.rd.tbl(); if (tbl.length < 1) { return; }
+ /* See $inv.d.applyState — drop stale/out-of-order dstate responses so an older refresh
+ can never roll back a newer one's totals/validation. */
+ let curVer = tbl.data('rdver');
+ if (typeof curVer === 'number' && typeof state.version === 'number' && state.version < curVer) {
+ return;
+ }
tbl.data('rdver', state.version).data('serverSums', state.sums).data('remid', state.remid || '');
$inv.rd.footer(tbl, state.sums || {});
$inv.rd.notes(state.notes || {});
@@ -949,6 +1030,8 @@ $inv.eHtml = function (ev) {
}
$ocms.dlgform(flds, sets);
};
+/* No client-side arithmetic (ADR 0006/0008): only the chosen VAT rate is stored on each row;
+ the server (InvoiceDraftCalculator.RecomputeLineValues) recomputes vat_val/svcvat_val from it. */
$inv.setVat = function (ev) {
let t = $(this), thisrow = ev.data;
let vat = prompt($rct.rqV);
@@ -961,12 +1044,6 @@ $inv.setVat = function (ev) {
thisrow.siblings('.itm').each(function () {
let rwi = $(this), dta = rwi.data();
dta.vat = fnum(vat, { style: 'percent' }).replace(' ', '');
- if ((dta.net_val || 0) > 0) {
- dta.vat_val = dta.net_val * vat;
- }
- if ((dta.svcnet_val || 0) > 0) {
- dta.svcvat_val = dta.svcnet_val * vat;
- }
});
$inv.t_fds_inv();
}
@@ -1026,12 +1103,14 @@ $inv.rrw = function () {
if (ph === false) {
bc.unshift($$.dc('ibtn edit', { title: $rct.cP }).append(gi('pencil')).click(rw, $inv.eRow));
bc.push($$.dc('ibtn del', { title: $rct.dR }).append(gi('trash')).click(function (e) { if (confirm($rct.cD)) { rw.remove(); $inv.t_fds_inv(); } }));
- /* "Auf Setpreis umstellen": only offered on a Set header item that is not yet
- priced from its members (fds__prepInvoice's [SetItmId] is null exactly for a
- Set header — either already set-priced, or not yet converted). Irreversible:
- sets this row's price to the sum of its members (rows whose [SetItmId] equals
- this row's id) and clears each member's price. */
- if ((dta.Type || '').toLowerCase() === 'set' && (dta.SetItmId || '') === '') {
+ /* "Auf Setpreis umstellen": offered on a Set header item that does not yet carry a
+ price. fds__prepInvoice's [SetItmId] now anchors on the still-unconverted (price 0)
+ header, so the header row's own SetItmId self-references its own id rather than being
+ null — the real signal for showing this button is still the header's own price/net_val
+ being 0 (once converted it carries a nonzero price and the button disappears).
+ Irreversible: the actual sum/clear mutation happens server-side (backend-authoritative,
+ see InvoiceDraftEditService.ApplyItemSetPrice) via the "item.setprice" patch target. */
+ if ((dta.Type || '').toLowerCase() === 'set' && (dta.net_val || 0) === 0) {
bc.push($$.dc('ibtn tosetp', { title: $rct.toSetP }).append(gi('scale')).click(rw, $inv.toSetPrice));
}
}
@@ -1041,7 +1120,7 @@ $inv.rrw = function () {
} else if (rw.is('.itm.osum') === true) {
co = { invrqid: dta.InvRqId, id: 'osum' + rw.index(), typ: 'osum', p: '', q: null, t: oHtml(dta.tbl.tbl), tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: false };
} else {
- co = { invrqid: dta.InvRqId, id: dta.Id || '', typ: dta.Type || 'other', p: '', q: null, t: '', tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: (dta.Note || '') !== '' && hn === false };
+ co = { invrqid: dta.InvRqId, id: dta.Id || '', typ: dta.Type || 'other', p: '', q: null, t: '', tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: (dta.Note || '') !== '' && hn === false, SetItmId: dta.SetItmId || null };
$$.dc('ibtn ico move', axf, { title: $rct.mR }); /* should be the last added */
co.p = dta.position || (dta.SortOrder || '');
@@ -1051,7 +1130,7 @@ $inv.rrw = function () {
co.t = dta.htmltext || (((dta.NameOrNumber || '').substr(0, 1) !== '#' ? oHtml($$[0]('p').text(dta.NameOrNumber)) : '') + (dta.Note || ''));
} else {
co.tt = co.det ? '' : $$.s(dta.Note || '').text();
- co.q = dta.quantity || (fnum(dta.quantityhours) + ' ' + (dta.UnitString || ''));
+ co.q = dta.quantity || ((dta.quantityhours || 0) !== 0 ? (fnum(dta.quantityhours) + ' ' + (dta.UnitString || '')) : ''); /* guard: no quantityhours -> blank, not fnum(undefined)="NaN" (e.g. the block set row) */
co.t = dta.htmltext ||(co.det ? (oHtml($$.s(dta.NameOrNumber || '')) + oHtml($$.dc('desc').html(dta.Note))) : oHtml($$.s(dta.NameOrNumber || '')));
co.v = dta.net
co.vt = dta.net_val
@@ -1070,75 +1149,62 @@ $inv.rrw = function () {
tda.push($$.td(rw, { colspan: 4 }).append(co.t));
} else {
Array.prototype.push.apply(tda, co.q ? [$$.tdc('keep').text(co.q)] : []);
+ /* ADR 0009: a null/undefined price renders an EMPTY cell (block-mode "Set mit Preis"
+ members, and the set row's own unit-price), distinct from a real 0,00 €. */
+ let cur = (x) => (x == null ? '' : fnum(x, $rct.cst));
Array.prototype.push.apply(tda, [
$$.tdc('txt', { colspan: !co.q ? 2 : 1, title: co.tt }).append(co.t),
- $$.tdc('currency').text(fnum(co.v, $rct.cst)),
- $$.tdc('currency inetval').text(fnum(co.vt, $rct.cst)).attr('title', $rct.svcPart + ': ' + fnum(co.vs, $rct.cst))
+ $$.tdc('currency').text(cur(co.v)),
+ $$.tdc('currency inetval').text(cur(co.vt)).attr('title', $rct.svcPart + ': ' + cur(co.vs))
]);
}
- rw.empty().attr('class', ph ? 'placeholder' : 'itm').aC(co.Typ).tC('hidenote', hn).append(tda);
+ rw.empty().attr('class', ph ? 'placeholder' : 'itm').aC(co.Typ)
+ .tC('sethdr', (co.typ || '').toString().toLowerCase() === 'set') /* emphasise set rows (fn1 header + block set row) */
+ .tC('hidenote', hn).append(tda);
dta.co = co;
};
-/* "Auf Setpreis umstellen" (see $inv.rrw): sets this Set-header row's price to the sum of
- its member rows' totals (rows in the same block whose [SetItmId] equals this row's id,
- the authoritative grouping from fds__prepInvoice), then clears each member's price so the
- member items show without a price — matching the SetPrice presentation, but as an actual,
- irreversible data change instead of a display-mode toggle (INVOICE_SET_PRICING.md's
- setmode remains display-only and is unaffected by this). */
+/* "Auf Setpreis umstellen" (see $inv.rrw): backend-authoritative (ADR 0006) — the browser only
+ posts the target set-header item id; the server (InvoiceDraftEditService.ApplyItemSetPrice)
+ sums the member rows (same block, [SetItmId] equal to this row's id), writes that sum onto
+ the set header and clears each member's price, then the normal draftReady refresh re-renders
+ both the header and its members from the authoritative session state. This mirrors the PDF's
+ read of the same cached session, so the online editor and PDF can never drift apart. */
$inv.toSetPrice = function (ev) {
let rw = ev.data, dta = rw.data(), id = (dta.Id || '').toString();
if (id === '') { return; }
if (confirm($rct.toSetPc) === false) { return; }
- let bdy = rw.closest('tbody'), members = bdy.find('tr.itm').filter(function () {
- return (($(this).data('SetItmId') || '').toString()) === id;
- });
- let sum_net_val = 0, sum_vat_val = 0, sum_svcnet_val = 0, sum_svcvat_val = 0;
- members.each(function () {
- let m = $(this).data();
- sum_net_val += (m.net_val || 0);
- sum_vat_val += (m.vat_val || 0);
- sum_svcnet_val += (m.svcnet_val || 0);
- sum_svcvat_val += (m.svcvat_val || 0);
- $.extend(m, { net: 0, net_val: 0, vat_val: 0, svcnet_val: 0, svcvat_val: 0, Discount: 0 });
- $inv.rrw.call($(this));
- });
- $.extend(dta, {
- net: sum_net_val, quantityhours: 1, Discount: 0,
- net_val: sum_net_val, vat_val: sum_vat_val, svcnet_val: sum_svcnet_val, svcvat_val: sum_svcvat_val
- });
- $inv.rrw.call(rw);
- $inv.t_fds_inv();
+ /* Wait for the flush of any pending local edits to actually reach the server before sending
+ the conversion delta — sending both in parallel let a delayed block.replace (still carrying
+ the pre-conversion, zero member/header values) land after item.setprice and silently
+ overwrite the just-converted totals back to 0. */
+ $.when($inv.t_fds_inv()).done(() => { $inv.d.sync({ Target: 'item.setprice', Ref: id }); });
};
+/* No client-side totals/footer/tax computation (ADR 0006/0008): this only re-assembles each
+ block's row contract array (needed to post the "req" shape to the server) and, on the very
+ first pass, seeds the authoritative backend session. Footer, VAT breakdown, service-refund
+ note figures and the per-block sum cell are never computed here — they are rendered exclusively
+ from the server's `dstate` response by $inv.d.footer / $inv.d.applyState once the draft has a
+ token. Before a token exists the footer/notes/isum cells are simply left empty; there is no
+ local approximation to display. */
$inv.invSumUpdate = function () {
- let tbl = $(this), ft = tbl.children('tfoot').empty(), p13b = bool((tbl.data().admin || {}).p13b || '', false);
- tbl.nextAll('.fnote').remove();
- let sms = { ttn: 0, ttb: 0, ttvat: 0, tscn: 0, tscvat: 0, vat: {}, itmnet: {} }, ba = [];
- let rwcy = (lbl, val, cls) => $$.tdc('currency', $$.tr(ft, { class: cls || 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text(lbl)]), fnum(val, $rct.cst)), fn = (t) => $$.dc('fnote').insertAfter(tbl).rwText(t);
- let csms = function (rrx, sms, sid) {
- sms.tscn += (rrx.svcnet_val || 0);
- sms.tscvat += (rrx.svcvat_val || 0);
- sms.ttn += (rrx.net_val || 0);
- sms.ttvat += (rrx.vat_val || 0);
- sms.ttb += ((rrx.net_val || 0) + (rrx.vat_val || 0));
- if ((rrx.vat || '') !== '') {
- sms.vat[rrx.vat] = (sms.vat[rrx.vat] || 0) + (rrx.vat_val || 0);
- }
- //sms.itmnet[sid] = (sms.itmnet[sid] || 0) + (rrx.net_val || 0);
- };
+ let tbl = $(this);
+ let ba = [];
let bds = tbl.children('tbody');
bds.each((bi, bdy) => {
- let b = $(bdy), rx = b.data() || {}, i = [], citems = [], cset = null, bnet = 0, itm = b.find('tr.itm'), iso = 0, ipos = 0;
+ let b = $(bdy), rx = b.data() || {}, i = [], citems = [], itm = b.find('tr.itm'), iso = 0, ipos = 0;
b.tC('empty', itm.length < 1);
itm.each((ti, tx) => {
-
- let rrx = $(tx).data() || {}; csms(rrx, sms, rx.Id); bnet += (rrx.net_val || 0); i.push(rrx.co);
- //console.debug('rrx %o', rrx);
+ let rrx = $(tx).data() || {};
+ i.push(rrx.co);
/* backend item contract (title/desc/qty/price_net/total_net + set flags), see InvoiceSetPricing.
- Set grouping: an item of Type 'set' is a header that claims the following items in this
- block as its members until the next set header (mfr__items has no explicit member link). */
+ Set grouping: fds__prepInvoice computes [SetItmId] per item, anchored on the still-unconverted
+ (price 0) Set header that owns it — this is the authoritative membership signal (not row order),
+ so items not tagged with a SetItmId by the server are never swept into a preceding set. The
+ header row's own SetItmId self-references its own id, but it is never its own member (excluded
+ by the id !== '' && !== citem.id check below). */
let citem = $inv.itemToContract(rrx);
- if (citem.type === 'set' && citem.id !== '') { cset = citem.id; }
- else if (cset !== null && (citem.id || '') !== '') { citem.setId = cset; }
+ let sid = (rrx.SetItmId || '').toString();
+ if (citem.type !== 'set' && sid !== '' && sid !== citem.id) { citem.setId = sid; }
citems.push(citem);
if (((typeof rrx.SortOrder === 'undefined' || rrx.SortOrder === null) ? -1 : rrx.SortOrder) > -1) {
if (['text', 'title'].includes((rrx.Type || 'other').toLowerCase()) === false) { ipos++; }
@@ -1147,41 +1213,10 @@ $inv.invSumUpdate = function () {
$inv.rrw.call(tx);
}
});
- //console.debug('%o', {
- // f: b.find('tr.isum > td.isumval'), t: fnum(bnet, $rct.cst), n: bnet
- //});
- b.find('tr.isum > td.isumval').text(fnum(bnet, $rct.cst));
- ba.push({ Id: rx.Id, nme: rx.Name, text: rx.text, itm: i, items: citems, netval: bnet });
+ ba.push({ Id: rx.Id, nme: rx.Name, text: rx.text, itm: i, items: citems });
});
let nonempty = tbl.find('tbody:not(.empty)').length;
bds.find('tr.isum').tC('hidden', nonempty < 2);
- //let fnet = $$.tdc('currency', $$.tr(ft, { class: 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Netto')]), fnum(sms.ttn, $rct.cst));
- rwcy('Netto', sms.ttn);
- if (p13b === false) {
- $.each(sms.vat, (vi, vx) => {
- //$$.tdc('currency vat', $$.tr(ft, { class: 'tvat' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Umsatzsteuer ' + vi)]), fnum(vx, $rct.cst));
- rwcy($rct.vat + ' ' + vi, vx, 'tvat');
- });
- } else {
- sms.ttb = sms.ttn;
- }
- //let fsum = $$.tdc('currency', $$.tr(ft, { class: 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Summe')]), fnum(sms.ttb, $rct.cst));
- rwcy('Summe', sms.ttb);
- let itype = tbl.data().admin.type;
- if (itype === 'i') {
- fn($rct.note2);
- fn($rct.note4);
- } else if (itype === 'c') {
- fn($rct.note2);
- } else {
- fn(string($rct.note3, [fnum((sms.tscn + sms.tscvat) * (tbl.data().admin.tax_servicerefund || 0), $rct.cst)])).aC('ntax');
- fn($rct.note2);
- fn(string($rct.note1, [fnum(sms.tscn + sms.tscvat, $rct.cst), fnum(sms.tscn, $rct.cst), fnum(sms.tscvat, $rct.cst)]));
- }
- if (p13b === true) {
- fn($rct.note13b);
- }
- tbl.data('sms', sms);
tbl.data('bai', ba);
/* Backend-authoritative seeding (ADR 0006): on the first calculation of an invoice
draft (invSumUpdate is only bound for invoices, never reminders), hand the assembled
@@ -1281,8 +1316,16 @@ $inv.t_fds_inv = () => {
let tbl = $('div.invoice_layout table.invi');
tbl.trigger('fds.inv');
/* After any local item mutation, push the changed block(s) to the authoritative
- server session as granular deltas (invoice drafts only — reminders have no token). */
- if ((tbl.data('dtoken') || '') !== '') { $inv.d.syncChanged(tbl); }
+ server session as granular deltas (invoice drafts only — reminders have no token,
+ nor a 'dseedpromise', so they correctly fall through to the no-op). While the initial
+ seed (inv/dopen) is still in flight there is no token yet either, but a 'dseedpromise'
+ is pending — wait for it instead of skipping the flush, otherwise an edit made in that
+ brief window is silently never sent. Returns the flush promise so callers that must
+ sequence a follow-up server delta after this flush (e.g. $inv.toSetPrice) can wait for
+ it instead of racing it. */
+ if ((tbl.data('dtoken') || '') !== '') { return $inv.d.syncChanged(tbl); }
+ let seeding = tbl.data('dseedpromise');
+ return seeding ? $.when(seeding).then(() => $inv.d.syncChanged(tbl)) : $.when();
};
$inv.sedit = () => {
$inv.sprev(true);
@@ -1349,7 +1392,10 @@ $inv.itemToContract = function (rrx) {
rrx = rrx || {};
let oHtml = (e) => $$.d().append(e).html();
let type = (rrx.Type || '').toString().toLowerCase();
- let ci = { id: (rrx.Id || '').toString(), type: type, title: '', desc: '', qty: '', price_net: '', total_net: (rrx.net_val || 0), vat: rrx.vat || '' };
+ /* ADR 0009: preserve null prices verbatim (null = empty cell, kept distinct from a real 0) so
+ block-mode nulled members and the set row round-trip unchanged when the block is re-posted. */
+ let nz = (x) => (x == null ? null : x);
+ let ci = { id: (rrx.Id || '').toString(), type: type, title: '', desc: '', qty: '', price_net: '', total_net: nz(rrx.net_val), vat: rrx.vat || '' };
if (rrx.co && rrx.co.typ === 'osum') {
/* combined single-sum line — the on-screen "title" is an HTML sub-table; render it as desc */
ci.desc = rrx.co.t || '';
@@ -1370,30 +1416,35 @@ $inv.itemToContract = function (rrx) {
ci.desc = rrx.Note || '';
}
ci.qty = rrx.quantity || ((rrx.quantityhours || 0) !== 0 ? (fnum(rrx.quantityhours) + (rrx.UnitString ? ' ' + rrx.UnitString : '')) : '');
- ci.price_net = (rrx.net || 0);
- ci.total_net = (rrx.net_val || 0);
+ ci.price_net = nz(rrx.net);
+ ci.total_net = nz(rrx.net_val);
}
return ci;
};
-/* 3-way set-pricing display switch. Mirrors §13b: writes the choice onto admin.setmode,
- which BuildInvoiceParams turns into the "setmode:" InvoiceOptions token the PDF reads. */
+/* 2-way set-pricing display switch (SetPrice / SetOnly). Mirrors §13b: writes the choice onto
+ admin.setmode, which BuildInvoiceParams turns into the "setmode:" InvoiceOptions token
+ the PDF reads. ItemPrices ("Positionen mit Preis – Set als Überschrift") was removed: it was
+ always just the implicit pre-conversion default and is not a state the user can switch back to
+ once a set has been converted via the "Auf Setpreis umstellen" item switch (see $inv.toSetPrice /
+ InvoiceDraftEditService.ApplyItemSetPrice) — that conversion is one-way. */
$inv.ssetmode = () => {
let l = $('div.invoice_layout'), tbl = l.find('table.invi'), d = tbl.data();
d.admin = d.admin || {};
let cur = (d.admin.setmode || 'setprice'), o;
let btn = (mode) => $$.dc('btn', $ict.setmo[mode]).tC('selected', cur === mode).click(() => { o.c.trigger('modal_close'); $inv.setSetmode(mode); });
- let fr = $$.dc('choicefrm').append([btn('setprice'), btn('itemprices'), btn('setonly')]);
+ let fr = $$.dc('choicefrm').append([btn('setprice'), btn('setonly')]);
o = $ocms.dlg(fr, { width: 800 });
};
+/* "Set mit Preis" / "Nur Set mit Preis" (ADR 0009): NOT a display toggle — an irreversible,
+ backend-authoritative mutation grouped by service-request block. The server inserts a dedicated
+ set row per block (block sum) and either nulls each member's price (setprice) or removes the
+ members (setonly); the normal draftReady refresh re-renders both via $inv.d.applyItems. The
+ browser only posts the chosen mode. Flush pending local edits first so a delayed block.replace
+ can't land after the conversion and overwrite it (same race guard as $inv.toSetPrice). */
$inv.setSetmode = (mode) => {
- let l = $('div.invoice_layout'), tbl = l.find('table.invi'), d = tbl.data();
- d.admin = d.admin || {};
- d.admin.setmode = mode; /* posted in admin -> BuildInvoiceParams writes setmode: into InvoiceOptions */
- d.inv = d.inv || {}; /* keep a local InvoiceOptions reflection in sync (cosmetic) */
- let opts = (d.inv.InvoiceOptions || '').split(',').filter(x => x !== '' && x.indexOf('setmode:') !== 0);
- if (mode && mode !== 'setprice') { opts.push('setmode:' + mode); }
- d.inv.InvoiceOptions = opts.join(',');
- $inv.d.sync({ Target: 'setmode', Value: mode });
+ if (confirm($rct.toSetMc || $rct.toSetPc) === false) { return; }
+ let target = (mode === 'setonly') ? 'block.setonly' : 'block.setprice';
+ $.when($inv.t_fds_inv()).done(() => { $inv.d.sync({ Target: target }); });
};
$inv.sctp = () => {
let flds = $invcol.ctp;
@@ -1416,24 +1467,21 @@ $inv.sctp = () => {
});
};
/* Normalises the editor's working model into the exact field names the C# backend
- (FdsInvoiceData.BuildInvoiceParams) reads, then returns the `invc` payload:
- - balances/service sums come from `sms` (ttn/ttb), exposed on `new` as total_net/total_gross;
- - every VAT rate's net amount is exposed as new.vat__net (the backend reads the highest);
+ (FdsInvoiceData.BuildInvoiceParams) reads, then returns the `invc` payload. No totals/VAT
+ are computed here (ADR 0006/0008: the online editor performs no arithmetic at all) — the
+ backend session computes total_net/total_gross/vat itself (InvoiceDraftCalculator) once
+ opened from this payload, and BuildFdsData/BuildInvoiceParams reads them from there:
- new.invoicetitle -> new.title, new.loc -> new.provisionlocation, admin.paymentterms ->
new.paymentterm, admin.CustomerId -> admin.customerid.
Originals are kept alongside; the source objects are not mutated. */
$inv.invcPayload = function (d) {
d = d || {};
- let sms = d.sms || {}, nw = $.extend({}, d.new), adm = $.extend({}, d.admin);
- nw.total_net = sms.ttn || 0;
- nw.total_gross = sms.ttb || 0;
- /* VAT (rate + amount) is taken by the backend straight from the posted sms.vat map
- (FdsInvoiceData.HighestVat), so no per-rate new.vat_* keys are needed here. */
+ let nw = $.extend({}, d.new), adm = $.extend({}, d.admin);
nw.title = (nw.invoicetitle != null ? nw.invoicetitle : (nw.title || ''));
nw.provisionlocation = (nw.loc != null ? nw.loc : (nw.provisionlocation || ''));
nw.paymentterm = (adm.paymentterms != null ? adm.paymentterms : (nw.paymentterm || ''));
adm.customerid = (adm.customerid != null ? adm.customerid : adm.CustomerId);
- return { admin: adm, req: d.bai, sms: d.sms, new: nw };
+ return { admin: adm, req: d.bai, new: nw };
};
/* Zwischenspeichern and preview now run against the backend-authoritative session
(ADR 0006): no full-invoice re-upload — the cached draft is flushed / rendered by
@@ -1447,20 +1495,11 @@ $inv.rReload = () => {
$inv.cInv2({ id: s.search });
} catch (e) { }
};
-$inv.quantChange = function (i) {
- //console.debug({ t: this, i: i });
- let t = $(this), f = t.closest('form'), fi = {}, pf = (i) => parseFloat(i.toString().replace('%', '').replace(',', '.')), rtp = (num) => num.toFixed(2);
- f.find(':input').each((i, e) => { fi[$(e).attr('name')] = $(e); });
- let qv = parseInt(fi.quantityhours.val() || '0'), nv = pf(fi.net.val() || '0'), vat = pf(fi.vat.val()) * 0.01;
- if (qv > 0 && nv > 0) {
- fi.net_val.val(rtp(qv * nv));
- fi.vat_val.val(rtp(qv * nv * vat));
- if (['Service'].includes(fi.Type.val())) {
- fi.svcnet_val.val(rtp(qv * nv));
- fi.svcvat_val.val(rtp(qv * nv * vat));
- }
- }
-};
+/* No client-side arithmetic (ADR 0006/0008): quantity/price/VAT edits are posted as raw values
+ and the server (InvoiceDraftCalculator.RecomputeLineValues) computes net_val/vat_val/
+ svcnet_val/svcvat_val. The fields are left as entered here; the authoritative values are
+ pushed back onto the row by $inv.d.applyItems once the change reaches the backend. */
+$inv.quantChange = function (i) { };
$inv.storno = function (id, fds) {
let o, fr = $$.dc('choicefrm').append([
$$.dc('btn', 'Storno ohne Details').click({ id: id, mode: 'simple' }, (ev) => { o.c.trigger('modal_close'); $inv.cSt(ev.data); })
diff --git a/Fuchs/js/intranet/modules/fis.inv_txt_de.js b/Fuchs/js/intranet/modules/fis.inv_txt_de.js
index 173472e..583bf94 100644
--- a/Fuchs/js/intranet/modules/fis.inv_txt_de.js
+++ b/Fuchs/js/intranet/modules/fis.inv_txt_de.js
@@ -43,7 +43,6 @@
setm: 'Set-Preisanzeige',
setmo: {
setprice: 'Set mit Preis – Positionen ohne Preis',
- itemprices: 'Positionen mit Preis – Set als Überschrift',
setonly: 'Nur Set mit Preis – Positionen ausgeblendet'
},
ctp: 'Ansprechpartner festlegen',
diff --git a/Fuchs/js/intranet/modules/fis.req_txt_de.js b/Fuchs/js/intranet/modules/fis.req_txt_de.js
index 1b15f7b..f52f98c 100644
--- a/Fuchs/js/intranet/modules/fis.req_txt_de.js
+++ b/Fuchs/js/intranet/modules/fis.req_txt_de.js
@@ -36,6 +36,7 @@
combP: 'Positionen zusammenfassen',
toSetP: 'Auf Setpreis umstellen (Positionen ohne Preis)',
toSetPc: 'Der Set-Preis wird auf die Summe seiner Positionen gesetzt und die Positionen selbst verlieren ihren Preis. Das ist nicht rückgängig zu machen (der Betrag kann danach nur noch manuell geändert werden). Fortfahren?',
+ toSetMc: 'Jeder Leistungsauftrag wird zu einer Set-Position mit der Summe als Preis zusammengefasst. Das ist nicht rückgängig zu machen (die Set-Preise können danach nur noch manuell geändert werden). Fortfahren?',
iSum: 'Zwischensumme',
dtRel: 'Freigegeben am: ',
dtCr: 'Erstellt am: ',
diff --git a/Fuchs/js/intranet/oci_basic.js b/Fuchs/js/intranet/oci_basic.js
index 4c0ec25..75dc871 100644
--- a/Fuchs/js/intranet/oci_basic.js
+++ b/Fuchs/js/intranet/oci_basic.js
@@ -577,7 +577,7 @@ $ocms.postXT = function (options) {
if ((typeof options.contentType === 'boolean' ? options.contentType === false : false) === true) {
ajo.contentType = false; /* needed for file uploads */
}
- $.ajax(ajo);
+ return $.ajax(ajo);
};
$ocms.cex_timer = function () {
if (!$ocms.cexi) {
diff --git a/Fuchs/js/intranet/oci_sortable.js b/Fuchs/js/intranet/oci_sortable.js
index 0ee2dbd..e870687 100644
--- a/Fuchs/js/intranet/oci_sortable.js
+++ b/Fuchs/js/intranet/oci_sortable.js
@@ -198,7 +198,15 @@ if (!Element.prototype.closest) {
_onPress: function (e) {
if (!e) { return; }
function op(tgt) {
- if (tgt && tgt.parentNode === this._container && (this._dragHandleClass === '' || e.target.className.indexOf(this._dragHandleClass) > -1) && tgt.className.indexOf("nosort") < 0) {
+ // Match the drag handle by real CSS class token, not substring. The old
+ // e.target.className.indexOf('ico') matched every Bootstrap "glyph[ico]n" icon,
+ // so clicking any icon button (edit/delete/set-price…) inside a sortable row
+ // started a zero-distance drag that swallowed the button's own click. Using
+ // closest('.') restricts dragging to the dedicated handle element (e.g.
+ // the ".ico" move button) and its descendants only.
+ var isHandle = this._dragHandleClass === '' ||
+ (e.target.closest && e.target.closest('.' + this._dragHandleClass) != null);
+ if (tgt && tgt.parentNode === this._container && isHandle && tgt.className.indexOf("nosort") < 0) {
e.preventDefault();
this._dragging = true;
this._click = getPoint(e);
diff --git a/Fuchs/wwwroot/web/fis.inv.de.js b/Fuchs/wwwroot/web/fis.inv.de.js
index a6d3108..4f5ec23 100644
--- a/Fuchs/wwwroot/web/fis.inv.de.js
+++ b/Fuchs/wwwroot/web/fis.inv.de.js
@@ -36,6 +36,7 @@ let $rct = {
combP: 'Positionen zusammenfassen',
toSetP: 'Auf Setpreis umstellen (Positionen ohne Preis)',
toSetPc: 'Der Set-Preis wird auf die Summe seiner Positionen gesetzt und die Positionen selbst verlieren ihren Preis. Das ist nicht rückgängig zu machen (der Betrag kann danach nur noch manuell geändert werden). Fortfahren?',
+ toSetMc: 'Jeder Leistungsauftrag wird zu einer Set-Position mit der Summe als Preis zusammengefasst. Das ist nicht rückgängig zu machen (die Set-Preise können danach nur noch manuell geändert werden). Fortfahren?',
iSum: 'Zwischensumme',
dtRel: 'Freigegeben am: ',
dtCr: 'Erstellt am: ',
@@ -151,7 +152,6 @@ let $ict = {
setm: 'Set-Preisanzeige',
setmo: {
setprice: 'Set mit Preis – Positionen ohne Preis',
- itemprices: 'Positionen mit Preis – Set als Überschrift',
setonly: 'Nur Set mit Preis – Positionen ausgeblendet'
},
ctp: 'Ansprechpartner festlegen',
@@ -673,10 +673,13 @@ $inv.d = {
return h;
},
/* Seed the authoritative server session from the assembled editor payload. Called
- once from invSumUpdate on open; thereafter the backend is the source of truth. */
+ once from invSumUpdate on open; thereafter the backend is the source of truth.
+ The in-flight ajax promise is stashed on 'dseedpromise' so a delta sent (e.g. via
+ a context-menu action) before seeding has actually completed can wait for the token
+ instead of silently no-op'ing (see $inv.d.sync). */
seed: function (payload) {
let l = $inv.d.layout(); l.aC('freeze');
- $ocms.postXT({
+ let p = $ocms.postXT({
url: $ocms.url('inv/dopen'), data: { payload: JSON.stringify(payload) }, success: (r) => {
$inv.d.tbl().data('dtoken', r.token).data('dver', r.version).data('dhashes', $inv.d.hashes()).data('dorder', $inv.d.order());
$fis.draft.bind(r.token, {
@@ -685,8 +688,10 @@ $inv.d = {
onClosed: (reason) => $inv.d.closed(reason)
});
$inv.d.refresh();
- }, error: () => { l.rC('freeze'); }, complete: () => { $inv.d.tbl().removeData('dseeding'); }
+ }, error: () => { l.rC('freeze'); }, complete: () => { $inv.d.tbl().removeData('dseeding').removeData('dseedpromise'); }
});
+ $inv.d.tbl().data('dseedpromise', p);
+ return p;
},
/* Re-fetch the authoritative state and render the totals footer + validation from it. */
refresh: function (cb) {
@@ -700,11 +705,21 @@ $inv.d = {
},
applyState: function (state) {
let tbl = $inv.d.tbl(); if (tbl.length < 1) { return; }
+ /* Concurrent refreshes (one per flushed block plus one for a follow-up delta such as
+ item.setprice, and SignalR draftReady on top) can have their dstate responses arrive
+ out of order. Applying a response older than the version already rendered would
+ silently roll back a just-applied server-side mutation (e.g. a set-price conversion
+ reverting to its pre-conversion 0/individually-priced state) — so stale responses are
+ dropped here instead of rendered. */
+ let curVer = tbl.data('dver');
+ if (typeof curVer === 'number' && typeof state.version === 'number' && state.version < curVer) {
+ return;
+ }
tbl.data('dver', state.version).data('serverSums', state.sums);
$inv.d.footer(tbl, state.sums || {}, state.admin || {});
$inv.d.notes(state.notes || []);
$inv.d.validation(state.validation || []);
- $inv.d.applyPositions(tbl, state.req || []);
+ $inv.d.applyItems(tbl, state.req || []);
$inv.d.applySetDisplay(tbl, state.setDisplay || {});
/* Keep the menu's "Set-Preisanzeige" entry in sync with the authoritative admin.setmode:
hides it right after a mode switch, and restores it if a discard reverted the draft to
@@ -724,19 +739,60 @@ $inv.d = {
/* Push the server's authoritative position numbers back onto the rendered rows so the online
editor and the PDF preview always agree (the server numbers priced lines continuously; the
browser must not keep its own numbering). Only the position cell is touched — no re-render. */
- applyPositions: function (tbl, req) {
- (req || []).forEach((b) => (b && b.itm || []).forEach((co) => {
- if (!co || (co.id || '') === '') { return; }
- let cell = tbl.find('#itm' + co.id + ' td.keep').first();
- if (cell.length) { cell.text(co.p != null ? co.p : ''); }
- }));
+ /* Reconciles each block's rendered rows against the authoritative server line list
+ (`req[].itm`, the co shape). The server may not only change a line's values but also
+ ADD lines (the block set row inserted by "Set mit Preis"/block.setprice) and REMOVE lines
+ ("Nur Set mit Preis"/block.setonly), and reorder them — the browser never computes any of
+ that (ADR 0006/0008/0009), it just mirrors the server. For each server line: patch/insert
+ the matching row, preserving null price fields verbatim (ADR 0009: null = empty cell, kept
+ distinct from 0). Rows the server no longer lists are removed; order follows the server.
+ Position numbers, net/VAT and the set-row emphasis all come from rrw off the mirrored data. */
+ applyItems: function (tbl, req) {
+ let val = (x) => (x === undefined ? null : x); // JSON null stays null; absent -> null
+ (req || []).forEach((b) => {
+ if (!b) { return; }
+ let bid = (b.Id || '').toString(); if (bid === '') { return; }
+ let bdy = tbl.children('tbody').filter((i, e) => (($(e).data() || {}).Id || '').toString() === bid).first();
+ if (bdy.length < 1) { return; }
+ let itms = b.itm || [], serverIds = {};
+ let title = bdy.find('tr.title').first();
+ let prev = title.length ? title : null;
+ itms.forEach((co) => {
+ let id = (co.id || '').toString(); if (id === '') { return; }
+ serverIds[id] = true;
+ let rw = bdy.find('#itm' + id).first(), isNew = rw.length < 1;
+ if (isNew) { rw = $$.tr(bdy, { id: 'itm' + id, class: 'itm' }); }
+ let dta = rw.data() || {};
+ let changed = isNew || (dta.Type || '') !== (co.typ || '')
+ || dta.net !== val(co.v) || dta.net_val !== val(co.vt) || dta.vat_val !== val(co.vv)
+ || dta.svcnet_val !== val(co.vs) || dta.svcvat_val !== val(co.vsv)
+ || (dta.position || '') !== (co.p != null ? co.p : '');
+ $.extend(dta, {
+ Id: id, Type: co.typ,
+ net: val(co.v), net_val: val(co.vt), vat_val: val(co.vv),
+ svcnet_val: val(co.vs), svcvat_val: val(co.vsv),
+ vat: co.vat, position: (co.p != null ? co.p : ''),
+ SetItmId: (co.SetItmId != null ? co.SetItmId : null)
+ });
+ if (isNew) { $.extend(dta, { htmltext: co.t, quantity: co.q }); } // text only for server-created rows (e.g. the set row)
+ rw.data(dta);
+ if (prev) { if (rw.prev()[0] !== prev[0]) { rw.insertAfter(prev); } } // keep server order, but don't churn already-ordered rows
+ else if (bdy.children().first()[0] !== rw[0]) { bdy.prepend(rw); }
+ prev = rw;
+ if (changed) { $inv.rrw.call(rw); }
+ });
+ bdy.find('tr.itm').each((i, tr) => {
+ let id = (($(tr).data() || {}).Id || '').toString();
+ if (id !== '' && !serverIds[id]) { $(tr).remove(); } // dropped server-side (block.setonly)
+ });
+ });
},
/* Applies the backend-authoritative set-pricing display flags (see BuildSetDisplay /
InvoiceSetPricing) onto the rendered rows: blanks the price/total cells for lines the
- server says should show no price (set members in SetPrice mode, the set header in
- ItemPrices mode), and emphasises the set header line — so the online editor always
- shows exactly what the PDF will print, without duplicating the pricing rules client-side.
- Rows not present in the map (no set in that block, or standalone items) are left untouched. */
+ server says should show no price (set members in SetPrice/SetOnly mode), and emphasises
+ the set header line — so the online editor always shows exactly what the PDF will print,
+ without duplicating the pricing rules client-side. Rows not present in the map (no set in
+ that block, or standalone items) are left untouched. */
applySetDisplay: function (tbl, setDisplay) {
tbl.find('tr.itm').each((i, tr) => {
let rw = $(tr), dta = rw.data() || {}, id = (dta.Id || '').toString();
@@ -748,11 +804,23 @@ $inv.d = {
}
});
},
- /* Send one change to the server; the draftReady signal and this success both refresh. */
+ /* Send one change to the server; the draftReady signal and this success both refresh.
+ Returns the underlying ajax promise so callers that must not race a follow-up delta
+ against this one (e.g. $inv.toSetPrice after a flush) can chain on it.
+ If the initial seeding (inv/dopen) is still in flight (no token yet, but a
+ 'dseedpromise' is pending), the delta previously vanished silently — the user saw no
+ network activity at all when clicking a context-menu action right after opening the
+ editor. Now the delta waits for the seed to finish and retries against the freshly
+ issued token instead of being dropped. */
sync: function (delta) {
- let t = $inv.d.token(); if (t === '') { return; }
+ let t = $inv.d.token();
+ if (t === '') {
+ let seeding = $inv.d.tbl().data('dseedpromise');
+ if (seeding) { return $.when(seeding).then(() => $inv.d.sync(delta)); }
+ return $.when();
+ }
$inv.d.layout().aC('freeze');
- $ocms.postXT({
+ return $ocms.postXT({
url: $ocms.url('inv/dpatch'), data: { token: t, delta: JSON.stringify(delta) },
success: () => { $inv.d.refresh(); },
error: (xhr) => { $inv.d.layout().rC('freeze'); if (xhr && xhr.status === 410) { $inv.d.closed('expired'); } }
@@ -763,22 +831,29 @@ $inv.d = {
/* Diff the freshly-rebuilt blocks against the last-synced state and send only the
changed/removed blocks as granular block.replace / block.remove deltas. A pure section
reorder (same blocks, new sequence) changes no block hash, so it is sent separately as a
- block.order delta; the server reorders the cache, renumbers positions and pushes them back. */
+ block.order delta; the server reorders the cache, renumbers positions and pushes them back.
+ No early return on an empty token here: sync() itself waits for an in-flight seed
+ (dseedpromise) instead of silently dropping the delta, so edits made in the brief window
+ before seeding completes are not lost. */
syncChanged: function (tbl) {
- if (($inv.d.token()) === '') { return; }
- let bai = tbl.data('bai') || [], prev = tbl.data('dhashes') || {}, next = {}, changed = [], removed = [];
+ let bai = tbl.data('bai') || [], prev = tbl.data('dhashes') || {}, next = {}, changed = [], removed = [], pending = [];
$.each(bai, (i, b) => { let id = (b.Id || '').toString(), h = JSON.stringify(b); next[id] = h; if (prev[id] !== h) { changed.push(b); } });
$.each(prev, (id) => { if (next[id] === undefined) { removed.push(id); } });
let order = $inv.d.order(), prevOrder = tbl.data('dorder') || [];
tbl.data('dhashes', next).data('dorder', order);
- changed.forEach((b) => $inv.d.sync({ Target: 'block.replace', Ref: (b.Id || '').toString(), Value: b }));
- removed.forEach((id) => $inv.d.sync({ Target: 'block.remove', Ref: id }));
+ changed.forEach((b) => pending.push($inv.d.sync({ Target: 'block.replace', Ref: (b.Id || '').toString(), Value: b })));
+ removed.forEach((id) => pending.push($inv.d.sync({ Target: 'block.remove', Ref: id })));
let sameSet = prevOrder.length === order.length && prevOrder.slice().sort().join(',') === order.slice().sort().join(',');
- if (sameSet && prevOrder.join(',') !== order.join(',')) { $inv.d.sync({ Target: 'block.order', Value: order }); }
+ if (sameSet && prevOrder.join(',') !== order.join(',')) { pending.push($inv.d.sync({ Target: 'block.order', Value: order })); }
+ /* $.when(...pending) so a caller (e.g. toSetPrice) can wait until every flushed block
+ has actually reached the server before sending a further delta that depends on it —
+ otherwise a delayed block.replace carrying pre-conversion values can land after and
+ silently overwrite a just-applied server-side mutation (e.g. item.setprice). */
+ return $.when.apply($, pending).promise();
},
- /* Map an inline recipient field to its delta target and send it. */
+ /* Map an inline recipient field to its delta target and send it. No token-guard here for the
+ same reason as syncChanged: sync() waits for an in-flight seed instead of dropping the edit. */
syncField: function (nme, val) {
- if ($inv.d.token() === '') { return; }
let map = { invoicetitle: 'title', invoiceaddress: 'address', invoiceemail: 'email', loc: 'provisionlocation', provisionlocation: 'provisionlocation', provisionperiod: 'provisionperiod' };
let target = map[nme]; if (!target) { return; }
$inv.d.sync({ Target: target, Value: val });
@@ -933,6 +1008,12 @@ $inv.rd = {
},
applyState: function (state) {
let tbl = $inv.rd.tbl(); if (tbl.length < 1) { return; }
+ /* See $inv.d.applyState — drop stale/out-of-order dstate responses so an older refresh
+ can never roll back a newer one's totals/validation. */
+ let curVer = tbl.data('rdver');
+ if (typeof curVer === 'number' && typeof state.version === 'number' && state.version < curVer) {
+ return;
+ }
tbl.data('rdver', state.version).data('serverSums', state.sums).data('remid', state.remid || '');
$inv.rd.footer(tbl, state.sums || {});
$inv.rd.notes(state.notes || {});
@@ -1492,6 +1573,8 @@ $inv.eHtml = function (ev) {
}
$ocms.dlgform(flds, sets);
};
+/* No client-side arithmetic (ADR 0006/0008): only the chosen VAT rate is stored on each row;
+ the server (InvoiceDraftCalculator.RecomputeLineValues) recomputes vat_val/svcvat_val from it. */
$inv.setVat = function (ev) {
let t = $(this), thisrow = ev.data;
let vat = prompt($rct.rqV);
@@ -1504,12 +1587,6 @@ $inv.setVat = function (ev) {
thisrow.siblings('.itm').each(function () {
let rwi = $(this), dta = rwi.data();
dta.vat = fnum(vat, { style: 'percent' }).replace(' ', '');
- if ((dta.net_val || 0) > 0) {
- dta.vat_val = dta.net_val * vat;
- }
- if ((dta.svcnet_val || 0) > 0) {
- dta.svcvat_val = dta.svcnet_val * vat;
- }
});
$inv.t_fds_inv();
}
@@ -1569,12 +1646,14 @@ $inv.rrw = function () {
if (ph === false) {
bc.unshift($$.dc('ibtn edit', { title: $rct.cP }).append(gi('pencil')).click(rw, $inv.eRow));
bc.push($$.dc('ibtn del', { title: $rct.dR }).append(gi('trash')).click(function (e) { if (confirm($rct.cD)) { rw.remove(); $inv.t_fds_inv(); } }));
- /* "Auf Setpreis umstellen": only offered on a Set header item that is not yet
- priced from its members (fds__prepInvoice's [SetItmId] is null exactly for a
- Set header — either already set-priced, or not yet converted). Irreversible:
- sets this row's price to the sum of its members (rows whose [SetItmId] equals
- this row's id) and clears each member's price. */
- if ((dta.Type || '').toLowerCase() === 'set' && (dta.SetItmId || '') === '') {
+ /* "Auf Setpreis umstellen": offered on a Set header item that does not yet carry a
+ price. fds__prepInvoice's [SetItmId] now anchors on the still-unconverted (price 0)
+ header, so the header row's own SetItmId self-references its own id rather than being
+ null — the real signal for showing this button is still the header's own price/net_val
+ being 0 (once converted it carries a nonzero price and the button disappears).
+ Irreversible: the actual sum/clear mutation happens server-side (backend-authoritative,
+ see InvoiceDraftEditService.ApplyItemSetPrice) via the "item.setprice" patch target. */
+ if ((dta.Type || '').toLowerCase() === 'set' && (dta.net_val || 0) === 0) {
bc.push($$.dc('ibtn tosetp', { title: $rct.toSetP }).append(gi('scale')).click(rw, $inv.toSetPrice));
}
}
@@ -1584,7 +1663,7 @@ $inv.rrw = function () {
} else if (rw.is('.itm.osum') === true) {
co = { invrqid: dta.InvRqId, id: 'osum' + rw.index(), typ: 'osum', p: '', q: null, t: oHtml(dta.tbl.tbl), tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: false };
} else {
- co = { invrqid: dta.InvRqId, id: dta.Id || '', typ: dta.Type || 'other', p: '', q: null, t: '', tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: (dta.Note || '') !== '' && hn === false };
+ co = { invrqid: dta.InvRqId, id: dta.Id || '', typ: dta.Type || 'other', p: '', q: null, t: '', tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: (dta.Note || '') !== '' && hn === false, SetItmId: dta.SetItmId || null };
$$.dc('ibtn ico move', axf, { title: $rct.mR }); /* should be the last added */
co.p = dta.position || (dta.SortOrder || '');
@@ -1594,7 +1673,7 @@ $inv.rrw = function () {
co.t = dta.htmltext || (((dta.NameOrNumber || '').substr(0, 1) !== '#' ? oHtml($$[0]('p').text(dta.NameOrNumber)) : '') + (dta.Note || ''));
} else {
co.tt = co.det ? '' : $$.s(dta.Note || '').text();
- co.q = dta.quantity || (fnum(dta.quantityhours) + ' ' + (dta.UnitString || ''));
+ co.q = dta.quantity || ((dta.quantityhours || 0) !== 0 ? (fnum(dta.quantityhours) + ' ' + (dta.UnitString || '')) : ''); /* guard: no quantityhours -> blank, not fnum(undefined)="NaN" (e.g. the block set row) */
co.t = dta.htmltext ||(co.det ? (oHtml($$.s(dta.NameOrNumber || '')) + oHtml($$.dc('desc').html(dta.Note))) : oHtml($$.s(dta.NameOrNumber || '')));
co.v = dta.net
co.vt = dta.net_val
@@ -1613,75 +1692,62 @@ $inv.rrw = function () {
tda.push($$.td(rw, { colspan: 4 }).append(co.t));
} else {
Array.prototype.push.apply(tda, co.q ? [$$.tdc('keep').text(co.q)] : []);
+ /* ADR 0009: a null/undefined price renders an EMPTY cell (block-mode "Set mit Preis"
+ members, and the set row's own unit-price), distinct from a real 0,00 €. */
+ let cur = (x) => (x == null ? '' : fnum(x, $rct.cst));
Array.prototype.push.apply(tda, [
$$.tdc('txt', { colspan: !co.q ? 2 : 1, title: co.tt }).append(co.t),
- $$.tdc('currency').text(fnum(co.v, $rct.cst)),
- $$.tdc('currency inetval').text(fnum(co.vt, $rct.cst)).attr('title', $rct.svcPart + ': ' + fnum(co.vs, $rct.cst))
+ $$.tdc('currency').text(cur(co.v)),
+ $$.tdc('currency inetval').text(cur(co.vt)).attr('title', $rct.svcPart + ': ' + cur(co.vs))
]);
}
- rw.empty().attr('class', ph ? 'placeholder' : 'itm').aC(co.Typ).tC('hidenote', hn).append(tda);
+ rw.empty().attr('class', ph ? 'placeholder' : 'itm').aC(co.Typ)
+ .tC('sethdr', (co.typ || '').toString().toLowerCase() === 'set') /* emphasise set rows (fn1 header + block set row) */
+ .tC('hidenote', hn).append(tda);
dta.co = co;
};
-/* "Auf Setpreis umstellen" (see $inv.rrw): sets this Set-header row's price to the sum of
- its member rows' totals (rows in the same block whose [SetItmId] equals this row's id,
- the authoritative grouping from fds__prepInvoice), then clears each member's price so the
- member items show without a price — matching the SetPrice presentation, but as an actual,
- irreversible data change instead of a display-mode toggle (INVOICE_SET_PRICING.md's
- setmode remains display-only and is unaffected by this). */
+/* "Auf Setpreis umstellen" (see $inv.rrw): backend-authoritative (ADR 0006) — the browser only
+ posts the target set-header item id; the server (InvoiceDraftEditService.ApplyItemSetPrice)
+ sums the member rows (same block, [SetItmId] equal to this row's id), writes that sum onto
+ the set header and clears each member's price, then the normal draftReady refresh re-renders
+ both the header and its members from the authoritative session state. This mirrors the PDF's
+ read of the same cached session, so the online editor and PDF can never drift apart. */
$inv.toSetPrice = function (ev) {
let rw = ev.data, dta = rw.data(), id = (dta.Id || '').toString();
if (id === '') { return; }
if (confirm($rct.toSetPc) === false) { return; }
- let bdy = rw.closest('tbody'), members = bdy.find('tr.itm').filter(function () {
- return (($(this).data('SetItmId') || '').toString()) === id;
- });
- let sum_net_val = 0, sum_vat_val = 0, sum_svcnet_val = 0, sum_svcvat_val = 0;
- members.each(function () {
- let m = $(this).data();
- sum_net_val += (m.net_val || 0);
- sum_vat_val += (m.vat_val || 0);
- sum_svcnet_val += (m.svcnet_val || 0);
- sum_svcvat_val += (m.svcvat_val || 0);
- $.extend(m, { net: 0, net_val: 0, vat_val: 0, svcnet_val: 0, svcvat_val: 0, Discount: 0 });
- $inv.rrw.call($(this));
- });
- $.extend(dta, {
- net: sum_net_val, quantityhours: 1, Discount: 0,
- net_val: sum_net_val, vat_val: sum_vat_val, svcnet_val: sum_svcnet_val, svcvat_val: sum_svcvat_val
- });
- $inv.rrw.call(rw);
- $inv.t_fds_inv();
+ /* Wait for the flush of any pending local edits to actually reach the server before sending
+ the conversion delta — sending both in parallel let a delayed block.replace (still carrying
+ the pre-conversion, zero member/header values) land after item.setprice and silently
+ overwrite the just-converted totals back to 0. */
+ $.when($inv.t_fds_inv()).done(() => { $inv.d.sync({ Target: 'item.setprice', Ref: id }); });
};
+/* No client-side totals/footer/tax computation (ADR 0006/0008): this only re-assembles each
+ block's row contract array (needed to post the "req" shape to the server) and, on the very
+ first pass, seeds the authoritative backend session. Footer, VAT breakdown, service-refund
+ note figures and the per-block sum cell are never computed here — they are rendered exclusively
+ from the server's `dstate` response by $inv.d.footer / $inv.d.applyState once the draft has a
+ token. Before a token exists the footer/notes/isum cells are simply left empty; there is no
+ local approximation to display. */
$inv.invSumUpdate = function () {
- let tbl = $(this), ft = tbl.children('tfoot').empty(), p13b = bool((tbl.data().admin || {}).p13b || '', false);
- tbl.nextAll('.fnote').remove();
- let sms = { ttn: 0, ttb: 0, ttvat: 0, tscn: 0, tscvat: 0, vat: {}, itmnet: {} }, ba = [];
- let rwcy = (lbl, val, cls) => $$.tdc('currency', $$.tr(ft, { class: cls || 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text(lbl)]), fnum(val, $rct.cst)), fn = (t) => $$.dc('fnote').insertAfter(tbl).rwText(t);
- let csms = function (rrx, sms, sid) {
- sms.tscn += (rrx.svcnet_val || 0);
- sms.tscvat += (rrx.svcvat_val || 0);
- sms.ttn += (rrx.net_val || 0);
- sms.ttvat += (rrx.vat_val || 0);
- sms.ttb += ((rrx.net_val || 0) + (rrx.vat_val || 0));
- if ((rrx.vat || '') !== '') {
- sms.vat[rrx.vat] = (sms.vat[rrx.vat] || 0) + (rrx.vat_val || 0);
- }
- //sms.itmnet[sid] = (sms.itmnet[sid] || 0) + (rrx.net_val || 0);
- };
+ let tbl = $(this);
+ let ba = [];
let bds = tbl.children('tbody');
bds.each((bi, bdy) => {
- let b = $(bdy), rx = b.data() || {}, i = [], citems = [], cset = null, bnet = 0, itm = b.find('tr.itm'), iso = 0, ipos = 0;
+ let b = $(bdy), rx = b.data() || {}, i = [], citems = [], itm = b.find('tr.itm'), iso = 0, ipos = 0;
b.tC('empty', itm.length < 1);
itm.each((ti, tx) => {
-
- let rrx = $(tx).data() || {}; csms(rrx, sms, rx.Id); bnet += (rrx.net_val || 0); i.push(rrx.co);
- //console.debug('rrx %o', rrx);
+ let rrx = $(tx).data() || {};
+ i.push(rrx.co);
/* backend item contract (title/desc/qty/price_net/total_net + set flags), see InvoiceSetPricing.
- Set grouping: an item of Type 'set' is a header that claims the following items in this
- block as its members until the next set header (mfr__items has no explicit member link). */
+ Set grouping: fds__prepInvoice computes [SetItmId] per item, anchored on the still-unconverted
+ (price 0) Set header that owns it — this is the authoritative membership signal (not row order),
+ so items not tagged with a SetItmId by the server are never swept into a preceding set. The
+ header row's own SetItmId self-references its own id, but it is never its own member (excluded
+ by the id !== '' && !== citem.id check below). */
let citem = $inv.itemToContract(rrx);
- if (citem.type === 'set' && citem.id !== '') { cset = citem.id; }
- else if (cset !== null && (citem.id || '') !== '') { citem.setId = cset; }
+ let sid = (rrx.SetItmId || '').toString();
+ if (citem.type !== 'set' && sid !== '' && sid !== citem.id) { citem.setId = sid; }
citems.push(citem);
if (((typeof rrx.SortOrder === 'undefined' || rrx.SortOrder === null) ? -1 : rrx.SortOrder) > -1) {
if (['text', 'title'].includes((rrx.Type || 'other').toLowerCase()) === false) { ipos++; }
@@ -1690,41 +1756,10 @@ $inv.invSumUpdate = function () {
$inv.rrw.call(tx);
}
});
- //console.debug('%o', {
- // f: b.find('tr.isum > td.isumval'), t: fnum(bnet, $rct.cst), n: bnet
- //});
- b.find('tr.isum > td.isumval').text(fnum(bnet, $rct.cst));
- ba.push({ Id: rx.Id, nme: rx.Name, text: rx.text, itm: i, items: citems, netval: bnet });
+ ba.push({ Id: rx.Id, nme: rx.Name, text: rx.text, itm: i, items: citems });
});
let nonempty = tbl.find('tbody:not(.empty)').length;
bds.find('tr.isum').tC('hidden', nonempty < 2);
- //let fnet = $$.tdc('currency', $$.tr(ft, { class: 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Netto')]), fnum(sms.ttn, $rct.cst));
- rwcy('Netto', sms.ttn);
- if (p13b === false) {
- $.each(sms.vat, (vi, vx) => {
- //$$.tdc('currency vat', $$.tr(ft, { class: 'tvat' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Umsatzsteuer ' + vi)]), fnum(vx, $rct.cst));
- rwcy($rct.vat + ' ' + vi, vx, 'tvat');
- });
- } else {
- sms.ttb = sms.ttn;
- }
- //let fsum = $$.tdc('currency', $$.tr(ft, { class: 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Summe')]), fnum(sms.ttb, $rct.cst));
- rwcy('Summe', sms.ttb);
- let itype = tbl.data().admin.type;
- if (itype === 'i') {
- fn($rct.note2);
- fn($rct.note4);
- } else if (itype === 'c') {
- fn($rct.note2);
- } else {
- fn(string($rct.note3, [fnum((sms.tscn + sms.tscvat) * (tbl.data().admin.tax_servicerefund || 0), $rct.cst)])).aC('ntax');
- fn($rct.note2);
- fn(string($rct.note1, [fnum(sms.tscn + sms.tscvat, $rct.cst), fnum(sms.tscn, $rct.cst), fnum(sms.tscvat, $rct.cst)]));
- }
- if (p13b === true) {
- fn($rct.note13b);
- }
- tbl.data('sms', sms);
tbl.data('bai', ba);
/* Backend-authoritative seeding (ADR 0006): on the first calculation of an invoice
draft (invSumUpdate is only bound for invoices, never reminders), hand the assembled
@@ -1824,8 +1859,16 @@ $inv.t_fds_inv = () => {
let tbl = $('div.invoice_layout table.invi');
tbl.trigger('fds.inv');
/* After any local item mutation, push the changed block(s) to the authoritative
- server session as granular deltas (invoice drafts only — reminders have no token). */
- if ((tbl.data('dtoken') || '') !== '') { $inv.d.syncChanged(tbl); }
+ server session as granular deltas (invoice drafts only — reminders have no token,
+ nor a 'dseedpromise', so they correctly fall through to the no-op). While the initial
+ seed (inv/dopen) is still in flight there is no token yet either, but a 'dseedpromise'
+ is pending — wait for it instead of skipping the flush, otherwise an edit made in that
+ brief window is silently never sent. Returns the flush promise so callers that must
+ sequence a follow-up server delta after this flush (e.g. $inv.toSetPrice) can wait for
+ it instead of racing it. */
+ if ((tbl.data('dtoken') || '') !== '') { return $inv.d.syncChanged(tbl); }
+ let seeding = tbl.data('dseedpromise');
+ return seeding ? $.when(seeding).then(() => $inv.d.syncChanged(tbl)) : $.when();
};
$inv.sedit = () => {
$inv.sprev(true);
@@ -1892,7 +1935,10 @@ $inv.itemToContract = function (rrx) {
rrx = rrx || {};
let oHtml = (e) => $$.d().append(e).html();
let type = (rrx.Type || '').toString().toLowerCase();
- let ci = { id: (rrx.Id || '').toString(), type: type, title: '', desc: '', qty: '', price_net: '', total_net: (rrx.net_val || 0), vat: rrx.vat || '' };
+ /* ADR 0009: preserve null prices verbatim (null = empty cell, kept distinct from a real 0) so
+ block-mode nulled members and the set row round-trip unchanged when the block is re-posted. */
+ let nz = (x) => (x == null ? null : x);
+ let ci = { id: (rrx.Id || '').toString(), type: type, title: '', desc: '', qty: '', price_net: '', total_net: nz(rrx.net_val), vat: rrx.vat || '' };
if (rrx.co && rrx.co.typ === 'osum') {
/* combined single-sum line — the on-screen "title" is an HTML sub-table; render it as desc */
ci.desc = rrx.co.t || '';
@@ -1913,30 +1959,35 @@ $inv.itemToContract = function (rrx) {
ci.desc = rrx.Note || '';
}
ci.qty = rrx.quantity || ((rrx.quantityhours || 0) !== 0 ? (fnum(rrx.quantityhours) + (rrx.UnitString ? ' ' + rrx.UnitString : '')) : '');
- ci.price_net = (rrx.net || 0);
- ci.total_net = (rrx.net_val || 0);
+ ci.price_net = nz(rrx.net);
+ ci.total_net = nz(rrx.net_val);
}
return ci;
};
-/* 3-way set-pricing display switch. Mirrors §13b: writes the choice onto admin.setmode,
- which BuildInvoiceParams turns into the "setmode:" InvoiceOptions token the PDF reads. */
+/* 2-way set-pricing display switch (SetPrice / SetOnly). Mirrors §13b: writes the choice onto
+ admin.setmode, which BuildInvoiceParams turns into the "setmode:" InvoiceOptions token
+ the PDF reads. ItemPrices ("Positionen mit Preis – Set als Überschrift") was removed: it was
+ always just the implicit pre-conversion default and is not a state the user can switch back to
+ once a set has been converted via the "Auf Setpreis umstellen" item switch (see $inv.toSetPrice /
+ InvoiceDraftEditService.ApplyItemSetPrice) — that conversion is one-way. */
$inv.ssetmode = () => {
let l = $('div.invoice_layout'), tbl = l.find('table.invi'), d = tbl.data();
d.admin = d.admin || {};
let cur = (d.admin.setmode || 'setprice'), o;
let btn = (mode) => $$.dc('btn', $ict.setmo[mode]).tC('selected', cur === mode).click(() => { o.c.trigger('modal_close'); $inv.setSetmode(mode); });
- let fr = $$.dc('choicefrm').append([btn('setprice'), btn('itemprices'), btn('setonly')]);
+ let fr = $$.dc('choicefrm').append([btn('setprice'), btn('setonly')]);
o = $ocms.dlg(fr, { width: 800 });
};
+/* "Set mit Preis" / "Nur Set mit Preis" (ADR 0009): NOT a display toggle — an irreversible,
+ backend-authoritative mutation grouped by service-request block. The server inserts a dedicated
+ set row per block (block sum) and either nulls each member's price (setprice) or removes the
+ members (setonly); the normal draftReady refresh re-renders both via $inv.d.applyItems. The
+ browser only posts the chosen mode. Flush pending local edits first so a delayed block.replace
+ can't land after the conversion and overwrite it (same race guard as $inv.toSetPrice). */
$inv.setSetmode = (mode) => {
- let l = $('div.invoice_layout'), tbl = l.find('table.invi'), d = tbl.data();
- d.admin = d.admin || {};
- d.admin.setmode = mode; /* posted in admin -> BuildInvoiceParams writes setmode: into InvoiceOptions */
- d.inv = d.inv || {}; /* keep a local InvoiceOptions reflection in sync (cosmetic) */
- let opts = (d.inv.InvoiceOptions || '').split(',').filter(x => x !== '' && x.indexOf('setmode:') !== 0);
- if (mode && mode !== 'setprice') { opts.push('setmode:' + mode); }
- d.inv.InvoiceOptions = opts.join(',');
- $inv.d.sync({ Target: 'setmode', Value: mode });
+ if (confirm($rct.toSetMc || $rct.toSetPc) === false) { return; }
+ let target = (mode === 'setonly') ? 'block.setonly' : 'block.setprice';
+ $.when($inv.t_fds_inv()).done(() => { $inv.d.sync({ Target: target }); });
};
$inv.sctp = () => {
let flds = $invcol.ctp;
@@ -1959,24 +2010,21 @@ $inv.sctp = () => {
});
};
/* Normalises the editor's working model into the exact field names the C# backend
- (FdsInvoiceData.BuildInvoiceParams) reads, then returns the `invc` payload:
- - balances/service sums come from `sms` (ttn/ttb), exposed on `new` as total_net/total_gross;
- - every VAT rate's net amount is exposed as new.vat__net (the backend reads the highest);
+ (FdsInvoiceData.BuildInvoiceParams) reads, then returns the `invc` payload. No totals/VAT
+ are computed here (ADR 0006/0008: the online editor performs no arithmetic at all) — the
+ backend session computes total_net/total_gross/vat itself (InvoiceDraftCalculator) once
+ opened from this payload, and BuildFdsData/BuildInvoiceParams reads them from there:
- new.invoicetitle -> new.title, new.loc -> new.provisionlocation, admin.paymentterms ->
new.paymentterm, admin.CustomerId -> admin.customerid.
Originals are kept alongside; the source objects are not mutated. */
$inv.invcPayload = function (d) {
d = d || {};
- let sms = d.sms || {}, nw = $.extend({}, d.new), adm = $.extend({}, d.admin);
- nw.total_net = sms.ttn || 0;
- nw.total_gross = sms.ttb || 0;
- /* VAT (rate + amount) is taken by the backend straight from the posted sms.vat map
- (FdsInvoiceData.HighestVat), so no per-rate new.vat_* keys are needed here. */
+ let nw = $.extend({}, d.new), adm = $.extend({}, d.admin);
nw.title = (nw.invoicetitle != null ? nw.invoicetitle : (nw.title || ''));
nw.provisionlocation = (nw.loc != null ? nw.loc : (nw.provisionlocation || ''));
nw.paymentterm = (adm.paymentterms != null ? adm.paymentterms : (nw.paymentterm || ''));
adm.customerid = (adm.customerid != null ? adm.customerid : adm.CustomerId);
- return { admin: adm, req: d.bai, sms: d.sms, new: nw };
+ return { admin: adm, req: d.bai, new: nw };
};
/* Zwischenspeichern and preview now run against the backend-authoritative session
(ADR 0006): no full-invoice re-upload — the cached draft is flushed / rendered by
@@ -1990,20 +2038,11 @@ $inv.rReload = () => {
$inv.cInv2({ id: s.search });
} catch (e) { }
};
-$inv.quantChange = function (i) {
- //console.debug({ t: this, i: i });
- let t = $(this), f = t.closest('form'), fi = {}, pf = (i) => parseFloat(i.toString().replace('%', '').replace(',', '.')), rtp = (num) => num.toFixed(2);
- f.find(':input').each((i, e) => { fi[$(e).attr('name')] = $(e); });
- let qv = parseInt(fi.quantityhours.val() || '0'), nv = pf(fi.net.val() || '0'), vat = pf(fi.vat.val()) * 0.01;
- if (qv > 0 && nv > 0) {
- fi.net_val.val(rtp(qv * nv));
- fi.vat_val.val(rtp(qv * nv * vat));
- if (['Service'].includes(fi.Type.val())) {
- fi.svcnet_val.val(rtp(qv * nv));
- fi.svcvat_val.val(rtp(qv * nv * vat));
- }
- }
-};
+/* No client-side arithmetic (ADR 0006/0008): quantity/price/VAT edits are posted as raw values
+ and the server (InvoiceDraftCalculator.RecomputeLineValues) computes net_val/vat_val/
+ svcnet_val/svcvat_val. The fields are left as entered here; the authoritative values are
+ pushed back onto the row by $inv.d.applyItems once the change reaches the backend. */
+$inv.quantChange = function (i) { };
$inv.storno = function (id, fds) {
let o, fr = $$.dc('choicefrm').append([
$$.dc('btn', 'Storno ohne Details').click({ id: id, mode: 'simple' }, (ev) => { o.c.trigger('modal_close'); $inv.cSt(ev.data); })
diff --git a/Fuchs/wwwroot/web/fis.inv.de.min.js b/Fuchs/wwwroot/web/fis.inv.de.min.js
index e437160..ad06eed 100644
--- a/Fuchs/wwwroot/web/fis.inv.de.min.js
+++ b/Fuchs/wwwroot/web/fis.inv.de.min.js
@@ -1 +1 @@
-let $rct={mdl:"Aufträge",or:"offene Aufträge",orr:"offene Aufträge (4 W)",rn:"Auftragsnummer",iov:{all:"Auftragsübersicht (alle)","":"Auftragsübersicht"},wk:"Woche",nd:"Keine Daten gefunden.",h:"Uhr",rq1:"Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",rq2:"Auftragsdaten werden geladen",rq1f:"Die Auftragsdaten von MFR konnten nicht oder nicht schnell genug abgerufen werde.\nMöchten Sie mit den bestehenden Daten trotzdem weitermachen?",note1:"Im Bruttobetrag sind {0} Lohnkosten enthalten (netto {1}). Die darin enthaltene Umsatzsteuer beträgt {2}.",note2:"Bitte beachten Sie, nach §14 Abs. 1 Umsatzsteuergesetz ist diese Rechnung ein Zahlungsbeleg oder eine andere beweiskräftige Unterlage für 2 Jahre nach Ablauf des Kalenderjahres der Ausstellung dieser Rechnung aufzubewahren, soweit nicht aufgrund anderer gesetzlicher Regelungen andere ggf.längere Aufbewahrungsfristen gelten.",note3:"Privathaushalten erstattet das Finanzamt bis zu {0} des Arbeitslohns mit der nächsten Steuererklärung.",note4:"Für bereits erbrachte Arbeiten, Dienstleistungen, Materiallieferungen und getätigte Bestellvorgänge zum oben genannten Bauvorhaben, die sich aus dem mit Ihnen geschlossenen Vertrag ergeben, stellen wir Ihnen vertragsgemäß unsere Akontozahlung in Rechnung. Eine Endabrechnung erhalten Sie als Schlussrechnung nach Abschluss des gesamten Bauvorhabens. Das Ausführungsdatum entnehmen Sie bitte dem Schlusstext dieser Rechnung. Wir danken Ihnen herzlich für das entgegengebrachte Vertrauen und bitten Sie um kurzfristigen Ausgleich der Akontorechnung.",note13b:"Gem. §13b Umsatzsteuergesetz unterliegen Sie der Steuerschuldnerschaft des Leistungsempfängers zur Umsatzsteuer aus dieser Rechnung mit einem Steuersatz von 19%.",crI:"Rechnung erstellen",crII:"Abschlagsrechnung erstellen",dII:"Für eine Abschlagsrechnung darf nur ein Auftrag gewählt werden.",dnS:"Für eine Rechnung muss mindestens ein Auftrag gewählt werden.",inv:"Rechnung",invs:"Rechnungen",req:"Auftrag",provP:"Leistungszeitraum",provD:"Leistungsdatum",cP:"Position ändern",iRb:"Zeile darunter einfügen",dR:"Zeile löschen",sV:"USt festlegen",cD:"Löschen?",mR:"Zeile verschieben",svcPart:"Service-Anteil",vat:"Umsatzsteuer",combP:"Positionen zusammenfassen",toSetP:"Auf Setpreis umstellen (Positionen ohne Preis)",toSetPc:"Der Set-Preis wird auf die Summe seiner Positionen gesetzt und die Positionen selbst verlieren ihren Preis. Das ist nicht rückgängig zu machen (der Betrag kann danach nur noch manuell geändert werden). Fortfahren?",iSum:"Zwischensumme",dtRel:"Freigegeben am: ",dtCr:"Erstellt am: ",rqV:"USt des Auftrags?",cthd:"wirklich aus-/einblenden ?",cst:{style:"currency",currency:"EUR"},sts:{IsWorkDone:"Arbeiten erledigt",Closed:"Auftrag geschlossen",SubcontractorPendingConfirmation:"Warten auf Bestätigung (Unterauftrag)",Scheduled:"Geplant",OfferIsRejected:"Angebot abgelehnt",OfferIsSend:"Offen (Angebot versandt)",CollaborationWaitingConfirmation:"Warten auf Bestätigung (Zusammenarbeit)",Released:"Freigegeben",OfferIsConfirmed:"Bestätigt",InProgress:"In Bearbeitung",ReadyForScheduling:"Zur Planung",Created:"Erstellt",Rejected:"Abgebrochen",Invoiced:"Rechnung gestellt","-":"-"},invHR:["Pos.","Menge","Artikelbezeichnung","VK","Summe"],frm:{invoiceaddress:"Adresse",loc:"Leistungsort / Lieferadresse",invoiceemail:"Email"}},$rcol={req:new fields_definition("Auftrag","Aufträge",[{name:"tags",label:"",type:"string",dfnc:function(e,t){""!==(e||"")&&($(this).aC("tags"),e.split(",").forEach((e=>{""!==e&&$(this).append($$.sc("tag "+e.replace(" ","_").replace("/","_").toLowerCase(),e))})))}},{name:"DateOfCreation",label:"Datum",type:"date",title:function(e){$(this).attr("title",$rct.dtCr+fdt(e.DateOfCreation).ne("-")+" \n"+$rct.dtRel+fdt(e.DateReleased).ne("-"))}},{name:"CustomerName",label:"Kunde (Firma)",type:"string"},{name:"Name",label:"Auftragsname",type:"string"},{name:"ExternalId",label:"Auftragsnummer",type:"string"},{name:"ParentExtenalId",label:"PAuftrag",type:"string"},{name:"InvoiceId",label:"RNummer",type:"string",dfnc:function(e,t){$(this).rwText(e," ").find("span").each((function(){$(this).aC("cla").click({id:$(this).text()},$inv.jdbn)}))}},{name:"State",label:"Status",type:"string"},{name:"WorkDoneAt",label:"Erledigt am",type:"date"},{name:"Description",label:"Beschreibung",type:"html"}]),itm:new fields_definition("Auftragsposition","Auftragspositionen",[{name:"NameOrNumber",label:"Bezeichnung",type:"string"},{name:"Type",label:"Typ",type:"select",required:!0,value:"Text",url:[{value:"Text",label:"Text"},{value:"Equipment",label:"Ausrüstung"},{value:"Material",label:"Material"},{value:"Service",label:"Arbeitsleistung"}],change:function(e){$req.quantChange.call(this,e)}},{name:"quantityhours",label:"Anzahl / Menge",type:"number",precision:"0.01",value:1,change:function(e){$inv.quantChange.call(this,e)}},{name:"UnitString",label:"Einheit",type:"select",url:["LFDM","Stck","Std.","QM","AW","Pauschal"],change:function(e){$inv.quantChange.call(this,e)}},{name:"net",label:"EinzelPreis netto",type:"number",precision:"0.01",value:0,change:function(e){$inv.quantChange.call(this,e)}},{name:"net_val",label:"GesamtPreis netto",type:"number",precision:"0.01",value:0},{name:"vat_val",label:"GesamtPreis USt",type:"number",precision:"0.01",value:0},{name:"svcnet_val",label:"Arbeitslohn netto",type:"number",precision:"0.01",value:0},{name:"svcvat_val",label:"Arbeitslohn USt",type:"number",precision:"0.01",value:0},{name:"net_pos",label:"Netto",type:"string"},{name:"bo_pos",label:"Brutto",type:"string"},{name:"vat",label:"USt",type:"string",value:"19,0%",change:function(e){$inv.quantChange.call(this,e)}},{name:"Note",label:"Details",type:"html",tinymce:!0}])},$ict={mdl:"Rechnungen",iov:{all:"Rechnungen (alle)","":"Rechnungen (nur fertige)","#d":"Rechnungen (nur Entwürfe)","#u":"Rechnungen (nur unbezahlt)","#r":"Rechnungen (nur angemahnt)","#a":"Rechnungen (nur Akonto)","#c":"Rechnungen (nur Storno)","#ru":"Rechnungen (nur angemahnt + unbez.)"},uba:", gesamter Zeitraum)",req:"Auftrag",inv:"Rechnung",rem:"Mahnung",in:"Rechnungsnummer",cc:"Kunde",wk:"Woche",nd:"Keine Daten gefunden.",dl:"Herunterladen",ed:"Bearbeiten",ced:"Bearbeitung fortsetzen",sItm:"Einzelheiten anzeigen",sPay:"Zahlungen anzeigen",cdI:"Entwurf der Rechnung löschen?",rel:"Neu Laden",relm:"Bitte laden Sie Liste manuell neu, um die Änderungen zu sehen.",dsp:"Rechnung anzeigen",storno:"Storno-Rechnung erstellen",credit:"Gutschrift erstellen",remd:"Mahnung erstellen",remdt:"Mahnung erstellen zur Rechnung {0}",remlst:"Mahnungen anzeigen",remdsp:"Mahnung anzeigen",remres:"Mahnung erneut senden",remresc:"Mahnung {0} wirklich erneut senden?",remresr:"Mahnung {0} wurde erfolgreich versandt.",setpyd:"Bezahlt markieren",cpyd:"Rechnung wirklich als bezahlt markieren?",setupd:"Bezahlt-Markierung aufheben",cupd:"Bezahlt-Markierung wirklich aufheben?",ivE:"Die Email-Adresse ist vermutlich nicht gültig.",ivEc:"\nMöchten Sie fortfahren?",pna:"Diese Seite ist in der Vorschau nicht verfügbar",tpe:"Die Anzahl von {0} Seiten wird aktuell nicht unterstützt",eis:"Der Rechnungsentwurf konnte nicht gespeichert werden.",iss:"Zwischenstand speichern.",p13b:"USt -> §13b",setm:"Set-Preisanzeige",setmo:{setprice:"Set mit Preis – Positionen ohne Preis",itemprices:"Positionen mit Preis – Set als Überschrift",setonly:"Nur Set mit Preis – Positionen ausgeblendet"},ctp:"Ansprechpartner festlegen",mfr:"Von MFR neu abrufen",rq1:"Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",rq2:"Auftragsdaten werden geladen",iq1:"Rechnungsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",iq2:"Rechnungsdaten werden geladen",sis:"Rechnung als versandt markieren",srs:"Mahnung als versandt markieren",sisc:"Rechnung wirklich als versandt markieren?",srsc:"Mahnung wirklich als versandt markieren?",iSt:{dft:"Entwurf",uns:"nicht versandt",pyd:"bezahlt",cc:"storniert",op:"offen",due:"fällig",ovd:"überfällig",rem:"angemahnt"},rSt:["","Überfällig","2. Mahnung","3. Stufe"],pSt:{a:"Vollst.",p:"Teilz."},ivT:{i:"AbschlagsR.",f:"SchlussR",r:"Rechnung",c:"StornoR."},rovlh:"Übersicht der bisherigen Mahnungen",rovl:["Betreff","Betrag","Betrag gezahlt","fertiggestellt am"],remHR:["Rechnung","vom","Rechnungsbetrag","bereits bezahlt","noch offen"],translatePaymentTerm:e=>(e||"").replace("wd"," Werktagen").replace("d"," Tagen").replace("wk"," Wochen")||"10 Tagen",payi:{account:"Konto",name:"Zahler",text:"Verw.Zweck",InvoiceID:"Rechnung",amount:"Betrag",date:"Datum",manual:"Typ"}},$invcol={datev:new fields_definition("Rechnung","Rechnungen",[{name:"Umsatz (ohne Soll/Haben-Kz)",label:"Umsatz (ohne Soll/Haben-Kz)",type:"string"},{name:"vf",label:"vf",type:"string"},{name:"Soll/Haben-Kennzeichen",label:"Soll/Haben-Kennzeichen",type:"string"},{name:"Konto",label:"Konto",type:"string"},{name:"Gegenkonto",label:"Gegenkonto",type:"string"},{name:"BU-Schlüssel",label:"BU-Schlüssel",type:"string"},{name:"Belegdatum",label:"Belegdatum",type:"string"},{name:"Belegfeld 1",label:"Belegfeld 1",type:"string"},{name:"Belegfeld 2",label:"Belegfeld 2",type:"string"},{name:"Buchungstext",label:"Buchungstext",type:"string"}]),inv:new fields_definition("Rechnung","Rechnungen",[{name:"invstatus",label:"Status",type:"select",url:$ict.iSt},{name:"balance",label:"Umsatz",type:"string",dtype:"currency"},{name:"CustomerName",label:"Kunde",type:"string"},{name:"InvoiceId",label:"RNummer",type:"string"},{name:"InvoiceType",label:"Typ",type:"select",url:$ict.ivT},{name:"request",label:"Auftrag",type:"string",dtype:"num"},{name:"vat",label:"MwSt",type:"string",dtype:"num"},{name:"deb_cred",label:"Soll/Haben",type:"string"},{name:"customer",label:"Konto",type:"string",dtype:"num"},{name:"contra_account",label:"Gegenkonto",type:"string",dtype:"num"},{name:"Belegdatum",label:"Belegdatum",type:"date"},{name:"reminderstatus",label:"MahnStatus",type:"select",url:$ict.rSt},{name:"reminder",label:"# Mahnungen",type:"integer"},{name:"Buchungstext",label:"Buchungstext",type:"string"},{name:"Payment",label:"Zahlung",type:"string"}]),rem:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"amount",label:"Rechnungsbetrag",type:"number",precision:"0.01",value:1},{name:"amount_payed",label:"bereits bezahlt",type:"number",precision:"0.01",value:1}]),rem2:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"DocumentName",label:"Name",type:"string"},{name:"subject",label:"Betreff",type:"string"},{name:"DateSent",label:"Versanddatum",type:"date"},{name:"status",label:"Status",type:"string"},{name:"amount_open",label:"offener Betrag",type:"number",precision:"0.01"},{name:"InvoiceId",label:"RNummer",type:"string"}]),rid:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"type",label:"Typ",type:"select",url:[["f","einfache Zahlungserinnerung"],["m","Mahnung"],["l","letzte Mahnung"]],required:!0},{name:"level",label:"Stufe",type:"select",url:[["1","Stufe 1"],["2","Stufe 2"],["3","Stufe 3"],["4","Stufe 4"],["5","Stufe 5"],["6","Stufe 6"]],required:!0}]),ctp:new fields_definition("Ansprechpartner","Ansprechpartner",[{name:"name",label:"Name",type:"string"},{name:"email",label:"Email",type:"string"}])},gi=(e,t)=>$$.sc("glyphicon glyphicon-"+e).aC(t),$inv={init2:function(e,t){e=e||"inv",t=t||{},$ocms.getScript([],(function(){$inv.init3(e,t)}))},init3:async function(e,t){$fis.cf(!0);let n=$fis.lf(!0);$("#topbar").ocmsmenu([]),$("#activemodule").text($ict.mdl);let i=[(async()=>{await $fis.getAuth("fds_inv")>0&&($inv.prepLst(""),n.aC("fix"))})(),new Promise(((e,t)=>{$fis.prepAuth(["fds_reminder"])}))];await Promise.all(i)},prepLst:function(e){let t=new Date,n=$fis.lf(!0).ldng(1),i=new Date("2021-01-01");$fis.frm_list().IN((function(){}));let a=[];$.each($ict.iov,((e,t)=>{a.push({lbl:t,fnc:()=>{$inv.prepLst(e),n.aC("fix")}})})),$fis.lfm().ocmsmenu([{lbl:"Filter",itm:a}]);$$.i({placeholder:$ict.in}).appendTo($$.dc("mth ivn",n)).enterKey((function(e){let t=$(this),n=t.val()||"";e.stopPropagation(),t.parent().siblings().rC("selected"),n.length>3&&(t.parent().aC("selected"),$inv.renderinv("i:"+n,"s","all"),t.val(""))})),$$.i({placeholder:$ict.cc}).appendTo($$.dc("mth ivc",n)).enterKey((function(e){let t=$(this),n=t.val()||"";e.stopPropagation(),t.parent().siblings().rC("selected"),n.length>=3&&(t.parent().aC("selected"),$inv.renderinv("c:"+n,"s","all"),t.val(""))}));"#"===e.substr(0,1)&&$$.dc("mth extra",n).text($ict.iov[e].replace(")",$ict.uba)).click((function(t){let n=$(this);if(t.stopPropagation(),n.siblings().rC("selected"),!0===n.is(".selected")){n.toggleClass("selected");let t=fdt(new Date,"yy-MM-dd");$inv.renderinv(t,"a",e)}n.aC("selected")})),n.append("
");let r=$$.dc("mthl",n),l=t.getFullYear(),d=t.getMonth()+1;for(let t=i.getFullYear();t<=l;t++){let n=$$.dc("yr").prependTo(r).text($ict.iov[e]+" - "+t.toString()).toggleClass("selected",t===l);n.click({yr:t},(function(e){e.stopPropagation(),n.siblings().rC("selected"),n.aC("selected")}));let a=$$.dc("mfrm",n);for(let n=0;n<(t!==l?12:d);n++){i=new Date(t,n,1);let r=$$.dc("mth").prependTo(a).text($ict.iov[e]+" - "+fdt(i,"MMM yyyy"));if(r.click({yr:t,mt:n},(function(t){if(t.stopPropagation(),r.siblings().rC("selected"),!0===r.is(".selected")){r.toggleClass("selected");let n=fdt(new Date(t.data.yr,t.data.mt,1),"yy-MM-dd");$inv.renderinv(n,"m",e)}r.aC("selected")})),""===e){$$.dc("mthdl",r).append(gi("compressed","ico")).click({yr:t,mt:n},(function(e){e.stopPropagation();let t=fdt(new Date(e.data.yr,e.data.mt,1),"yy-MM-dd");$inv.downloadzip(t,"m")}))}let l=getMonday(i),d=new Date(i);d.setMonth(d.getMonth()+1),d.setDate(0),d=getMonday(d);let s=$$.dc("wfrm",r);for(;l<=d;){let t=$$.dc("wk",s).text(($ict.wk||"W")+" "+fdt(l,"dd.MM.yy"));t.click({rd:new Date(l)},(function(n){n.stopPropagation();let i=fdt(n.data.rd,"yy-MM-dd");$inv.renderinv(i,"w",e),r.siblings().rC("selected").find(".wk").rC("selected"),r.aC("selected").find(".wk").rC("selected"),t.aC("selected")})),$$.dc("wkdl",t).append(gi("compressed","ico")).click({rd:new Date(l)},(function(e){e.stopPropagation();let t=fdt(e.data.rd,"yy-MM-dd");$inv.downloadzip(t,"w")})),l.setDate(l.getDate()+7)}}}n.ldng(0)},rerenderinv:function(){let e=$("#contentframe .invfrm:first");if(e.length>0){let t=e.data("sets")||{};t.mode&&$inv.renderinv(t.tgt,t.mode,t.includes)}},renderinv:function(e,t,n){let i=$fis.frm_list(!0,!0).ldng(1),a=$$.dc("invfrm",i).aC("md"+t).data("sets",$.extend({},{tgt:e,mode:t,includes:n})),r=$fis.lf();$ocms.postXT({url:$ocms.url("inv/invl"),data:{mode:t,tgt:e,includes:n},success:i=>{r.rC("fix").aC("hd"),$$.dc("ovhd",a).text(i.admin.title);let l=$$.tblset({},a),d=$invcol.inv,s=$$.tr(l.hd);$$.th(s);$.each(d.fields||[],((e,t)=>{$$.th(s).text(t.label),"vat"===t.name&&$$.th(s)})),$.each(i.invoices||[],((s,c)=>{let o=$$.tr(l.bdy);o.click((function(){r.rC("fix").aC("hd"),o.toggleClass("selected").siblings().rC("selected").find("td.av").rC("av"),o.find("td.av").rC("av"),!0===o.is(".selected")?$inv.iMn(c):$inv.eM()}));let u=$$.td(o,{class:"raux"});c.hasFile?($$.dc("idl ilbtn",u,{title:$ict.dl+"\n"+c.DocumentName}).append(gi("save-file","ico")).click({id:c.Id},$inv.downloadinv),$$.dc("idl ilbtn",u,{title:$ict.dsp+"\n"+c.DocumentName}).append(gi("eye-open","ico")).click({id:c.Id,typ:"inv"},$inv.jdisp)):!1===c.isFinal&&!0===$fis.isAuth("fds_inv",2)&&$$.dc("idl ilbtn",u,{title:$ict.ed}).append(gi("edit","ico")).click({id:c.Id},$inv.doContInv),$$.dc("iitm ilbtn",u,{title:$ict.sItm}).append(gi("list","ico")).click({id:c.Id},$inv.showitm),$$.dc("iitm ilbtn",u,{title:$ict.sPay}).append(gi("euro","ico")).click({id:c.Id},$inv.showpay),$.each(d.fields||[],((r,l)=>{let d,s,u=$$.td(o).aC(l.dtype);switch("select"===(l.type||"")?u.text((l.url||{})[c[l.name]]||""):u.text(c[l.name]),l.name||""){case"vat":d=$$.sel().appendTo($$.td(o,{class:"vsel"})),s=(i.admin.ust_options||"19,0%;16,0%;0,0%").split(";"),$.each(s,((e,t)=>{$$.opt(t,t).appendTo(d)})),d.click((function(e){e.stopPropagation()})).val(c[l.name]).change().change({frm:a,tgt:e,mode:t,id:c.Id,td:u,includes:n},$inv.setvat),u.toggleClass("hl",c[l.name].substr(0,2)!==s[0].substr(0,2)).click((function(e){e.stopPropagation(),$(this).toggleClass("av")}));break;case"balance":u.aC("sh_"+(c.SollHaben||"").toLowerCase());break;case"invstatus":case"reminderstatus":u.aC(("invstatus"===l.name?"is_":"rs_")+c[l.name])}}))}))},complete:()=>{i.ldng(0)}})},setvat:function(e){let t=$(this),n=e.data||{};$ocms.postXT({url:$ocms.url("inv/setvat"),data:{id:n.id,val:t.val()},success:e=>{n.td.rC("av"),$inv.renderinv(n.tgt,n.mode,n.includes)}})},downloadzip:function(e,t){$(this).empty();window.open($ocms.url("inv/datevzip?mode="+t+"&tgt="+encodeURIComponent(e)),"_blank")},showitm:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&$ocms.postXT({url:$ocms.url("inv/rqi"),data:{id:e.data.id},success:e=>{let t=$$.dc("rfrm");(e.requests||[]).length<1?t.text($ict.nd):$.each(e.requests||[],(function(e,n){let i=$$.dc("srq",t);$$.dc("nme",i).text(n.name);let a=$$.tblset({class:"if"},i);$.each(n.items||[],((e,t)=>{let n=$$.tr({id:"itm"+t.Id}).appendTo(a.bdy);$$.td(n).text(t.NameOrNumber),$$.td(n).text(t.Type),$$.td(n).aC("currency").text(t.net_pos),$$.td(n).aC("currency").text(t.bo_pos),$$.td(n).aC("num").text(t.vat)}))})),$ocms.dlg(t,{width:1e3})}})},showpay:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&$ocms.postXT({url:$ocms.url("inv/pyi"),data:{id:e.data.id},success:e=>{let t=$$.dc("rfrm");if((e.payments||[]).length<1)t.text($ict.nd);else{let n=$$.tblset({class:"if"},t),i=$$.tr(n.hd);$.each(["date","account","name","text","InvoiceID","amount","manual"],((e,t)=>{$$.th(i,$ict.payi[t])})),$.each(e.payments,((e,t)=>{let i=$$.tr({id:"itm"+t.banking_uid}).appendTo(n.bdy);$$.td(i).aC("date").text(t.date),$$.td(i).text(t.account),$$.td(i).text(t.name),$$.td(i).text(t.text),$$.td(i).text(t.InvoiceID),$$.td(i).aC("currency").text(t.amount),$$.td(i).text(t.manual)}))}$ocms.dlg(t,{width:1e3,title:"Übersicht der Zahlungen"})}})},downloadinv:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&window.open($ocms.url("inv/rdoc?id="+e.data.id),"_blank")},doContInv:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&$inv.cntInv({id:e.data.id})}},$$inv={init2:$inv.init2,auth:{}};export default $$inv;$inv.cInv=function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&!1!==$fis.isAuth("fds_inv",2)&&$inv.cInv2({id:e.data.id})},$inv.rMn=e=>{let t=[{lbl:$ict.req,itm:[]}];return!0===bool(e,!1)&&!0===$fis.isAuth("fds_inv",2)&&Array.prototype.push.apply(t[0].itm,[{lbl:$rct.crI,fnc:$inv.ccInv,data:{typ:"r"}},{lbl:$rct.crII,fnc:$inv.ccInv,data:{typ:"i"}}]),t.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(t)},$inv.iMnr=e=>{let t=booln(e.isFinal,!0),n=e.Id,i=booln(e.fds,!1),a=[{glyph:"glyphicon-menu-left",fnc:()=>{$fis.frm_edit().remove()}},{lbl:$ict.inv,itm:[]},{lbl:$ict.rem,itm:[]}];return!1===t&&!0===$fis.isAuth("fds_inv",2)?a[1].itm.push({lbl:$ict.ced,fnc:$inv.clCntInv}):!0===$fis.isAuth("fds_inv",1)&&a[1].itm.push({lbl:$ict.dsp,fnc:()=>$inv.disp(n,"inv")}),!0===i&&!0===t&&!0===$fis.isAuth("fds_inv",2)&&(a[1].itm.push({lbl:$ict.storno,fnc:()=>$inv.storno(n,i)}),a[1].itm.push({lbl:$ict.credit,fnc:()=>$inv.credit(n,i)})),!0===t&&!0===$fis.isAuth("fds_reminder",2)&&(a[2].itm.push({lbl:$ict.remd,fnc:()=>$inv.ccRem(n,e.InvoiceId)}),a[2].itm.push({lbl:$ict.remlst,fnc:()=>$inv.dspRem(n)})),!0===t&&!0===$fis.isAuth("fds_reminder",2)&&!1===booln(e.IsSent,!1)&&a[2].itm.push({lbl:$ict.srs,fnc:()=>$inv.srs(n)}),a.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(a)},$inv.iMn=e=>{let t=booln(e.isFinal,!0),n=e.Id,i=booln(e.fds,!1),a=[{glyph:"glyphicon-menu-left",fnc:()=>{$fis.frm_edit().remove()}},{lbl:$ict.inv,itm:[]},{lbl:$ict.rem,itm:[]}];return!1===t&&!0===$fis.isAuth("fds_inv",2)?a[1].itm.push({lbl:$ict.ced,fnc:()=>{$inv.cntInv({id:n})}}):!0===$fis.isAuth("fds_inv",1)&&a[1].itm.push({lbl:$ict.dsp,fnc:()=>$inv.disp(n,"inv")}),!0===$fis.isAuth("fds_inv",2)&&(a[1].itm.push({lbl:$ict.storno,fnc:()=>$inv.storno(n,i)}),a[1].itm.push({lbl:$ict.credit,fnc:()=>$inv.credit(n,i)})),!0===t&&!1===booln(e.IsPayed,!1)?(!0===$fis.isAuth("fds_reminder",2)&&a[2].itm.push({lbl:$ict.remd,fnc:()=>$inv.ccRem(n,e.InvoiceId)}),!0===$fis.isAuth("fds_inv",2)&&a[1].itm.push({lbl:$ict.setpyd,fnc:()=>$inv.setPyd(n)})):!0===t&&!0===booln(e.IsPayed,!1)&&"m"===(e.PaymentStatus||"")&&!0===$fis.isAuth("fds_inv",2)&&a[1].itm.push({lbl:$ict.setupd,fnc:()=>$inv.setUpd(n)}),!0===$fis.isAuth("fds_reminder",2)&&a[2].itm.push({lbl:$ict.remlst,fnc:()=>$inv.dspRem(n)}),!0===t&&!0===$fis.isAuth("fds_inv",2)&&!1===booln(e.IsSent,!1)&&a[1].itm.push({lbl:$ict.sis,fnc:()=>$inv.sis(n)}),!1===i&&a[1].itm.push({lbl:$ict.mfr,fnc:()=>$inv.mfrrel(n)}),$("#topbar").ocmsmenu(a)},$inv.emOpt=e=>"iss,p13b,ctp"+(""===((e||{}).setmode||"")?",setm":""),$inv.eM=(e,t,n)=>{let i=[];return!0!==booln(e,!1)&&!0!==booln(t,!1)||i.push({glyph:"glyphicon-menu-left",fnc:()=>{$fis.lf(!0),$fis.frm_edit().remove()}}),!0===(n||"").split(",").includes("iss")&&i.push({lbl:$ict.iss,fnc:$inv.ssave}),!0===(n||"").split(",").includes("ctp")&&i.push({lbl:$ict.ctp,fnc:$inv.sctp}),!0===(n||"").split(",").includes("p13b")&&i.push({lbl:$ict.p13b,fnc:$inv.sp13b}),!0===(n||"").split(",").includes("setm")&&i.push({lbl:$ict.setm,fnc:$inv.ssetmode}),!0===(n||"").split(",").includes("iss")&&(i.push({lbl:"Änderungshistorie",fnc:()=>$inv.d.history()}),i.push({lbl:"Änderungen verwerfen",fnc:()=>$inv.d.discard()})),!0===booln(e,!1)&&i.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(i)},$inv.d={tbl:()=>$("div.invoice_layout table.invi"),layout:()=>$("div.invoice_layout"),token:function(){return $inv.d.tbl().data("dtoken")||""},hashes:function(){let e=$inv.d.tbl().data("bai")||[],t={};return $.each(e,((e,n)=>{t[(n.Id||"").toString()]=JSON.stringify(n)})),t},seed:function(e){let t=$inv.d.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dopen"),data:{payload:JSON.stringify(e)},success:e=>{$inv.d.tbl().data("dtoken",e.token).data("dver",e.version).data("dhashes",$inv.d.hashes()).data("dorder",$inv.d.order()),$fis.draft.bind(e.token,{onReady:()=>$inv.d.refresh(),onExpiring:e=>$inv.d.warnExpiry(e),onClosed:e=>$inv.d.closed(e)}),$inv.d.refresh()},error:()=>{t.rC("freeze")},complete:()=>{$inv.d.tbl().removeData("dseeding")}})},refresh:function(e){let t=$inv.d.token();""!==t&&$ocms.postXT({url:$ocms.url("inv/dstate"),data:{token:t},success:t=>{$inv.d.applyState(t),"function"==typeof e&&e(t)},error:e=>{e&&410===e.status&&$inv.d.closed("expired")},complete:()=>{$inv.d.layout().rC("freeze")}})},applyState:function(e){let t=$inv.d.tbl();t.length<1||(t.data("dver",e.version).data("serverSums",e.sums),$inv.d.footer(t,e.sums||{},e.admin||{}),$inv.d.notes(e.notes||[]),$inv.d.validation(e.validation||[]),$inv.d.applyPositions(t,e.req||[]),$inv.d.applySetDisplay(t,e.setDisplay||{}),$inv.eM(!1,!0,$inv.emOpt(e.admin||{})))},notes:function(e){let t=$inv.d.layout();if(t.length<1)return;let n=t.children(".dnotes");n.length<1&&(n=$$.dc("dnotes"),t.append(n)),n.empty(),(e||[]).forEach((e=>$$.dc("dnote").aC(e.style||"InvoiceNotes").text(e.text)))},applyPositions:function(e,t){(t||[]).forEach((t=>(t&&t.itm||[]).forEach((t=>{if(!t||""===(t.id||""))return;let n=e.find("#itm"+t.id+" td.keep").first();n.length&&n.text(null!=t.p?t.p:"")}))))},applySetDisplay:function(e,t){e.find("tr.itm").each(((e,n)=>{let i=$(n),a=((i.data()||{}).Id||"").toString();if(""===a||!Object.prototype.hasOwnProperty.call(t,a))return;let r=t[a]||{};i.tC("sethdr",bool(r.h,!1)),!1===bool(r.p,!0)&&i.find("td.currency").text("")}))},sync:function(e){let t=$inv.d.token();""!==t&&($inv.d.layout().aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dpatch"),data:{token:t,delta:JSON.stringify(e)},success:()=>{$inv.d.refresh()},error:e=>{$inv.d.layout().rC("freeze"),e&&410===e.status&&$inv.d.closed("expired")}}))},order:function(){return($inv.d.tbl().data("bai")||[]).map((e=>(e.Id||"").toString()))},syncChanged:function(e){if(""===$inv.d.token())return;let t=e.data("bai")||[],n=e.data("dhashes")||{},i={},a=[],r=[];$.each(t,((e,t)=>{let r=(t.Id||"").toString(),l=JSON.stringify(t);i[r]=l,n[r]!==l&&a.push(t)})),$.each(n,(e=>{void 0===i[e]&&r.push(e)}));let l=$inv.d.order(),d=e.data("dorder")||[];e.data("dhashes",i).data("dorder",l),a.forEach((e=>$inv.d.sync({Target:"block.replace",Ref:(e.Id||"").toString(),Value:e}))),r.forEach((e=>$inv.d.sync({Target:"block.remove",Ref:e}))),d.length===l.length&&d.slice().sort().join(",")===l.slice().sort().join(",")&&d.join(",")!==l.join(",")&&$inv.d.sync({Target:"block.order",Value:l})},syncField:function(e,t){if(""===$inv.d.token())return;let n={invoicetitle:"title",invoiceaddress:"address",invoiceemail:"email",loc:"provisionlocation",provisionlocation:"provisionlocation",provisionperiod:"provisionperiod"}[e];n&&$inv.d.sync({Target:n,Value:t})},footer:function(e,t,n){let i=e.children("tfoot").empty();e.nextAll(".fnote").remove();let a=bool(n.p13b,!1),r=(e,t,n)=>$$.tdc("currency",$$.tr(i,{class:n||"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text(e)]),fnum(t,$rct.cst)),l=t=>$$.dc("fnote").insertAfter(e).rwText(t);r("Netto",t.total_net||0),!1===a&&$.each(t.vat||{},((e,t)=>r($rct.vat+" "+e+"%",t,"tvat"))),r("Summe",t.total_gross||0);let d=n.type||"";"i"===d?(l($rct.note2),l($rct.note4)):"c"===d?l($rct.note2):(l(string($rct.note3,[fnum(((t.service_net||0)+(t.service_vat||0))*(n.tax_servicerefund||0),$rct.cst)])).aC("ntax"),l($rct.note2),l(string($rct.note1,[fnum((t.service_net||0)+(t.service_vat||0),$rct.cst),fnum(t.service_net||0,$rct.cst),fnum(t.service_vat||0,$rct.cst)]))),!0===a&&l($rct.note13b)},validation:function(e){let t=$("div.invoice_layout");if(t.length<1)return;let n=t.children(".dvalidation");n.length<1&&(n=$$.dc("dvalidation"),t.prepend(n)),n.empty().tC("hidden",(e||[]).length<1),$.each(e||[],((e,t)=>$$.dc("dvmsg",n).aC(t.severity).text(t.message)))},preview:function(){let e=$inv.d.token();if(""===e)return;let t=$inv.d.layout(),n=($inv.d.tbl().data("new")||{}).invoiceemail||"";!1===$fis.ValidateEmail(n)&&!1===bool(confirm($ict.ivE+$ict.ivEc),!1)||(t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dpreview"),data:{token:e},success:n=>{t.rC("freeze");let i=$$.dc("imagecollection pdfpreview"),a=Math.round(.88*vh()),r=n.total;r>10&&$$.dc("note warn",i).text($ict.tpe),$.each(n.img||[],((e,t)=>{$$.dc("pdfp",i).append($$.img(t).css("max-height",(a-rpx(6)).toString()+"px"))}));for(let e=(n.img||[]).length+1;e<=r;e++)$$.dc("pdfp ph",i).append($$.dc("note",$ict.pna));$ocms.dlg(i,{size:[a,Math.round(.88*vw())],zindex:50,form:!1,button:$rct.crI,confirm:function(n){let i=$(this);t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dsave"),data:{token:e},success:e=>{$ocms.postXT({url:$ocms.url("req/sconf"),data:{id:e.invid},success:t=>{i.trigger("modal_close"),!0===t.hasFile&&window.open($ocms.url("req/idoc")+"?id="+e.invid,"_blank"),$inv.d.close(),$ocms.init("req"),$inv.rReload()},error:()=>{alert($t.f1),i.trigger("modal_close")},complete:()=>{t.rC("freeze")}})},error:()=>{t.rC("freeze"),alert($ict.eis)}})},cancel:function(e){confirm($ict.cdI)&&($inv.d.close(),$inv.rReload())}})},error:()=>{t.rC("freeze"),alert($ict.eis)}}))},save:function(){let e=$inv.d.token();if(""===e)return;let t=$inv.d.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dsave"),data:{token:e},success:e=>{$inv.d.tbl().data("invid",e.invid)},error:()=>{alert($ict.eis)},complete:()=>{t.rC("freeze")}})},history:function(){let e=$inv.d.token();""!==e&&$ocms.postXT({url:$ocms.url("inv/dhistory"),data:{token:e},success:e=>{let t=$$.dc("dhist");if((e.history||[]).length<1)$$.dc("note",t).text("Noch keine Änderungen erfasst.");else{let n=$$.tblset({class:"invtbl fullwidth"},t);$$.tr(n.hd).append([$$.th().text("Zeit"),$$.th().text("Feld"),$$.th().text("Alt"),$$.th().text("Neu")]),$.each(e.history,((e,t)=>$$.tr(n.bdy).append([$$.tdc("keep",fdt(t.timestamp)),$$.td().text(t.target),$$.td().text(t.oldValue),$$.td().text(t.newValue)])))}$ocms.dlg(t,{width:800,form:!1})}})},discard:function(){let e=$inv.d.tbl().data("invid")||"";""!==e?!1!==confirm("Alle Änderungen verwerfen und den zuletzt gespeicherten Stand neu laden?")&&($inv.d.close(),$inv.cntInv({id:e})):alert("Es wurde noch kein Zwischenstand gespeichert, der wiederhergestellt werden könnte.")},warnExpiry:function(e){let t=Math.max(1,Math.round((e||0)/60));$fis.notifications.push({severity:"info",title:"Entwurf läuft ab",message:"Der Rechnungsentwurf läuft in etwa "+t+" Minute(n) ab. Bitte zwischenspeichern, sonst gehen die Änderungen verloren."})},closed:function(e){let t=$inv.d.token();$inv.d.tbl().removeData("dtoken"),""!==t&&$fis.draft.release(t),$fis.frm_edit().remove(),$fis.lf(!0),$fis.notifications.push({severity:"error",title:"Entwurf geschlossen",message:"expired"===e?"Der Rechnungsentwurf ist wegen Inaktivität abgelaufen. Nicht gespeicherte Änderungen sind verloren.":"Der Rechnungsentwurf wurde geschlossen."});try{$inv.rReload()}catch(e){}},close:function(){let e=$inv.d.token();""!==e&&($ocms.postXT({url:$ocms.url("inv/dclose"),data:{token:e}}),$fis.draft.release(e)),$inv.d.tbl().removeData("dtoken")}},$inv.rd={tbl:()=>$("div.invoice_layout table.invi"),layout:()=>$("div.invoice_layout"),token:function(){return $inv.rd.tbl().data("rdtoken")||""},seed:function(e){let t=$inv.rd.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dopen"),data:{payload:JSON.stringify(e)},success:e=>{$inv.rd.tbl().data("rdtoken",e.token).data("rdver",e.version),$fis.draft.bind(e.token,{onReady:()=>$inv.rd.refresh(),onExpiring:e=>$inv.rd.warnExpiry(e),onClosed:e=>$inv.rd.closed(e)}),$inv.rd.refresh()},error:()=>{t.rC("freeze")}})},refresh:function(e){let t=$inv.rd.token();""!==t&&$ocms.postXT({url:$ocms.url("rem/dstate"),data:{token:t},success:t=>{$inv.rd.applyState(t),"function"==typeof e&&e(t)},error:e=>{e&&410===e.status&&$inv.rd.closed("expired")},complete:()=>{$inv.rd.layout().rC("freeze")}})},applyState:function(e){let t=$inv.rd.tbl();t.length<1||(t.data("rdver",e.version).data("serverSums",e.sums).data("remid",e.remid||""),$inv.rd.footer(t,e.sums||{}),$inv.rd.notes(e.notes||{}),$inv.rd.validation(e.validation||[]))},notes:function(e){let t=$inv.rd.layout();if(t.length<1)return;let n=t.find(".srq");if(n.length<1)return;n.children(".dnote").remove();let i=(e||{}).intro||[],a=n.children().first();i.slice().reverse().forEach((e=>{let t=$$[0]("p").aC("dnote intro").rwText(e);a.length?t.insertBefore(a):t.appendTo(n)})),((e||{}).closing||[]).forEach((e=>$$[0]("p").aC("dnote closing").rwText(e).appendTo(n)))},sync:function(e){let t=$inv.rd.token();""!==t&&($inv.rd.layout().aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dpatch"),data:{token:t,delta:JSON.stringify(e)},success:()=>{$inv.rd.refresh()},error:e=>{$inv.rd.layout().rC("freeze"),e&&410===e.status&&$inv.rd.closed("expired")}}))},syncField:function(e,t){if(""===$inv.rd.token())return;let n={subject:"subject",invoiceaddress:"address",invoiceemail:"email",text:"text"}[e];n&&$inv.rd.sync({Target:n,Value:t})},syncAmount:function(e,t){""!==$inv.rd.token()&&($inv.rd.sync({Target:"amount",Value:(null!=e?e:0).toString()}),$inv.rd.sync({Target:"amount_payed",Value:(null!=t?t:0).toString()}))},footer:function(e,t){let n=e.children("tfoot").empty(),i=$$.tr(n,{class:"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text("Offener Betrag")]);$$.tdc("currency",i,fnum(t.amount_open||0,$rct.cst))},validation:function(e){let t=$inv.rd.layout();if(t.length<1)return;let n=t.children(".dvalidation");n.length<1&&(n=$$.dc("dvalidation"),t.prepend(n)),n.empty().tC("hidden",(e||[]).length<1),$.each(e||[],((e,t)=>$$.dc("dvmsg",n).aC(t.severity).text(t.message)))},preview:function(){let e=$inv.rd.token();if(""===e)return;let t=$inv.rd.layout(),n=($inv.rd.tbl().data("new")||{}).invoiceemail||"";!1===$fis.ValidateEmail(n)&&!1===bool(confirm($ict.ivE+$ict.ivEc),!1)||(t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dpreview"),data:{token:e},success:n=>{t.rC("freeze");let i=$$.dc("imagecollection pdfpreview"),a=Math.round(.88*vh());$.each(n.img||[],((e,t)=>{$$.dc("pdfp",i).append($$.img(t).css("max-height",(a-rpx(6)).toString()+"px"))})),$ocms.dlg(i,{size:[a,Math.round(.88*vw())],zindex:50,form:!1,button:$ict.remd,confirm:function(n){let i=$(this);t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dsave"),data:{token:e},success:e=>{$ocms.postXT({url:$ocms.url("rem/conf"),data:{id:e.remid},success:()=>{i.trigger("modal_close"),window.open($ocms.url("rem/idoc")+"?id="+e.remid,"_blank"),$inv.rd.close(),$ocms.init("req"),$inv.rReload()},error:()=>{alert($t.f1),i.trigger("modal_close")},complete:()=>{t.rC("freeze")}})},error:()=>{t.rC("freeze"),alert($t.f1)}})},cancel:function(e){confirm($ict.cdI)&&($inv.rd.close(),$inv.rReload())}})},error:()=>{t.rC("freeze"),alert($t.f1)}}))},save:function(){let e=$inv.rd.token();if(""===e)return;let t=$inv.rd.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dsave"),data:{token:e},success:e=>{$inv.rd.tbl().data("remid",e.remid)},error:()=>{alert($t.f1)},complete:()=>{t.rC("freeze")}})},history:function(){let e=$inv.rd.token();""!==e&&$ocms.postXT({url:$ocms.url("rem/dhistory"),data:{token:e},success:e=>{let t=$$.dc("dhist");if((e.history||[]).length<1)$$.dc("note",t).text("Noch keine Änderungen erfasst.");else{let n=$$.tblset({class:"invtbl fullwidth"},t);$$.tr(n.hd).append([$$.th().text("Zeit"),$$.th().text("Feld"),$$.th().text("Alt"),$$.th().text("Neu")]),$.each(e.history,((e,t)=>$$.tr(n.bdy).append([$$.tdc("keep",fdt(t.timestamp)),$$.td().text(t.target),$$.td().text(t.oldValue),$$.td().text(t.newValue)])))}$ocms.dlg(t,{width:800,form:!1})}})},warnExpiry:function(e){let t=Math.max(1,Math.round((e||0)/60));$fis.notifications.push({severity:"info",title:"Entwurf läuft ab",message:"Der Mahnentwurf läuft in etwa "+t+" Minute(n) ab. Bitte zwischenspeichern, sonst gehen die Änderungen verloren."})},closed:function(e){let t=$inv.rd.token();$inv.rd.tbl().removeData("rdtoken"),""!==t&&$fis.draft.release(t),$fis.frm_edit().remove(),$fis.lf(!0),$fis.notifications.push({severity:"error",title:"Entwurf geschlossen",message:"expired"===e?"Der Mahnentwurf ist wegen Inaktivität abgelaufen. Nicht gespeicherte Änderungen sind verloren.":"Der Mahnentwurf wurde geschlossen."});try{$inv.rReload()}catch(e){}},close:function(){let e=$inv.rd.token();""!==e&&($ocms.postXT({url:$ocms.url("rem/dclose"),data:{token:e}}),$fis.draft.release(e)),$inv.rd.tbl().removeData("rdtoken")}},$inv.cInv2=function(e){let t=$$.dc("rfrm").ldng(1),n=$ocms.dlg(t,{width:1e3});n&&n.ft.rwText($rct.rq1);let i=()=>{$ocms.postXT({url:$ocms.url("req/get"),timeout:60,data:{id:e.id,mode:"r"},success:t=>{t.admin=t.admin||{};let n=$fis.lf(!0).aC("fix").rC("hd");if($fis.frm_edit().IN(),$inv.eM(!0,!0),(t.requests||[]).length<1)n.aC("fix").text($rct.nd);else{$$.dc("lh",n,$rct.mdl);let i=$$.d(),a=$$.ul({class:"rql"}).data({search:e.id,parent:t.admin.parent}).appendTo(n),r={},l=$rcol.req.lbl();$.each(t.requests||[],(function(e,t){let n=$$.li({class:"cli rli"}).data($.extend({},t)).appendTo(a),d=$$.dc("lihd",n).addClass(t.state);!0===booln(t.open,!1)&&d.append($$.sc("cbox").click((()=>{n.tC("checked"),i.find("li").rC("checked"),!0===n.is(".checked")?$inv.rMn(t.open):$inv.eM(!0)}))),d.append([$$.sc("eid",t.ExternalId),$$.sc("nme",t.Name)]),$$.dc("lidt",n).append([$$.dc("rqs").append([$$.s(l.State+": "),$$.s($rct.sts[t.State||"-"])]),$$.dc("ivn").append([$$.s(l.InvoiceId+": "),$$.s(t.InvoiceId||"- -")]),$$.dc("wda").append([$$.s(l.WorkDoneAt+": "),$$.s(fdt(t.WorkDoneAt,"dd.MM.yyyy"))])]),r[t.Id]=n})),(t.inv||[]).length>0&&($$.dc("lh",n,$rct.invs),i=$$.ul({class:"ivl"}).appendTo(n),$.each(t.inv||[],((e,t)=>{let n=$$.li({class:"cli ili"}).data($.extend({},t)).appendTo(i),r=$$.dc("lihd",n).addClass(t.invstatus);!1===booln(t.isFinal,!0)?r.append($$.sc("cbox").click((()=>{""!==(t.Id||"")&&(n.tC("checked").siblings().rC("checked"),a.find("li").rC("checked"),!0===n.is(".checked")?$inv.iMnr(t):$inv.eM(!0))}))):["","dft"].indexOf(t.invstatus)<0&&r.append($$.sc("dli").click((function(){$inv.disp(t.Id,"inv")}))),r.append($$.sc("nme",t.DocumentName||t.Id)),$$.dc("lidt",n).append([$$.dc("wda").append([$$.s(fdt(t.DateCreated,"dd.MM.yyyy"))]),$$.d().text($ict.iSt[t.invstatus]||t.invstatus)])})))}},complete:()=>{n&&n.c.trigger("modal_close")}})};$ocms.postXT({url:$ocms.url("req/pget"),timeout:90,data:{id:e.id},success:e=>{n&&n.ft.rwText($rct.rq2),i()},error:()=>{confirm($rct.rq1f)?(n&&n.ft.rwText($rct.rq2),i()):n&&n.c.trigger("modal_close")}})},$inv.ccInv=function(e){let t=(e.data||{}).typ||"r",n=$fis.lf(),i=n.children("ul.rql"),a=i.data("parent"),r=[];if(i.find("li.rli.checked").each((function(){r.push($(this).data("Id"))})),r.length<1)return void alert($rct.dnS);if("i"===t&&r.length>1)return void alert($rct.dII);let l=$fis.frm_edit(),d=$$.dc("invoice_layout",l).append($$.dc("btn sprev").click($inv.sprev)),s=$fis.cf().width()>d.width()+n.width()+20;n.tC("fix",s).tC("hd",!s),$inv.eM(!1,!0);let c=$$.dc("rfrm").ldng(1),o=$ocms.dlg(c,{width:1e3});o.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("req/iget"),timeout:60,data:{id:a,mode:"ful",typ:t,sel:r.join(",")},success:e=>{let t=$$.dc("srq",d),n=$$.tblset({class:"invi"},t);n.bdy.remove(),n.ft=$$[0]("tfoot"),e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b")),n.tbl.data($.extend({new:{},sms:{},itm:{}},{admin:e.admin,companies:e.companies,locations:e.locations}));let i=$$.tr(n.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(i,e))),n.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.requests||[],(function(t,i){if(0!==(i.Id||0)){let t=$inv.worknotes(i);i.text="i"===e.admin.type?$rct.req+jine([i.ExternalId,i.Name],": ").eine(" ",""):jine([jine([fdt(i.WorkDoneAt,"dd.MM.yy"),i.ExternalId]," - "+$rct.req+" "),t.ne(i.Name)],": \n");let a=$$.tbody(n.tbl).data($.extend({},i));$inv.rendersrq.call(a)}}));let a=$$.tr($$.tbody(n.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(a),n.ft.appendTo(n.tbl);let r,l,s=e.admin||{},c=(e,t,i,a,r)=>{let l=$$.dc("inpfrm",d).aC(e).append("string"==typeof a?$$.dc("ahd",a):a>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",l).rwText(t);$$.dc("axf",l).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{n.tbl.data("new")[i]=e}},r),$inv.eHtml)),n.tbl.data("new")[i]=t};c("tfrm",s.invoicetitle,"invoicetitle",0,null),c("adrfrm",s.invoiceaddress,"invoiceaddress",0,null),c("locfrm","","loc",1,{list:deepCopy(e.locations),lbl:"ref",property:"address"}),c("emailfrm",s.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",d).append($$.dc("content").text(s.sender)),s.provisionend&&(l=s.provisionstart?$rct.provP:$rct.provD,r=s.provisionstart?fdt(s.provisionstart,"dd.MM.yyyy")+" - "+fdt(s.provisionend,"dd.MM.yyyy"):fdt(s.provisionend,"dd.MM.yyyy")),c("admfrm",r,"provisionperiod",l,1),n.tbl.data("new").CustomValues=s.CustomValues||"",$$.dc("inpfrm ctpfrm",d).text(jObj(s.CustomValues,"contactName")),n.tbl.children("tbody").each($inv.bdysort),n.tbl.trigger("fds.inv"),$inv.eM(!1,!0,$inv.emOpt(s))},complete:()=>{o.c.trigger("modal_close")}})},$inv.ccStInv=function(e){let t=e.data||{},n=$fis.lf(),i=t.id,a=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sprev)),r=$fis.cf().width()>a.width()+n.width()+20;n.tC("fix",r).tC("hd",!r),$inv.eM(!1,!0);let l=$$.dc("rfrm").ldng(1),d=$ocms.dlg(l,{width:1e3});d.ft.rwText($ict.iq1),$ocms.postXT({url:$ocms.url("inv/pget"),timeout:90,data:{id:t.id},success:e=>{d&&d.ft.rwText($ict.iq2),$ocms.postXT({url:$ocms.url("inv/icget"),timeout:60,data:{id:i},success:e=>{let t=$$.dc("srq",a),n=$$.tblset({class:"invi"},t);n.bdy.remove(),n.ft=$$[0]("tfoot"),e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b")),n.tbl.data($.extend({new:{},sms:{},itm:{}},{admin:e.admin,companies:e.companies,locations:e.locations}));let i=$$.tr(n.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(i,e))),n.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.requests||[],(function(t,i){if(0!==(i.Id||0)){let t=$inv.worknotes(i);i.text="i"===e.admin.type?$rct.req+jine([i.ExternalId,i.Name],": ").eine(" ",""):jine([fdt(i.WorkDoneAt,"dd.MM.yy")+t.ne(i.Name)],": ");let a=$$.tbody(n.tbl).data($.extend({},i));$inv.rendersrq.call(a)}}));let r=$$.tr($$.tbody(n.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(r),n.ft.appendTo(n.tbl);let l,d,s=e.admin||{},c=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",a).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{n.tbl.data("new")[i]=e}},l),$inv.eHtml)),n.tbl.data("new")[i]=t};c("tfrm",s.invoicetitle,"invoicetitle",0,null),c("adrfrm",s.invoiceaddress,"invoiceaddress",0,null),c("locfrm",s.provisionlocation,"loc",1,{list:deepCopy(e.locations),lbl:"ref",property:"address"}),c("emailfrm",s.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",a).append($$.dc("content").text(s.sender)),s.provisionend&&(d=s.provisionstart?$rct.provP:$rct.provD,l=s.provisionstart?fdt(s.provisionstart,"dd.MM.yyyy")+" - "+fdt(s.provisionend,"dd.MM.yyyy"):fdt(s.provisionend,"dd.MM.yyyy")),c("admfrm",l,"provisionperiod",d,1),n.tbl.data("new").CustomValues=s.CustomValues||"",$$.dc("inpfrm ctpfrm",a).text(jObj(s.CustomValues,"contactName")),n.tbl.children("tbody").each($inv.bdysort),n.tbl.trigger("fds.inv")},complete:()=>{d.c.trigger("modal_close")}})},error:()=>{d&&d.c.trigger("modal_close")}})},$inv.clCntInv=function(e){let t=$fis.lf(!1),n=[];t.find("li.ili.checked").each((function(){n.push($(this).data("Id"))})),1===n.length&&$inv.cntInv({id:n[0]})},$inv.cntInv=function(e){e=e||{};$fis.lf(!1).rC("fix").aC("hd");let t=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sedit));$inv.eM(!1,!0);let n=$$.dc("rfrm").ldng(1),i=$ocms.dlg(n,{width:1e3});i.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("inv/get"),timeout:60,data:{id:e.id},success:e=>{e.admin=e.admin||{};let n=e.inv||{},i=$$.dc("srq",t),a=$$.tblset({class:"invi"},i);a.bdy.remove(),a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:n.Id,new:{},sms:{},itm:{},bai:[]},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(r,e))),a.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.req||[],(function(e,t){let n=$$.tbody(a.tbl).data($.extend({},t));$inv.rendersrq.call(n)}));let l=$$.tr($$.tbody(a.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(l),a.ft.appendTo(a.tbl);let d=(e,n,i,r,l)=>{let d=$$.dc("inpfrm",t).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(n);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=n};d("tfrm",n.InvoiceTitle,"invoicetitle",0,null),d("adrfrm",n.SendToAddress,"invoiceaddress",0,null),d("locfrm",n.ProvisionLocation,"loc",1,null),d("emailfrm",n.SendToEmail,"invoiceemail",0,null),$$.dc("sndfrm",t).append($$.dc("content").text(e.admin.sender)),d("admfrm",n.ProvisionPeriod,"provisionperiod",!0===(n.ProvisionPeriod||"").includes("-")?$rct.provP:$rct.provD,1),a.tbl.data("new").CustomValues=n.CustomValues||"",$$.dc("inpfrm ctpfrm",t).text(jObj(n.CustomValues,"contactName")),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv"),$inv.eM(!1,!0,$inv.emOpt(e.admin))},complete:()=>{i.c.trigger("modal_close")}})},$inv.cSt=function(e){e=e||{};let t=$fis.lf(),n=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sedit)),i=$fis.cf().width()>n.width()+t.width()+20;t.tC("fix",i).tC("hd",!i),$inv.eM(!1,!0);let a=$$.dc("rfrm").ldng(1),r=$ocms.dlg(a,{width:1e3});r.ft.rwText($ict.iq1),$ocms.postXT({url:$ocms.url("inv/pget"),data:{id:e.id},success:t=>{r&&r.ft.rwText($ict.iq2),$ocms.postXT({url:$ocms.url("inv/storno"),data:{id:e.id,mode:e.mode},success:e=>{e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b"));let t=e.inv||{},i=$$.dc("srq",n),a=$$.tblset({class:"invi"},i);a.bdy.remove(),a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:t.Id,new:{},sms:{},itm:{},bai:[]},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(r,e))),a.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.req||[],(function(e,t){let n=$$.tbody(a.tbl).data($.extend({},t));$inv.rendersrq.call(n)}));let l=$$.tr($$.tbody(a.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(l),a.ft.appendTo(a.tbl);let d=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",n).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=t};d("tfrm",t.InvoiceTitle,"invoicetitle",0,null),d("adrfrm",t.SendToAddress,"invoiceaddress",0,null),d("locfrm",t.ProvisionLocation,"loc",1,null),d("emailfrm",t.SendToEmail,"invoiceemail",0,null),$$.dc("sndfrm",n).append($$.dc("content").text(e.admin.sender)),d("admfrm",t.ProvisionPeriod,"provisionperiod",!0===(t.ProvisionPeriod||"").includes("-")?$rct.provP:$rct.provD,1),a.tbl.data("new").CustomValues=t.CustomValues||"",$$.dc("inpfrm ctpfrm",n).text(jObj(t.CustomValues,"contactName")),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv")},complete:()=>{r.c.trigger("modal_close")}})},error:()=>{r&&r.c.trigger("modal_close")}})},$inv.eHtml=function(e){let t=$(this),n=e.data instanceof jQuery?e.data:e.data.t,i=["invoiceemail","provisionperiod","invoicetitle"].includes(e.data.nme),a=i?[{name:"txt",label:"Text",type:"text",value:n.text()}]:[{name:"txt",label:"Text",type:"html",value:n.html(),tinymce:!0,attr:{style:"height: 300px"}}],r=e.data.change||null,l={title:t.data("dialog")||"",success:function(t){i?n.text(t.txt||""):n.html(t.txt),"function"==typeof r&&r(t.txt),$inv.d.syncField(e.data.nme,i?t.txt||"":t.txt),$inv.rd.syncField(e.data.nme,i?t.txt||"":t.txt)},tinymce:{valid_elements:"br",hidemenu:!0,hidetoolbar:!0}};if(Array.isArray(e.data.list)){let t=$$.dc("lstfrm");$.each(e.data.list,((n,i)=>{let a=$$.dc("li",t).append(""!==(e.data.lbl||"")?$$.dc("lbl").rwText(i[e.data.lbl]):null);$$.dc("adr",a).rwText(i[e.data.property]).data("val",i[e.data.property]).click((function(){let e=$(this),t=e.closest(".modal-body").find(':input[name="txt"]');t.is(".tinymce")?tinymce.get(t.attr("id")).setContent($$.s().rwText(e.data("val")).html()):"TEXTAREA"===t.prop("tagName")?t.val(e.data("val")).change():t.rwText(e.data("val"))}))})),l.addcontent=t}$ocms.dlgform(a,l)},$inv.setVat=function(e){$(this);let t=e.data,n=prompt($rct.rqV);n&&(n=parseFloat(n.replace("%","")),n>1&&(n*=.01),!1===isNaN(n)&&(t.siblings(".itm").each((function(){let e=$(this).data();e.vat=fnum(n,{style:"percent"}).replace(" ",""),(e.net_val||0)>0&&(e.vat_val=e.net_val*n),(e.svcnet_val||0)>0&&(e.svcvat_val=e.svcnet_val*n)})),$inv.t_fds_inv()))},$inv.inRow=function(e){let t=$(this),n=e.data,i={},a=$rcol.itm.clone(["SortOrder","NameOrNumber","Type","quantityhours","UnitString","net","svcnet_val","svcvat_val","net_val","vat_val","vat","Note"]),r="N"+(65536*(1+Math.random())||0).toString(16).substr(6),l=$$.tr({id:"itm_"+r.toString(),class:"itm"});$ocms.dlgform(a,{title:t.data("dialog")||"",success:function(e){l.data($.extend({Id:r},i,e)),$inv.rrw.call(l),l.insertAfter(n),$inv.t_fds_inv()},typedvalues:!0})},$inv.eRow=function(e){let t=$(this),n=e.data,i=n.data()||{},a=["SortOrder","NameOrNumber","Type","quantityhours","UnitString","net","svcnet_val","svcvat_val","net_val","vat_val","vat","Note"];i.id||""!==(i.Type||"")||a.unshift("Type");let r=$rcol.itm.clone(a).applyValues(i);r.set("Type","hidden","type"),$inv.eRw.call(t,n,i,r)},$inv.eRw=function(e,t,n){let i=$(this);$ocms.dlgform(n,{title:i.data("dialog")||"",success:function(n){let i={};""===(t.Id||"")&&(i.Id="N"+(65536*(1+Math.random())||0).toString(16).substr(6),e.attr("id","itm_"+i.Id.toString())),i.quantity=((n.quantityhours||"").toString()+" "+(n.UnitString||"").toString()).trimEnd(),e.data($.extend({},t,n,i)),console.debug("eRw success %o",e.data()),$inv.rrw.call(e),$inv.t_fds_inv()},typedvalues:!0})},$inv.bdysort=(e,t)=>{$(t).Sortable({dragItem:!1,dragHandleClass:"ico",parentident:"tr",onend:()=>{$inv.t_fds_inv()}})},$inv.rrw=function(){let e=$(this),t=e.data(),n={},i=e.is(".placeholder"),a=e.is(".hidenote"),r=e=>$$.d().append(e).html(),l=[$$.dc("ibtn insb",{title:$rct.iRb}).append(gi("indent-left")).click(e,$inv.inRow)];!1===i&&(l.unshift($$.dc("ibtn edit",{title:$rct.cP}).append(gi("pencil")).click(e,$inv.eRow)),l.push($$.dc("ibtn del",{title:$rct.dR}).append(gi("trash")).click((function(t){confirm($rct.cD)&&(e.remove(),$inv.t_fds_inv())}))),"set"===(t.Type||"").toLowerCase()&&""===(t.SetItmId||"")&&l.push($$.dc("ibtn tosetp",{title:$rct.toSetP}).append(gi("scale")).click(e,$inv.toSetPrice)));let d=$$.dc("axf").append(l);!0===i?n={id:"",typ:"placeholder"}:!0===e.is(".itm.osum")?n={invrqid:t.InvRqId,id:"osum"+e.index(),typ:"osum",p:"",q:null,t:r(t.tbl.tbl),tt:null,v:null,vt:t.net_val,vs:t.svcnet_val,vat:t.vat,vv:t.vat_val,vsv:t.svcvat_val,det:!1}:(n={invrqid:t.InvRqId,id:t.Id||"",typ:t.Type||"other",p:"",q:null,t:"",tt:null,v:null,vt:t.net_val,vs:t.svcnet_val,vat:t.vat,vv:t.vat_val,vsv:t.svcvat_val,det:""!==(t.Note||"")&&!1===a},$$.dc("ibtn ico move",d,{title:$rct.mR}),n.p=t.position||t.SortOrder||"",""===n.id?n.t="":["Text","Title"].includes(n.typ)&&0===(t.net_val||0)?n.t=t.htmltext||("#"!==(t.NameOrNumber||"").substr(0,1)?r($$[0]("p").text(t.NameOrNumber)):"")+(t.Note||""):(n.tt=n.det?"":$$.s(t.Note||"").text(),n.q=t.quantity||fnum(t.quantityhours)+" "+(t.UnitString||""),n.t=t.htmltext||(n.det?r($$.s(t.NameOrNumber||""))+r($$.dc("desc").html(t.Note)):r($$.s(t.NameOrNumber||""))),n.v=t.net,n.vt=t.net_val)),""!==(t.Note||"")&&$$.dc("ibtn add",d).append(gi("object-align-left")).click((function(t){$inv.rrw.call(e.tC("hidenote"))}));let s=[$$.tdc("aux").append(d),$$.tdc("keep").text(n.p)];""===n.id?s.push($$.td(e,{colspan:4}).append(n.t)):(Array.prototype.push.apply(s,n.q?[$$.tdc("keep").text(n.q)]:[]),Array.prototype.push.apply(s,[$$.tdc("txt",{colspan:n.q?1:2,title:n.tt}).append(n.t),$$.tdc("currency").text(fnum(n.v,$rct.cst)),$$.tdc("currency inetval").text(fnum(n.vt,$rct.cst)).attr("title",$rct.svcPart+": "+fnum(n.vs,$rct.cst))])),e.empty().attr("class",i?"placeholder":"itm").aC(n.Typ).tC("hidenote",a).append(s),t.co=n},$inv.toSetPrice=function(e){let t=e.data,n=t.data(),i=(n.Id||"").toString();if(""===i)return;if(!1===confirm($rct.toSetPc))return;let a=t.closest("tbody").find("tr.itm").filter((function(){return($(this).data("SetItmId")||"").toString()===i})),r=0,l=0,d=0,s=0;a.each((function(){let e=$(this).data();r+=e.net_val||0,l+=e.vat_val||0,d+=e.svcnet_val||0,s+=e.svcvat_val||0,$.extend(e,{net:0,net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,Discount:0}),$inv.rrw.call($(this))})),$.extend(n,{net:r,quantityhours:1,Discount:0,net_val:r,vat_val:l,svcnet_val:d,svcvat_val:s}),$inv.rrw.call(t),$inv.t_fds_inv()},$inv.invSumUpdate=function(){let e=$(this),t=e.children("tfoot").empty(),n=bool((e.data().admin||{}).p13b||"",!1);e.nextAll(".fnote").remove();let i={ttn:0,ttb:0,ttvat:0,tscn:0,tscvat:0,vat:{},itmnet:{}},a=[],r=(e,n,i)=>$$.tdc("currency",$$.tr(t,{class:i||"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text(e)]),fnum(n,$rct.cst)),l=t=>$$.dc("fnote").insertAfter(e).rwText(t),d=e.children("tbody");d.each(((e,t)=>{let n=$(t),r=n.data()||{},l=[],d=[],s=null,c=0,o=n.find("tr.itm"),u=0;n.tC("empty",o.length<1),o.each(((e,t)=>{let n=$(t).data()||{};!function(e,t,n){t.tscn+=e.svcnet_val||0,t.tscvat+=e.svcvat_val||0,t.ttn+=e.net_val||0,t.ttvat+=e.vat_val||0,t.ttb+=(e.net_val||0)+(e.vat_val||0),""!==(e.vat||"")&&(t.vat[e.vat]=(t.vat[e.vat]||0)+(e.vat_val||0))}(n,i,r.Id),c+=n.net_val||0,l.push(n.co);let a=$inv.itemToContract(n);"set"===a.type&&""!==a.id?s=a.id:null!==s&&""!==(a.id||"")&&(a.setId=s),d.push(a),(void 0===n.SortOrder||null===n.SortOrder?-1:n.SortOrder)>-1&&(!1===["text","title"].includes((n.Type||"other").toLowerCase())&&u++,n.SortOrder=0,n.position=u,$inv.rrw.call(t))})),n.find("tr.isum > td.isumval").text(fnum(c,$rct.cst)),a.push({Id:r.Id,nme:r.Name,text:r.text,itm:l,items:d,netval:c})}));let s=e.find("tbody:not(.empty)").length;d.find("tr.isum").tC("hidden",s<2),r("Netto",i.ttn),!1===n?$.each(i.vat,((e,t)=>{r($rct.vat+" "+e,t,"tvat")})):i.ttb=i.ttn,r("Summe",i.ttb);let c=e.data().admin.type;"i"===c?(l($rct.note2),l($rct.note4)):"c"===c?l($rct.note2):(l(string($rct.note3,[fnum((i.tscn+i.tscvat)*(e.data().admin.tax_servicerefund||0),$rct.cst)])).aC("ntax"),l($rct.note2),l(string($rct.note1,[fnum(i.tscn+i.tscvat,$rct.cst),fnum(i.tscn,$rct.cst),fnum(i.tscvat,$rct.cst)]))),!0===n&&l($rct.note13b),e.data("sms",i),e.data("bai",a),""===(e.data("dtoken")||"")&&!1===bool(e.data("dseeding"),!1)&&null!=(e.data("admin")||{}).type&&(e.data("dseeding",!0),$inv.d.seed($.extend($inv.invcPayload(e.data()),{invid:e.data("invid")||""})))},$inv.worknotes=function(e){let t="";return e.steps.forEach(((e,n)=>{let i;try{i=JSON.parse(e.Data||{}).fields||[]}catch(e){console.debug(e),i=[]}!0!==Array.isArray(i||"")&&(i="object"==typeof i&&!0===Array.isArray(i.field||"")?i.field:[]),i.forEach(((e,n)=>{"Ausgeführte Arbeiten"===e.name&&(t=e.result||"")}))})),t},$inv.rendersrq=function(){let e=$(this).empty(),t=e.is(".onesum"),n=e.data(),i=$$.tr(e,{id:"srq"+n.Id}).aC("title nosort"),a=($rcol.itm.lbl(),$$.dc("axf").appendTo($$.tdc("aux",i)));$$.dc("ibtn osum",a,{title:$rct.combP}).append(gi("euro")).click((function(t){e.tC("onesum"),$inv.rendersrq.call(e),$inv.t_fds_inv()})),$$.dc("ibtn setvat",a,{title:$rct.sV}).append(gi("gbp")).click(i,$inv.setVat),$$.dc("ibtn insb",a,{title:$rct.iRb}).append(gi("indent-left")).click(i,$inv.inRow);let r,l=$$.sc("text",n.text),d=($$.td(i,{colspan:t?4:5}).append(l),["net_val","vat_val","svcnet_val","svcvat_val","net"]);if($$.dc("ibtn edit",a).data("dialog",$rcol.req.lbl().Name).append(gi("pencil")).click({t:l,change:e=>{n.text=e,$inv.t_fds_inv()}},$inv.eHtml),t&&($$.tdc("currency isumval",i),r={Id:n.Id.toString()+"_osum",net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0},r.tbl=$$.tblset({class:"stbl"})),$.each(n.items||[],((n,i)=>{let a,l={Id:i.Id,net_val:i.net_val||0,vat_val:i.vat_val||0,svcnet_val:0,svcvat_val:0,net:i.net||0,Note:i.Note||""};if("service"===i.Type.toLowerCase())l.svcnet_val=i.net_val||0,l.svcvat_val=i.vat_val||0;t?(a=$$.tr(r.tbl.bdy,{id:"itm"+i.Id,class:"sitm"}).aC(i.Type),"Text"===i.Type||"Title"===i.Type?$$.td(a,{colspan:2}).html(i.htmltext||i.Note):($$.tdc("keep",a).text(i.quantity||((i.quantityhours||0)>0?fnum(i.quantityhours)+(i.UnitString||"").eine(" ",""):"")),i.htmltext?$$.tdc("txt",a).html(i.htmltext):$$.tdc("txt",a).text(i.NameOrNumber).attr("title",i.Note)),$.each(d,((e,t)=>{r[t]+=l[t]})),a.data(l)):($.extend(l,i),a=$$.tr(e,{id:"itm"+i.Id,class:"itm"}),a.data(l),$inv.rrw.call(a))})),t){let t=$$.tr(e,{id:"itmsq"+n.Id,class:"itm osum"}).data(r);$inv.rrw.call(t)}else{let t=$$.tr(e).aC("isum nosort");$$.tdc("aux",t),$$.td(t,{colspan:4}).text($rct.iSum),$$.tdc("currency isumval",t)}},$inv.t_fds_inv=()=>{let e=$("div.invoice_layout table.invi");e.trigger("fds.inv"),""!==(e.data("dtoken")||"")&&$inv.d.syncChanged(e)},$inv.sedit=()=>{$inv.sprev(!0)},$inv.jdisp=function(e){e.stopPropagation(),e.data.id&&$inv.disp(e.data.id,e.data.typ||"")},$inv.disp=(e,t)=>{let n="";switch(t){case"inv":n="inv/rdoc";break;case"rem":n="rem/rdoc"}""!==n&&$ocms.postXT({url:$ocms.url(n),data:{id:e||"",typ:"img"},success:e=>{let t=$$.dc("imagecollection pdfpreview"),n=Math.round(.88*vh());e.id;$.each(e.img||[],(function(e,i){$$.dc("pdfp",t).append($$.img(i).css("max-height",(n-rpx(6)).toString()+"px"))})),$ocms.dlg(t,{size:[n,Math.round(.88*vw())],zindex_min:50,form:!1,exclusive:!1})}})},$inv.jdbn=function(e){$ocms.postXT({url:$ocms.url("inv/rdocn"),data:{name:e.data.id||"",typ:"img"},success:e=>{let t=$$.dc("imagecollection pdfpreview"),n=Math.round(.88*vh());e.id;$.each(e.img||[],(function(e,i){$$.dc("pdfp",t).append($$.img(i).css("max-height",(n-rpx(6)).toString()+"px"))})),$ocms.dlg(t,{size:[n,Math.round(.88*vw())],zindex:50,form:!1})}})},$inv.sp13b=()=>{var e=$("div.invoice_layout").find("table.invi"),t=e.data();t.admin.p13b=!0,!1===(t.inv.InvoiceOptions||"").split(",").includes("§13b")&&(t.inv.InvoiceOptions+=",§13b"),e.trigger("fds.inv"),$inv.d.sync({Target:"p13b",Value:t.admin.p13b})},$inv.itemToContract=function(e){let t=((e=e||{}).Type||"").toString().toLowerCase(),n={id:(e.Id||"").toString(),type:t,title:"",desc:"",qty:"",price_net:"",total_net:e.net_val||0,vat:e.vat||""};var i;return e.co&&"osum"===e.co.typ?(n.desc=e.co.t||"",n.total_net=e.net_val||0):["text","title"].includes(t)&&0===(e.net_val||0)?(n.desc=e.htmltext||("#"!==(e.NameOrNumber||"").substr(0,1)?(i=$$[0]("p").text(e.NameOrNumber||""),$$.d().append(i).html()):"")+(e.Note||""),n.total_net=""):(e.htmltext?n.desc=e.htmltext:(n.title=e.NameOrNumber||"",n.desc=e.Note||""),n.qty=e.quantity||(0!==(e.quantityhours||0)?fnum(e.quantityhours)+(e.UnitString?" "+e.UnitString:""):""),n.price_net=e.net||0,n.total_net=e.net_val||0),n},$inv.ssetmode=()=>{let e=$("div.invoice_layout").find("table.invi").data();e.admin=e.admin||{};let t,n=e.admin.setmode||"setprice",i=e=>$$.dc("btn",$ict.setmo[e]).tC("selected",n===e).click((()=>{t.c.trigger("modal_close"),$inv.setSetmode(e)})),a=$$.dc("choicefrm").append([i("setprice"),i("itemprices"),i("setonly")]);t=$ocms.dlg(a,{width:800})},$inv.setSetmode=e=>{let t=$("div.invoice_layout").find("table.invi").data();t.admin=t.admin||{},t.admin.setmode=e,t.inv=t.inv||{};let n=(t.inv.InvoiceOptions||"").split(",").filter((e=>""!==e&&0!==e.indexOf("setmode:")));e&&"setprice"!==e&&n.push("setmode:"+e),t.inv.InvoiceOptions=n.join(","),$inv.d.sync({Target:"setmode",Value:e})},$inv.sctp=()=>{let e=$invcol.ctp;$ocms.dlgform(e,{title:$ict.ctp,success:function(e){var t=$("div.invoice_layout"),n=t.find("table.invi").data();let i={};void 0!==n.new&&"{"===(n.new.CustomValues||"").substr(0,1)&&(i=JSON.parse(n.inv.CustomValues)),i.contactName=e.name,i.contactEmail=e.email,n.new.CustomValues=JSON.stringify(i),t.find(".ctpfrm").text(ne(e.name,e.email)),$inv.d.sync({Target:"contact",Value:{name:e.name,email:e.email}})},typedvalues:!0})},$inv.invcPayload=function(e){let t=(e=e||{}).sms||{},n=$.extend({},e.new),i=$.extend({},e.admin);return n.total_net=t.ttn||0,n.total_gross=t.ttb||0,n.title=null!=n.invoicetitle?n.invoicetitle:n.title||"",n.provisionlocation=null!=n.loc?n.loc:n.provisionlocation||"",n.paymentterm=null!=i.paymentterms?i.paymentterms:n.paymentterm||"",i.customerid=null!=i.customerid?i.customerid:i.CustomerId,{admin:i,req:e.bai,sms:e.sms,new:n}},$inv.ssave=()=>{$inv.d.save()},$inv.sprev=e=>{$inv.d.preview()},$inv.rReload=()=>{try{let e=$("#listframe ul.rql:first").data();$inv.cInv2({id:e.search})}catch(e){}},$inv.quantChange=function(e){let t=$(this).closest("form"),n={},i=e=>parseFloat(e.toString().replace("%","").replace(",",".")),a=e=>e.toFixed(2);t.find(":input").each(((e,t)=>{n[$(t).attr("name")]=$(t)}));let r=parseInt(n.quantityhours.val()||"0"),l=i(n.net.val()||"0"),d=.01*i(n.vat.val());r>0&&l>0&&(n.net_val.val(a(r*l)),n.vat_val.val(a(r*l*d)),["Service"].includes(n.Type.val())&&(n.svcnet_val.val(a(r*l)),n.svcvat_val.val(a(r*l*d))))},$inv.storno=function(e,t){let n,i=$$.dc("choicefrm").append([$$.dc("btn","Storno ohne Details").click({id:e,mode:"simple"},(e=>{n.c.trigger("modal_close"),$inv.cSt(e.data)})),$$.dc("btn","Storno mit neuer Rechnung").click({id:e},(e=>{n.c.trigger("modal_close"),$inv.ccStInv(e)})),$$.dc("btn","Storno mit best. Rechnung").tC("inactive",!1===bool(t,!1)).click({id:e,mode:"copy"},(e=>{!0===bool(t,!1)&&(n.c.trigger("modal_close"),$inv.cSt(e.data))}))]);n=$ocms.dlg(i,{width:1e3})},$inv.credit=function(e,t){let n,i=$$.dc("choicefrm").append([$$.dc("btn","Gutschrift").click({id:e,mode:"credit"},(e=>{n.c.trigger("modal_close"),$inv.cSt(e.data)}))]);n=$ocms.dlg(i,{width:1e3})},$inv.setPyd=function(e){confirm($ict.cpyd)&&$ocms.postXT({url:$ocms.url("inv/setpyd"),timeout:60,data:{id:e},success:e=>{alert($ict.relm)},error:()=>{alert($t.f1)}})},$inv.setUpd=function(e){confirm($ict.cupd)&&$ocms.postXT({url:$ocms.url("inv/setupd"),timeout:60,data:{id:e},success:e=>{alert($ict.relm)},error:()=>{alert($t.f1)}})},$inv.resendRem=function(e){e.stopPropagation(),e.data.id&&confirm(string($ict.remresc,[e.data.name]))&&$ocms.postXT({url:$ocms.url("rem/resend"),timeout:60,data:{id:e.data.id},success:t=>{alert(string($ict.remresr,[e.data.name]))},error:()=>{alert($t.f1)}})},$inv.dspRem=function(e){let t=$$.dc("rfrm").ldng(1),n=$ocms.dlg(t,{width:1e3});n.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("inv/getrem"),timeout:60,data:{id:e,drafts:!1},success:e=>{n.ft.empty();let i=$$.tblset({class:"invtbl"},t.empty()),a=$invcol.rem2,r=$$.tr(i.hd);$$.th(r);$.each(a.fields||[],((e,t)=>{$$.th(r).text(t.label)}));let l=!1;$.each(e,((e,t)=>{l=!l;let n=$$.tr(i.bdy).tC("alt",l),r=$$.td(n);n.click((function(){n.tC("selected").siblings().rC("selected")})),!0===bool(t.hasFile,!1)&&($$.dc("idl ilbtn",r,{title:$ict.dl+"\n"+t.DocumentName}).append(gi("save-file","ico")).click({id:t.Id},$inv.downloadrem),$$.dc("idl ilbtn",r,{title:$ict.remdsp+"\n"+t.DocumentName}).append(gi("eye-open","ico")).click({id:t.Id,typ:"rem"},$inv.jdisp),$$.dc("idl ilbtn",r,{title:$ict.remres+"\n"+t.DocumentName}).append(gi("refresh","ico")).click({id:t.Id,typ:"rem",name:t.DocumentName},$inv.resendRem)),$.each(a.fields||[],((e,i)=>{let a=$$.td(n).aC(i.dtype),r=t[i.name];if("function"==typeof i.dfnc)i.dfnc.call(a,r,t);else switch(i.type||""){case"date":a.text(fdt(t[i.name],"dd.MM.yy"));break;case"datetime":a.text(fdt(t[i.name]));break;case"html":a.append($$.dc("ctw").html(r)),a.append($$.dc("ttip").html(r));break;default:a.text(t[i.name])}if("InvoiceId"===(i.name||""))a.aC("keep");switch(typeof i.title){case"function":i.title.call(a,t);break;case"string":a.attr("title",cs.title)}}))}))},error:()=>{t.empty(),n.ft.rwText($t.f1)},complete:()=>{t.ldng(0)}})},$inv.ccRem=function(e,t){$(this);$ocms.postXT({url:$ocms.url("rem/lrem"),timeout:60,data:{id:e},success:n=>{let i=$invcol.rid.clone();i.applyValues(n.ov);let a=$$.dc("ac"),r=$$.tblset({class:"fullgrid fullwidth"},a);if((n.lst||[]).length>0){$$.d({style:"margin: 1.5rem 0 1rem 0;font-size: 110%;text-decoration: underline;"}).prependTo(a).text($ict.rovlh);let e=$$.tr(r.hd);$ict.rovl.forEach(((t,n)=>$$.th(e,t))),$.each(n.lst,((e,t)=>{$$.tr(r.bdy).append([$$.tdc("keep",t.subject),$$.tdc("currency",fnum(t.amount,$rct.cst)),$$.tdc("currency",fnum(t.amount_payed,$rct.cst)),$$.tdc("keep",fdt(t.DateFinalized,"dd.MM.yy"))])}))}else $$.td($$.tr(r.bdy),$ict.nd);$ocms.dlgform(i,{addcontent:a,title:string($ict.remdt,[t||"?"]),success:function(t){$inv.ccRem_s2(e,t)},typedvalues:!0})}})},$inv.rRemRw=function(e){let t=$(this),n=e.rm||{};t.empty().data({invoiceid:n.invoiceid,invoicedate:n.invoicedate,amount:n.amount,amount_payed:n.amount_payed});let i=$$.dc("axf").append($$.dc("ibtn edit",{title:$rct.cP}).append(gi("pencil")).click(t,$inv.eRowR));t.append([$$.tdc("aux").append(i),$$.tdc("keep",n.invoiceid),$$.tdc("keep",fdt(n.invoicedate,"dd.MM.yy")),$$.tdc("currency",fnum(n.amount,$rct.cst)),$$.tdc("currency",fnum(n.amount_payed,$rct.cst)),$$.tdc("currency",fnum(n.amount-n.amount_payed,$rct.cst))])},$inv.eRowR=function(e){let t=$(this),n=e.data,i=n.data()||{},a=$invcol.rem.clone().applyValues(i);$ocms.dlgform(a,{title:t.data("dialog")||"",success:function(e){let i=t.closest("table"),a=i.data();$.extend(a.rm,e),i.data(a),$inv.rRemRw.call(n,a),$inv.rd.syncAmount(a.rm.amount,a.rm.amount_payed)},typedvalues:!0})},$inv.ccRem_s2=function(e,t){$fis.lf(!1).rC("fix").aC("hd");let n=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.rprev));$inv.eM(!1,!0);$$.dc("rfrm").ldng(1);$ocms.postXT({url:$ocms.url("rem/get"),timeout:60,data:$.extend({id:e},t),success:e=>{let t=e.rm||{},i=$$.dc("srq",n),a=$$.tblset({class:"invi"},i);a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:t.invid,new:{}},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$ict.remHR.forEach((e=>$$.th(r,e))),$inv.rRemRw.call($$.tr(a.bdy),a.tbl.data()),a.ft.appendTo(a.tbl);let l=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",n).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=t};l("tfrm",t.subject,"subject",0,null),l("adrfrm",t.invoiceaddress,"invoiceaddress",0,null),l("emailfrm",t.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",n).append($$.dc("content").text(t.sender)),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv");let d=a.tbl.data("new");d.amount=t.amount,d.amount_payed=t.amount_payed,$inv.rd.seed({rem:{invid:t.invid,type:t.type,invoiceid:t.invoiceid,invoicedate:t.invoicedate},new:d})},complete:()=>{}})},$inv.rprev=()=>{$inv.rd.preview()},$inv.sis=e=>{confirm($ict.sisc)&&$ocms.postXT({url:$ocms.url("inv/sis"),data:{id:e||""},success:e=>{}})},$inv.srs=e=>{confirm($ict.srsc)&&$ocms.postXT({url:$ocms.url("rem/srs"),data:{id:e||""},success:e=>{}})},$inv.mfrrel=e=>{$("#contentframe").ldng(),$ocms.postXT({url:$ocms.url("inv/mfrrel"),data:{id:e||""},success:e=>{$inv.rerenderinv()},complete:()=>{$("#contentframe").ldng(0)}})};
\ No newline at end of file
+let $rct={mdl:"Aufträge",or:"offene Aufträge",orr:"offene Aufträge (4 W)",rn:"Auftragsnummer",iov:{all:"Auftragsübersicht (alle)","":"Auftragsübersicht"},wk:"Woche",nd:"Keine Daten gefunden.",h:"Uhr",rq1:"Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",rq2:"Auftragsdaten werden geladen",rq1f:"Die Auftragsdaten von MFR konnten nicht oder nicht schnell genug abgerufen werde.\nMöchten Sie mit den bestehenden Daten trotzdem weitermachen?",note1:"Im Bruttobetrag sind {0} Lohnkosten enthalten (netto {1}). Die darin enthaltene Umsatzsteuer beträgt {2}.",note2:"Bitte beachten Sie, nach §14 Abs. 1 Umsatzsteuergesetz ist diese Rechnung ein Zahlungsbeleg oder eine andere beweiskräftige Unterlage für 2 Jahre nach Ablauf des Kalenderjahres der Ausstellung dieser Rechnung aufzubewahren, soweit nicht aufgrund anderer gesetzlicher Regelungen andere ggf.längere Aufbewahrungsfristen gelten.",note3:"Privathaushalten erstattet das Finanzamt bis zu {0} des Arbeitslohns mit der nächsten Steuererklärung.",note4:"Für bereits erbrachte Arbeiten, Dienstleistungen, Materiallieferungen und getätigte Bestellvorgänge zum oben genannten Bauvorhaben, die sich aus dem mit Ihnen geschlossenen Vertrag ergeben, stellen wir Ihnen vertragsgemäß unsere Akontozahlung in Rechnung. Eine Endabrechnung erhalten Sie als Schlussrechnung nach Abschluss des gesamten Bauvorhabens. Das Ausführungsdatum entnehmen Sie bitte dem Schlusstext dieser Rechnung. Wir danken Ihnen herzlich für das entgegengebrachte Vertrauen und bitten Sie um kurzfristigen Ausgleich der Akontorechnung.",note13b:"Gem. §13b Umsatzsteuergesetz unterliegen Sie der Steuerschuldnerschaft des Leistungsempfängers zur Umsatzsteuer aus dieser Rechnung mit einem Steuersatz von 19%.",crI:"Rechnung erstellen",crII:"Abschlagsrechnung erstellen",dII:"Für eine Abschlagsrechnung darf nur ein Auftrag gewählt werden.",dnS:"Für eine Rechnung muss mindestens ein Auftrag gewählt werden.",inv:"Rechnung",invs:"Rechnungen",req:"Auftrag",provP:"Leistungszeitraum",provD:"Leistungsdatum",cP:"Position ändern",iRb:"Zeile darunter einfügen",dR:"Zeile löschen",sV:"USt festlegen",cD:"Löschen?",mR:"Zeile verschieben",svcPart:"Service-Anteil",vat:"Umsatzsteuer",combP:"Positionen zusammenfassen",toSetP:"Auf Setpreis umstellen (Positionen ohne Preis)",toSetPc:"Der Set-Preis wird auf die Summe seiner Positionen gesetzt und die Positionen selbst verlieren ihren Preis. Das ist nicht rückgängig zu machen (der Betrag kann danach nur noch manuell geändert werden). Fortfahren?",toSetMc:"Jeder Leistungsauftrag wird zu einer Set-Position mit der Summe als Preis zusammengefasst. Das ist nicht rückgängig zu machen (die Set-Preise können danach nur noch manuell geändert werden). Fortfahren?",iSum:"Zwischensumme",dtRel:"Freigegeben am: ",dtCr:"Erstellt am: ",rqV:"USt des Auftrags?",cthd:"wirklich aus-/einblenden ?",cst:{style:"currency",currency:"EUR"},sts:{IsWorkDone:"Arbeiten erledigt",Closed:"Auftrag geschlossen",SubcontractorPendingConfirmation:"Warten auf Bestätigung (Unterauftrag)",Scheduled:"Geplant",OfferIsRejected:"Angebot abgelehnt",OfferIsSend:"Offen (Angebot versandt)",CollaborationWaitingConfirmation:"Warten auf Bestätigung (Zusammenarbeit)",Released:"Freigegeben",OfferIsConfirmed:"Bestätigt",InProgress:"In Bearbeitung",ReadyForScheduling:"Zur Planung",Created:"Erstellt",Rejected:"Abgebrochen",Invoiced:"Rechnung gestellt","-":"-"},invHR:["Pos.","Menge","Artikelbezeichnung","VK","Summe"],frm:{invoiceaddress:"Adresse",loc:"Leistungsort / Lieferadresse",invoiceemail:"Email"}},$rcol={req:new fields_definition("Auftrag","Aufträge",[{name:"tags",label:"",type:"string",dfnc:function(e,t){""!==(e||"")&&($(this).aC("tags"),e.split(",").forEach((e=>{""!==e&&$(this).append($$.sc("tag "+e.replace(" ","_").replace("/","_").toLowerCase(),e))})))}},{name:"DateOfCreation",label:"Datum",type:"date",title:function(e){$(this).attr("title",$rct.dtCr+fdt(e.DateOfCreation).ne("-")+" \n"+$rct.dtRel+fdt(e.DateReleased).ne("-"))}},{name:"CustomerName",label:"Kunde (Firma)",type:"string"},{name:"Name",label:"Auftragsname",type:"string"},{name:"ExternalId",label:"Auftragsnummer",type:"string"},{name:"ParentExtenalId",label:"PAuftrag",type:"string"},{name:"InvoiceId",label:"RNummer",type:"string",dfnc:function(e,t){$(this).rwText(e," ").find("span").each((function(){$(this).aC("cla").click({id:$(this).text()},$inv.jdbn)}))}},{name:"State",label:"Status",type:"string"},{name:"WorkDoneAt",label:"Erledigt am",type:"date"},{name:"Description",label:"Beschreibung",type:"html"}]),itm:new fields_definition("Auftragsposition","Auftragspositionen",[{name:"NameOrNumber",label:"Bezeichnung",type:"string"},{name:"Type",label:"Typ",type:"select",required:!0,value:"Text",url:[{value:"Text",label:"Text"},{value:"Equipment",label:"Ausrüstung"},{value:"Material",label:"Material"},{value:"Service",label:"Arbeitsleistung"}],change:function(e){$req.quantChange.call(this,e)}},{name:"quantityhours",label:"Anzahl / Menge",type:"number",precision:"0.01",value:1,change:function(e){$inv.quantChange.call(this,e)}},{name:"UnitString",label:"Einheit",type:"select",url:["LFDM","Stck","Std.","QM","AW","Pauschal"],change:function(e){$inv.quantChange.call(this,e)}},{name:"net",label:"EinzelPreis netto",type:"number",precision:"0.01",value:0,change:function(e){$inv.quantChange.call(this,e)}},{name:"net_val",label:"GesamtPreis netto",type:"number",precision:"0.01",value:0},{name:"vat_val",label:"GesamtPreis USt",type:"number",precision:"0.01",value:0},{name:"svcnet_val",label:"Arbeitslohn netto",type:"number",precision:"0.01",value:0},{name:"svcvat_val",label:"Arbeitslohn USt",type:"number",precision:"0.01",value:0},{name:"net_pos",label:"Netto",type:"string"},{name:"bo_pos",label:"Brutto",type:"string"},{name:"vat",label:"USt",type:"string",value:"19,0%",change:function(e){$inv.quantChange.call(this,e)}},{name:"Note",label:"Details",type:"html",tinymce:!0}])},$ict={mdl:"Rechnungen",iov:{all:"Rechnungen (alle)","":"Rechnungen (nur fertige)","#d":"Rechnungen (nur Entwürfe)","#u":"Rechnungen (nur unbezahlt)","#r":"Rechnungen (nur angemahnt)","#a":"Rechnungen (nur Akonto)","#c":"Rechnungen (nur Storno)","#ru":"Rechnungen (nur angemahnt + unbez.)"},uba:", gesamter Zeitraum)",req:"Auftrag",inv:"Rechnung",rem:"Mahnung",in:"Rechnungsnummer",cc:"Kunde",wk:"Woche",nd:"Keine Daten gefunden.",dl:"Herunterladen",ed:"Bearbeiten",ced:"Bearbeitung fortsetzen",sItm:"Einzelheiten anzeigen",sPay:"Zahlungen anzeigen",cdI:"Entwurf der Rechnung löschen?",rel:"Neu Laden",relm:"Bitte laden Sie Liste manuell neu, um die Änderungen zu sehen.",dsp:"Rechnung anzeigen",storno:"Storno-Rechnung erstellen",credit:"Gutschrift erstellen",remd:"Mahnung erstellen",remdt:"Mahnung erstellen zur Rechnung {0}",remlst:"Mahnungen anzeigen",remdsp:"Mahnung anzeigen",remres:"Mahnung erneut senden",remresc:"Mahnung {0} wirklich erneut senden?",remresr:"Mahnung {0} wurde erfolgreich versandt.",setpyd:"Bezahlt markieren",cpyd:"Rechnung wirklich als bezahlt markieren?",setupd:"Bezahlt-Markierung aufheben",cupd:"Bezahlt-Markierung wirklich aufheben?",ivE:"Die Email-Adresse ist vermutlich nicht gültig.",ivEc:"\nMöchten Sie fortfahren?",pna:"Diese Seite ist in der Vorschau nicht verfügbar",tpe:"Die Anzahl von {0} Seiten wird aktuell nicht unterstützt",eis:"Der Rechnungsentwurf konnte nicht gespeichert werden.",iss:"Zwischenstand speichern.",p13b:"USt -> §13b",setm:"Set-Preisanzeige",setmo:{setprice:"Set mit Preis – Positionen ohne Preis",setonly:"Nur Set mit Preis – Positionen ausgeblendet"},ctp:"Ansprechpartner festlegen",mfr:"Von MFR neu abrufen",rq1:"Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",rq2:"Auftragsdaten werden geladen",iq1:"Rechnungsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",iq2:"Rechnungsdaten werden geladen",sis:"Rechnung als versandt markieren",srs:"Mahnung als versandt markieren",sisc:"Rechnung wirklich als versandt markieren?",srsc:"Mahnung wirklich als versandt markieren?",iSt:{dft:"Entwurf",uns:"nicht versandt",pyd:"bezahlt",cc:"storniert",op:"offen",due:"fällig",ovd:"überfällig",rem:"angemahnt"},rSt:["","Überfällig","2. Mahnung","3. Stufe"],pSt:{a:"Vollst.",p:"Teilz."},ivT:{i:"AbschlagsR.",f:"SchlussR",r:"Rechnung",c:"StornoR."},rovlh:"Übersicht der bisherigen Mahnungen",rovl:["Betreff","Betrag","Betrag gezahlt","fertiggestellt am"],remHR:["Rechnung","vom","Rechnungsbetrag","bereits bezahlt","noch offen"],translatePaymentTerm:e=>(e||"").replace("wd"," Werktagen").replace("d"," Tagen").replace("wk"," Wochen")||"10 Tagen",payi:{account:"Konto",name:"Zahler",text:"Verw.Zweck",InvoiceID:"Rechnung",amount:"Betrag",date:"Datum",manual:"Typ"}},$invcol={datev:new fields_definition("Rechnung","Rechnungen",[{name:"Umsatz (ohne Soll/Haben-Kz)",label:"Umsatz (ohne Soll/Haben-Kz)",type:"string"},{name:"vf",label:"vf",type:"string"},{name:"Soll/Haben-Kennzeichen",label:"Soll/Haben-Kennzeichen",type:"string"},{name:"Konto",label:"Konto",type:"string"},{name:"Gegenkonto",label:"Gegenkonto",type:"string"},{name:"BU-Schlüssel",label:"BU-Schlüssel",type:"string"},{name:"Belegdatum",label:"Belegdatum",type:"string"},{name:"Belegfeld 1",label:"Belegfeld 1",type:"string"},{name:"Belegfeld 2",label:"Belegfeld 2",type:"string"},{name:"Buchungstext",label:"Buchungstext",type:"string"}]),inv:new fields_definition("Rechnung","Rechnungen",[{name:"invstatus",label:"Status",type:"select",url:$ict.iSt},{name:"balance",label:"Umsatz",type:"string",dtype:"currency"},{name:"CustomerName",label:"Kunde",type:"string"},{name:"InvoiceId",label:"RNummer",type:"string"},{name:"InvoiceType",label:"Typ",type:"select",url:$ict.ivT},{name:"request",label:"Auftrag",type:"string",dtype:"num"},{name:"vat",label:"MwSt",type:"string",dtype:"num"},{name:"deb_cred",label:"Soll/Haben",type:"string"},{name:"customer",label:"Konto",type:"string",dtype:"num"},{name:"contra_account",label:"Gegenkonto",type:"string",dtype:"num"},{name:"Belegdatum",label:"Belegdatum",type:"date"},{name:"reminderstatus",label:"MahnStatus",type:"select",url:$ict.rSt},{name:"reminder",label:"# Mahnungen",type:"integer"},{name:"Buchungstext",label:"Buchungstext",type:"string"},{name:"Payment",label:"Zahlung",type:"string"}]),rem:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"amount",label:"Rechnungsbetrag",type:"number",precision:"0.01",value:1},{name:"amount_payed",label:"bereits bezahlt",type:"number",precision:"0.01",value:1}]),rem2:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"DocumentName",label:"Name",type:"string"},{name:"subject",label:"Betreff",type:"string"},{name:"DateSent",label:"Versanddatum",type:"date"},{name:"status",label:"Status",type:"string"},{name:"amount_open",label:"offener Betrag",type:"number",precision:"0.01"},{name:"InvoiceId",label:"RNummer",type:"string"}]),rid:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"type",label:"Typ",type:"select",url:[["f","einfache Zahlungserinnerung"],["m","Mahnung"],["l","letzte Mahnung"]],required:!0},{name:"level",label:"Stufe",type:"select",url:[["1","Stufe 1"],["2","Stufe 2"],["3","Stufe 3"],["4","Stufe 4"],["5","Stufe 5"],["6","Stufe 6"]],required:!0}]),ctp:new fields_definition("Ansprechpartner","Ansprechpartner",[{name:"name",label:"Name",type:"string"},{name:"email",label:"Email",type:"string"}])},gi=(e,t)=>$$.sc("glyphicon glyphicon-"+e).aC(t),$inv={init2:function(e,t){e=e||"inv",t=t||{},$ocms.getScript([],(function(){$inv.init3(e,t)}))},init3:async function(e,t){$fis.cf(!0);let n=$fis.lf(!0);$("#topbar").ocmsmenu([]),$("#activemodule").text($ict.mdl);let i=[(async()=>{await $fis.getAuth("fds_inv")>0&&($inv.prepLst(""),n.aC("fix"))})(),new Promise(((e,t)=>{$fis.prepAuth(["fds_reminder"])}))];await Promise.all(i)},prepLst:function(e){let t=new Date,n=$fis.lf(!0).ldng(1),i=new Date("2021-01-01");$fis.frm_list().IN((function(){}));let a=[];$.each($ict.iov,((e,t)=>{a.push({lbl:t,fnc:()=>{$inv.prepLst(e),n.aC("fix")}})})),$fis.lfm().ocmsmenu([{lbl:"Filter",itm:a}]);$$.i({placeholder:$ict.in}).appendTo($$.dc("mth ivn",n)).enterKey((function(e){let t=$(this),n=t.val()||"";e.stopPropagation(),t.parent().siblings().rC("selected"),n.length>3&&(t.parent().aC("selected"),$inv.renderinv("i:"+n,"s","all"),t.val(""))})),$$.i({placeholder:$ict.cc}).appendTo($$.dc("mth ivc",n)).enterKey((function(e){let t=$(this),n=t.val()||"";e.stopPropagation(),t.parent().siblings().rC("selected"),n.length>=3&&(t.parent().aC("selected"),$inv.renderinv("c:"+n,"s","all"),t.val(""))}));"#"===e.substr(0,1)&&$$.dc("mth extra",n).text($ict.iov[e].replace(")",$ict.uba)).click((function(t){let n=$(this);if(t.stopPropagation(),n.siblings().rC("selected"),!0===n.is(".selected")){n.toggleClass("selected");let t=fdt(new Date,"yy-MM-dd");$inv.renderinv(t,"a",e)}n.aC("selected")})),n.append("
");let r=$$.dc("mthl",n),l=t.getFullYear(),d=t.getMonth()+1;for(let t=i.getFullYear();t<=l;t++){let n=$$.dc("yr").prependTo(r).text($ict.iov[e]+" - "+t.toString()).toggleClass("selected",t===l);n.click({yr:t},(function(e){e.stopPropagation(),n.siblings().rC("selected"),n.aC("selected")}));let a=$$.dc("mfrm",n);for(let n=0;n<(t!==l?12:d);n++){i=new Date(t,n,1);let r=$$.dc("mth").prependTo(a).text($ict.iov[e]+" - "+fdt(i,"MMM yyyy"));if(r.click({yr:t,mt:n},(function(t){if(t.stopPropagation(),r.siblings().rC("selected"),!0===r.is(".selected")){r.toggleClass("selected");let n=fdt(new Date(t.data.yr,t.data.mt,1),"yy-MM-dd");$inv.renderinv(n,"m",e)}r.aC("selected")})),""===e){$$.dc("mthdl",r).append(gi("compressed","ico")).click({yr:t,mt:n},(function(e){e.stopPropagation();let t=fdt(new Date(e.data.yr,e.data.mt,1),"yy-MM-dd");$inv.downloadzip(t,"m")}))}let l=getMonday(i),d=new Date(i);d.setMonth(d.getMonth()+1),d.setDate(0),d=getMonday(d);let s=$$.dc("wfrm",r);for(;l<=d;){let t=$$.dc("wk",s).text(($ict.wk||"W")+" "+fdt(l,"dd.MM.yy"));t.click({rd:new Date(l)},(function(n){n.stopPropagation();let i=fdt(n.data.rd,"yy-MM-dd");$inv.renderinv(i,"w",e),r.siblings().rC("selected").find(".wk").rC("selected"),r.aC("selected").find(".wk").rC("selected"),t.aC("selected")})),$$.dc("wkdl",t).append(gi("compressed","ico")).click({rd:new Date(l)},(function(e){e.stopPropagation();let t=fdt(e.data.rd,"yy-MM-dd");$inv.downloadzip(t,"w")})),l.setDate(l.getDate()+7)}}}n.ldng(0)},rerenderinv:function(){let e=$("#contentframe .invfrm:first");if(e.length>0){let t=e.data("sets")||{};t.mode&&$inv.renderinv(t.tgt,t.mode,t.includes)}},renderinv:function(e,t,n){let i=$fis.frm_list(!0,!0).ldng(1),a=$$.dc("invfrm",i).aC("md"+t).data("sets",$.extend({},{tgt:e,mode:t,includes:n})),r=$fis.lf();$ocms.postXT({url:$ocms.url("inv/invl"),data:{mode:t,tgt:e,includes:n},success:i=>{r.rC("fix").aC("hd"),$$.dc("ovhd",a).text(i.admin.title);let l=$$.tblset({},a),d=$invcol.inv,s=$$.tr(l.hd);$$.th(s);$.each(d.fields||[],((e,t)=>{$$.th(s).text(t.label),"vat"===t.name&&$$.th(s)})),$.each(i.invoices||[],((s,c)=>{let o=$$.tr(l.bdy);o.click((function(){r.rC("fix").aC("hd"),o.toggleClass("selected").siblings().rC("selected").find("td.av").rC("av"),o.find("td.av").rC("av"),!0===o.is(".selected")?$inv.iMn(c):$inv.eM()}));let u=$$.td(o,{class:"raux"});c.hasFile?($$.dc("idl ilbtn",u,{title:$ict.dl+"\n"+c.DocumentName}).append(gi("save-file","ico")).click({id:c.Id},$inv.downloadinv),$$.dc("idl ilbtn",u,{title:$ict.dsp+"\n"+c.DocumentName}).append(gi("eye-open","ico")).click({id:c.Id,typ:"inv"},$inv.jdisp)):!1===c.isFinal&&!0===$fis.isAuth("fds_inv",2)&&$$.dc("idl ilbtn",u,{title:$ict.ed}).append(gi("edit","ico")).click({id:c.Id},$inv.doContInv),$$.dc("iitm ilbtn",u,{title:$ict.sItm}).append(gi("list","ico")).click({id:c.Id},$inv.showitm),$$.dc("iitm ilbtn",u,{title:$ict.sPay}).append(gi("euro","ico")).click({id:c.Id},$inv.showpay),$.each(d.fields||[],((r,l)=>{let d,s,u=$$.td(o).aC(l.dtype);switch("select"===(l.type||"")?u.text((l.url||{})[c[l.name]]||""):u.text(c[l.name]),l.name||""){case"vat":d=$$.sel().appendTo($$.td(o,{class:"vsel"})),s=(i.admin.ust_options||"19,0%;16,0%;0,0%").split(";"),$.each(s,((e,t)=>{$$.opt(t,t).appendTo(d)})),d.click((function(e){e.stopPropagation()})).val(c[l.name]).change().change({frm:a,tgt:e,mode:t,id:c.Id,td:u,includes:n},$inv.setvat),u.toggleClass("hl",c[l.name].substr(0,2)!==s[0].substr(0,2)).click((function(e){e.stopPropagation(),$(this).toggleClass("av")}));break;case"balance":u.aC("sh_"+(c.SollHaben||"").toLowerCase());break;case"invstatus":case"reminderstatus":u.aC(("invstatus"===l.name?"is_":"rs_")+c[l.name])}}))}))},complete:()=>{i.ldng(0)}})},setvat:function(e){let t=$(this),n=e.data||{};$ocms.postXT({url:$ocms.url("inv/setvat"),data:{id:n.id,val:t.val()},success:e=>{n.td.rC("av"),$inv.renderinv(n.tgt,n.mode,n.includes)}})},downloadzip:function(e,t){$(this).empty();window.open($ocms.url("inv/datevzip?mode="+t+"&tgt="+encodeURIComponent(e)),"_blank")},showitm:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&$ocms.postXT({url:$ocms.url("inv/rqi"),data:{id:e.data.id},success:e=>{let t=$$.dc("rfrm");(e.requests||[]).length<1?t.text($ict.nd):$.each(e.requests||[],(function(e,n){let i=$$.dc("srq",t);$$.dc("nme",i).text(n.name);let a=$$.tblset({class:"if"},i);$.each(n.items||[],((e,t)=>{let n=$$.tr({id:"itm"+t.Id}).appendTo(a.bdy);$$.td(n).text(t.NameOrNumber),$$.td(n).text(t.Type),$$.td(n).aC("currency").text(t.net_pos),$$.td(n).aC("currency").text(t.bo_pos),$$.td(n).aC("num").text(t.vat)}))})),$ocms.dlg(t,{width:1e3})}})},showpay:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&$ocms.postXT({url:$ocms.url("inv/pyi"),data:{id:e.data.id},success:e=>{let t=$$.dc("rfrm");if((e.payments||[]).length<1)t.text($ict.nd);else{let n=$$.tblset({class:"if"},t),i=$$.tr(n.hd);$.each(["date","account","name","text","InvoiceID","amount","manual"],((e,t)=>{$$.th(i,$ict.payi[t])})),$.each(e.payments,((e,t)=>{let i=$$.tr({id:"itm"+t.banking_uid}).appendTo(n.bdy);$$.td(i).aC("date").text(t.date),$$.td(i).text(t.account),$$.td(i).text(t.name),$$.td(i).text(t.text),$$.td(i).text(t.InvoiceID),$$.td(i).aC("currency").text(t.amount),$$.td(i).text(t.manual)}))}$ocms.dlg(t,{width:1e3,title:"Übersicht der Zahlungen"})}})},downloadinv:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&window.open($ocms.url("inv/rdoc?id="+e.data.id),"_blank")},doContInv:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&$inv.cntInv({id:e.data.id})}},$$inv={init2:$inv.init2,auth:{}};export default $$inv;$inv.cInv=function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&!1!==$fis.isAuth("fds_inv",2)&&$inv.cInv2({id:e.data.id})},$inv.rMn=e=>{let t=[{lbl:$ict.req,itm:[]}];return!0===bool(e,!1)&&!0===$fis.isAuth("fds_inv",2)&&Array.prototype.push.apply(t[0].itm,[{lbl:$rct.crI,fnc:$inv.ccInv,data:{typ:"r"}},{lbl:$rct.crII,fnc:$inv.ccInv,data:{typ:"i"}}]),t.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(t)},$inv.iMnr=e=>{let t=booln(e.isFinal,!0),n=e.Id,i=booln(e.fds,!1),a=[{glyph:"glyphicon-menu-left",fnc:()=>{$fis.frm_edit().remove()}},{lbl:$ict.inv,itm:[]},{lbl:$ict.rem,itm:[]}];return!1===t&&!0===$fis.isAuth("fds_inv",2)?a[1].itm.push({lbl:$ict.ced,fnc:$inv.clCntInv}):!0===$fis.isAuth("fds_inv",1)&&a[1].itm.push({lbl:$ict.dsp,fnc:()=>$inv.disp(n,"inv")}),!0===i&&!0===t&&!0===$fis.isAuth("fds_inv",2)&&(a[1].itm.push({lbl:$ict.storno,fnc:()=>$inv.storno(n,i)}),a[1].itm.push({lbl:$ict.credit,fnc:()=>$inv.credit(n,i)})),!0===t&&!0===$fis.isAuth("fds_reminder",2)&&(a[2].itm.push({lbl:$ict.remd,fnc:()=>$inv.ccRem(n,e.InvoiceId)}),a[2].itm.push({lbl:$ict.remlst,fnc:()=>$inv.dspRem(n)})),!0===t&&!0===$fis.isAuth("fds_reminder",2)&&!1===booln(e.IsSent,!1)&&a[2].itm.push({lbl:$ict.srs,fnc:()=>$inv.srs(n)}),a.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(a)},$inv.iMn=e=>{let t=booln(e.isFinal,!0),n=e.Id,i=booln(e.fds,!1),a=[{glyph:"glyphicon-menu-left",fnc:()=>{$fis.frm_edit().remove()}},{lbl:$ict.inv,itm:[]},{lbl:$ict.rem,itm:[]}];return!1===t&&!0===$fis.isAuth("fds_inv",2)?a[1].itm.push({lbl:$ict.ced,fnc:()=>{$inv.cntInv({id:n})}}):!0===$fis.isAuth("fds_inv",1)&&a[1].itm.push({lbl:$ict.dsp,fnc:()=>$inv.disp(n,"inv")}),!0===$fis.isAuth("fds_inv",2)&&(a[1].itm.push({lbl:$ict.storno,fnc:()=>$inv.storno(n,i)}),a[1].itm.push({lbl:$ict.credit,fnc:()=>$inv.credit(n,i)})),!0===t&&!1===booln(e.IsPayed,!1)?(!0===$fis.isAuth("fds_reminder",2)&&a[2].itm.push({lbl:$ict.remd,fnc:()=>$inv.ccRem(n,e.InvoiceId)}),!0===$fis.isAuth("fds_inv",2)&&a[1].itm.push({lbl:$ict.setpyd,fnc:()=>$inv.setPyd(n)})):!0===t&&!0===booln(e.IsPayed,!1)&&"m"===(e.PaymentStatus||"")&&!0===$fis.isAuth("fds_inv",2)&&a[1].itm.push({lbl:$ict.setupd,fnc:()=>$inv.setUpd(n)}),!0===$fis.isAuth("fds_reminder",2)&&a[2].itm.push({lbl:$ict.remlst,fnc:()=>$inv.dspRem(n)}),!0===t&&!0===$fis.isAuth("fds_inv",2)&&!1===booln(e.IsSent,!1)&&a[1].itm.push({lbl:$ict.sis,fnc:()=>$inv.sis(n)}),!1===i&&a[1].itm.push({lbl:$ict.mfr,fnc:()=>$inv.mfrrel(n)}),$("#topbar").ocmsmenu(a)},$inv.emOpt=e=>"iss,p13b,ctp"+(""===((e||{}).setmode||"")?",setm":""),$inv.eM=(e,t,n)=>{let i=[];return!0!==booln(e,!1)&&!0!==booln(t,!1)||i.push({glyph:"glyphicon-menu-left",fnc:()=>{$fis.lf(!0),$fis.frm_edit().remove()}}),!0===(n||"").split(",").includes("iss")&&i.push({lbl:$ict.iss,fnc:$inv.ssave}),!0===(n||"").split(",").includes("ctp")&&i.push({lbl:$ict.ctp,fnc:$inv.sctp}),!0===(n||"").split(",").includes("p13b")&&i.push({lbl:$ict.p13b,fnc:$inv.sp13b}),!0===(n||"").split(",").includes("setm")&&i.push({lbl:$ict.setm,fnc:$inv.ssetmode}),!0===(n||"").split(",").includes("iss")&&(i.push({lbl:"Änderungshistorie",fnc:()=>$inv.d.history()}),i.push({lbl:"Änderungen verwerfen",fnc:()=>$inv.d.discard()})),!0===booln(e,!1)&&i.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(i)},$inv.d={tbl:()=>$("div.invoice_layout table.invi"),layout:()=>$("div.invoice_layout"),token:function(){return $inv.d.tbl().data("dtoken")||""},hashes:function(){let e=$inv.d.tbl().data("bai")||[],t={};return $.each(e,((e,n)=>{t[(n.Id||"").toString()]=JSON.stringify(n)})),t},seed:function(e){let t=$inv.d.layout();t.aC("freeze");let n=$ocms.postXT({url:$ocms.url("inv/dopen"),data:{payload:JSON.stringify(e)},success:e=>{$inv.d.tbl().data("dtoken",e.token).data("dver",e.version).data("dhashes",$inv.d.hashes()).data("dorder",$inv.d.order()),$fis.draft.bind(e.token,{onReady:()=>$inv.d.refresh(),onExpiring:e=>$inv.d.warnExpiry(e),onClosed:e=>$inv.d.closed(e)}),$inv.d.refresh()},error:()=>{t.rC("freeze")},complete:()=>{$inv.d.tbl().removeData("dseeding").removeData("dseedpromise")}});return $inv.d.tbl().data("dseedpromise",n),n},refresh:function(e){let t=$inv.d.token();""!==t&&$ocms.postXT({url:$ocms.url("inv/dstate"),data:{token:t},success:t=>{$inv.d.applyState(t),"function"==typeof e&&e(t)},error:e=>{e&&410===e.status&&$inv.d.closed("expired")},complete:()=>{$inv.d.layout().rC("freeze")}})},applyState:function(e){let t=$inv.d.tbl();if(t.length<1)return;let n=t.data("dver");"number"==typeof n&&"number"==typeof e.version&&e.version$$.dc("dnote").aC(e.style||"InvoiceNotes").text(e.text)))},applyItems:function(e,t){let n=e=>void 0===e?null:e;(t||[]).forEach((t=>{if(!t)return;let i=(t.Id||"").toString();if(""===i)return;let a=e.children("tbody").filter(((e,t)=>(($(t).data()||{}).Id||"").toString()===i)).first();if(a.length<1)return;let r=t.itm||[],l={},d=a.find("tr.title").first(),s=d.length?d:null;r.forEach((e=>{let t=(e.id||"").toString();if(""===t)return;l[t]=!0;let i=a.find("#itm"+t).first(),r=i.length<1;r&&(i=$$.tr(a,{id:"itm"+t,class:"itm"}));let d=i.data()||{},c=r||(d.Type||"")!==(e.typ||"")||d.net!==n(e.v)||d.net_val!==n(e.vt)||d.vat_val!==n(e.vv)||d.svcnet_val!==n(e.vs)||d.svcvat_val!==n(e.vsv)||(d.position||"")!==(null!=e.p?e.p:"");$.extend(d,{Id:t,Type:e.typ,net:n(e.v),net_val:n(e.vt),vat_val:n(e.vv),svcnet_val:n(e.vs),svcvat_val:n(e.vsv),vat:e.vat,position:null!=e.p?e.p:"",SetItmId:null!=e.SetItmId?e.SetItmId:null}),r&&$.extend(d,{htmltext:e.t,quantity:e.q}),i.data(d),s?i.prev()[0]!==s[0]&&i.insertAfter(s):a.children().first()[0]!==i[0]&&a.prepend(i),s=i,c&&$inv.rrw.call(i)})),a.find("tr.itm").each(((e,t)=>{let n=(($(t).data()||{}).Id||"").toString();""===n||l[n]||$(t).remove()}))}))},applySetDisplay:function(e,t){e.find("tr.itm").each(((e,n)=>{let i=$(n),a=((i.data()||{}).Id||"").toString();if(""===a||!Object.prototype.hasOwnProperty.call(t,a))return;let r=t[a]||{};i.tC("sethdr",bool(r.h,!1)),!1===bool(r.p,!0)&&i.find("td.currency").text("")}))},sync:function(e){let t=$inv.d.token();if(""===t){let t=$inv.d.tbl().data("dseedpromise");return t?$.when(t).then((()=>$inv.d.sync(e))):$.when()}return $inv.d.layout().aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dpatch"),data:{token:t,delta:JSON.stringify(e)},success:()=>{$inv.d.refresh()},error:e=>{$inv.d.layout().rC("freeze"),e&&410===e.status&&$inv.d.closed("expired")}})},order:function(){return($inv.d.tbl().data("bai")||[]).map((e=>(e.Id||"").toString()))},syncChanged:function(e){let t=e.data("bai")||[],n=e.data("dhashes")||{},i={},a=[],r=[],l=[];$.each(t,((e,t)=>{let r=(t.Id||"").toString(),l=JSON.stringify(t);i[r]=l,n[r]!==l&&a.push(t)})),$.each(n,(e=>{void 0===i[e]&&r.push(e)}));let d=$inv.d.order(),s=e.data("dorder")||[];return e.data("dhashes",i).data("dorder",d),a.forEach((e=>l.push($inv.d.sync({Target:"block.replace",Ref:(e.Id||"").toString(),Value:e})))),r.forEach((e=>l.push($inv.d.sync({Target:"block.remove",Ref:e})))),s.length===d.length&&s.slice().sort().join(",")===d.slice().sort().join(",")&&s.join(",")!==d.join(",")&&l.push($inv.d.sync({Target:"block.order",Value:d})),$.when.apply($,l).promise()},syncField:function(e,t){let n={invoicetitle:"title",invoiceaddress:"address",invoiceemail:"email",loc:"provisionlocation",provisionlocation:"provisionlocation",provisionperiod:"provisionperiod"}[e];n&&$inv.d.sync({Target:n,Value:t})},footer:function(e,t,n){let i=e.children("tfoot").empty();e.nextAll(".fnote").remove();let a=bool(n.p13b,!1),r=(e,t,n)=>$$.tdc("currency",$$.tr(i,{class:n||"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text(e)]),fnum(t,$rct.cst)),l=t=>$$.dc("fnote").insertAfter(e).rwText(t);r("Netto",t.total_net||0),!1===a&&$.each(t.vat||{},((e,t)=>r($rct.vat+" "+e+"%",t,"tvat"))),r("Summe",t.total_gross||0);let d=n.type||"";"i"===d?(l($rct.note2),l($rct.note4)):"c"===d?l($rct.note2):(l(string($rct.note3,[fnum(((t.service_net||0)+(t.service_vat||0))*(n.tax_servicerefund||0),$rct.cst)])).aC("ntax"),l($rct.note2),l(string($rct.note1,[fnum((t.service_net||0)+(t.service_vat||0),$rct.cst),fnum(t.service_net||0,$rct.cst),fnum(t.service_vat||0,$rct.cst)]))),!0===a&&l($rct.note13b)},validation:function(e){let t=$("div.invoice_layout");if(t.length<1)return;let n=t.children(".dvalidation");n.length<1&&(n=$$.dc("dvalidation"),t.prepend(n)),n.empty().tC("hidden",(e||[]).length<1),$.each(e||[],((e,t)=>$$.dc("dvmsg",n).aC(t.severity).text(t.message)))},preview:function(){let e=$inv.d.token();if(""===e)return;let t=$inv.d.layout(),n=($inv.d.tbl().data("new")||{}).invoiceemail||"";!1===$fis.ValidateEmail(n)&&!1===bool(confirm($ict.ivE+$ict.ivEc),!1)||(t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dpreview"),data:{token:e},success:n=>{t.rC("freeze");let i=$$.dc("imagecollection pdfpreview"),a=Math.round(.88*vh()),r=n.total;r>10&&$$.dc("note warn",i).text($ict.tpe),$.each(n.img||[],((e,t)=>{$$.dc("pdfp",i).append($$.img(t).css("max-height",(a-rpx(6)).toString()+"px"))}));for(let e=(n.img||[]).length+1;e<=r;e++)$$.dc("pdfp ph",i).append($$.dc("note",$ict.pna));$ocms.dlg(i,{size:[a,Math.round(.88*vw())],zindex:50,form:!1,button:$rct.crI,confirm:function(n){let i=$(this);t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dsave"),data:{token:e},success:e=>{$ocms.postXT({url:$ocms.url("req/sconf"),data:{id:e.invid},success:t=>{i.trigger("modal_close"),!0===t.hasFile&&window.open($ocms.url("req/idoc")+"?id="+e.invid,"_blank"),$inv.d.close(),$ocms.init("req"),$inv.rReload()},error:()=>{alert($t.f1),i.trigger("modal_close")},complete:()=>{t.rC("freeze")}})},error:()=>{t.rC("freeze"),alert($ict.eis)}})},cancel:function(e){confirm($ict.cdI)&&($inv.d.close(),$inv.rReload())}})},error:()=>{t.rC("freeze"),alert($ict.eis)}}))},save:function(){let e=$inv.d.token();if(""===e)return;let t=$inv.d.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dsave"),data:{token:e},success:e=>{$inv.d.tbl().data("invid",e.invid)},error:()=>{alert($ict.eis)},complete:()=>{t.rC("freeze")}})},history:function(){let e=$inv.d.token();""!==e&&$ocms.postXT({url:$ocms.url("inv/dhistory"),data:{token:e},success:e=>{let t=$$.dc("dhist");if((e.history||[]).length<1)$$.dc("note",t).text("Noch keine Änderungen erfasst.");else{let n=$$.tblset({class:"invtbl fullwidth"},t);$$.tr(n.hd).append([$$.th().text("Zeit"),$$.th().text("Feld"),$$.th().text("Alt"),$$.th().text("Neu")]),$.each(e.history,((e,t)=>$$.tr(n.bdy).append([$$.tdc("keep",fdt(t.timestamp)),$$.td().text(t.target),$$.td().text(t.oldValue),$$.td().text(t.newValue)])))}$ocms.dlg(t,{width:800,form:!1})}})},discard:function(){let e=$inv.d.tbl().data("invid")||"";""!==e?!1!==confirm("Alle Änderungen verwerfen und den zuletzt gespeicherten Stand neu laden?")&&($inv.d.close(),$inv.cntInv({id:e})):alert("Es wurde noch kein Zwischenstand gespeichert, der wiederhergestellt werden könnte.")},warnExpiry:function(e){let t=Math.max(1,Math.round((e||0)/60));$fis.notifications.push({severity:"info",title:"Entwurf läuft ab",message:"Der Rechnungsentwurf läuft in etwa "+t+" Minute(n) ab. Bitte zwischenspeichern, sonst gehen die Änderungen verloren."})},closed:function(e){let t=$inv.d.token();$inv.d.tbl().removeData("dtoken"),""!==t&&$fis.draft.release(t),$fis.frm_edit().remove(),$fis.lf(!0),$fis.notifications.push({severity:"error",title:"Entwurf geschlossen",message:"expired"===e?"Der Rechnungsentwurf ist wegen Inaktivität abgelaufen. Nicht gespeicherte Änderungen sind verloren.":"Der Rechnungsentwurf wurde geschlossen."});try{$inv.rReload()}catch(e){}},close:function(){let e=$inv.d.token();""!==e&&($ocms.postXT({url:$ocms.url("inv/dclose"),data:{token:e}}),$fis.draft.release(e)),$inv.d.tbl().removeData("dtoken")}},$inv.rd={tbl:()=>$("div.invoice_layout table.invi"),layout:()=>$("div.invoice_layout"),token:function(){return $inv.rd.tbl().data("rdtoken")||""},seed:function(e){let t=$inv.rd.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dopen"),data:{payload:JSON.stringify(e)},success:e=>{$inv.rd.tbl().data("rdtoken",e.token).data("rdver",e.version),$fis.draft.bind(e.token,{onReady:()=>$inv.rd.refresh(),onExpiring:e=>$inv.rd.warnExpiry(e),onClosed:e=>$inv.rd.closed(e)}),$inv.rd.refresh()},error:()=>{t.rC("freeze")}})},refresh:function(e){let t=$inv.rd.token();""!==t&&$ocms.postXT({url:$ocms.url("rem/dstate"),data:{token:t},success:t=>{$inv.rd.applyState(t),"function"==typeof e&&e(t)},error:e=>{e&&410===e.status&&$inv.rd.closed("expired")},complete:()=>{$inv.rd.layout().rC("freeze")}})},applyState:function(e){let t=$inv.rd.tbl();if(t.length<1)return;let n=t.data("rdver");"number"==typeof n&&"number"==typeof e.version&&e.version{let t=$$[0]("p").aC("dnote intro").rwText(e);a.length?t.insertBefore(a):t.appendTo(n)})),((e||{}).closing||[]).forEach((e=>$$[0]("p").aC("dnote closing").rwText(e).appendTo(n)))},sync:function(e){let t=$inv.rd.token();""!==t&&($inv.rd.layout().aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dpatch"),data:{token:t,delta:JSON.stringify(e)},success:()=>{$inv.rd.refresh()},error:e=>{$inv.rd.layout().rC("freeze"),e&&410===e.status&&$inv.rd.closed("expired")}}))},syncField:function(e,t){if(""===$inv.rd.token())return;let n={subject:"subject",invoiceaddress:"address",invoiceemail:"email",text:"text"}[e];n&&$inv.rd.sync({Target:n,Value:t})},syncAmount:function(e,t){""!==$inv.rd.token()&&($inv.rd.sync({Target:"amount",Value:(null!=e?e:0).toString()}),$inv.rd.sync({Target:"amount_payed",Value:(null!=t?t:0).toString()}))},footer:function(e,t){let n=e.children("tfoot").empty(),i=$$.tr(n,{class:"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text("Offener Betrag")]);$$.tdc("currency",i,fnum(t.amount_open||0,$rct.cst))},validation:function(e){let t=$inv.rd.layout();if(t.length<1)return;let n=t.children(".dvalidation");n.length<1&&(n=$$.dc("dvalidation"),t.prepend(n)),n.empty().tC("hidden",(e||[]).length<1),$.each(e||[],((e,t)=>$$.dc("dvmsg",n).aC(t.severity).text(t.message)))},preview:function(){let e=$inv.rd.token();if(""===e)return;let t=$inv.rd.layout(),n=($inv.rd.tbl().data("new")||{}).invoiceemail||"";!1===$fis.ValidateEmail(n)&&!1===bool(confirm($ict.ivE+$ict.ivEc),!1)||(t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dpreview"),data:{token:e},success:n=>{t.rC("freeze");let i=$$.dc("imagecollection pdfpreview"),a=Math.round(.88*vh());$.each(n.img||[],((e,t)=>{$$.dc("pdfp",i).append($$.img(t).css("max-height",(a-rpx(6)).toString()+"px"))})),$ocms.dlg(i,{size:[a,Math.round(.88*vw())],zindex:50,form:!1,button:$ict.remd,confirm:function(n){let i=$(this);t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dsave"),data:{token:e},success:e=>{$ocms.postXT({url:$ocms.url("rem/conf"),data:{id:e.remid},success:()=>{i.trigger("modal_close"),window.open($ocms.url("rem/idoc")+"?id="+e.remid,"_blank"),$inv.rd.close(),$ocms.init("req"),$inv.rReload()},error:()=>{alert($t.f1),i.trigger("modal_close")},complete:()=>{t.rC("freeze")}})},error:()=>{t.rC("freeze"),alert($t.f1)}})},cancel:function(e){confirm($ict.cdI)&&($inv.rd.close(),$inv.rReload())}})},error:()=>{t.rC("freeze"),alert($t.f1)}}))},save:function(){let e=$inv.rd.token();if(""===e)return;let t=$inv.rd.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dsave"),data:{token:e},success:e=>{$inv.rd.tbl().data("remid",e.remid)},error:()=>{alert($t.f1)},complete:()=>{t.rC("freeze")}})},history:function(){let e=$inv.rd.token();""!==e&&$ocms.postXT({url:$ocms.url("rem/dhistory"),data:{token:e},success:e=>{let t=$$.dc("dhist");if((e.history||[]).length<1)$$.dc("note",t).text("Noch keine Änderungen erfasst.");else{let n=$$.tblset({class:"invtbl fullwidth"},t);$$.tr(n.hd).append([$$.th().text("Zeit"),$$.th().text("Feld"),$$.th().text("Alt"),$$.th().text("Neu")]),$.each(e.history,((e,t)=>$$.tr(n.bdy).append([$$.tdc("keep",fdt(t.timestamp)),$$.td().text(t.target),$$.td().text(t.oldValue),$$.td().text(t.newValue)])))}$ocms.dlg(t,{width:800,form:!1})}})},warnExpiry:function(e){let t=Math.max(1,Math.round((e||0)/60));$fis.notifications.push({severity:"info",title:"Entwurf läuft ab",message:"Der Mahnentwurf läuft in etwa "+t+" Minute(n) ab. Bitte zwischenspeichern, sonst gehen die Änderungen verloren."})},closed:function(e){let t=$inv.rd.token();$inv.rd.tbl().removeData("rdtoken"),""!==t&&$fis.draft.release(t),$fis.frm_edit().remove(),$fis.lf(!0),$fis.notifications.push({severity:"error",title:"Entwurf geschlossen",message:"expired"===e?"Der Mahnentwurf ist wegen Inaktivität abgelaufen. Nicht gespeicherte Änderungen sind verloren.":"Der Mahnentwurf wurde geschlossen."});try{$inv.rReload()}catch(e){}},close:function(){let e=$inv.rd.token();""!==e&&($ocms.postXT({url:$ocms.url("rem/dclose"),data:{token:e}}),$fis.draft.release(e)),$inv.rd.tbl().removeData("rdtoken")}},$inv.cInv2=function(e){let t=$$.dc("rfrm").ldng(1),n=$ocms.dlg(t,{width:1e3});n&&n.ft.rwText($rct.rq1);let i=()=>{$ocms.postXT({url:$ocms.url("req/get"),timeout:60,data:{id:e.id,mode:"r"},success:t=>{t.admin=t.admin||{};let n=$fis.lf(!0).aC("fix").rC("hd");if($fis.frm_edit().IN(),$inv.eM(!0,!0),(t.requests||[]).length<1)n.aC("fix").text($rct.nd);else{$$.dc("lh",n,$rct.mdl);let i=$$.d(),a=$$.ul({class:"rql"}).data({search:e.id,parent:t.admin.parent}).appendTo(n),r={},l=$rcol.req.lbl();$.each(t.requests||[],(function(e,t){let n=$$.li({class:"cli rli"}).data($.extend({},t)).appendTo(a),d=$$.dc("lihd",n).addClass(t.state);!0===booln(t.open,!1)&&d.append($$.sc("cbox").click((()=>{n.tC("checked"),i.find("li").rC("checked"),!0===n.is(".checked")?$inv.rMn(t.open):$inv.eM(!0)}))),d.append([$$.sc("eid",t.ExternalId),$$.sc("nme",t.Name)]),$$.dc("lidt",n).append([$$.dc("rqs").append([$$.s(l.State+": "),$$.s($rct.sts[t.State||"-"])]),$$.dc("ivn").append([$$.s(l.InvoiceId+": "),$$.s(t.InvoiceId||"- -")]),$$.dc("wda").append([$$.s(l.WorkDoneAt+": "),$$.s(fdt(t.WorkDoneAt,"dd.MM.yyyy"))])]),r[t.Id]=n})),(t.inv||[]).length>0&&($$.dc("lh",n,$rct.invs),i=$$.ul({class:"ivl"}).appendTo(n),$.each(t.inv||[],((e,t)=>{let n=$$.li({class:"cli ili"}).data($.extend({},t)).appendTo(i),r=$$.dc("lihd",n).addClass(t.invstatus);!1===booln(t.isFinal,!0)?r.append($$.sc("cbox").click((()=>{""!==(t.Id||"")&&(n.tC("checked").siblings().rC("checked"),a.find("li").rC("checked"),!0===n.is(".checked")?$inv.iMnr(t):$inv.eM(!0))}))):["","dft"].indexOf(t.invstatus)<0&&r.append($$.sc("dli").click((function(){$inv.disp(t.Id,"inv")}))),r.append($$.sc("nme",t.DocumentName||t.Id)),$$.dc("lidt",n).append([$$.dc("wda").append([$$.s(fdt(t.DateCreated,"dd.MM.yyyy"))]),$$.d().text($ict.iSt[t.invstatus]||t.invstatus)])})))}},complete:()=>{n&&n.c.trigger("modal_close")}})};$ocms.postXT({url:$ocms.url("req/pget"),timeout:90,data:{id:e.id},success:e=>{n&&n.ft.rwText($rct.rq2),i()},error:()=>{confirm($rct.rq1f)?(n&&n.ft.rwText($rct.rq2),i()):n&&n.c.trigger("modal_close")}})},$inv.ccInv=function(e){let t=(e.data||{}).typ||"r",n=$fis.lf(),i=n.children("ul.rql"),a=i.data("parent"),r=[];if(i.find("li.rli.checked").each((function(){r.push($(this).data("Id"))})),r.length<1)return void alert($rct.dnS);if("i"===t&&r.length>1)return void alert($rct.dII);let l=$fis.frm_edit(),d=$$.dc("invoice_layout",l).append($$.dc("btn sprev").click($inv.sprev)),s=$fis.cf().width()>d.width()+n.width()+20;n.tC("fix",s).tC("hd",!s),$inv.eM(!1,!0);let c=$$.dc("rfrm").ldng(1),o=$ocms.dlg(c,{width:1e3});o.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("req/iget"),timeout:60,data:{id:a,mode:"ful",typ:t,sel:r.join(",")},success:e=>{let t=$$.dc("srq",d),n=$$.tblset({class:"invi"},t);n.bdy.remove(),n.ft=$$[0]("tfoot"),e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b")),n.tbl.data($.extend({new:{},sms:{},itm:{}},{admin:e.admin,companies:e.companies,locations:e.locations}));let i=$$.tr(n.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(i,e))),n.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.requests||[],(function(t,i){if(0!==(i.Id||0)){let t=$inv.worknotes(i);i.text="i"===e.admin.type?$rct.req+jine([i.ExternalId,i.Name],": ").eine(" ",""):jine([jine([fdt(i.WorkDoneAt,"dd.MM.yy"),i.ExternalId]," - "+$rct.req+" "),t.ne(i.Name)],": \n");let a=$$.tbody(n.tbl).data($.extend({},i));$inv.rendersrq.call(a)}}));let a=$$.tr($$.tbody(n.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(a),n.ft.appendTo(n.tbl);let r,l,s=e.admin||{},c=(e,t,i,a,r)=>{let l=$$.dc("inpfrm",d).aC(e).append("string"==typeof a?$$.dc("ahd",a):a>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",l).rwText(t);$$.dc("axf",l).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{n.tbl.data("new")[i]=e}},r),$inv.eHtml)),n.tbl.data("new")[i]=t};c("tfrm",s.invoicetitle,"invoicetitle",0,null),c("adrfrm",s.invoiceaddress,"invoiceaddress",0,null),c("locfrm","","loc",1,{list:deepCopy(e.locations),lbl:"ref",property:"address"}),c("emailfrm",s.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",d).append($$.dc("content").text(s.sender)),s.provisionend&&(l=s.provisionstart?$rct.provP:$rct.provD,r=s.provisionstart?fdt(s.provisionstart,"dd.MM.yyyy")+" - "+fdt(s.provisionend,"dd.MM.yyyy"):fdt(s.provisionend,"dd.MM.yyyy")),c("admfrm",r,"provisionperiod",l,1),n.tbl.data("new").CustomValues=s.CustomValues||"",$$.dc("inpfrm ctpfrm",d).text(jObj(s.CustomValues,"contactName")),n.tbl.children("tbody").each($inv.bdysort),n.tbl.trigger("fds.inv"),$inv.eM(!1,!0,$inv.emOpt(s))},complete:()=>{o.c.trigger("modal_close")}})},$inv.ccStInv=function(e){let t=e.data||{},n=$fis.lf(),i=t.id,a=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sprev)),r=$fis.cf().width()>a.width()+n.width()+20;n.tC("fix",r).tC("hd",!r),$inv.eM(!1,!0);let l=$$.dc("rfrm").ldng(1),d=$ocms.dlg(l,{width:1e3});d.ft.rwText($ict.iq1),$ocms.postXT({url:$ocms.url("inv/pget"),timeout:90,data:{id:t.id},success:e=>{d&&d.ft.rwText($ict.iq2),$ocms.postXT({url:$ocms.url("inv/icget"),timeout:60,data:{id:i},success:e=>{let t=$$.dc("srq",a),n=$$.tblset({class:"invi"},t);n.bdy.remove(),n.ft=$$[0]("tfoot"),e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b")),n.tbl.data($.extend({new:{},sms:{},itm:{}},{admin:e.admin,companies:e.companies,locations:e.locations}));let i=$$.tr(n.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(i,e))),n.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.requests||[],(function(t,i){if(0!==(i.Id||0)){let t=$inv.worknotes(i);i.text="i"===e.admin.type?$rct.req+jine([i.ExternalId,i.Name],": ").eine(" ",""):jine([fdt(i.WorkDoneAt,"dd.MM.yy")+t.ne(i.Name)],": ");let a=$$.tbody(n.tbl).data($.extend({},i));$inv.rendersrq.call(a)}}));let r=$$.tr($$.tbody(n.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(r),n.ft.appendTo(n.tbl);let l,d,s=e.admin||{},c=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",a).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{n.tbl.data("new")[i]=e}},l),$inv.eHtml)),n.tbl.data("new")[i]=t};c("tfrm",s.invoicetitle,"invoicetitle",0,null),c("adrfrm",s.invoiceaddress,"invoiceaddress",0,null),c("locfrm",s.provisionlocation,"loc",1,{list:deepCopy(e.locations),lbl:"ref",property:"address"}),c("emailfrm",s.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",a).append($$.dc("content").text(s.sender)),s.provisionend&&(d=s.provisionstart?$rct.provP:$rct.provD,l=s.provisionstart?fdt(s.provisionstart,"dd.MM.yyyy")+" - "+fdt(s.provisionend,"dd.MM.yyyy"):fdt(s.provisionend,"dd.MM.yyyy")),c("admfrm",l,"provisionperiod",d,1),n.tbl.data("new").CustomValues=s.CustomValues||"",$$.dc("inpfrm ctpfrm",a).text(jObj(s.CustomValues,"contactName")),n.tbl.children("tbody").each($inv.bdysort),n.tbl.trigger("fds.inv")},complete:()=>{d.c.trigger("modal_close")}})},error:()=>{d&&d.c.trigger("modal_close")}})},$inv.clCntInv=function(e){let t=$fis.lf(!1),n=[];t.find("li.ili.checked").each((function(){n.push($(this).data("Id"))})),1===n.length&&$inv.cntInv({id:n[0]})},$inv.cntInv=function(e){e=e||{};$fis.lf(!1).rC("fix").aC("hd");let t=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sedit));$inv.eM(!1,!0);let n=$$.dc("rfrm").ldng(1),i=$ocms.dlg(n,{width:1e3});i.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("inv/get"),timeout:60,data:{id:e.id},success:e=>{e.admin=e.admin||{};let n=e.inv||{},i=$$.dc("srq",t),a=$$.tblset({class:"invi"},i);a.bdy.remove(),a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:n.Id,new:{},sms:{},itm:{},bai:[]},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(r,e))),a.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.req||[],(function(e,t){let n=$$.tbody(a.tbl).data($.extend({},t));$inv.rendersrq.call(n)}));let l=$$.tr($$.tbody(a.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(l),a.ft.appendTo(a.tbl);let d=(e,n,i,r,l)=>{let d=$$.dc("inpfrm",t).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(n);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=n};d("tfrm",n.InvoiceTitle,"invoicetitle",0,null),d("adrfrm",n.SendToAddress,"invoiceaddress",0,null),d("locfrm",n.ProvisionLocation,"loc",1,null),d("emailfrm",n.SendToEmail,"invoiceemail",0,null),$$.dc("sndfrm",t).append($$.dc("content").text(e.admin.sender)),d("admfrm",n.ProvisionPeriod,"provisionperiod",!0===(n.ProvisionPeriod||"").includes("-")?$rct.provP:$rct.provD,1),a.tbl.data("new").CustomValues=n.CustomValues||"",$$.dc("inpfrm ctpfrm",t).text(jObj(n.CustomValues,"contactName")),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv"),$inv.eM(!1,!0,$inv.emOpt(e.admin))},complete:()=>{i.c.trigger("modal_close")}})},$inv.cSt=function(e){e=e||{};let t=$fis.lf(),n=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sedit)),i=$fis.cf().width()>n.width()+t.width()+20;t.tC("fix",i).tC("hd",!i),$inv.eM(!1,!0);let a=$$.dc("rfrm").ldng(1),r=$ocms.dlg(a,{width:1e3});r.ft.rwText($ict.iq1),$ocms.postXT({url:$ocms.url("inv/pget"),data:{id:e.id},success:t=>{r&&r.ft.rwText($ict.iq2),$ocms.postXT({url:$ocms.url("inv/storno"),data:{id:e.id,mode:e.mode},success:e=>{e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b"));let t=e.inv||{},i=$$.dc("srq",n),a=$$.tblset({class:"invi"},i);a.bdy.remove(),a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:t.Id,new:{},sms:{},itm:{},bai:[]},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(r,e))),a.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.req||[],(function(e,t){let n=$$.tbody(a.tbl).data($.extend({},t));$inv.rendersrq.call(n)}));let l=$$.tr($$.tbody(a.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(l),a.ft.appendTo(a.tbl);let d=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",n).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=t};d("tfrm",t.InvoiceTitle,"invoicetitle",0,null),d("adrfrm",t.SendToAddress,"invoiceaddress",0,null),d("locfrm",t.ProvisionLocation,"loc",1,null),d("emailfrm",t.SendToEmail,"invoiceemail",0,null),$$.dc("sndfrm",n).append($$.dc("content").text(e.admin.sender)),d("admfrm",t.ProvisionPeriod,"provisionperiod",!0===(t.ProvisionPeriod||"").includes("-")?$rct.provP:$rct.provD,1),a.tbl.data("new").CustomValues=t.CustomValues||"",$$.dc("inpfrm ctpfrm",n).text(jObj(t.CustomValues,"contactName")),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv")},complete:()=>{r.c.trigger("modal_close")}})},error:()=>{r&&r.c.trigger("modal_close")}})},$inv.eHtml=function(e){let t=$(this),n=e.data instanceof jQuery?e.data:e.data.t,i=["invoiceemail","provisionperiod","invoicetitle"].includes(e.data.nme),a=i?[{name:"txt",label:"Text",type:"text",value:n.text()}]:[{name:"txt",label:"Text",type:"html",value:n.html(),tinymce:!0,attr:{style:"height: 300px"}}],r=e.data.change||null,l={title:t.data("dialog")||"",success:function(t){i?n.text(t.txt||""):n.html(t.txt),"function"==typeof r&&r(t.txt),$inv.d.syncField(e.data.nme,i?t.txt||"":t.txt),$inv.rd.syncField(e.data.nme,i?t.txt||"":t.txt)},tinymce:{valid_elements:"br",hidemenu:!0,hidetoolbar:!0}};if(Array.isArray(e.data.list)){let t=$$.dc("lstfrm");$.each(e.data.list,((n,i)=>{let a=$$.dc("li",t).append(""!==(e.data.lbl||"")?$$.dc("lbl").rwText(i[e.data.lbl]):null);$$.dc("adr",a).rwText(i[e.data.property]).data("val",i[e.data.property]).click((function(){let e=$(this),t=e.closest(".modal-body").find(':input[name="txt"]');t.is(".tinymce")?tinymce.get(t.attr("id")).setContent($$.s().rwText(e.data("val")).html()):"TEXTAREA"===t.prop("tagName")?t.val(e.data("val")).change():t.rwText(e.data("val"))}))})),l.addcontent=t}$ocms.dlgform(a,l)},$inv.setVat=function(e){$(this);let t=e.data,n=prompt($rct.rqV);n&&(n=parseFloat(n.replace("%","")),n>1&&(n*=.01),!1===isNaN(n)&&(t.siblings(".itm").each((function(){$(this).data().vat=fnum(n,{style:"percent"}).replace(" ","")})),$inv.t_fds_inv()))},$inv.inRow=function(e){let t=$(this),n=e.data,i={},a=$rcol.itm.clone(["SortOrder","NameOrNumber","Type","quantityhours","UnitString","net","svcnet_val","svcvat_val","net_val","vat_val","vat","Note"]),r="N"+(65536*(1+Math.random())||0).toString(16).substr(6),l=$$.tr({id:"itm_"+r.toString(),class:"itm"});$ocms.dlgform(a,{title:t.data("dialog")||"",success:function(e){l.data($.extend({Id:r},i,e)),$inv.rrw.call(l),l.insertAfter(n),$inv.t_fds_inv()},typedvalues:!0})},$inv.eRow=function(e){let t=$(this),n=e.data,i=n.data()||{},a=["SortOrder","NameOrNumber","Type","quantityhours","UnitString","net","svcnet_val","svcvat_val","net_val","vat_val","vat","Note"];i.id||""!==(i.Type||"")||a.unshift("Type");let r=$rcol.itm.clone(a).applyValues(i);r.set("Type","hidden","type"),$inv.eRw.call(t,n,i,r)},$inv.eRw=function(e,t,n){let i=$(this);$ocms.dlgform(n,{title:i.data("dialog")||"",success:function(n){let i={};""===(t.Id||"")&&(i.Id="N"+(65536*(1+Math.random())||0).toString(16).substr(6),e.attr("id","itm_"+i.Id.toString())),i.quantity=((n.quantityhours||"").toString()+" "+(n.UnitString||"").toString()).trimEnd(),e.data($.extend({},t,n,i)),console.debug("eRw success %o",e.data()),$inv.rrw.call(e),$inv.t_fds_inv()},typedvalues:!0})},$inv.bdysort=(e,t)=>{$(t).Sortable({dragItem:!1,dragHandleClass:"ico",parentident:"tr",onend:()=>{$inv.t_fds_inv()}})},$inv.rrw=function(){let e=$(this),t=e.data(),n={},i=e.is(".placeholder"),a=e.is(".hidenote"),r=e=>$$.d().append(e).html(),l=[$$.dc("ibtn insb",{title:$rct.iRb}).append(gi("indent-left")).click(e,$inv.inRow)];!1===i&&(l.unshift($$.dc("ibtn edit",{title:$rct.cP}).append(gi("pencil")).click(e,$inv.eRow)),l.push($$.dc("ibtn del",{title:$rct.dR}).append(gi("trash")).click((function(t){confirm($rct.cD)&&(e.remove(),$inv.t_fds_inv())}))),"set"===(t.Type||"").toLowerCase()&&0===(t.net_val||0)&&l.push($$.dc("ibtn tosetp",{title:$rct.toSetP}).append(gi("scale")).click(e,$inv.toSetPrice)));let d=$$.dc("axf").append(l);!0===i?n={id:"",typ:"placeholder"}:!0===e.is(".itm.osum")?n={invrqid:t.InvRqId,id:"osum"+e.index(),typ:"osum",p:"",q:null,t:r(t.tbl.tbl),tt:null,v:null,vt:t.net_val,vs:t.svcnet_val,vat:t.vat,vv:t.vat_val,vsv:t.svcvat_val,det:!1}:(n={invrqid:t.InvRqId,id:t.Id||"",typ:t.Type||"other",p:"",q:null,t:"",tt:null,v:null,vt:t.net_val,vs:t.svcnet_val,vat:t.vat,vv:t.vat_val,vsv:t.svcvat_val,det:""!==(t.Note||"")&&!1===a,SetItmId:t.SetItmId||null},$$.dc("ibtn ico move",d,{title:$rct.mR}),n.p=t.position||t.SortOrder||"",""===n.id?n.t="":["Text","Title"].includes(n.typ)&&0===(t.net_val||0)?n.t=t.htmltext||("#"!==(t.NameOrNumber||"").substr(0,1)?r($$[0]("p").text(t.NameOrNumber)):"")+(t.Note||""):(n.tt=n.det?"":$$.s(t.Note||"").text(),n.q=t.quantity||(0!==(t.quantityhours||0)?fnum(t.quantityhours)+" "+(t.UnitString||""):""),n.t=t.htmltext||(n.det?r($$.s(t.NameOrNumber||""))+r($$.dc("desc").html(t.Note)):r($$.s(t.NameOrNumber||""))),n.v=t.net,n.vt=t.net_val)),""!==(t.Note||"")&&$$.dc("ibtn add",d).append(gi("object-align-left")).click((function(t){$inv.rrw.call(e.tC("hidenote"))}));let s=[$$.tdc("aux").append(d),$$.tdc("keep").text(n.p)];if(""===n.id)s.push($$.td(e,{colspan:4}).append(n.t));else{Array.prototype.push.apply(s,n.q?[$$.tdc("keep").text(n.q)]:[]);let e=e=>null==e?"":fnum(e,$rct.cst);Array.prototype.push.apply(s,[$$.tdc("txt",{colspan:n.q?1:2,title:n.tt}).append(n.t),$$.tdc("currency").text(e(n.v)),$$.tdc("currency inetval").text(e(n.vt)).attr("title",$rct.svcPart+": "+e(n.vs))])}e.empty().attr("class",i?"placeholder":"itm").aC(n.Typ).tC("sethdr","set"===(n.typ||"").toString().toLowerCase()).tC("hidenote",a).append(s),t.co=n},$inv.toSetPrice=function(e){let t=(e.data.data().Id||"").toString();""!==t&&!1!==confirm($rct.toSetPc)&&$.when($inv.t_fds_inv()).done((()=>{$inv.d.sync({Target:"item.setprice",Ref:t})}))},$inv.invSumUpdate=function(){let e=$(this),t=[],n=e.children("tbody");n.each(((e,n)=>{let i=$(n),a=i.data()||{},r=[],l=[],d=i.find("tr.itm"),s=0;i.tC("empty",d.length<1),d.each(((e,t)=>{let n=$(t).data()||{};r.push(n.co);let i=$inv.itemToContract(n),a=(n.SetItmId||"").toString();"set"!==i.type&&""!==a&&a!==i.id&&(i.setId=a),l.push(i),(void 0===n.SortOrder||null===n.SortOrder?-1:n.SortOrder)>-1&&(!1===["text","title"].includes((n.Type||"other").toLowerCase())&&s++,n.SortOrder=0,n.position=s,$inv.rrw.call(t))})),t.push({Id:a.Id,nme:a.Name,text:a.text,itm:r,items:l})}));let i=e.find("tbody:not(.empty)").length;n.find("tr.isum").tC("hidden",i<2),e.data("bai",t),""===(e.data("dtoken")||"")&&!1===bool(e.data("dseeding"),!1)&&null!=(e.data("admin")||{}).type&&(e.data("dseeding",!0),$inv.d.seed($.extend($inv.invcPayload(e.data()),{invid:e.data("invid")||""})))},$inv.worknotes=function(e){let t="";return e.steps.forEach(((e,n)=>{let i;try{i=JSON.parse(e.Data||{}).fields||[]}catch(e){console.debug(e),i=[]}!0!==Array.isArray(i||"")&&(i="object"==typeof i&&!0===Array.isArray(i.field||"")?i.field:[]),i.forEach(((e,n)=>{"Ausgeführte Arbeiten"===e.name&&(t=e.result||"")}))})),t},$inv.rendersrq=function(){let e=$(this).empty(),t=e.is(".onesum"),n=e.data(),i=$$.tr(e,{id:"srq"+n.Id}).aC("title nosort"),a=($rcol.itm.lbl(),$$.dc("axf").appendTo($$.tdc("aux",i)));$$.dc("ibtn osum",a,{title:$rct.combP}).append(gi("euro")).click((function(t){e.tC("onesum"),$inv.rendersrq.call(e),$inv.t_fds_inv()})),$$.dc("ibtn setvat",a,{title:$rct.sV}).append(gi("gbp")).click(i,$inv.setVat),$$.dc("ibtn insb",a,{title:$rct.iRb}).append(gi("indent-left")).click(i,$inv.inRow);let r,l=$$.sc("text",n.text),d=($$.td(i,{colspan:t?4:5}).append(l),["net_val","vat_val","svcnet_val","svcvat_val","net"]);if($$.dc("ibtn edit",a).data("dialog",$rcol.req.lbl().Name).append(gi("pencil")).click({t:l,change:e=>{n.text=e,$inv.t_fds_inv()}},$inv.eHtml),t&&($$.tdc("currency isumval",i),r={Id:n.Id.toString()+"_osum",net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0},r.tbl=$$.tblset({class:"stbl"})),$.each(n.items||[],((n,i)=>{let a,l={Id:i.Id,net_val:i.net_val||0,vat_val:i.vat_val||0,svcnet_val:0,svcvat_val:0,net:i.net||0,Note:i.Note||""};if("service"===i.Type.toLowerCase())l.svcnet_val=i.net_val||0,l.svcvat_val=i.vat_val||0;t?(a=$$.tr(r.tbl.bdy,{id:"itm"+i.Id,class:"sitm"}).aC(i.Type),"Text"===i.Type||"Title"===i.Type?$$.td(a,{colspan:2}).html(i.htmltext||i.Note):($$.tdc("keep",a).text(i.quantity||((i.quantityhours||0)>0?fnum(i.quantityhours)+(i.UnitString||"").eine(" ",""):"")),i.htmltext?$$.tdc("txt",a).html(i.htmltext):$$.tdc("txt",a).text(i.NameOrNumber).attr("title",i.Note)),$.each(d,((e,t)=>{r[t]+=l[t]})),a.data(l)):($.extend(l,i),a=$$.tr(e,{id:"itm"+i.Id,class:"itm"}),a.data(l),$inv.rrw.call(a))})),t){let t=$$.tr(e,{id:"itmsq"+n.Id,class:"itm osum"}).data(r);$inv.rrw.call(t)}else{let t=$$.tr(e).aC("isum nosort");$$.tdc("aux",t),$$.td(t,{colspan:4}).text($rct.iSum),$$.tdc("currency isumval",t)}},$inv.t_fds_inv=()=>{let e=$("div.invoice_layout table.invi");if(e.trigger("fds.inv"),""!==(e.data("dtoken")||""))return $inv.d.syncChanged(e);let t=e.data("dseedpromise");return t?$.when(t).then((()=>$inv.d.syncChanged(e))):$.when()},$inv.sedit=()=>{$inv.sprev(!0)},$inv.jdisp=function(e){e.stopPropagation(),e.data.id&&$inv.disp(e.data.id,e.data.typ||"")},$inv.disp=(e,t)=>{let n="";switch(t){case"inv":n="inv/rdoc";break;case"rem":n="rem/rdoc"}""!==n&&$ocms.postXT({url:$ocms.url(n),data:{id:e||"",typ:"img"},success:e=>{let t=$$.dc("imagecollection pdfpreview"),n=Math.round(.88*vh());e.id;$.each(e.img||[],(function(e,i){$$.dc("pdfp",t).append($$.img(i).css("max-height",(n-rpx(6)).toString()+"px"))})),$ocms.dlg(t,{size:[n,Math.round(.88*vw())],zindex_min:50,form:!1,exclusive:!1})}})},$inv.jdbn=function(e){$ocms.postXT({url:$ocms.url("inv/rdocn"),data:{name:e.data.id||"",typ:"img"},success:e=>{let t=$$.dc("imagecollection pdfpreview"),n=Math.round(.88*vh());e.id;$.each(e.img||[],(function(e,i){$$.dc("pdfp",t).append($$.img(i).css("max-height",(n-rpx(6)).toString()+"px"))})),$ocms.dlg(t,{size:[n,Math.round(.88*vw())],zindex:50,form:!1})}})},$inv.sp13b=()=>{var e=$("div.invoice_layout").find("table.invi"),t=e.data();t.admin.p13b=!0,!1===(t.inv.InvoiceOptions||"").split(",").includes("§13b")&&(t.inv.InvoiceOptions+=",§13b"),e.trigger("fds.inv"),$inv.d.sync({Target:"p13b",Value:t.admin.p13b})},$inv.itemToContract=function(e){let t=((e=e||{}).Type||"").toString().toLowerCase(),n=e=>e??null,i={id:(e.Id||"").toString(),type:t,title:"",desc:"",qty:"",price_net:"",total_net:n(e.net_val),vat:e.vat||""};var a;return e.co&&"osum"===e.co.typ?(i.desc=e.co.t||"",i.total_net=e.net_val||0):["text","title"].includes(t)&&0===(e.net_val||0)?(i.desc=e.htmltext||("#"!==(e.NameOrNumber||"").substr(0,1)?(a=$$[0]("p").text(e.NameOrNumber||""),$$.d().append(a).html()):"")+(e.Note||""),i.total_net=""):(e.htmltext?i.desc=e.htmltext:(i.title=e.NameOrNumber||"",i.desc=e.Note||""),i.qty=e.quantity||(0!==(e.quantityhours||0)?fnum(e.quantityhours)+(e.UnitString?" "+e.UnitString:""):""),i.price_net=n(e.net),i.total_net=n(e.net_val)),i},$inv.ssetmode=()=>{let e=$("div.invoice_layout").find("table.invi").data();e.admin=e.admin||{};let t,n=e.admin.setmode||"setprice",i=e=>$$.dc("btn",$ict.setmo[e]).tC("selected",n===e).click((()=>{t.c.trigger("modal_close"),$inv.setSetmode(e)})),a=$$.dc("choicefrm").append([i("setprice"),i("setonly")]);t=$ocms.dlg(a,{width:800})},$inv.setSetmode=e=>{if(!1===confirm($rct.toSetMc||$rct.toSetPc))return;let t="setonly"===e?"block.setonly":"block.setprice";$.when($inv.t_fds_inv()).done((()=>{$inv.d.sync({Target:t})}))},$inv.sctp=()=>{let e=$invcol.ctp;$ocms.dlgform(e,{title:$ict.ctp,success:function(e){var t=$("div.invoice_layout"),n=t.find("table.invi").data();let i={};void 0!==n.new&&"{"===(n.new.CustomValues||"").substr(0,1)&&(i=JSON.parse(n.inv.CustomValues)),i.contactName=e.name,i.contactEmail=e.email,n.new.CustomValues=JSON.stringify(i),t.find(".ctpfrm").text(ne(e.name,e.email)),$inv.d.sync({Target:"contact",Value:{name:e.name,email:e.email}})},typedvalues:!0})},$inv.invcPayload=function(e){e=e||{};let t=$.extend({},e.new),n=$.extend({},e.admin);return t.title=null!=t.invoicetitle?t.invoicetitle:t.title||"",t.provisionlocation=null!=t.loc?t.loc:t.provisionlocation||"",t.paymentterm=null!=n.paymentterms?n.paymentterms:t.paymentterm||"",n.customerid=null!=n.customerid?n.customerid:n.CustomerId,{admin:n,req:e.bai,new:t}},$inv.ssave=()=>{$inv.d.save()},$inv.sprev=e=>{$inv.d.preview()},$inv.rReload=()=>{try{let e=$("#listframe ul.rql:first").data();$inv.cInv2({id:e.search})}catch(e){}},$inv.quantChange=function(e){},$inv.storno=function(e,t){let n,i=$$.dc("choicefrm").append([$$.dc("btn","Storno ohne Details").click({id:e,mode:"simple"},(e=>{n.c.trigger("modal_close"),$inv.cSt(e.data)})),$$.dc("btn","Storno mit neuer Rechnung").click({id:e},(e=>{n.c.trigger("modal_close"),$inv.ccStInv(e)})),$$.dc("btn","Storno mit best. Rechnung").tC("inactive",!1===bool(t,!1)).click({id:e,mode:"copy"},(e=>{!0===bool(t,!1)&&(n.c.trigger("modal_close"),$inv.cSt(e.data))}))]);n=$ocms.dlg(i,{width:1e3})},$inv.credit=function(e,t){let n,i=$$.dc("choicefrm").append([$$.dc("btn","Gutschrift").click({id:e,mode:"credit"},(e=>{n.c.trigger("modal_close"),$inv.cSt(e.data)}))]);n=$ocms.dlg(i,{width:1e3})},$inv.setPyd=function(e){confirm($ict.cpyd)&&$ocms.postXT({url:$ocms.url("inv/setpyd"),timeout:60,data:{id:e},success:e=>{alert($ict.relm)},error:()=>{alert($t.f1)}})},$inv.setUpd=function(e){confirm($ict.cupd)&&$ocms.postXT({url:$ocms.url("inv/setupd"),timeout:60,data:{id:e},success:e=>{alert($ict.relm)},error:()=>{alert($t.f1)}})},$inv.resendRem=function(e){e.stopPropagation(),e.data.id&&confirm(string($ict.remresc,[e.data.name]))&&$ocms.postXT({url:$ocms.url("rem/resend"),timeout:60,data:{id:e.data.id},success:t=>{alert(string($ict.remresr,[e.data.name]))},error:()=>{alert($t.f1)}})},$inv.dspRem=function(e){let t=$$.dc("rfrm").ldng(1),n=$ocms.dlg(t,{width:1e3});n.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("inv/getrem"),timeout:60,data:{id:e,drafts:!1},success:e=>{n.ft.empty();let i=$$.tblset({class:"invtbl"},t.empty()),a=$invcol.rem2,r=$$.tr(i.hd);$$.th(r);$.each(a.fields||[],((e,t)=>{$$.th(r).text(t.label)}));let l=!1;$.each(e,((e,t)=>{l=!l;let n=$$.tr(i.bdy).tC("alt",l),r=$$.td(n);n.click((function(){n.tC("selected").siblings().rC("selected")})),!0===bool(t.hasFile,!1)&&($$.dc("idl ilbtn",r,{title:$ict.dl+"\n"+t.DocumentName}).append(gi("save-file","ico")).click({id:t.Id},$inv.downloadrem),$$.dc("idl ilbtn",r,{title:$ict.remdsp+"\n"+t.DocumentName}).append(gi("eye-open","ico")).click({id:t.Id,typ:"rem"},$inv.jdisp),$$.dc("idl ilbtn",r,{title:$ict.remres+"\n"+t.DocumentName}).append(gi("refresh","ico")).click({id:t.Id,typ:"rem",name:t.DocumentName},$inv.resendRem)),$.each(a.fields||[],((e,i)=>{let a=$$.td(n).aC(i.dtype),r=t[i.name];if("function"==typeof i.dfnc)i.dfnc.call(a,r,t);else switch(i.type||""){case"date":a.text(fdt(t[i.name],"dd.MM.yy"));break;case"datetime":a.text(fdt(t[i.name]));break;case"html":a.append($$.dc("ctw").html(r)),a.append($$.dc("ttip").html(r));break;default:a.text(t[i.name])}if("InvoiceId"===(i.name||""))a.aC("keep");switch(typeof i.title){case"function":i.title.call(a,t);break;case"string":a.attr("title",cs.title)}}))}))},error:()=>{t.empty(),n.ft.rwText($t.f1)},complete:()=>{t.ldng(0)}})},$inv.ccRem=function(e,t){$(this);$ocms.postXT({url:$ocms.url("rem/lrem"),timeout:60,data:{id:e},success:n=>{let i=$invcol.rid.clone();i.applyValues(n.ov);let a=$$.dc("ac"),r=$$.tblset({class:"fullgrid fullwidth"},a);if((n.lst||[]).length>0){$$.d({style:"margin: 1.5rem 0 1rem 0;font-size: 110%;text-decoration: underline;"}).prependTo(a).text($ict.rovlh);let e=$$.tr(r.hd);$ict.rovl.forEach(((t,n)=>$$.th(e,t))),$.each(n.lst,((e,t)=>{$$.tr(r.bdy).append([$$.tdc("keep",t.subject),$$.tdc("currency",fnum(t.amount,$rct.cst)),$$.tdc("currency",fnum(t.amount_payed,$rct.cst)),$$.tdc("keep",fdt(t.DateFinalized,"dd.MM.yy"))])}))}else $$.td($$.tr(r.bdy),$ict.nd);$ocms.dlgform(i,{addcontent:a,title:string($ict.remdt,[t||"?"]),success:function(t){$inv.ccRem_s2(e,t)},typedvalues:!0})}})},$inv.rRemRw=function(e){let t=$(this),n=e.rm||{};t.empty().data({invoiceid:n.invoiceid,invoicedate:n.invoicedate,amount:n.amount,amount_payed:n.amount_payed});let i=$$.dc("axf").append($$.dc("ibtn edit",{title:$rct.cP}).append(gi("pencil")).click(t,$inv.eRowR));t.append([$$.tdc("aux").append(i),$$.tdc("keep",n.invoiceid),$$.tdc("keep",fdt(n.invoicedate,"dd.MM.yy")),$$.tdc("currency",fnum(n.amount,$rct.cst)),$$.tdc("currency",fnum(n.amount_payed,$rct.cst)),$$.tdc("currency",fnum(n.amount-n.amount_payed,$rct.cst))])},$inv.eRowR=function(e){let t=$(this),n=e.data,i=n.data()||{},a=$invcol.rem.clone().applyValues(i);$ocms.dlgform(a,{title:t.data("dialog")||"",success:function(e){let i=t.closest("table"),a=i.data();$.extend(a.rm,e),i.data(a),$inv.rRemRw.call(n,a),$inv.rd.syncAmount(a.rm.amount,a.rm.amount_payed)},typedvalues:!0})},$inv.ccRem_s2=function(e,t){$fis.lf(!1).rC("fix").aC("hd");let n=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.rprev));$inv.eM(!1,!0);$$.dc("rfrm").ldng(1);$ocms.postXT({url:$ocms.url("rem/get"),timeout:60,data:$.extend({id:e},t),success:e=>{let t=e.rm||{},i=$$.dc("srq",n),a=$$.tblset({class:"invi"},i);a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:t.invid,new:{}},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$ict.remHR.forEach((e=>$$.th(r,e))),$inv.rRemRw.call($$.tr(a.bdy),a.tbl.data()),a.ft.appendTo(a.tbl);let l=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",n).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=t};l("tfrm",t.subject,"subject",0,null),l("adrfrm",t.invoiceaddress,"invoiceaddress",0,null),l("emailfrm",t.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",n).append($$.dc("content").text(t.sender)),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv");let d=a.tbl.data("new");d.amount=t.amount,d.amount_payed=t.amount_payed,$inv.rd.seed({rem:{invid:t.invid,type:t.type,invoiceid:t.invoiceid,invoicedate:t.invoicedate},new:d})},complete:()=>{}})},$inv.rprev=()=>{$inv.rd.preview()},$inv.sis=e=>{confirm($ict.sisc)&&$ocms.postXT({url:$ocms.url("inv/sis"),data:{id:e||""},success:e=>{}})},$inv.srs=e=>{confirm($ict.srsc)&&$ocms.postXT({url:$ocms.url("rem/srs"),data:{id:e||""},success:e=>{}})},$inv.mfrrel=e=>{$("#contentframe").ldng(),$ocms.postXT({url:$ocms.url("inv/mfrrel"),data:{id:e||""},success:e=>{$inv.rerenderinv()},complete:()=>{$("#contentframe").ldng(0)}})};
\ No newline at end of file
diff --git a/Fuchs/wwwroot/web/fis.js b/Fuchs/wwwroot/web/fis.js
index 771051e..a094592 100644
--- a/Fuchs/wwwroot/web/fis.js
+++ b/Fuchs/wwwroot/web/fis.js
@@ -814,7 +814,7 @@ $ocms.postXT = function (options) {
if ((typeof options.contentType === 'boolean' ? options.contentType === false : false) === true) {
ajo.contentType = false; /* needed for file uploads */
}
- $.ajax(ajo);
+ return $.ajax(ajo);
};
$ocms.cex_timer = function () {
if (!$ocms.cexi) {
@@ -2670,7 +2670,15 @@ if (!Element.prototype.closest) {
_onPress: function (e) {
if (!e) { return; }
function op(tgt) {
- if (tgt && tgt.parentNode === this._container && (this._dragHandleClass === '' || e.target.className.indexOf(this._dragHandleClass) > -1) && tgt.className.indexOf("nosort") < 0) {
+ // Match the drag handle by real CSS class token, not substring. The old
+ // e.target.className.indexOf('ico') matched every Bootstrap "glyph[ico]n" icon,
+ // so clicking any icon button (edit/delete/set-price…) inside a sortable row
+ // started a zero-distance drag that swallowed the button's own click. Using
+ // closest('.') restricts dragging to the dedicated handle element (e.g.
+ // the ".ico" move button) and its descendants only.
+ var isHandle = this._dragHandleClass === '' ||
+ (e.target.closest && e.target.closest('.' + this._dragHandleClass) != null);
+ if (tgt && tgt.parentNode === this._container && isHandle && tgt.className.indexOf("nosort") < 0) {
e.preventDefault();
this._dragging = true;
this._click = getPoint(e);
diff --git a/Fuchs/wwwroot/web/fis.min.js b/Fuchs/wwwroot/web/fis.min.js
index bdb74a6..111832d 100644
--- a/Fuchs/wwwroot/web/fis.min.js
+++ b/Fuchs/wwwroot/web/fis.min.js
@@ -1,4 +1,4 @@
var t,e,$t={lng:"de-DE",dn:["So","Mo","Di","Mi","Do","Fr","Sa"],mn:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],ma:["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],datepattern:"(0[1-9]|1[0-9]|2[0-9]|3[01]).(0[1-9]|1[012]).[0-9]{4}",datetimepattern:"(0[1-9]|1[0-9]|2[0-9]|3[01]).(0[1-9]|1[012]).[0-9]{4}\\s([0-5][0-9]):([0-5][0-9])",dateplaceholder:"dd.MM.yyyy",datetimeplaceholder:"dd.MM.yyyy HH:mm",dateformat:"dd.MM.yyyy",datetimeformat:"dd.MM.yyyy HH:mm",f1:"Der Server hat einen Fehler gemeldet: \n",f2:"Bitte versuchen Sie es erneut.",m0:"Diese Internet-Seite benötigt einen html5-kompatiblen Browser.",m0b:"Unterstützt werden bspw: Internet Explorer ab Version 10, Firefox ab Version 31, Chrome ab Version 31, Safari ab Version 7, Opera ab Version 27",m1:"Dieser Datensatz ist momentan von jemand anderem zur Bearbeitung gesperrt.",m2:"Diese Funktion ist zur Zeit nicht verfügbar",t1:"Eingabe erforderlich.",t2:"Eingabe ist nicht erforderlich.",true:"Ja",false:"Nein",alert:"Hinweis",confirm:"Bestätigen",open:"Öffnen","not implemented":"Diese Funktion in zur Zeit noch nicht verfügbar.",l0:"Anmeldung",l1:"Email / Anmeldename",l2:"Email-Adresse / Anmeldename",l3:"Passwort",l4:"Benutzer",l5:"Wird vom System ermittelt...",l6:"Anmelden",l7:"Passwort vergessen?",l7a:'Die "Passwort vergessen"-Funktion läuft in zwei Schritten ab:\n \nIm ersten Schritt wird eine SMS mit einem Code an die hinterlegte Mobilfunk-Nummer versandt.\nIm zweiten Schritt geben Sie bitte diesen Code in das Formular ein und übermitteln es erneut.\n \nIn beiden Schritten wird aus Sicherheitsgründen kein Fehler angezeigt und auch dann ein erfolgreicher Versand bestätigt, wenn die Kombination aus Email-Adresse und Nachname nicht gefunden wurde und/oder der code falsch ist.',l8:"Keinen Account?",l9:"Anmeldenamen der Email-Adresse wurde nicht erkannt.",l10:"Nachname",l11:"Email-Adresse",l12:"Passwort zusenden",l13:"Das Passwort wurde erfolgreich verschickt",l14:"Das Passwort konnte nicht verschickt werden",l15:"Sie sind nicht berechtigt, diese Funktion auszuführen.",l16:"Sie müssen zunächst einen Account angeben.",l17:"Die Kombination aus Anmeldenamen und Passwort konnte nicht bestätigt werden.",l18:"Es gibt ein Problem mit dem Formular.\nEs kann momentan nicht verarbeitet und versendet werden.",name:"Name",submit:"Senden",cancel:"Abbrechen",noop:"Diese Funktion is noch nicht verfügar."};t=self,e=()=>(()=>{var t={d:(e,n)=>{for(var i in n)t.o(n,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:n[i]})}};t.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),t.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),t.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"t",{value:!0})};var e,n={};t.r(n),t.d(n,{AbortError:()=>r,DefaultHttpClient:()=>D,HttpClient:()=>h,HttpError:()=>i,HttpResponse:()=>d,HttpTransportType:()=>U,HubConnection:()=>O,HubConnectionBuilder:()=>tt,HubConnectionState:()=>j,JsonHubProtocol:()=>K,LogLevel:()=>e,MessageType:()=>N,NullLogger:()=>p,Subject:()=>q,TimeoutError:()=>o,TransferFormat:()=>B,VERSION:()=>f});class i extends Error{constructor(t,e){const n=new.target.prototype;super(`${t}: Status code '${e}'`),this.statusCode=e,this.__proto__=n}}class o extends Error{constructor(t="A timeout occurred."){const e=new.target.prototype;super(t),this.__proto__=e}}class r extends Error{constructor(t="An abort occurred."){const e=new.target.prototype;super(t),this.__proto__=e}}class s extends Error{constructor(t,e){const n=new.target.prototype;super(t),this.transport=e,this.errorType="UnsupportedTransportError",this.__proto__=n}}class a extends Error{constructor(t,e){const n=new.target.prototype;super(t),this.transport=e,this.errorType="DisabledTransportError",this.__proto__=n}}class c extends Error{constructor(t,e){const n=new.target.prototype;super(t),this.transport=e,this.errorType="FailedToStartTransportError",this.__proto__=n}}class l extends Error{constructor(t){const e=new.target.prototype;super(t),this.errorType="FailedToNegotiateWithServerError",this.__proto__=e}}class u extends Error{constructor(t,e){const n=new.target.prototype;super(t),this.innerErrors=e,this.__proto__=n}}class d{constructor(t,e,n){this.statusCode=t,this.statusText=e,this.content=n}}class h{get(t,e){return this.send({...e,method:"GET",url:t})}post(t,e){return this.send({...e,method:"POST",url:t})}delete(t,e){return this.send({...e,method:"DELETE",url:t})}getCookieString(t){return""}}!function(t){t[t.Trace=0]="Trace",t[t.Debug=1]="Debug",t[t.Information=2]="Information",t[t.Warning=3]="Warning",t[t.Error=4]="Error",t[t.Critical=5]="Critical",t[t.None=6]="None"}(e||(e={}));class p{constructor(){}log(t,e){}}p.instance=new p;const f="10.0.0";class m{static isRequired(t,e){if(null==t)throw new Error(`The '${e}' argument is required.`)}static isNotEmpty(t,e){if(!t||t.match(/^\s*$/))throw new Error(`The '${e}' argument should not be empty.`)}static isIn(t,e,n){if(!(t in e))throw new Error(`Unknown ${n} value: ${t}.`)}}class g{static get isBrowser(){return!g.isNode&&"object"==typeof window&&"object"==typeof window.document}static get isWebWorker(){return!g.isNode&&"object"==typeof self&&"importScripts"in self}static get isReactNative(){return!g.isNode&&"object"==typeof window&&void 0===window.document}static get isNode(){return"undefined"!=typeof process&&process.release&&"node"===process.release.name}}function y(t,e){let n="";return v(t)?(n=`Binary data of length ${t.byteLength}`,e&&(n+=`. Content: '${function(t){const e=new Uint8Array(t);let n="";return e.forEach((t=>{n+=`0x${t<16?"0":""}${t.toString(16)} `})),n.substring(0,n.length-1)}(t)}'`)):"string"==typeof t&&(n=`String data of length ${t.length}`,e&&(n+=`. Content: '${t}'`)),n}function v(t){return t&&"undefined"!=typeof ArrayBuffer&&(t instanceof ArrayBuffer||t.constructor&&"ArrayBuffer"===t.constructor.name)}async function b(t,n,i,o,r,s){const a={},[c,l]=C();a[c]=l,t.log(e.Trace,`(${n} transport) sending data. ${y(r,s.logMessageContent)}.`);const u=v(r)?"arraybuffer":"text",d=await i.post(o,{content:r,headers:{...a,...s.headers},responseType:u,timeout:s.timeout,withCredentials:s.withCredentials});t.log(e.Trace,`(${n} transport) request complete. Response status: ${d.statusCode}.`)}class ${constructor(t,e){this.i=t,this.h=e}dispose(){const t=this.i.observers.indexOf(this.h);t>-1&&this.i.observers.splice(t,1),0===this.i.observers.length&&this.i.cancelCallback&&this.i.cancelCallback().catch((t=>{}))}}class w{constructor(t){this.l=t,this.out=console}log(t,n){if(t>=this.l){const i=`[${(new Date).toISOString()}] ${e[t]}: ${n}`;switch(t){case e.Critical:case e.Error:this.out.error(i);break;case e.Warning:this.out.warn(i);break;case e.Information:this.out.info(i);break;default:this.out.log(i)}}}}function C(){let t="X-SignalR-User-Agent";return g.isNode&&(t="User-Agent"),[t,S(f,x(),g.isNode?"NodeJS":"Browser",_())]}function S(t,e,n,i){let o="Microsoft SignalR/";const r=t.split(".");return o+=`${r[0]}.${r[1]}`,o+=` (${t}; `,o+=e&&""!==e?`${e}; `:"Unknown OS; ",o+=`${n}`,o+=i?`; ${i}`:"; Unknown Runtime Version",o+=")",o}function x(){if(!g.isNode)return"";switch(process.platform){case"win32":return"Windows NT";case"darwin":return"macOS";case"linux":return"Linux";default:return process.platform}}function _(){if(g.isNode)return process.versions.node}function T(t){return t.stack?t.stack:t.message?t.message:`${t}`}class E extends h{constructor(e){if(super(),this.u=e,"undefined"==typeof fetch||g.isNode){const t=require;this.p=new(t("tough-cookie").CookieJar),"undefined"==typeof fetch?this.m=t("node-fetch"):this.m=fetch,this.m=t("fetch-cookie")(this.m,this.p)}else this.m=fetch.bind(function(){if("undefined"!=typeof globalThis)return globalThis;if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==t.g)return t.g;throw new Error("could not find global")}());if("undefined"==typeof AbortController){const t=require;this.v=t("abort-controller")}else this.v=AbortController}async send(t){if(t.abortSignal&&t.abortSignal.aborted)throw new r;if(!t.method)throw new Error("No method defined.");if(!t.url)throw new Error("No url defined.");const n=new this.v;let s;t.abortSignal&&(t.abortSignal.onabort=()=>{n.abort(),s=new r});let a,c=null;if(t.timeout){const i=t.timeout;c=setTimeout((()=>{n.abort(),this.u.log(e.Warning,"Timeout from HTTP request."),s=new o}),i)}""===t.content&&(t.content=void 0),t.content&&(t.headers=t.headers||{},v(t.content)?t.headers["Content-Type"]="application/octet-stream":t.headers["Content-Type"]="text/plain;charset=UTF-8");try{a=await this.m(t.url,{body:t.content,cache:"no-cache",credentials:!0===t.withCredentials?"include":"same-origin",headers:{"X-Requested-With":"XMLHttpRequest",...t.headers},method:t.method,mode:"cors",redirect:"follow",signal:n.signal})}catch(t){if(s)throw s;throw this.u.log(e.Warning,`Error from HTTP request. ${t}.`),t}finally{c&&clearTimeout(c),t.abortSignal&&(t.abortSignal.onabort=null)}if(!a.ok){const t=await k(a,"text");throw new i(t||a.statusText,a.status)}const l=k(a,t.responseType),u=await l;return new d(a.status,a.statusText,u)}getCookieString(t){let e="";return g.isNode&&this.p&&this.p.getCookies(t,((t,n)=>e=n.join("; "))),e}}function k(t,e){let n;switch(e){case"arraybuffer":n=t.arrayBuffer();break;case"text":default:n=t.text();break;case"blob":case"document":case"json":throw new Error(`${e} is not supported.`)}return n}class I extends h{constructor(t){super(),this.u=t}send(t){return t.abortSignal&&t.abortSignal.aborted?Promise.reject(new r):t.method?t.url?new Promise(((n,s)=>{const a=new XMLHttpRequest;a.open(t.method,t.url,!0),a.withCredentials=void 0===t.withCredentials||t.withCredentials,a.setRequestHeader("X-Requested-With","XMLHttpRequest"),""===t.content&&(t.content=void 0),t.content&&(v(t.content)?a.setRequestHeader("Content-Type","application/octet-stream"):a.setRequestHeader("Content-Type","text/plain;charset=UTF-8"));const c=t.headers;c&&Object.keys(c).forEach((t=>{a.setRequestHeader(t,c[t])})),t.responseType&&(a.responseType=t.responseType),t.abortSignal&&(t.abortSignal.onabort=()=>{a.abort(),s(new r)}),t.timeout&&(a.timeout=t.timeout),a.onload=()=>{t.abortSignal&&(t.abortSignal.onabort=null),a.status>=200&&a.status<300?n(new d(a.status,a.statusText,a.response||a.responseText)):s(new i(a.response||a.responseText||a.statusText,a.status))},a.onerror=()=>{this.u.log(e.Warning,`Error from HTTP request. ${a.status}: ${a.statusText}.`),s(new i(a.statusText,a.status))},a.ontimeout=()=>{this.u.log(e.Warning,"Timeout from HTTP request."),s(new o)},a.send(t.content)})):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))}}class D extends h{constructor(t){if(super(),"undefined"!=typeof fetch||g.isNode)this.$=new E(t);else{if("undefined"==typeof XMLHttpRequest)throw new Error("No usable HttpClient found.");this.$=new I(t)}}send(t){return t.abortSignal&&t.abortSignal.aborted?Promise.reject(new r):t.method?t.url?this.$.send(t):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))}getCookieString(t){return this.$.getCookieString(t)}}class A{static write(t){return`${t}${A.RecordSeparator}`}static parse(t){if(t[t.length-1]!==A.RecordSeparator)throw new Error("Message is incomplete.");const e=t.split(A.RecordSeparator);return e.pop(),e}}A.RecordSeparatorCode=30,A.RecordSeparator=String.fromCharCode(A.RecordSeparatorCode);class P{writeHandshakeRequest(t){return A.write(JSON.stringify(t))}parseHandshakeResponse(t){let e,n;if(v(t)){const i=new Uint8Array(t),o=i.indexOf(A.RecordSeparatorCode);if(-1===o)throw new Error("Message is incomplete.");const r=o+1;e=String.fromCharCode.apply(null,Array.prototype.slice.call(i.slice(0,r))),n=i.byteLength>r?i.slice(r).buffer:null}else{const i=t,o=i.indexOf(A.RecordSeparator);if(-1===o)throw new Error("Message is incomplete.");const r=o+1;e=i.substring(0,r),n=i.length>r?i.substring(r):null}const i=A.parse(e),o=JSON.parse(i[0]);if(o.type)throw new Error("Expected a handshake response from the server.");return[n,o]}}var N,j;!function(t){t[t.Invocation=1]="Invocation",t[t.StreamItem=2]="StreamItem",t[t.Completion=3]="Completion",t[t.StreamInvocation=4]="StreamInvocation",t[t.CancelInvocation=5]="CancelInvocation",t[t.Ping=6]="Ping",t[t.Close=7]="Close",t[t.Ack=8]="Ack",t[t.Sequence=9]="Sequence"}(N||(N={}));class q{constructor(){this.observers=[]}next(t){for(const e of this.observers)e.next(t)}error(t){for(const e of this.observers)e.error&&e.error(t)}complete(){for(const t of this.observers)t.complete&&t.complete()}subscribe(t){return this.observers.push(t),new $(this,t)}}class M{constructor(t,e,n){this.C=1e5,this.S=[],this.k=0,this.P=!1,this.T=1,this.I=0,this._=0,this.H=!1,this.D=t,this.R=e,this.C=n}async A(t){const e=this.D.writeMessage(t);let n=Promise.resolve();if(this.U(t)){this.k++;let t=()=>{},i=()=>{};v(e)?this._+=e.byteLength:this._+=e.length,this._>=this.C&&(n=new Promise(((e,n)=>{t=e,i=n}))),this.S.push(new R(e,this.k,t,i))}try{this.H||await this.R.send(e)}catch{this.L()}await n}N(t){let e=-1;for(let n=0;nthis.T?this.R.stop(new Error("Sequence ID greater than amount of messages we've received.")):this.T=t.sequenceId}L(){this.H=!0,this.P=!0}async B(){const t=0!==this.S.length?this.S[0].q:this.k+1;await this.R.send(this.D.writeMessage({type:N.Sequence,sequenceId:t}));const e=this.S;for(const t of e)await this.R.send(t.M);this.H=!1}X(t){null!=t||(t=new Error("Unable to reconnect to server."));for(const e of this.S)e.J(t)}U(t){switch(t.type){case N.Invocation:case N.StreamItem:case N.Completion:case N.StreamInvocation:case N.CancelInvocation:return!0;case N.Close:case N.Sequence:case N.Ping:case N.Ack:return!1}}O(){void 0===this.V&&(this.V=setTimeout((async()=>{try{this.H||await this.R.send(this.D.writeMessage({type:N.Ack,sequenceId:this.I}))}catch{}clearTimeout(this.V),this.V=void 0}),1e3))}}class R{constructor(t,e,n,i){this.M=t,this.q=e,this.j=n,this.J=i}}!function(t){t.Disconnected="Disconnected",t.Connecting="Connecting",t.Connected="Connected",t.Disconnecting="Disconnecting",t.Reconnecting="Reconnecting"}(j||(j={}));class O{static create(t,e,n,i,o,r,s){return new O(t,e,n,i,o,r,s)}constructor(t,n,i,o,r,s,a){this.K=0,this.G=()=>{this.u.log(e.Warning,"The page is being frozen, this will likely lead to the connection being closed and messages being lost. For more information see the docs at https://learn.microsoft.com/aspnet/core/signalr/javascript-client#bsleep")},m.isRequired(t,"connection"),m.isRequired(n,"logger"),m.isRequired(i,"protocol"),this.serverTimeoutInMilliseconds=null!=r?r:3e4,this.keepAliveIntervalInMilliseconds=null!=s?s:15e3,this.Y=null!=a?a:1e5,this.u=n,this.D=i,this.connection=t,this.Z=o,this.tt=new P,this.connection.onreceive=t=>this.et(t),this.connection.onclose=t=>this.st(t),this.it={},this.nt={},this.rt=[],this.ot=[],this.ht=[],this.ct=0,this.lt=!1,this.ut=j.Disconnected,this.dt=!1,this.ft=this.D.writeMessage({type:N.Ping})}get state(){return this.ut}get connectionId(){return this.connection&&this.connection.connectionId||null}get baseUrl(){return this.connection.baseUrl||""}set baseUrl(t){if(this.ut!==j.Disconnected&&this.ut!==j.Reconnecting)throw new Error("The HubConnection must be in the Disconnected or Reconnecting state to change the url.");if(!t)throw new Error("The HubConnection url must be a valid url.");this.connection.baseUrl=t}start(){return this.wt=this.gt(),this.wt}async gt(){if(this.ut!==j.Disconnected)return Promise.reject(new Error("Cannot start a HubConnection that is not in the 'Disconnected' state."));this.ut=j.Connecting,this.u.log(e.Debug,"Starting HubConnection.");try{await this.yt(),g.isBrowser&&window.document.addEventListener("freeze",this.G),this.ut=j.Connected,this.dt=!0,this.u.log(e.Debug,"HubConnection connected successfully.")}catch(t){return this.ut=j.Disconnected,this.u.log(e.Debug,`HubConnection failed to start successfully because of error '${t}'.`),Promise.reject(t)}}async yt(){this.vt=void 0,this.lt=!1;const t=new Promise(((t,e)=>{this.bt=t,this.Et=e}));await this.connection.start(this.D.transferFormat);try{let n=this.D.version;this.connection.features.reconnect||(n=1);const i={protocol:this.D.name,version:n};if(this.u.log(e.Debug,"Sending handshake request."),await this.$t(this.tt.writeHandshakeRequest(i)),this.u.log(e.Information,`Using HubProtocol '${this.D.name}'.`),this.Ct(),this.St(),this.kt(),await t,this.vt)throw this.vt;!!this.connection.features.reconnect&&(this.Pt=new M(this.D,this.connection,this.Y),this.connection.features.disconnected=this.Pt.L.bind(this.Pt),this.connection.features.resend=()=>{if(this.Pt)return this.Pt.B()}),this.connection.features.inherentKeepAlive||await this.$t(this.ft)}catch(t){throw this.u.log(e.Debug,`Hub handshake failed with error '${t}' during start(). Stopping HubConnection.`),this.Ct(),this.Tt(),await this.connection.stop(t),t}}async stop(){const t=this.wt;this.connection.features.reconnect=!1,this.It=this._t(),await this.It;try{await t}catch(t){}}_t(t){if(this.ut===j.Disconnected)return this.u.log(e.Debug,`Call to HubConnection.stop(${t}) ignored because it is already in the disconnected state.`),Promise.resolve();if(this.ut===j.Disconnecting)return this.u.log(e.Debug,`Call to HttpConnection.stop(${t}) ignored because the connection is already in the disconnecting state.`),this.It;const n=this.ut;return this.ut=j.Disconnecting,this.u.log(e.Debug,"Stopping HubConnection."),this.Ht?(this.u.log(e.Debug,"Connection stopped during reconnect delay. Done reconnecting."),clearTimeout(this.Ht),this.Ht=void 0,this.Dt(),Promise.resolve()):(n===j.Connected&&this.Rt(),this.Ct(),this.Tt(),this.vt=t||new r("The connection was stopped before the hub handshake could complete."),this.connection.stop(t))}async Rt(){try{await this.xt(this.At())}catch{}}stream(t,...e){const[n,i]=this.Ut(e),o=this.Lt(t,e,i);let r;const s=new q;return s.cancelCallback=()=>{const t=this.Nt(o.invocationId);return delete this.it[o.invocationId],r.then((()=>this.xt(t)))},this.it[o.invocationId]=(t,e)=>{e?s.error(e):t&&(t.type===N.Completion?t.error?s.error(new Error(t.error)):s.complete():s.next(t.item))},r=this.xt(o).catch((t=>{s.error(t),delete this.it[o.invocationId]})),this.qt(n,r),s}$t(t){return this.kt(),this.connection.send(t)}xt(t){return this.Pt?this.Pt.A(t):this.$t(this.D.writeMessage(t))}send(t,...e){const[n,i]=this.Ut(e),o=this.xt(this.Mt(t,e,!0,i));return this.qt(n,o),o}invoke(t,...e){const[n,i]=this.Ut(e),o=this.Mt(t,e,!1,i);return new Promise(((t,e)=>{this.it[o.invocationId]=(n,i)=>{i?e(i):n&&(n.type===N.Completion?n.error?e(new Error(n.error)):t(n.result):e(new Error(`Unexpected message type: ${n.type}`)))};const i=this.xt(o).catch((t=>{e(t),delete this.it[o.invocationId]}));this.qt(n,i)}))}on(t,e){t&&e&&(t=t.toLowerCase(),this.nt[t]||(this.nt[t]=[]),-1===this.nt[t].indexOf(e)&&this.nt[t].push(e))}off(t,e){if(!t)return;t=t.toLowerCase();const n=this.nt[t];if(n)if(e){const i=n.indexOf(e);-1!==i&&(n.splice(i,1),0===n.length&&delete this.nt[t])}else delete this.nt[t]}onclose(t){t&&this.rt.push(t)}onreconnecting(t){t&&this.ot.push(t)}onreconnected(t){t&&this.ht.push(t)}et(t){if(this.Ct(),this.lt||(t=this.jt(t),this.lt=!0),t){const n=this.D.parseMessages(t,this.u);for(const i of n)if(!this.Pt||this.Pt.W(i))switch(i.type){case N.Invocation:this.Wt(i).catch((t=>{this.u.log(e.Error,`Invoke client method threw error: ${T(t)}`)}));break;case N.StreamItem:case N.Completion:{const n=this.it[i.invocationId];if(n){i.type===N.Completion&&delete this.it[i.invocationId];try{n(i)}catch(t){this.u.log(e.Error,`Stream callback threw error: ${T(t)}`)}}break}case N.Ping:break;case N.Close:{this.u.log(e.Information,"Close message received from server.");const t=i.error?new Error("Server returned an error on close: "+i.error):void 0;!0===i.allowReconnect?this.connection.stop(t):this.It=this._t(t);break}case N.Ack:this.Pt&&this.Pt.N(i);break;case N.Sequence:this.Pt&&this.Pt.F(i);break;default:this.u.log(e.Warning,`Invalid message type: ${i.type}.`)}}this.St()}jt(t){let n,i;try{[i,n]=this.tt.parseHandshakeResponse(t)}catch(t){const n="Error parsing handshake response: "+t;this.u.log(e.Error,n);const i=new Error(n);throw this.Et(i),i}if(n.error){const t="Server returned handshake error: "+n.error;this.u.log(e.Error,t);const i=new Error(t);throw this.Et(i),i}return this.u.log(e.Debug,"Server handshake complete."),this.bt(),i}kt(){this.connection.features.inherentKeepAlive||(this.K=(new Date).getTime()+this.keepAliveIntervalInMilliseconds,this.Tt())}St(){if(!this.connection.features||!this.connection.features.inherentKeepAlive){this.Ot=setTimeout((()=>this.serverTimeout()),this.serverTimeoutInMilliseconds);let t=this.K-(new Date).getTime();if(t<0)return void(this.ut===j.Connected&&this.Ft());void 0===this.Bt&&(t<0&&(t=0),this.Bt=setTimeout((async()=>{this.ut===j.Connected&&await this.Ft()}),t))}}serverTimeout(){this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server."))}async Wt(t){const n=t.target.toLowerCase(),i=this.nt[n];if(!i)return this.u.log(e.Warning,`No client method with the name '${n}' found.`),void(t.invocationId&&(this.u.log(e.Warning,`No result given for '${n}' method and invocation ID '${t.invocationId}'.`),await this.xt(this.Xt(t.invocationId,"Client didn't provide a result.",null))));const o=i.slice(),r=!!t.invocationId;let s,a,c;for(const i of o)try{const o=s;s=await i.apply(this,t.arguments),r&&s&&o&&(this.u.log(e.Error,`Multiple results provided for '${n}'. Sending error to server.`),c=this.Xt(t.invocationId,"Client provided multiple results.",null)),a=void 0}catch(t){a=t,this.u.log(e.Error,`A callback for the method '${n}' threw error '${t}'.`)}c?await this.xt(c):r?(a?c=this.Xt(t.invocationId,`${a}`,null):void 0!==s?c=this.Xt(t.invocationId,null,s):(this.u.log(e.Warning,`No result given for '${n}' method and invocation ID '${t.invocationId}'.`),c=this.Xt(t.invocationId,"Client didn't provide a result.",null)),await this.xt(c)):s&&this.u.log(e.Error,`Result given for '${n}' method but server is not expecting a result.`)}st(t){this.u.log(e.Debug,`HubConnection.connectionClosed(${t}) called while in state ${this.ut}.`),this.vt=this.vt||t||new r("The underlying connection was closed before the hub handshake could complete."),this.bt&&this.bt(),this.Jt(t||new Error("Invocation canceled due to the underlying connection being closed.")),this.Ct(),this.Tt(),this.ut===j.Disconnecting?this.Dt(t):this.ut===j.Connected&&this.Z?this.zt(t):this.ut===j.Connected&&this.Dt(t)}Dt(t){if(this.dt){this.ut=j.Disconnected,this.dt=!1,this.Pt&&(this.Pt.X(null!=t?t:new Error("Connection closed.")),this.Pt=void 0),g.isBrowser&&window.document.removeEventListener("freeze",this.G);try{this.rt.forEach((e=>e.apply(this,[t])))}catch(n){this.u.log(e.Error,`An onclose callback called with error '${t}' threw error '${n}'.`)}}}async zt(t){const n=Date.now();let i=0,o=void 0!==t?t:new Error("Attempting to reconnect due to a unknown error."),r=this.Vt(i,0,o);if(null===r)return this.u.log(e.Debug,"Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt."),void this.Dt(t);if(this.ut=j.Reconnecting,t?this.u.log(e.Information,`Connection reconnecting because of error '${t}'.`):this.u.log(e.Information,"Connection reconnecting."),0!==this.ot.length){try{this.ot.forEach((e=>e.apply(this,[t])))}catch(n){this.u.log(e.Error,`An onreconnecting callback called with error '${t}' threw error '${n}'.`)}if(this.ut!==j.Reconnecting)return void this.u.log(e.Debug,"Connection left the reconnecting state in onreconnecting callback. Done reconnecting.")}for(;null!==r;){if(this.u.log(e.Information,`Reconnect attempt number ${i+1} will start in ${r} ms.`),await new Promise((t=>{this.Ht=setTimeout(t,r)})),this.Ht=void 0,this.ut!==j.Reconnecting)return void this.u.log(e.Debug,"Connection left the reconnecting state during reconnect delay. Done reconnecting.");try{if(await this.yt(),this.ut=j.Connected,this.u.log(e.Information,"HubConnection reconnected successfully."),0!==this.ht.length)try{this.ht.forEach((t=>t.apply(this,[this.connection.connectionId])))}catch(t){this.u.log(e.Error,`An onreconnected callback called with connectionId '${this.connection.connectionId}; threw error '${t}'.`)}return}catch(t){if(this.u.log(e.Information,`Reconnect attempt failed because of error '${t}'.`),this.ut!==j.Reconnecting)return this.u.log(e.Debug,`Connection moved to the '${this.ut}' from the reconnecting state during reconnect attempt. Done reconnecting.`),void(this.ut===j.Disconnecting&&this.Dt());i++,o=t instanceof Error?t:new Error(t.toString()),r=this.Vt(i,Date.now()-n,o)}}this.u.log(e.Information,`Reconnect retries have been exhausted after ${Date.now()-n} ms and ${i} failed attempts. Connection disconnecting.`),this.Dt()}Vt(t,n,i){try{return this.Z.nextRetryDelayInMilliseconds({elapsedMilliseconds:n,previousRetryCount:t,retryReason:i})}catch(i){return this.u.log(e.Error,`IRetryPolicy.nextRetryDelayInMilliseconds(${t}, ${n}) threw error '${i}'.`),null}}Jt(t){const n=this.it;this.it={},Object.keys(n).forEach((i=>{const o=n[i];try{o(null,t)}catch(n){this.u.log(e.Error,`Stream 'error' callback called with '${t}' threw error: ${T(n)}`)}}))}Tt(){this.Bt&&(clearTimeout(this.Bt),this.Bt=void 0)}Ct(){this.Ot&&clearTimeout(this.Ot)}Mt(t,e,n,i){if(n)return 0!==i.length?{target:t,arguments:e,streamIds:i,type:N.Invocation}:{target:t,arguments:e,type:N.Invocation};{const n=this.ct;return this.ct++,0!==i.length?{target:t,arguments:e,invocationId:n.toString(),streamIds:i,type:N.Invocation}:{target:t,arguments:e,invocationId:n.toString(),type:N.Invocation}}}qt(t,e){if(0!==t.length){e||(e=Promise.resolve());for(const n in t)t[n].subscribe({complete:()=>{e=e.then((()=>this.xt(this.Xt(n))))},error:t=>{let i;i=t instanceof Error?t.message:t&&t.toString?t.toString():"Unknown error",e=e.then((()=>this.xt(this.Xt(n,i))))},next:t=>{e=e.then((()=>this.xt(this.Kt(n,t))))}})}}Ut(t){const e=[],n=[];for(let i=0;i0)&&(e=!1,this.te=await this.Zt()),this.ee(t);const n=await this.Yt.send(t);return e&&401===n.statusCode&&this.Zt?(this.te=await this.Zt(),this.ee(t),await this.Yt.send(t)):n}ee(t){t.headers||(t.headers={}),this.te?t.headers[z.Authorization]=`Bearer ${this.te}`:this.Zt&&t.headers[z.Authorization]&&delete t.headers[z.Authorization]}getCookieString(t){return this.Yt.getCookieString(t)}}var U,B;!function(t){t[t.None=0]="None",t[t.WebSockets=1]="WebSockets",t[t.ServerSentEvents=2]="ServerSentEvents",t[t.LongPolling=4]="LongPolling"}(U||(U={})),function(t){t[t.Text=1]="Text",t[t.Binary=2]="Binary"}(B||(B={}));class W{constructor(){this.se=!1,this.onabort=null}abort(){this.se||(this.se=!0,this.onabort&&this.onabort())}get signal(){return this}get aborted(){return this.se}}class X{get pollAborted(){return this.ie.aborted}constructor(t,e,n){this.$=t,this.u=e,this.ie=new W,this.ne=n,this.re=!1,this.onreceive=null,this.onclose=null}async connect(t,n){if(m.isRequired(t,"url"),m.isRequired(n,"transferFormat"),m.isIn(n,B,"transferFormat"),this.oe=t,this.u.log(e.Trace,"(LongPolling transport) Connecting."),n===B.Binary&&"undefined"!=typeof XMLHttpRequest&&"string"!=typeof(new XMLHttpRequest).responseType)throw new Error("Binary protocols over XmlHttpRequest not implementing advanced features are not supported.");const[o,r]=C(),s={[o]:r,...this.ne.headers},a={abortSignal:this.ie.signal,headers:s,timeout:1e5,withCredentials:this.ne.withCredentials};n===B.Binary&&(a.responseType="arraybuffer");const c=`${t}&_=${Date.now()}`;this.u.log(e.Trace,`(LongPolling transport) polling: ${c}.`);const l=await this.$.get(c,a);200!==l.statusCode?(this.u.log(e.Error,`(LongPolling transport) Unexpected response code: ${l.statusCode}.`),this.he=new i(l.statusText||"",l.statusCode),this.re=!1):this.re=!0,this.ce=this.ae(this.oe,a)}async ae(t,n){try{for(;this.re;)try{const o=`${t}&_=${Date.now()}`;this.u.log(e.Trace,`(LongPolling transport) polling: ${o}.`);const r=await this.$.get(o,n);204===r.statusCode?(this.u.log(e.Information,"(LongPolling transport) Poll terminated by server."),this.re=!1):200!==r.statusCode?(this.u.log(e.Error,`(LongPolling transport) Unexpected response code: ${r.statusCode}.`),this.he=new i(r.statusText||"",r.statusCode),this.re=!1):r.content?(this.u.log(e.Trace,`(LongPolling transport) data received. ${y(r.content,this.ne.logMessageContent)}.`),this.onreceive&&this.onreceive(r.content)):this.u.log(e.Trace,"(LongPolling transport) Poll timed out, reissuing.")}catch(t){this.re?t instanceof o?this.u.log(e.Trace,"(LongPolling transport) Poll timed out, reissuing."):(this.he=t,this.re=!1):this.u.log(e.Trace,`(LongPolling transport) Poll errored after shutdown: ${t.message}`)}}finally{this.u.log(e.Trace,"(LongPolling transport) Polling complete."),this.pollAborted||this.le()}}async send(t){return this.re?b(this.u,"LongPolling",this.$,this.oe,t,this.ne):Promise.reject(new Error("Cannot send until the transport is connected"))}async stop(){this.u.log(e.Trace,"(LongPolling transport) Stopping polling."),this.re=!1,this.ie.abort();try{await this.ce,this.u.log(e.Trace,`(LongPolling transport) sending DELETE request to ${this.oe}.`);const t={},[n,o]=C();t[n]=o;const r={headers:{...t,...this.ne.headers},timeout:this.ne.timeout,withCredentials:this.ne.withCredentials};let s;try{await this.$.delete(this.oe,r)}catch(t){s=t}s?s instanceof i&&(404===s.statusCode?this.u.log(e.Trace,"(LongPolling transport) A 404 response was returned from sending a DELETE request."):this.u.log(e.Trace,`(LongPolling transport) Error sending a DELETE request: ${s}`)):this.u.log(e.Trace,"(LongPolling transport) DELETE request accepted.")}finally{this.u.log(e.Trace,"(LongPolling transport) Stop finished."),this.le()}}le(){if(this.onclose){let t="(LongPolling transport) Firing onclose event.";this.he&&(t+=" Error: "+this.he),this.u.log(e.Trace,t),this.onclose(this.he)}}}class V{constructor(t,e,n,i){this.$=t,this.te=e,this.u=n,this.ne=i,this.onreceive=null,this.onclose=null}async connect(t,n){return m.isRequired(t,"url"),m.isRequired(n,"transferFormat"),m.isIn(n,B,"transferFormat"),this.u.log(e.Trace,"(SSE transport) Connecting."),this.oe=t,this.te&&(t+=(t.indexOf("?")<0?"?":"&")+`access_token=${encodeURIComponent(this.te)}`),new Promise(((i,o)=>{let r,s=!1;if(n===B.Text){if(g.isBrowser||g.isWebWorker)r=new this.ne.EventSource(t,{withCredentials:this.ne.withCredentials});else{const e=this.$.getCookieString(t),n={};n.Cookie=e;const[i,o]=C();n[i]=o,r=new this.ne.EventSource(t,{withCredentials:this.ne.withCredentials,headers:{...n,...this.ne.headers}})}try{r.onmessage=t=>{if(this.onreceive)try{this.u.log(e.Trace,`(SSE transport) data received. ${y(t.data,this.ne.logMessageContent)}.`),this.onreceive(t.data)}catch(t){return void this.ue(t)}},r.onerror=t=>{s?this.ue():o(new Error("EventSource failed to connect. The connection could not be found on the server, either the connection ID is not present on the server, or a proxy is refusing/buffering the connection. If you have multiple servers check that sticky sessions are enabled."))},r.onopen=()=>{this.u.log(e.Information,`SSE connected to ${this.oe}`),this.de=r,s=!0,i()}}catch(t){return void o(t)}}else o(new Error("The Server-Sent Events transport only supports the 'Text' transfer format"))}))}async send(t){return this.de?b(this.u,"SSE",this.$,this.oe,t,this.ne):Promise.reject(new Error("Cannot send until the transport is connected"))}stop(){return this.ue(),Promise.resolve()}ue(t){this.de&&(this.de.close(),this.de=void 0,this.onclose&&this.onclose(t))}}class J{constructor(t,e,n,i,o,r){this.u=n,this.Zt=e,this.fe=i,this.pe=o,this.$=t,this.onreceive=null,this.onclose=null,this.we=r}async connect(t,n){let i;return m.isRequired(t,"url"),m.isRequired(n,"transferFormat"),m.isIn(n,B,"transferFormat"),this.u.log(e.Trace,"(WebSockets transport) Connecting."),this.Zt&&(i=await this.Zt()),new Promise(((o,r)=>{let s;t=t.replace(/^http/,"ws");const a=this.$.getCookieString(t);let c=!1;if(g.isNode||g.isReactNative){const e={},[n,o]=C();e[n]=o,i&&(e[z.Authorization]=`Bearer ${i}`),a&&(e[z.Cookie]=a),s=new this.pe(t,void 0,{headers:{...e,...this.we}})}else i&&(t+=(t.indexOf("?")<0?"?":"&")+`access_token=${encodeURIComponent(i)}`);s||(s=new this.pe(t)),n===B.Binary&&(s.binaryType="arraybuffer"),s.onopen=n=>{this.u.log(e.Information,`WebSocket connected to ${t}.`),this.ge=s,c=!0,o()},s.onerror=t=>{let n=null;n="undefined"!=typeof ErrorEvent&&t instanceof ErrorEvent?t.error:"There was an error with the transport",this.u.log(e.Information,`(WebSockets transport) ${n}.`)},s.onmessage=t=>{if(this.u.log(e.Trace,`(WebSockets transport) data received. ${y(t.data,this.fe)}.`),this.onreceive)try{this.onreceive(t.data)}catch(t){return void this.ue(t)}},s.onclose=t=>{if(c)this.ue(t);else{let e=null;e="undefined"!=typeof ErrorEvent&&t instanceof ErrorEvent?t.error:"WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.",r(new Error(e))}}}))}send(t){return this.ge&&this.ge.readyState===this.pe.OPEN?(this.u.log(e.Trace,`(WebSockets transport) sending data. ${y(t,this.fe)}.`),this.ge.send(t),Promise.resolve()):Promise.reject("WebSocket is not in the OPEN state")}stop(){return this.ge&&this.ue(void 0),Promise.resolve()}ue(t){this.ge&&(this.ge.onclose=()=>{},this.ge.onmessage=()=>{},this.ge.onerror=()=>{},this.ge.close(),this.ge=void 0),this.u.log(e.Trace,"(WebSockets transport) socket closed."),this.onclose&&(!this.me(t)||!1!==t.wasClean&&1e3===t.code?t instanceof Error?this.onclose(t):this.onclose():this.onclose(new Error(`WebSocket closed with status code: ${t.code} (${t.reason||"no reason given"}).`)))}me(t){return t&&"boolean"==typeof t.wasClean&&"number"==typeof t.code}}class Z{constructor(t,n={}){var i;if(this.ye=()=>{},this.features={},this.ve=1,m.isRequired(t,"url"),this.u=void 0===(i=n.logger)?new w(e.Information):null===i?p.instance:void 0!==i.log?i:new w(i),this.baseUrl=this.be(t),(n=n||{}).logMessageContent=void 0!==n.logMessageContent&&n.logMessageContent,"boolean"!=typeof n.withCredentials&&void 0!==n.withCredentials)throw new Error("withCredentials option was not a 'boolean' or 'undefined' value");n.withCredentials=void 0===n.withCredentials||n.withCredentials,n.timeout=void 0===n.timeout?1e5:n.timeout;let o=null,r=null;if(g.isNode){const t=require;o=t("ws"),r=t("eventsource")}g.isNode||"undefined"==typeof WebSocket||n.WebSocket?g.isNode&&!n.WebSocket&&o&&(n.WebSocket=o):n.WebSocket=WebSocket,g.isNode||"undefined"==typeof EventSource||n.EventSource?g.isNode&&!n.EventSource&&void 0!==r&&(n.EventSource=r):n.EventSource=EventSource,this.$=new F(n.httpClient||new D(this.u),n.accessTokenFactory),this.ut="Disconnected",this.dt=!1,this.ne=n,this.onreceive=null,this.onclose=null}async start(t){if(t=t||B.Binary,m.isIn(t,B,"transferFormat"),this.u.log(e.Debug,`Starting connection with transfer format '${B[t]}'.`),"Disconnected"!==this.ut)return Promise.reject(new Error("Cannot start an HttpConnection that is not in the 'Disconnected' state."));if(this.ut="Connecting",this.Ee=this.yt(t),await this.Ee,"Disconnecting"===this.ut){const t="Failed to start the HttpConnection before stop() was called.";return this.u.log(e.Error,t),await this.It,Promise.reject(new r(t))}if("Connected"!==this.ut){const t="HttpConnection.startInternal completed gracefully but didn't enter the connection into the connected state!";return this.u.log(e.Error,t),Promise.reject(new r(t))}this.dt=!0}send(t){return"Connected"!==this.ut?Promise.reject(new Error("Cannot send data if the connection is not in the 'Connected' State.")):(this.$e||(this.$e=new Y(this.transport)),this.$e.send(t))}async stop(t){return"Disconnected"===this.ut?(this.u.log(e.Debug,`Call to HttpConnection.stop(${t}) ignored because the connection is already in the disconnected state.`),Promise.resolve()):"Disconnecting"===this.ut?(this.u.log(e.Debug,`Call to HttpConnection.stop(${t}) ignored because the connection is already in the disconnecting state.`),this.It):(this.ut="Disconnecting",this.It=new Promise((t=>{this.ye=t})),await this._t(t),void await this.It)}async _t(t){this.Ce=t;try{await this.Ee}catch(t){}if(this.transport){try{await this.transport.stop()}catch(t){this.u.log(e.Error,`HttpConnection.transport.stop() threw error '${t}'.`),this.Se()}this.transport=void 0}else this.u.log(e.Debug,"HttpConnection.transport is undefined in HttpConnection.stop() because start() failed.")}async yt(t){let n=this.baseUrl;this.Zt=this.ne.accessTokenFactory,this.$.Zt=this.Zt;try{if(this.ne.skipNegotiation){if(this.ne.transport!==U.WebSockets)throw new Error("Negotiation can only be skipped when using the WebSocket transport directly.");this.transport=this.ke(U.WebSockets),await this.Pe(n,t)}else{let e=null,i=0;do{if(e=await this.Te(n),"Disconnecting"===this.ut||"Disconnected"===this.ut)throw new r("The connection was stopped during negotiation.");if(e.error)throw new Error(e.error);if(e.ProtocolVersion)throw new Error("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.");if(e.url&&(n=e.url),e.accessToken){const t=e.accessToken;this.Zt=()=>t,this.$.te=t,this.$.Zt=void 0}i++}while(e.url&&i<100);if(100===i&&e.url)throw new Error("Negotiate redirection limit exceeded.");await this.Ie(n,this.ne.transport,e,t)}this.transport instanceof X&&(this.features.inherentKeepAlive=!0),"Connecting"===this.ut&&(this.u.log(e.Debug,"The HttpConnection connected successfully."),this.ut="Connected")}catch(t){return this.u.log(e.Error,"Failed to start the connection: "+t),this.ut="Disconnected",this.transport=void 0,this.ye(),Promise.reject(t)}}async Te(t){const n={},[o,r]=C();n[o]=r;const s=this._e(t);this.u.log(e.Debug,`Sending negotiation request: ${s}.`);try{const t=await this.$.post(s,{content:"",headers:{...n,...this.ne.headers},timeout:this.ne.timeout,withCredentials:this.ne.withCredentials});if(200!==t.statusCode)return Promise.reject(new Error(`Unexpected status code returned from negotiate '${t.statusCode}'`));const e=JSON.parse(t.content);return(!e.negotiateVersion||e.negotiateVersion<1)&&(e.connectionToken=e.connectionId),e.useStatefulReconnect&&!0!==this.ne.He?Promise.reject(new l("Client didn't negotiate Stateful Reconnect but the server did.")):e}catch(t){let n="Failed to complete negotiation with the server: "+t;return t instanceof i&&404===t.statusCode&&(n+=" Either this is not a SignalR endpoint or there is a proxy blocking the connection."),this.u.log(e.Error,n),Promise.reject(new l(n))}}De(t,e){return e?t+(-1===t.indexOf("?")?"?":"&")+`id=${e}`:t}async Ie(t,n,i,o){let s=this.De(t,i.connectionToken);if(this.Re(n))return this.u.log(e.Debug,"Connection was provided an instance of ITransport, using that directly."),this.transport=n,await this.Pe(s,o),void(this.connectionId=i.connectionId);const a=[],l=i.availableTransports||[];let d=i;for(const i of l){const l=this.xe(i,n,o,!0===(null==d?void 0:d.useStatefulReconnect));if(l instanceof Error)a.push(`${i.transport} failed:`),a.push(l);else if(this.Re(l)){if(this.transport=l,!d){try{d=await this.Te(t)}catch(t){return Promise.reject(t)}s=this.De(t,d.connectionToken)}try{return await this.Pe(s,o),void(this.connectionId=d.connectionId)}catch(t){if(this.u.log(e.Error,`Failed to start the transport '${i.transport}': ${t}`),d=void 0,a.push(new c(`${i.transport} failed: ${t}`,U[i.transport])),"Connecting"!==this.ut){const t="Failed to select transport before stop() was called.";return this.u.log(e.Debug,t),Promise.reject(new r(t))}}}}return a.length>0?Promise.reject(new u(`Unable to connect to the server with any of the available transports. ${a.join(" ")}`,a)):Promise.reject(new Error("None of the transports supported by the client are supported by the server."))}ke(t){switch(t){case U.WebSockets:if(!this.ne.WebSocket)throw new Error("'WebSocket' is not supported in your environment.");return new J(this.$,this.Zt,this.u,this.ne.logMessageContent,this.ne.WebSocket,this.ne.headers||{});case U.ServerSentEvents:if(!this.ne.EventSource)throw new Error("'EventSource' is not supported in your environment.");return new V(this.$,this.$.te,this.u,this.ne);case U.LongPolling:return new X(this.$,this.u,this.ne);default:throw new Error(`Unknown transport: ${t}.`)}}Pe(t,e){return this.transport.onreceive=this.onreceive,this.features.reconnect?this.transport.onclose=async n=>{let i=!1;if(this.features.reconnect){try{this.features.disconnected(),await this.transport.connect(t,e),await this.features.resend()}catch{i=!0}i&&this.Se(n)}else this.Se(n)}:this.transport.onclose=t=>this.Se(t),this.transport.connect(t,e)}xe(t,n,i,o){const r=U[t.transport];if(null==r)return this.u.log(e.Debug,`Skipping transport '${t.transport}' because it is not supported by this client.`),new Error(`Skipping transport '${t.transport}' because it is not supported by this client.`);if(!function(t,e){return!t||!!(e&t)}(n,r))return this.u.log(e.Debug,`Skipping transport '${U[r]}' because it was disabled by the client.`),new a(`'${U[r]}' is disabled by the client.`,r);if(!(t.transferFormats.map((t=>B[t])).indexOf(i)>=0))return this.u.log(e.Debug,`Skipping transport '${U[r]}' because it does not support the requested transfer format '${B[i]}'.`),new Error(`'${U[r]}' does not support ${B[i]}.`);if(r===U.WebSockets&&!this.ne.WebSocket||r===U.ServerSentEvents&&!this.ne.EventSource)return this.u.log(e.Debug,`Skipping transport '${U[r]}' because it is not supported in your environment.'`),new s(`'${U[r]}' is not supported in your environment.`,r);this.u.log(e.Debug,`Selecting transport '${U[r]}'.`);try{return this.features.reconnect=r===U.WebSockets?o:void 0,this.ke(r)}catch(t){return t}}Re(t){return t&&"object"==typeof t&&"connect"in t}Se(t){if(this.u.log(e.Debug,`HttpConnection.stopConnection(${t}) called while in state ${this.ut}.`),this.transport=void 0,t=this.Ce||t,this.Ce=void 0,"Disconnected"!==this.ut){if("Connecting"===this.ut)throw this.u.log(e.Warning,`Call to HttpConnection.stopConnection(${t}) was ignored because the connection is still in the connecting state.`),new Error(`HttpConnection.stopConnection(${t}) was called while the connection is still in the connecting state.`);if("Disconnecting"===this.ut&&this.ye(),t?this.u.log(e.Error,`Connection disconnected with error '${t}'.`):this.u.log(e.Information,"Connection disconnected."),this.$e&&(this.$e.stop().catch((t=>{this.u.log(e.Error,`TransportSendQueue.stop() threw error '${t}'.`)})),this.$e=void 0),this.connectionId=void 0,this.ut="Disconnected",this.dt){this.dt=!1;try{this.onclose&&this.onclose(t)}catch(n){this.u.log(e.Error,`HttpConnection.onclose(${t}) threw error '${n}'.`)}}}else this.u.log(e.Debug,`Call to HttpConnection.stopConnection(${t}) was ignored because the connection is already in the disconnected state.`)}be(t){if(0===t.lastIndexOf("https://",0)||0===t.lastIndexOf("http://",0))return t;if(!g.isBrowser)throw new Error(`Cannot resolve '${t}'.`);const n=window.document.createElement("a");return n.href=t,this.u.log(e.Information,`Normalizing '${t}' to '${n.href}'.`),n.href}_e(t){const e=new URL(t);e.pathname.endsWith("/")?e.pathname+="negotiate":e.pathname+="/negotiate";const n=new URLSearchParams(e.searchParams);return n.has("negotiateVersion")||n.append("negotiateVersion",this.ve.toString()),n.has("useStatefulReconnect")?"true"===n.get("useStatefulReconnect")&&(this.ne.He=!0):!0===this.ne.He&&n.append("useStatefulReconnect","true"),e.search=n.toString(),e.toString()}}class Y{constructor(t){this.Ae=t,this.Ue=[],this.Le=!0,this.Ne=new Q,this.qe=new Q,this.Me=this.je()}send(t){return this.We(t),this.qe||(this.qe=new Q),this.qe.promise}stop(){return this.Le=!1,this.Ne.resolve(),this.Me}We(t){if(this.Ue.length&&typeof this.Ue[0]!=typeof t)throw new Error(`Expected data to be of type ${typeof this.Ue} but was of type ${typeof t}`);this.Ue.push(t),this.Ne.resolve()}async je(){for(;;){if(await this.Ne.promise,!this.Le){this.qe&&this.qe.reject("Connection stopped.");break}this.Ne=new Q;const t=this.qe;this.qe=void 0;const e="string"==typeof this.Ue[0]?this.Ue.join(""):Y.Oe(this.Ue);this.Ue.length=0;try{await this.Ae.send(e),t.resolve()}catch(e){t.reject(e)}}}static Oe(t){const e=t.map((t=>t.byteLength)).reduce(((t,e)=>t+e)),n=new Uint8Array(e);let i=0;for(const e of t)n.set(new Uint8Array(e),i),i+=e.byteLength;return n.buffer}}class Q{constructor(){this.promise=new Promise(((t,e)=>[this.j,this.Fe]=[t,e]))}resolve(){this.j()}reject(t){this.Fe(t)}}class K{constructor(){this.name="json",this.version=2,this.transferFormat=B.Text}parseMessages(t,n){if("string"!=typeof t)throw new Error("Invalid input for JSON hub protocol. Expected a string.");if(!t)return[];null===n&&(n=p.instance);const i=A.parse(t),o=[];for(const t of i){const i=JSON.parse(t);if("number"!=typeof i.type)throw new Error("Invalid payload.");switch(i.type){case N.Invocation:this.U(i);break;case N.StreamItem:this.Be(i);break;case N.Completion:this.Xe(i);break;case N.Ping:case N.Close:break;case N.Ack:this.Je(i);break;case N.Sequence:this.ze(i);break;default:n.log(e.Information,"Unknown message type '"+i.type+"' ignored.");continue}o.push(i)}return o}writeMessage(t){return A.write(JSON.stringify(t))}U(t){this.Ve(t.target,"Invalid payload for Invocation message."),void 0!==t.invocationId&&this.Ve(t.invocationId,"Invalid payload for Invocation message.")}Be(t){if(this.Ve(t.invocationId,"Invalid payload for StreamItem message."),void 0===t.item)throw new Error("Invalid payload for StreamItem message.")}Xe(t){if(t.result&&t.error)throw new Error("Invalid payload for Completion message.");!t.result&&t.error&&this.Ve(t.error,"Invalid payload for Completion message."),this.Ve(t.invocationId,"Invalid payload for Completion message.")}Je(t){if("number"!=typeof t.sequenceId)throw new Error("Invalid SequenceId for Ack message.")}ze(t){if("number"!=typeof t.sequenceId)throw new Error("Invalid SequenceId for Sequence message.")}Ve(t,e){if("string"!=typeof t||""===t)throw new Error(e)}}const G={trace:e.Trace,debug:e.Debug,info:e.Information,information:e.Information,warn:e.Warning,warning:e.Warning,error:e.Error,critical:e.Critical,none:e.None};class tt{configureLogging(t){if(m.isRequired(t,"logging"),void 0!==t.log)this.logger=t;else if("string"==typeof t){const e=function(t){const e=G[t.toLowerCase()];if(void 0!==e)return e;throw new Error(`Unknown log level: ${t}`)}(t);this.logger=new w(e)}else this.logger=new w(t);return this}withUrl(t,e){return m.isRequired(t,"url"),m.isNotEmpty(t,"url"),this.url=t,this.httpConnectionOptions="object"==typeof e?{...this.httpConnectionOptions,...e}:{...this.httpConnectionOptions,transport:e},this}withHubProtocol(t){return m.isRequired(t,"protocol"),this.protocol=t,this}withAutomaticReconnect(t){if(this.reconnectPolicy)throw new Error("A reconnectPolicy has already been set.");return t?Array.isArray(t)?this.reconnectPolicy=new L(t):this.reconnectPolicy=t:this.reconnectPolicy=new L,this}withServerTimeout(t){return m.isRequired(t,"milliseconds"),this.Ke=t,this}withKeepAliveInterval(t){return m.isRequired(t,"milliseconds"),this.Ge=t,this}withStatefulReconnect(t){return void 0===this.httpConnectionOptions&&(this.httpConnectionOptions={}),this.httpConnectionOptions.He=!0,this.Y=null==t?void 0:t.bufferSize,this}build(){const t=this.httpConnectionOptions||{};if(void 0===t.logger&&(t.logger=this.logger),!this.url)throw new Error("The 'HubConnectionBuilder.withUrl' method must be called before building the connection.");const e=new Z(this.url,t);return O.create(e,this.logger||p.instance,this.protocol||new K,this.reconnectPolicy,this.Ke,this.Ge,this.Y)}}return Uint8Array.prototype.indexOf||Object.defineProperty(Uint8Array.prototype,"indexOf",{value:Array.prototype.indexOf,writable:!0}),Uint8Array.prototype.slice||Object.defineProperty(Uint8Array.prototype,"slice",{value:function(t,e){return new Uint8Array(Array.prototype.slice.call(this,t,e))},writable:!0}),Uint8Array.prototype.forEach||Object.defineProperty(Uint8Array.prototype,"forEach",{value:Array.prototype.forEach,writable:!0}),n})(),"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.signalR=e():t.signalR=e(),$.extend($t,{t1:"Eingabe erforderlich",t2:"Bitte überprüfen Sie Ihre Eingaben im Formular.",b0:"Erstellt",b1:"Zuletzt geändert",b2:"von",t12:"Der Server hat einen Fehler zurückgegeben. Bitte versuchen Sie es erneut.",t17:"Eine Email mit einem Aktivierungs-Link wurde an deine Adresse versandt.",t18:"Ein Account mit deinem Namen existiert bereits. Dennoch erstellen?",t19:"Einträge sind entweder unngültig oder zu kurz.",t20:"Der Server hat einen Fehler gemeldet. Bitte versuch es erneut.",t21:"Der Zugang wurde nicht gefunden.",t30a:"Als erledigt markieren.",t30b:"Als unerledigt markieren.",t55:"Ein Email mit einem Aktivierungs-Link wurde an Ihre Adresse versandt.",t56:"Ein Zugang für diesen Namen besteht bereits. Trotzdem erstellen?",t57:"Ein bestehender Zugang wurde für diese Serie registriert.",t60:"Bitte geben Sie Email-Adresse an, die Sie hier hinterlegt haben.",t61:"Ihr Passwort wurde erfolgreich versandt.",t62:"Die angegebene Email-Adresse stimmt nicht mit der hier hinterlegten überein.",ov:"Persönliche Übersicht"});var $v={};
/*! loadCSS. [c]2020 Filament Group, Inc. MIT License */
/*! onloadCSS. (onload callback for loadCSS) [c]2017 Filament Group, Inc. MIT License */
-function onloadCSS(t,e){e=e||{};let n=function(e){return new Promise(((n,i)=>{t.addEventListener?e.addEventListener("load",newcb):t.attachEvent&&e.attachEvent("onload",newcb),"isApplicationInstalled"in navigator&&"onloadcssdefined"in t&&e.onloadcssdefined(newcb)}))};if(Array.isArray(t)){let i=t.length;Promise.all(t.map(n)).then((function(t){var n=t.reduce(((t,e)=>t+(!0===e?1:0)));!async function(t){!0===t&&"function"==typeof e.success?e.success():!0===t&&"object"==typeof e.success&&e.success instanceof Promise&&await e.success(),e.complete()}(i===n)}))}else n(t)}!function(t){"use strict";var e=function(e,n,i,o){var r,s=t.document,a=s.createElement("link");if(n)r=n;else{var c=(s.body||s.getElementsByTagName("head")[0]).childNodes;r=c[c.length-1]}var l=s.styleSheets;if(o)for(var u in o)o.hasOwnProperty(u)&&a.setAttribute(u,o[u]);a.rel="stylesheet",a.href=e,a.media="only x",function t(e){if(s.body)return e();setTimeout((function(){t(e)}))}((function(){r.parentNode.insertBefore(a,n?r:r.nextSibling)}));var d=function(t){for(var e=a.href,n=l.length;n--;)if(l[n].href===e)return t();setTimeout((function(){d(t)}))};function h(){a.addEventListener&&a.removeEventListener("load",h),a.media=i||"all"}return a.addEventListener&&a.addEventListener("load",h),a.onloadcssdefined=d,d(h),a};"undefined"!=typeof exports?exports.loadCSS=e:t.loadCSS=e}("undefined"!=typeof global?global:this);const isIE=/MSIE\/|Trident/gi.test(window.navigator.userAgent)||void 0!==window.document.documentMode,isfileapi=!!(window.File&&window.FileReader&&window.FileList&&window.Blob);var $ocms={auth:{},no:function(t){t.stopPropagation()},vmin:function(t){var e=$(window).width*(t||1),n=$(window).height*(t||1);return e($ocms.baseurl+"/"+(t||"")).replace(/\/\//,"/"),cexi:null};function deepCopy(t){var e,n,i;if("object"!=typeof t||null===t)return t;for(i in e=Array.isArray(t)?[]:{},t)n=t[i],e[i]=deepCopy(n);return e}function fields_definition(t,e,n){this.label_sng=!0===Array.isArray(t)?"":t||"",this.label_pl=!0===Array.isArray(t)?"":e||"",this.fields=!0===Array.isArray(t)?t:n||[],this.itm=function(t){for(var e=0;e0)for(var n=0;nt||"")).filter(((t,e)=>""!==t)).join(e)}function parseDt(t,e,n){t=(t||"").substr(0,e.length);var i=e,o=t.length>0&&e.split(";").some((function(e){for(var n,o=/[^yMdhms0-9]/gi,r=!0;null!==(n=o.exec(e));)r=r&&e.substr(n.index,1)===t.substr(n.index,1);var s=t.length===e.length&&r;return!0===s&&(i=e),s}));if(!0===o){for(var r,s=[0,0,0,0,0,0,0],a=/(mm{1,2}|dd{1,2}|MM{1,2}|(yy){2,4}|ss{1,2}|hh{1,2})(?!\w)/g;null!==(r=a.exec(i));)s["yMdhms".indexOf(r[0].substr(0,1))]=parseInt(("yy"===r[0]?"20":"")+t.substr(r.index,r[0].length))-("M"===r[0].substr(0,1)?1:0);var c=new(Function.prototype.bind.apply(Date,[null].concat(s)));return"string"==typeof n?fdt(c,n):c}return!1}function bool(t,e){return"boolean"==typeof t?t:"boolean"==typeof e&&e}function booln(t,e){return"boolean"==typeof t?t:"number"==typeof t?1===t:"boolean"==typeof e&&e}Date.prototype.isValid=function(){return!isNaN(this)},Date.prototype.format=function(t){return fdt(this,t)},Date.prototype.addDays=function(t){return this.setDate(this.getDate()+t),this},Date.prototype.isBetween=function(t,e){return this>t&&this section");$(window).scroll((function(e){let n=$(window).scrollTop(),i=$("body");i.toggleClass("unfocus",n>vh()-1.2*t),i.toggleClass("btb",n>.5*vh()-t)}))},$ocms.cf_reset=function(){return $("#contentframe").empty()},function(t){t.fn.scrollTo=function(e){if(t(this).length>0){var n=t(this).offset().top||0;n>0&&t("html, body").animate({scrollTop:n-hh()},2e3)}},t.fn.ldng=function(e){var n=!0;return"boolean"==typeof e?n=e:"number"==typeof e&&(n=e>0),t(this).toggleClass("loading",n)},"function"!=typeof t.noop&&(t.noop=function(){}),t.fn.hasAttr=function(e){var n=t(this).attr(e);return void 0!==n&&!1!==n},t.fn.parseCssPx=function(e){try{return parseFloat(t(this).css(e).replace("px","")||0)}catch(t){return 0}},t.max=function(t,e){return isNaN(t)&&isNaN(e)?null:isNaN(t)&&!isNaN(e)?e:!isNaN(e)&&isNaN(e)||t>=e?t:e},t.min=function(t,e){return isNaN(t)&&isNaN(e)?null:isNaN(t)&&!isNaN(e)?e:!isNaN(e)&&isNaN(e)||t<=e?t:e},t.lim=function(t,e){return isNaN(t)?null:isNaN(e)?t:e<=t?e:t},t.fn.enterKey=function(e){return this.each((function(){t(this).keypress((function(t){"13"===(t.keyCode?t.keyCode:t.which).toString()&&e.call(this,t)}))}))}}(jQuery),$ocms.defaultTimeout=3e4,$ocms.AjaxEX=function(t){var e=this;e.responseText=e.responseText||"";var n=e.getResponseHeader("x-ocms-code")||"";e.internalCode=""!==n&&!1===isNaN(n)?parseInt(n):-1,e.isInternal=e.internalCode>-1,e.internalText=decodeURIComponent((e.getResponseHeader("x-ocms-desc")||"").replace(/\+/g,"%20")||"");var i=e.internalText||t,o=e.internalCode||e.status;e.logtext=i+" ("+o+")"},$ocms.postXTS=function(t){$ocms.postXT.call(this,$.extend(t,{sync:!0}))},$ocms.postXT=function(t){if((t=t||{}).trycount=t.trycount||0,""!==(t.url||"")){t.url=-1!==t.url.indexOf("&yy=")?t.url:t.url.indexOf("?")>-1?t.url+"&yy="+(new Date).getTime():t.url+"?yy="+(new Date).getTime();var e=t.context||this;switch(t.context=e,t.retryLimit=t.retryLimit||0,t.timeout=t.timeout||$ocms.defaultTimeout,t.timeout<100&&(t.timeout=1e3*t.timeout),t.data=t.data||{},t.contentType=t.contentType||"multipart/form-data; charset=UTF-8",t.islogin="boolean"==typeof t.islogin&&t.islogin,t.contentType){case"":case"json":t.contentType="application/json; charset=utf-8";break;case"form":t.contentType="application/x-www-form-urlencoded; charset=UTF-8";break;case"multi":t.contentType="multipart/form-data";break;case"text":t.contentType="text/plain; charset=UTF-8"}if(t.form instanceof jQuery?(t.data=t.form.serializeObject(),t.contentType="form-data"):t.lzw instanceof jQuery&&(t.data.lzw=$.ccLZW(t.lzw.serializeAnything(!0)).join(",")),"multipart/form-data"!==t.contentType.substr(0,19)&&"form-data"!==t.contentType.substr(0,9)||t.data instanceof FormData!=!1)t.data instanceof FormData&&(t.contentType=!1,t.processData=!1);else{t.contentType=!1;var n=new FormData;$.each(t.files||[],(function(t,e){n.append("upload_file",e)})),$.each(t.data||{},(function(t,e){n.append(t,e)})),t.data=n,t.processData=!1}var i={type:t.method||"post",url:t.url,data:t.data,processData:"boolean"!=typeof t.processData||t.processData,contentType:t.contentType,cache:t.cache||!1,timeout:t.timeout,beforeSend:function(n){$(t.loading).ldng(),$("body").addClass("ldng"),"function"==typeof t.beforesend&&t.beforesend.apply(e,[n])},success:function(n,i,o){"false"===n||"not authorized"===n?("function"==typeof t.error&&t.error.apply(e,[o,i,n]),"function"==typeof $.status&&$.status(i+" - "+n)):"function"==typeof t.success&&t.success.apply(e,[n,i,o])},error:function(n,i,o){if($ocms.AjaxEX.call(n,i),-1===t.url.indexOf("doc.ashx")||-1!==t.url.indexOf("ftest")){if(401===n.status&&111===n.internalCode&&!1===t.islogin&&"function"==typeof $ocms.login.dlg)$ocms.login.dlg({ajo:t});else if("timeout"===i||302===n.status)return t.tryCount++,t.tryCount<=t.retryLimit?void $ocms.postXT(t):void 0;"function"==typeof t.error?t.error.apply(e,[n,i,o]):"function"==typeof $ocms.failure?$ocms.failure.apply(e,[n]):"function"==typeof $.status&&$.status("Server error: "+i+" - "+o)}},dataType:t.datatype||"json",complete:function(n,i){"function"==typeof t.complete&&t.complete.apply(e,[n,i]),$(t.loading).ldng(0),$("body").removeClass("ldng");let o=$("body > .timer");if(o.length>0){let t=new Date(n.getResponseHeader("ocms_cec")||""),e=new Date(n.getResponseHeader("ocms_cex")||"");if(t.isValid()&&e.isValid()){let n=new Date,i=Math.abs(e-t);n.setMilliseconds(n.getMilliseconds()+i),o.data({cex:n,ctt:i}),$ocms.cex_timer()}}},context:e,async:!0};"boolean"==typeof t.sync&&(i.async=!1===t.sync),!0==("boolean"==typeof t.contentType&&!1===t.contentType)&&(i.contentType=!1),$.ajax(i)}},$ocms.cex_timer=function(){$ocms.cexi||($ocms.cexi=setInterval($ocms.cex_timer,15e3));let t=$("body > .timer"),e=t.data("cex"),n=t.data("ctt"),i=new Date;if(e instanceof Date&&e.isValid()&&"number"==typeof n&&n>0&&e>i){let o=Math.abs(i-e)/n*100;t.css("width",o.toString()+"%"),o<98&&(!$ocms.cex_lp||Math.abs(i-$ocms.cex_lp)>6e5)&&$ocms.postXT({url:$ocms.url("ping"),success:()=>{$ocms.cex_lp=i},timeout:5e3,error:()=>{}})}},$ocms.vbl_send=function(t){var e=t.data||{};if(""!==(e.url||"")){var n=$("#contentframe form:first"),i={url:e.url,data:new FormData,success:function(t){"function"==typeof e.success?e.success(t):"string"==typeof e.success&&alert(e.success)},error:function(t,n,i){"function"==typeof e.error?e.error(i):"string"==typeof e.error&&alert(e.error)},complete:function(){n.ldng(0)}},o=!0;n.find("input").each((function(){var t=$(this),e=t.nza("name"),n=t.val(),r=$(this).prop("required")||!1;if(""!==e){var s=""!==n||!1===r;o=o&&s,!0===s?(i.data.append(e,n),t[0].setCustomValidity("")):""!==$(this).nza("ocms-nvnote")&&t[0].setCustomValidity($(this).nza("ocms-nvnote"))}})),!0===o&&(n.ldng(1),$ocms.postXT.call(this,i))}},function(t){t.fn.nza=function(e,n){var i=t(this).attr(e);return void 0!==i&&!1!==i?i:n||""},t.fn.serializeObject=function(e,n){var i=/\r?\n/g,o=/^(?:submit|button|image|reset|file)$/i,r=/^(?:input|select|textarea|keygen)/i,s=/^(?:checkbox|radio)$/i,a=bool((n=n||{}).typedvalues,!1),c={},l=t(this),u=l.find(':input:not([nosend],[type="file"])').addBack(":input"),d=!0;return t.each(u.not(".tinymce").get(),(function(n,l){var u=t(this),h=this,p=(this.type||"").toLowerCase(),f=u.prop("required")||!1;if(!0===(h.name&&!u.is(":disabled")&&r.test(h.nodeName)&&!o.test(p))){var m=u.val(),g=h.name,y=u.nza("data-format").split(":"),v=u.nza("pattern")||".*";if(!0===s.test(p)&&(m=h.checked?""!==m?m:"true":""),"date"===y[0].substr(0,4)&&y.length>1)"boolean"==typeof(m=parseDt(m,y.slice(1).join(":")))&&(m=null),null===m&&"date"===u.prop("type").substr(0,4)&&!1===isNaN(new Date(u.val()))&&(m=new Date(u.val())),m instanceof Date==!0&&"function"==typeof m.getMonth?!1===a&&(m=fdt(m,"date"===y[0]?"dts":"iso")):m=null;else if(("number"===p||"float"===y[0]||"integer"===y[0])&&!0===a){let t,e=String(m).replace(",",".");t="integer"===y[0]?parseInt(e):parseFloat(e),m=isNaN(t)?m:t}if(!0===f&&(""===m||null==m||"string"==typeof m&&null===m.match(v))?(!0===bool(e,!1)&&h.setCustomValidity(u.nza("ocms-nvnote",$ocms.t.inv||"Invalid field")),m=null):!0===bool(e,!1)&&h.setCustomValidity(""),null!=m&&"string"==typeof m){let t=c[g];null!=t?Array.isArray(t)?t.push(m.replace(i,"\r\n")):c[g]=[t,m.replace(i,"\r\n")]:c[g]=m.replace(i,"\r\n")}else if(null!=m){let t=c[g];null!=t?Array.isArray(t)?t.push(m):c[g]=[t,m]:c[g]=m}else d=!1}})),u.filter(".tinymce").each((function(e,n){var i=t(this),o=((this.type||"").toLowerCase(),i.prop("required")||!1);try{var r=tinymce.get(t(n).attr("id"));if(r){var s=t(n).attr("name"),a=r.getContent();!1===o||""!==(a||"")?c[s]=a:d=!1}}catch(e){t.noop()}})),l.toggleClass("invalid",!d),d?c:null},t.fn.sendForm=function(e,n,i){var o=t(this);i=i||{};var r={url:e,success:function(t){if(i.response=t,"function"==typeof n)n(t);o.closest("div.modal").remove()},error:function(t,e,n){"function"==typeof i.error?i.error.call(this,t):$ocms.failure.call(this,t)},complete:function(){o.ldng(0),"function"==typeof i.complete&&i.complete.call(this,jqXHR)}},s=o.find('input[type="file"]');r.data=new FormData,s.length>0&&t.each(s[0].files,(function(t,e){r.data.append(t,e),r.data.append("file_lastmodified",$ocms.isodt(e.lastModifiedDate))}));var a=o.serializeObject();t.each(a||{},(function(t,e){r.data.append(t,e)})),o.ldng(),$ocms.postXT.call(this,r)},t.fn.checkValidity=function(){var e=t(this),n=!0;return e.each((function(t,e){n=n&&e.checkValidity()})),n},t.fn.wrap=function(e,n){var i=t(this),o=$$.dc(e).attr(n||{}).insertAfter(i);return i.append(o),o}}(jQuery),$ocms.logout=function(){$ocms.postXT({url:$ocms.url("logout"),complete:function(){window.location.reload()}})},$ocms.login={send:function(t){t.preventDefault();var e=$(this);if(!0===e.find("#dbtn-confirm").hasClass("disabled"))return!1;var n=e.serializeObject();return n.loginaccount=ne(n.loginaccount,$ocms.auth.account||$ocms.auth.requestedaccount||""),n.loginaccount=ne(n.loginaccount,$ocms.auth.account||$ocms.auth.requestedaccount||""),""===ne(n.loginaccount)&&!0===bool($ocms.auth.accountrequired,!0)?(alert($t.l16),!1):($ocms.postXT({url:$ocms.url("login"),data:n,success:function(){window.location.reload()}}),!1)},uichange:function(){let t=$(this),e=t.closest("form"),n=bool($ocms.auth.accountrequired,!0),i=ne(e.find('[name="loginaccount"]').val(),$ocms.auth.account||$ocms.auth.requestedaccount||"");if(""!==i||!1===n){var o=e.find('[name="userlogin"]').empty().val(""),r=e.find('[name="username"]').empty().val(""),s=$("#dlg_userlogin_sel").empty().val(""),a=t.val()||"";if(!1===t.checkValidity()&&""===a)return;var c=t.closest("table").ldng();$ocms.postXT.call(this,{url:$ocms.url("auth"),data:{userinfo:a,account:i||""},success:function(t,e,n){if(1===t.length){var i=t[0];o.val(i.login).change().attr("required","").removeAttr("nosend"),r.val(i.name).change().attr("required","").show(),s.removeAttr("required").attr("nosend","").hide()}else t.length>0?(r.hide().removeAttr("required"),o.removeAttr("required").attr("nosend",""),0===s.length&&(s=$("").attr({name:"userlogin",size:t.length,id:"dlg_userlogin_sel",class:"form-control",required:""}).css({width:"100%","max-width":"100%",padding:"2px"}).insertAfter(r)),$.each(t,(function(t,e){var n=$("").attr({value:e.login,style:"padding-top: 2px; padding-bottom: 5px;","border-bottom":"1px solid #EEE;"}).text(e.name).appendTo(s);t%2==0&&n.css({"background-color":"#F9F9F9"})})),s.attr("required","").removeAttr("nosend")):(s.hide().attr("nosend",""),r.attr("required","").show(),o.attr("required","").removeAttr("nosend"),alert($t.l9))},error:function(t){$ocms.failure.call(this,t)},complete:function(){c.ldng(0)}})}else alert($t.l18)},sendpassword:function(t){var e=$(''),n=e.find(".form-body"),i=null;e.find("form").submit((function(t){t.preventDefault();var o=$(this).serializeObject(!0),r=null===i,s=r?"spwc":"spw";return $ocms.postXT.call(this,{url:$ocms.url(s),data:o,complete:function(){r?(n.append('Ihnen wurde ein Code per SMS zugesandt.
Bitte tragen Sie den hier ein:'),i=$('').appendTo(n)):(alert($t.l13),e.remove())},error:()=>{}}),!1})),e.find(".modal-close").click((function(){e.remove()}));var o=[];$.each($t.l7a.split("\n"),((t,e)=>{Array.prototype.push.apply(o,[$("
"),$("").text(e)])})),e.find(".modal-note").append($('').text($t.alert)).append(o),e.appendTo("body"),setTimeout((function(){$(".modal").find('input[name="lastname"]').focus()}),600)}};var $$={s:function(t){return $("").text(t)},br:function(){return $("
")},sc:function(t,e){return $("").addClass(t).text(e)},td:function(t,e){var n=$(" ");return t instanceof jQuery==!0?n.appendTo(t):"object"==typeof t?n.attr(t):"string"==typeof t&&n.text(t),"object"==typeof e?n.attr(e):"string"==typeof e&&n.text(e),n},th:function(t,e){var n=$(" ");return t instanceof jQuery==!0?n.appendTo(t):"object"==typeof t?n.attr(t):"string"==typeof t&&n.text(t),"object"==typeof e?n.attr(e):"string"==typeof e&&n.text(e),n},tdc:function(t,e,n){return $$.td(e,n).addClass(t)},td2:function(t){var e=$(' ');return"string"===$.type(t)?e.text(t):t instanceof jQuery?e.append(t):"function"==typeof t?t.call(e):e.html(" "),e},td3:function(t){var e=$(' ');return"string"===$.type(t)?e.text(t):t instanceof jQuery?e.append(t):"function"==typeof t?t.call(e):e.html(" "),e},tdtr:function(t,e){var n=$$.tr().appendTo(e);return t instanceof jQuery==!0||"string"==typeof t?t.appendTo($$.td().appendTo(n)):!0===Array.isArray(t)&&$.each(t,(function(t,e){$(e).appendTo($$.td().appendTo(n))})),n},tr:function(t,e){var n=$(" ");return t instanceof jQuery==!0?n.appendTo(t):"object"==typeof t&&n.attr(t),"object"==typeof e&&n.attr(e),n},trc:function(t,e){var n=$(" ").addClass(t);return e instanceof jQuery==!0?n.appendTo(e):"object"==typeof e&&n.attr(e),n},d:function(t){return $("").attr(t||{})},dc:function(t,e,n,i){var o=$("").addClass(t);return e instanceof jQuery==!0?o.appendTo(e):"object"==typeof e?o.attr(e):"function"==typeof e?o.click(e):"string"==typeof e&&o.text(e),"string"==typeof n?o.text(n):"object"==typeof n?o.attr(n):"function"==typeof n&&o.click(n),"string"==typeof i?o.text(i):"object"==typeof i?o.attr(i):"function"==typeof i&&o.click(i),o},df:function(t){return $(" ").attr(t||{})},opt:function(t,e,n){var i=$("");return"string"==typeof t?i.attr("value",t):"object"==typeof t&&i.attr(t),"string"==typeof e?i.text(e):"object"==typeof e&&i.attr(e),"object"==typeof n&&i.attr(n),i},eOpt:function(t){var e=$('');return t&&e.attr("selected","selected"),e},tbl:function(t){return $("
").attr(t||{})},tblc:function(t){return $("
").addClass(t)},thead:function(t){let e=$("");return t instanceof jQuery&&e.prependTo(t),e},tbody:function(t){let e=$("");return t instanceof jQuery&&e.appendTo(t),e},tblset:function(t,e){let n=$$.tbl(t||{});return e instanceof jQuery&&e.append(n),{tbl:n,hd:$$.thead().appendTo(n),bdy:$$.tbody().appendTo(n)}},i:function(t){return $("").attr(t||{})},img:function(t,e){return $("
").attr("src",t).attr(e||{})},sel:function(t){return $("").attr(t||{})},btn:function(t){return $("").attr(t||{})},a:function(t){return $("").attr(t||{})},li:function(t){return $("").attr(t||{})},ul:function(t){return $("
").attr(t||{})},nav:function(t){return $("").attr(t||{})},lbl:function(t,e){var n=$("");return"string"==typeof t&&n.text(t),"object"==typeof t?n.attr(t):"object"==typeof e&&n.attr(e),n},txt:function(t){return $("").attr(t||{})},0:function(t,e){return $("<"+t+">"+t+">").attr(e||{})},bbtn:function(t,e){return $$.btn({type:"button",class:"btn"}).addClass(e).text(t)},svg:t=>$(document.createElementNS("http://www.w3.org/2000/svg",t))};function getMonday(t){var e=(t=new Date(t)).getDay(),n=t.getDate()-e+(0==e?-6:1);return new Date(t.setDate(n))}function $lf(t){var e=void 0===t?null:"number"==typeof t&&1!==t||"boolean"==typeof cl&&!1===t;return $("#listframe").tC("hd",e).is(".hd")}function $nuf(t){if(t&&t.stopPropagation(),!$(this).is(".disabled")){var e=function(t){t.removeClass("vis").find("li.dropdown").removeClass("open").removeClass("vis").attr("aria-expanded","false")},n=$(this).parent("li.dropdown");if(n.length>0){n.tC("open"),navs=!0===n.is(".open")?"true":"false",n.attr("aria-expanded",navs);var i=n.closest("nav");i.find("li.dropdown").not(n.parentsUntil("nav")).not(n).removeClass("open").attr("aria-expanded","false"),!1===n.is(".open")&&n.find("li.dropdown").removeClass("open").attr("aria-expanded","false"),e($("nav").not(i))}else e($("nav"))}}function $tbr(){return $lf(0),$("#topbar").ocmsmenu([])}function $lfr(){return $("#sidebar").empty(),$("#listframe").removeClass("fix").addClass("hd").empty()}function $cfr(){return $tbr(),$("#contentframe").empty()}function jObj(t,e){let n={};if("{"===(t||"").substr(0,1))try{n=JSON.parse(t)}catch(t){n={}}return n[e]||""}function string(t,e){var n,i=t||"";return $.each(e||[],(function(t,e){n=new RegExp("\\{"+t.toString()+"\\}","ig"),i=i.replace(n,e)})),i}function init_tooltip(t){var e=!0===("boolean"==typeof t&&t)&&"mouse";$("[title]").qtip({position:{target:e,adjust:{x:2,y:2},viewport:!0},events:{hidden:$ocms.tooltip_hidden},effect:!1}),$("div.tooltiptext").each((function(){$(this).filter(":not(:empty)").parent().qtip({suppress:!1,content:{text:$(this).clone()},position:{target:e,adjust:{x:2,y:2},viewport:!0},events:{hidden:$ocms.tooltip_hidden}})}))}String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")},String.prototype.left=function(t){if("string"===$.type(t)){var e=this.indexOf(t);return e>0?this.slice(0,e):""}return this.substring(0,t)},String.prototype.right=function(t){if("string"===$.type(t)){var e=this.indexOf(t);return e>0?this.substring(this.length-e):""}return this.substring(this.length-t)},Array.prototype.move=function(t,e){if(e>=this.length)for(var n=e-this.length;1+n--;)this.push(void 0);return this.splice(e,0,this.splice(t,1)[0]),this},function(t){t.fn.appendToIf=function(e,n){var i=t(this),o="function"==typeof n?n(i):n;return!0===("boolean"!=typeof o||o)&&i.appendTo(e),i},t.fn.appendIf=function(e,n){var i=t(this),o="function"==typeof n?n(i):n;return!0===("boolean"!=typeof o||o)&&i.append(e),i},t.fn.rwText=function(e,n,i){var o=t(this).empty();i=t.extend({wrap:!0},i);var r=!0===Array.isArray(e)?e:(null==e?"":String(e)).split("\n");return t.each(r,(function(t,e){""!==(e||"")&&(t>0&&o.append($$.br()),o.append(!0===i.wrap?$$.s(e):e))})),n&&o.attr("title",n),o},t.fn.loadSel=function(e,n,i){if("SELECT"===t(this).prop("tagName").toUpperCase()){var o=t(this);$ocms.postXT.call(this,{url:e,data:n||{},success:function(e){t.each(e,(function(){o.append($$.opt(e.value,e.text))}))},complete:function(){o.ldng(0),"function"==typeof i&&i.call(o)}})}},t.fn.emptyWithEditors=function(e){var n=t(this);return n.find(":input.tinymce").each((function(e,n){try{var i=tinymce.get(t(n).attr("id"));i&&i.remove()}catch(e){t.noop()}})),n.empty()},t.fn.cssValue=function(t){if(this.length>0){var e=this.css(t)||"";if(""===e)return 0;var n=/(^[\d\.]*)(\D{1,3}$)/gi.exec(e);return null!==n?"rem"===n[2]?$ocms.rpx(parseFloat(n[1])):parseFloat(n[1]):!1===isNaN(e)?parseFloat(e):0}return 0},t.fn.veryInnerHeight=function(){let e=e=>t(this).cssValue(e);return t(this).innerHeight()-e("padding-top")-e("padding-bottom")},t.fn.veryInnerWidth=function(){let e=e=>t(this).cssValue(e);return t(this).innerWidth()-e("padding-left")-e("padding-right")},t.fn.marginWidth=function(){let e=e=>t(this).cssValue(e);return e("margin-left")+e("margin-right")},t.fn.marginHeight=function(){let e=e=>t(this).cssValue(e);return e("margin-top")+e("margin-bottom")},t.inArrayRegEx=function(e,n,i){var o="regexp"===t.type(e)?e:new RegExp(e);if(!n)return-1;for(var r=i=i||0;r7){i=e.split(","),o=(n||(t<0?"rgb(0,0,0)":"rgb(255,255,255)")).split(",");var c=a(i[0].slice(4)),l=a(i[1]),u=a(i[2]);return"rgb("+(s((a(o[0].slice(4))-c)*r)+c)+","+(s((a(o[1])-l)*r)+l)+","+(s((a(o[2])-u)*r)+u)+")"}var d=(i=a(e.slice(1),16))>>16,h=i>>8&255,p=255&i;return"#"+(16777216+65536*(s((((o=a((n||(t<0?"#000000":"#FFFFFF")).slice(1),16))>>16)-d)*r)+d)+256*(s(((o>>8&255)-h)*r)+h)+(s(((255&o)-p)*r)+p)).toString(16).slice(1)},t.fn.IN=function(e){return t(this).fadeIn(400,e),t(this)},t.fn.OUT=function(e){return t(this).fadeOut(400,e),t(this)},t.fn.tooltip=function(e,n){var i=!0===("boolean"==typeof e&&e)&&"mouse",o="boolean"==typeof n&&n,r=t(this);return r.each((function(){var e=o?t(this).find(".tooltiptext"):t(this).children(".tooltiptext");t(e).length>0?e.each((function(){var e=t(this);t(this).filter(":not(:empty)").parent().qtip({suppress:!1,content:{text:e.clone()},position:{target:i,adjust:{x:2,y:2},viewport:!0},events:{hidden:$ocms.tooltip_hidden},show:{effect:!1},hide:{effect:!1}}),e.remove()})):t(this).qtip({position:{target:i,adjust:{x:2,y:2},viewport:!0},events:{hidden:$ocms.tooltip_hidden},effect:!1})})),r},t.fn.rC=function(e){return t(this).removeClass(e)},t.fn.aC=function(e){return t(this).addClass(e)},t.fn.tC=function(e,n){return t(this).toggleClass(e,n)}}(jQuery),function(t){t.fn.ocmsmenu=function(e,n){var i=t(this);return $ocms.menu.call(i,e,n),i},t.fn.activatemenu=function(){var e=t(this).filter("nav");return e.find("a").not(".on").addClass("on").click($nuf),e.find(".nav-btn").not(".on").addClass("on").click((function(e){e.stopPropagation();var n=t(this);t(n.attr("data-target")).tC(n.attr("data-toggle"))})),e}}(jQuery);class ObjectArray extends Array{isEmpty(){return 0===this[0].length}static get[Symbol.species](){return Array}filter(t){return"function"==typeof t?new ObjectArray(this[0].filter(t)):this}remove(t){if("function"!=typeof t)return this;{let e=this[0].findIndex(t);for(;e>-1;)this[0].splice(e),e=this[0].findIndex(t)}}sortBy(t){return"function"==typeof t&&this[0].sort(t),this}sortString(t){return this[0].sort(((e,n)=>{let i=(e[t]||"").toString().toUpperCase(),o=(n[t]||"").toString().toUpperCase();return console.debug(i.localeCompare(o)),i.localeCompare(o)})),this}sortNum(t){return this[0].sort(((e,n)=>{let i=e[t],o=n[t];return!0===isNaN(o)&&!1===isNaN(i)||io?1:0})),this}sum(t){return this[0].reduce(((e,n)=>e+(!0===isNaN(n[t])?0:n[t])),0)}groupBy(t){return this[0].reduce((function(e,n){let i=n[t];return e[i]||(e[i]=[]),e[i].push(n),e}),{})}each(t){if("function"==typeof t){let e=!1;this[0].forEach(((n,i,o)=>{if(!1===e){let r=t(n,i,o);"boolean"==typeof r&&!1===r&&(e=!0)}}))}}get toArray(){return this[0]}}class NumArray extends Array{sum(){return this.reduce(((t,e)=>t+e))}first(){return this[0]}last(){return this[this.length-1]}average(){return this.sum()/this.length}range(){let t=this.map((t=>t)).sort();return{min:t[0],max:t[this.length-1]}}static get[Symbol.species](){return Array}}$ocms.ocmsmenu=[{lbl:"",id:"m_home",ico:"glyphicon glyphicon-home",fnc:"init:home"},{fnc:"separator"}],function(t){t.multline=function(t){let e=t.split("\n"),n=$$.d();return $.each(e,((t,e)=>{n.append($$.s(e))})),n.html()},t.tooltip_hidden=function(t,e){$(this).remove(),e.rendered=!1},t.isJSONDateString=function(t){return"string"==typeof t&&/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?)?$/.test(t)},t.failure=function(e){11110===(e.internalCode||-1)?t.login.dlg():alert($t.f1+"\n"+(e.internalText||""))},t.getScript=function(e,n){var i=[],o=[],r=function(t){return"string"==typeof t&&""!==(t||"")},s=function(t,e){!0===bool(e.condition,!0)&&(""!==(e.script||"")&&o.push({url:e.script,module:e.module||""}),!0===r(e.css||"")?i.push(e.css):!0===Array.isArray(e.css)&&Array.prototype.push.apply(i,e.css.filter(r)))};!0===r(e||"")?o.push(e):!0===Array.isArray(e)?$.each(e,s):"object"==typeof e&&""!==(e.script||"")&&s(0,e);let a=[];$.each(i,(function(t,e){""!==(e||"")&&a.push(loadCSS(e))}));let c=o.map((function(e,n){let i=e.url,r=e.module||"";if(""===r){let t=new Promise((function(t,e){try{!async function(){$.ajax({url:i,dataType:"script",success:function(){t(o)},error:function(){e(o)},timeout:3e4})}()}catch(t){console.debug(t.message+"%o",t)}}));return t}return t.loadmodule(r,i,e.alias)}));Promise.all(c).then(n)},t.loadmodule=function(e,n,i){let o=new Promise((function(o,r){!async function(){try{let s=(n.startsWith("/")||n.startsWith(".")?"":"/")+n;import(s).then((n=>{t[e]=n[i||"default"],o(e)})).catch((t=>{console.debug(t.message+"%o",t),r(e)}))}catch(t){console.debug(t.message+"%o",t)}}()}));return o},t.ocms_auth=function(e,n,i,o){!1===$.isPlainObject(t.auth.modules)&&(t.auth.modules={});var r=0;t.auth.modules[e+(i||"")]?((r=t.auth.modules[e+(i||"")])<2&&(i||"")===auth.guid&&(r=2),r>=(n||0)&&o(false)):t.postXT({url:t.url("auth"),data:{module:e,person_guid:i||""},success:function(s){r=s[e],t.auth.modules[e+(i||"")]=r,r<2&&(i||"")===t.auth.person_guid&&(r=2),r>=(n||0)&&o(false)},error:function(e){t.failure.call(this,e)}})},t.auth.locale="de",t.ocms_prepauth=function(e,n,i){t.postXT({url:t.url("auth"),data:{fn:"csv",modules:e,person_guid:n||""},success:function(e){t.ocms_regauth(e)},error:function(e){t.failure.call(this,e)},complete:function(){i()}})},t.ocms_regauth=function(t){$.each(t||{},(function(t,e){auth.modules[t]=parseInt(e)}))},t.init=function(e){var n="string"==typeof e?e:(e.data||{}).fn||"";""!==n&&("home"===n?($cfr(),$lfr(),$("#topbar").ocmsmenu([],!0),$("#activemodule").text($t.ov),t.ov.call($("#contentframe"))):($cfr(),$lfr(),$("#topbar").ocmsmenu([]),t.postXT({url:t.url(n+"/auth"),success:function(e){void 0===t[n]&&(t[n]={}),t[n].auth=e,e.manage>0&&t.getScript({module:n,script:["web/imdl",n,t.auth.locale||"de","js"].join("."),css:["web/imdl",n,"css"].join("."),condition:"function"!=typeof t[n].init2},(function(){t[n].init2()}))},error:function(){$("#contentframe").empty()}})))},t.menuarray=function(t){this.array=[],this.sep=function(){this.length>0&&"separator"!==this.array[array.length-1].fnc&&this.push({fnc:"separator"})},this.push=function(t){return void 0===t?null:(!0===Array.isArray(t)?Array.prototype.push.apply(this.array,t):"object"==typeof t&&this.array.push(t),t)},this.unshift=function(t){return void 0===t?null:(!0===Array.isArray(t)?Array.prototype.unshift.apply(this.array,t):"object"==typeof t&&this.array.unshift(t),t)},this.push(t)},t.menu=function(e,n){e=e||[];var i=$(this).removeClass("vis");if(!0===bool(n,!0)&&!1===i.is("#mainmenu")&&i.empty(),!1===bool(n,!1)&&i.is("#sidebar,#topbar")&&(e.unshift({id:"sbctrl",glyph:"glyphicon-th-list",aclass:"fbtn",fnc:function(){$lf()}}),$lf(0)),0===(e||[]).length)i.empty().addClass("hd");else{i.removeClass("hd");var o=!0===i.is("nav")?i:i.children("nav");1!==o.length&&(o=$("").tC("nv",i.is("#sidebar")).tC("ctxt",i.is("#topbar")).appendTo(i));var r,s=$$.ul().appendTo(o),a=function(t,e){var n=$(this).addClass("dropdown submenu");t.append($$.sc("caret dd")).addClass("dds dropdown-toggle").attr({"aria-expanded":"false"}),""!==(e.ico||"")&&t.prepend($$.sc("ico "+e.ico));var i=$$.ul({class:"dropdown-menu",role:"menu"}).appendTo(n);$.each(e.itm||[],(function(t,e){r.call(i,e)}))},c=function(t){$(this).tC("disabled","boolean"==typeof t.disabled?t.disabled:"string"==typeof t.disabled&&"subs"===t.disabled&&0===(t.itm||[]).length)};r=function(e){var n,i=$$.li({id:e.id}).attr(e.attr||{}).addClass(e.lclass).appendTo($(this)),o="string"==typeof e.fnc&&""!==e.fnc?e.fnc.split(":")[0]:"";""!==o&&"init"!==o?i.attr("role",o).appendIf($$.s(e.lbl),""!==ne(e.lbl)):(n=$$.a({class:"on",role:"button"}).addClass(e.aclass).appendTo(i).append($$.s(e.lbl)),c.call(n,e),(e.itm||[]).length>0&&a.call(i,n,e),n.click($nuf),"function"==typeof e.fnc?n.click(e.data||{},e.fnc):"init"===o&&n.click($.extend({},e.data||{},{fn:e.fnc.split(":")[1]}),t.init))},$.each(e,(function(e,n){var i,o=$$.li({id:n.id}).attr(n.attr||{}).addClass(n.lclass),a="string"==typeof n.fnc&&""!==n.fnc?n.fnc.split(":")[0]:"";if(""!==a&&"init"!==a)o.attr("role",a).appendIf($$.s(n.lbl),""!==ne(n.lbl));else{if(i=$$.a({class:"on",role:"button"}).addClass(n.aclass).appendTo(o),c.call(i,n),""!==(n.lbl||"")&&i.append($$.s(n.lbl)),""!==(n.ico||"")&&i.prepend($$.sc("ico "+n.ico)),""!==(n.glyph||"")&&i.prepend($$.sc("glyphicon "+n.glyph)),(n.itm||[]).length>0){o.addClass("dropdown"),i.append($$.sc("caret dd")).addClass("dds dropdown-toggle").attr({"aria-expanded":"false"});var l=$$.ul({class:"dropdown-menu",role:"menu"}).appendTo(o);$.each(n.itm||[],(function(t,e){r.call(l,e)}))}(n.sel||[]).length>0||(i.click($nuf),"function"==typeof n.fnc?i.click(n.data||{},n.fnc):"init"===a&&i.click($.extend({},n.data||{},{fn:n.fnc.split(":")[1]}),t.init))}o.appendTo(s)})),o.activatemenu()}},t.easytbl=(t,e)=>{e=e||{};let n=$$.tbl().addClass(e.class).css("border-collapse","collapse"),i=($$.tbody(n),!0===bool(e.frame,!1)?{padding:"5px",border:"1px solid #727272"}:{});if(!0===Array.isArray(e.header)){let t=$$.thead(n);$.each(e.header,((n,o)=>$$.th(t).css(e.cellcss||i).rwText(o)))}else if(!0===bool(e.header,!1)&&(t||[]).length>0){let o=$$.thead(n);$.each(Object.keys(t[0]),((t,n)=>$$.th(o).css(e.cellcss||i).rwText(n)))}return $.each(t||[],((t,o)=>{let r=$$.tr();$.each(o,((t,n)=>{n=n||"";let o=$$.td(r).css(e.cellcss||i);n instanceof jQuery?o.append(n):"string"==typeof n&&("<"===n.substring(0,1)?o.append(n):o.text(n))})),n.append(r)})),n},t.dlgtbl=(e,n,i)=>{i=i||{};let o=t.easytbl(e,i);t.dlg(o,$.extend({title:n},i))},t.dlg=function(t,n){n=n||{};let i=$("body > .modal").length>0,o=t=>typeof n[t],r=t=>"function"===o(t);if(!0===bool(n.exclusive,!0)&&!0===i)return void alert($t.dbldlg||"Es ist bereits ein Dialog geöffnet");let s=$$.dc("modal",$("body")),a=$$.dc("modal-dialog",s);!1===isNaN(n.zindex)?s.css("zIndex",n.zindex):!0===i&&s.css("zIndex",parseInt($("body > .modal:last").cssValue("zIndex"))+200),!1===isNaN(n.zindex_min)&&s.cssValue("zIndex")').appendTo(d)),""!==ne(n.title)&&(c=$$.dc("modal-header",d),$("").text(n.title).appendTo(c));let p=$$.dc("modal-body",d),f=$$.dc("modal-footer",d);t instanceof jQuery==!0&&p.append(t);let m=function(t){t&&"function"==typeof t.stopPropagation&&t.stopPropagation(),a.removeClass("in"),!0===r("closing")&&n.closing.call(d),p.hide().emptyWithEditors(),s.remove(),!0===r("close")&&n.close.call(d)};if(d.find(":input[required]").length>0&&($$.dc("note_required",f).append($$.sc("ind_required","*")).append($$.s($t.t1||"Eingabe erforderlich")),$$.dc("note_invalid",f).append($$.s($t.t2||"Bitte überprüfen Sie Ihre Eingaben im Formular."))),!0===r("cancel")){$$.bbtn(n.cancelbutton||"Abbrechen","cancel").attr({type:"button",role:"cancel"}).appendTo(f).click((function(t){n.cancel.call(d,t);t.stopPropagation(),m()}))}if(!0===r("confirm")){let t=$$.bbtn(n.button||"OK","confirm").attr({type:!0===bool(n.form,!1)?"submit":"button",role:"confirm"}).appendTo(f);!0===h?(d.submit((function(t){try{n.confirm.call(d,t)}finally{t.preventDefault()}return!1})),d.on("modal_submit",(function(){n.confirm.call(d,e)}))):(t.click((function(t){n.confirm.call(d,t);t.stopPropagation()})),d.on("modal_submit",(function(){t.click()})))}else!0===h&&d.submit((function(t){return t.preventDefault(),!1}));return d.on("modal_close",(function(){m()})),l.click(m),!0===r("opening")&&n.opening.call(d),a.addClass("in"),ne(n.mode).indexOf("maxbody")>-1&&p.css("min-height",(u.height()-c.outerHeight()-f.outerHeight()).toString()+"px"),!0===r("open")&&n.open.call(d),{hd:c,bdy:p,ft:f,ct:u,dlg:a,c:d}},t.mform=function(e){let n=$$.dc("form-body"),i=Array.isArray(e)?e:e instanceof fields_definition?e.fields:[];return $.each(i||[],(function(e,i){let o=i.type||"";if("ignore"===o)return!0;let r=$$.dc("form-group",n),s=i.id||"dlg_"+(i.name||"")+("html"===i.type?"_"+(65536*(1+Math.random())||0).toString(16).substr(9):""),a=$$.lbl(i.label||i.name,{for:s}).appendTo($$.dc("form-itm",r)),c=$$.dc("form-itm",r),l=$$.i({id:s,name:i.name,placeholder:i.placeholder,type:i.type});switch(o){case"email":i.pattern=ne(i.pattern,"[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$");break;case"url":i.pattern=ne(i.pattern,"https?://.+");break;case"number":i.pattern=ne(i.pattern,"[-+]?[0-9]*[.,]?[0-9]*"),l.attr("type","text"),l.attr("inputmode","decimal"),l.attr("step",i.precision||"any"),l.attr("data-format","float");break;case"integer":case"int":i.pattern=ne(i.pattern,"[-+]?[0-9]*"),l.attr("type","number"),l.attr("data-format","integer");break;case"date":if(""!==ne(i.pattern,$t.datepattern)&&(i.pattern=ne(i.pattern,"("+$t.datepattern+")|([0-9]{4}.(0[1-9]|1[012]).(0[1-9]|1[0-9]|2[0-9]|3[01]))")),""!==ne(i.placeholder,$t.dateplaceholder)&&l.attr("placeholder",ne(i.placeholder,$t.dateplaceholder)),"string"==typeof i.value){var u=i.value.substr(0,10);i.value="date"!==l.prop("type")?fdt(u+"T00:00:00",ne(i.dateformat,$t.dateformat)):u}l.attr("data-format","date:"+ne(i.dateformat,$t.dateformat)+";yyyy-MM-dd");break;case"datetime":l.attr("type","datetime-local"),""!==ne(i.pattern,$t.datetimepattern)&&(i.pattern=ne(i.pattern,"("+$t.datetimepattern+")|([0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])\\s([0-5][0-9]):([0-5][0-9]))")),""!==ne(i.placeholder,$t.datetimeplaceholder)&&l.attr("placeholder",ne(i.placeholder,$t.datetimeplaceholder)),"string"==typeof i.value&&"T"===i.value.substr(10,1)&&(i.value="datetime"!==l.prop("type").substr(0,8)?fdt(i.value,ne(i.datetimeformat,$t.datetimeformat)):i.value),l.attr("data-format","datetime:"+ne(i.datetimeformat,$t.datetimeformat)+";yyyy-MM-dd HH:mm:ss");break;case"hidden":r.addClass("hd");break;case"html":case"text":l=$$.txt({id:s,name:i.name,placeholder:i.placeholder,type:i.type}),l.tC("tinymce","html"===i.type);break;case"bool":case"boolean":i.url=[{value:"true",label:($t||{}).true||"Yes"},{value:"false",label:($t||{}).false||"No"}],"boolean"==typeof i.value&&(i.value=i.value?"true":"false");case"select":l=$$.sel({id:s,name:i.name,type:i.type}),!1===bool(i.required,!1)&&$$.eOpt().appendTo(l);try{var d=function(t){!0===Array.isArray(t)&&$.each(t,(function(t,e){"string"==typeof e?$$.opt(e,e).appendTo(l):!0===Array.isArray(e)?$$.opt(e[0],e[1]).appendTo(l):"object"==typeof e&&$$.opt(e.value,e.label||e.text).appendTo(l)}))};!0===Array.isArray(i.url)?d(i.url):"function"==typeof i.url?i.url.call(l):"string"==typeof i.url&&t.postXT({url:i.url,success:d})}catch(t){$.noop()}break;default:""!==ne(i["max-length"])&&l.attr("max-length",i["max-length"])}""!==ne(i.pattern)&&l.attr("pattern",i.pattern),l.val(i.value).change(),l.change((function(){$(this)[0].setCustomValidity("")})),l.addClass("form-control").prop("required",bool(i.required,!1)).prop("readonly",bool(i.readonly,!1)).appendTo(c),!0===bool(i.required,!1)&&a.append($$.sc("ind_required","*")),"object"==typeof i.attr&&l.attr(i.attr),"object"==typeof i.prop&&l.prop(i.prop),"string"==typeof i.class&&l.addClass(i.class),"function"==typeof i.change&&(l.change(i.change),!0===bool(i.applychange,!1)&&void 0!==i.value&&l.change()),""!==(i.note||"")&&$$.dc("form-note",c).rwText(i.note),"function"==typeof i.complete&&i.complete.call(l)})),n},t.initMCE=function(t,e){t=$(t),e=e||{};try{let n={target:t[0],inline:!1,width:e.width||"100%",statusbar:!1,document_base_url:window.location.origin+"/",content_style:"ph:before {content: '«'; color: #BBB; font-style:italic; } ph:after {content: '»'; color: #BBB; font-style:italic; } ph { color: #AAA; font-style:italic; }",relative_urls:!1,remove_script_host:!1};!0===bool(e.hidemenu,!1)&&(n.menubar=!1,n.menu={}),!0===bool(e.hidetoolbar,!1)&&(n.toolbar=!1),$.extend(n,e||{}),tinymce.init(n)}catch(t){alert(t.message)}},t.dlgform=function(e,n){n=n||{};let i,o=$$.dc("frm").append(t.mform(e||[]).addClass("stacked"));n.addcontent instanceof jQuery&&o.append(n.addcontent),"function"==typeof n.submit?i=n.submit:"function"==typeof n.success&&(i=function(e){var i=$(this).ldng(1),o=$.extend({loginaccount:t.auth.account||""},i.serializeObject(bool(n.checkvalidity,!0),{typedvalues:bool(n.typedvalues,!1)}));""!==(n.url||"")?t.postXT({url:n.url,data:o,success:function(t){n.success.call(this,t),i.trigger("modal_close")},error:function(){alert($t.l17)},complete:function(){i.ldng(0)},timeout:6e4}):(n.success.call(this,o),i.trigger("modal_close"))});let r={form:!0,title:n.title||"",button:n.button||$t.submit,confirm:i,size:n.size||[500,600],open:function(){let e=$(this).find(".tinymce");e.length>0&&t.initMCE(e,n.tinymce||{})}};return t.dlg.call(this,o,r)},t.login.dlg=function(e){e=e||{};let n=[{name:"userinfo",label:$t.l1,type:"string",value:t.auth.login,change:t.login.uichange,required:!0},{name:"userlogin",type:"hidden",required:!0,value:t.auth.login},{name:"username",type:"string",label:$t.l4,required:!0,readonly:!0,placeholder:$t.l5,value:t.auth.fullname_rev},{name:"userpass",type:"password",label:$t.l3,required:!0,placeholder:$t.l3}];""===(t.auth.account||"")&&n.unshift({id:"dlg_loginaccount",name:"loginaccount",type:"string",required:!0,value:t.auth.account});let i=$$.dc("frm").append(t.mform(n).addClass("stacked")),o=t.dlg.call(this,i,{form:!0,title:$t.l0,button:$t.submit,confirm:function(n){var i=$(this).ldng(1),o=$.extend({loginaccount:t.auth.account||""},i.serializeObject());t.postXT({url:"/vt/login",data:o,success:function(n){""!==((n||{}).login||"")&&(i.trigger("modal_close"),t.auth=n,"object"==typeof e.ajo&&(e.ajo.islogin,$.ajax(e.ajo)))},error:function(){alert($t.l17)},complete:function(){i.ldng(0)},timeout:6e4})},size:[500,600]}),r=$$.dc("modal-content").css("height","auto").attr("novalidate","true").append($$.dc("modal-header").appendIf($("").text(t.auth.accountname),""!==(t.auth.accountname||"")).append($("Vereinsmanager
")));o.dlg.prepend(r)},t.addNoEntryInfo=function(t){$(this).append($$.dc("noentryinfo").text(t||$t.t11))}}($ocms),Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector),Element.prototype.closest||(Element.prototype.closest=function(t){var e=this;do{if(Element.prototype.matches.call(e,t))return e;e=e.parentElement||e.parentNode}while(null!==e&&1===e.nodeType);return null}),function(t,e){var n,i;"object"==typeof window&&(window[t]=(n=function(t){var e=window,n=document.body,i=document.documentElement,o=Math.max(0,e.pageXOffset||i.scrollLeft||n.scrollLeft||0)-(i.clientLeft||0),r=Math.max(0,e.pageYOffset||i.scrollTop||n.scrollTop||0)-(i.clientTop||0);return{x:t?Math.max(0,t.pageX||t.clientX||0)-o:0,y:t?Math.max(0,t.pageY||t.clientY||0)-r:0}},(i=function(t,e){t&&t instanceof Element&&(this._container=t,this._options=e||{},this._clickItem=null,this._dragItem=null,this._showDragItem="boolean"!=typeof this._options.dragItem||!1!==this._options.dragItem,this._hovItem=null,this._sortLists=[],this._click={},this._dragging=!1,this._dragHandleClass=this._options.dragHandleClass||"",this._parentident=this._options.parentident||"",this._swapdone="function"==typeof this._options.swapdone?this._options.swapdone:null,this._onend="function"==typeof this._options.onend?this._options.onend:null,this._container.setAttribute("data-is-sortable",1),this._container.classList.add("sortable"),this._container.style.position="static",window.addEventListener("mousedown",this._onPress.bind(this),!0),window.addEventListener("touchstart",this._onPress.bind(this),!0),window.addEventListener("mouseup",this._onRelease.bind(this),!0),window.addEventListener("touchend",this._onRelease.bind(this),!0),window.addEventListener("mousemove",this._onMove.bind(this),!0),window.addEventListener("touchmove",this._onMove.bind(this),!0))}).prototype={constructor:i,toArray:function(t){t=t||"id";for(var e=[],n="",i=0;ii.left&&ei.top&&n-1)&&e.className.indexOf("nosort")<0)&&(t.preventDefault(),this._dragging=!0,this._click=n(t),this._makeDragItem(e),this._onMove(t),!0)}t&&!1===e.call(this,t.target)&&""!==this._parentident&&t.target.closest(this._parentident)&&e.call(this,t.target.closest(this._parentident))},_onRelease:function(t){var e=!0===this._dragging&&null!==this._clickItem;this._dragging=!1,this._trashDragItem(),e&&"function"==typeof this._onend&&this._onend()},_onMove:function(t){if(this._dragItem&&this._dragging){t.preventDefault();var e=n(t),i=this._container;!0===this._showDragItem&&this._moveItem(this._dragItem,e.x-this._click.x,e.y-this._click.y);for(var o=0;o0?a.mousedown(c).addClass("dctrl"):s.mousedown(c).addClass("dctrl"),t(this)}}(jQuery),$(document).ready((function(){$("html").click((function(t){$nuf()})),$("#listframe").click((function(t){t.stopPropagation(),$nuf()})),$("#mainmenu").ocmsmenu($ocms.ocmsmenu),$("#mainmenu").activatemenu()})),$.extend($t,{m_inv:"Rechnungen",m_req:"Aufträge",m_rep:"Berichte",m_todo:"ToDos",m_bcd:"BankBuchungen",rsp:"Passwort ändern",pnm:"Die Passwörter stimmen nicht überein",cps:"Das neue Passwort wurde gespeichert.",pwr:"Bitte wählen Sie ein starkes Passwort (min 8 Zeichen, davon jeweils min 2 Zahlen, kleine und große Buchstaben, Sonderzeichen sind optional).",smsc:"Sie beötigen für diese Funktion einen SMS-Code.\nSoll dieser nun versandt werden?",wdc:"Doppelt klicken, um die Box zu aktualisieren.",wdg:{}}),$t.rspf={sms:"Der SMS-Code konnte nicht bestätigt werden",valid:"Das alte Passwort ist nicht korrekt",requirements:"Das Passwort entspricht nicht den Anforderungen.\n"+$t.pwr},$fd={rsp:new fields_definition("","",[{name:"opw",label:"aktuelles Passwort",type:"password",required:!0,attr:{"auto-complete":"current-password"}},{name:"npw",label:"neues Passwort",type:"password",required:!0,pattern:"(.{6,})",attr:{"auto-complete":"new-password"}},{name:"npwc",label:"neues Passwort (Bestätigung)",type:"password",required:!0,attr:{"auto-complete":"new-password"},note:$t.pwr},{name:"code",label:"SMS-Code",type:"string",required:!0,attr:{"auto-complete":"one-time-code"}}])},$ocms.init=function(t){var e="string"==typeof t?t:(t.data||{}).fn||"";""!==e&&("home"===e?($cfr(),$lfr(),$("#topbar").ocmsmenu([],!0),$("#activemodule").text($t.ov),$fis.ov()):($cfr(),$lfr(),$("#topbar").ocmsmenu([]),$ocms.postXT({url:$ocms.url(e+"/auth"),success:function(t){void 0===$ocms[e]&&($ocms[e]={}),$ocms[e].auth=t,t.manage>0&&$ocms.getScript({module:e,script:["/web/fis",e,$ocms.auth.locale||"de","js"].join("."),css:["/web/fis",e,"css"].join("."),condition:"function"!=typeof $ocms[e].init2},(function(){$ocms[e].init2()}))},error:function(){$("#contentframe").empty()}})))};var $fis={auth:{},db:function(){$("#mainmenu_activemodule").text($t.ov);let t=$(this).empty(),e=$$.d({id:"dashboard_frame"}).appendTo(t);$ocms.postXT({url:$ocms.url("wdg/my"),success:function(t){$.each(t,(function(t,n){var i=$$.dc("wdg_frame",e,{"data-wdg":n}).ldng(1);$ocms.wdg.call(i,{wdg:n})}))},loading:e})},ValidateEmail:function(t){return!!/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(t)},cf:t=>{let e=$("#contentframe");return!0===bool(t,!1)&&e.empty().rC("hd"),e},lf:t=>{let e=$("#listframe");return!0===bool(t,!1)&&e.empty().aC("hd").rC("fix"),e},frm_edit:function(t){let e=$fis.cf(!1),n=e.children(".cfrm"),i=e.children(".edit_frm");return n.length<1?n=$$.dc("cfrm hd").prependTo(e):!0===bool(t,!1)&&n.empty(),i.length<1&&(i=$$.dc("edit_frm").insertAfter(n)),i.empty()},frm_list:function(t,e){let n=$fis.cf(!1),i=n.children(".cfrm"),o=n.children(".list_frm");return i.length<1?i=$$.dc("cfrm hd").prependTo(n):!0===bool(t,!1)&&i.empty(),!0===bool(e,!1)&&n.children(".edit_frm").remove(),o.length<1&&(o=$$.dc("list_frm").appendTo(n)),o.empty()},lfm:()=>{let t=$fis.lf(!1),e=t.children(".lfrm");return e.length<1&&(e=$$.dc("lfrm").prependTo(t)),e},getAuth:(t,e)=>new Promise(((n,i)=>{$fis.auth[t]&&!1===bool(e,!1)?n($fis.auth[t]||-1):$ocms.postXT({url:$ocms.url("auth"),data:{module:t},success:e=>{$fis.auth[t]=e.auth||-1,n($fis.auth[t]||-1)},error:()=>{i()}})})),prepAuth:t=>new Promise(((e,n)=>{$ocms.postXT({url:$ocms.url("auth"),data:{module:t,array:1},success:t=>{$.extend($fis.auth,t||{})},complete:()=>{e()}})})),isAuth:(t,e)=>($fis.auth[t]||-1)>=(e||1),resetPass:function(t,e){confirm($t.smsc)&&($ocms.postXT({url:$ocms.url("account/sms"),data:{fn:"pwc"}}),$ocms.dlgform($fd.rsp.clone(),{title:$t.rsp||"",submit:function(t){var e=$(this).ldng(1),n=$.extend({loginaccount:$ocms.auth.account||""},e.serializeObject(!0,{typedvalues:!0}));(n.npw||"")!==(n.npwc||"")?e.find('input[name="npw"]:first')[0].setCustomValidity($t.pnm):$ocms.postXT({url:$ocms.url("account/changepassword"),data:n,success:function(t){alert($t.cps),e.trigger("modal_close")},error:function(t){alert($t.rspf[t.getResponseHeader("x-ocms-std")])},complete:function(){e.ldng(0)},timeout:6e4})}}))},wdg:function(t){let e=$(this).empty();$ocms.postXT({url:$ocms.url("wdg/one"),data:{short_name:t.wdg},timeout:9e4,success:function(n,i,o){let r=t.wdg,s=n[r];if(!s)return void e.ldng(0);let a=$.inArrayRegEx("dblwidth",s.rendering_options)>-1,c=$.inArrayRegEx("tiny",s.rendering_options)>-1;e.toggleClass("dbl",a&&!c).toggleClass("tny",c);$$.dc("wdg_hd",e,{title:ne(s.description,$t.wdc)}).toggleClass("dbl",a).text(ne(s.name,t.wdg)).dblclick((function(t){t.stopPropagation(),$fis.wdg.call(e,{wdg:r})}));let l=$$.dc("wdg_cnt",e).toggleClass("dbl",a).hide(),u=$.inArrayRegEx("bgcolor",s.rendering_options);switch(u>-1&&l.css("backgroundColor",s.rendering_options[u].toString().right(":")),s.type){case"table":var d=$$.tblset({},l),h=$$.tr().appendTo(d.hd),p=$t.wdg[r.indexOf("wdg_ev_")>=0?"wdg_ev_":r]||{};$.each(s.columns,(function(t,e){var n=p[e]?p[e].label:e;$$.th().text(n).appendTo(h)})),$.each(s.data,(function(t,e){var n=$$.tr().appendTo(d.bdy);$.each(s.columns,(function(t,i){var o=$$.td().appendTo(n);e[i]instanceof Date||!0===$ocms.isJSONDateString(e[i])?o.text(fdt(e[i],$t.dateformat)):o.rwText(e[i])}))})),$.inArray("firstrow_bold",s.rendering_options)>-1&&h.nextAll("tr:first").css("font-weight","bold");break;case"ind":$$.dc("ind",l).addClass("sts_"+(s.data.status||"")).append([$$.dc("ind").text(s.data.value),$$.lbl(s.data.label)]);break;case"image_url":l.css("background","url('"+s.url+"') no-repeat center center transparent");break;case"image_base64":l.css("background","url('data:image/png;base64,"+s.image+"') no-repeat center center transparent");break;case"html":if(l.html(s.html),$.inArray("reload_10min",s.rendering_options)>-1){var f=l.find("iframe");setTimeout((function(){f.attr("src",(function(t,e){return e}))}),6e5)}}$.inArray("reload_30min",s.rendering_options)>-1&&"html"!==s.type&&setTimeout((function(){$fis.wdg.call(e,{wdg:r})}),18e5),l.slideDown(150)},error:function(t){e.slideUp(150),$fis.failure.call(this,t)},complete:function(){e.ldng(0)}})},ov:function(){$fis.lf(!0);let t=$("#contentframe").empty(),e=$$.d({id:"dashboard_frame"}).appendTo(t);$ocms.postXT({url:$ocms.url("wdg/my"),success:function(t){$.each(t,(function(t,n){var i=$$.dc("wdg_frame",e,{"data-wdg":n}).ldng(1);$fis.wdg.call(i,{wdg:n})}))},loading:e})}};$fis.notifications={connection:null,init:function(){"undefined"!=typeof signalR&&null===this.connection&&$ocms.auth.useraccount_id&&(this.ensureFrame(),this.connection=(new signalR.HubConnectionBuilder).withUrl("/notifications").withAutomaticReconnect().build(),this.connection.on("notification",(t=>{this.push(t)})),this.connection.onclose((()=>{console.warn("Notification connection closed; retrying in 5s."),this.connection=null,setTimeout((()=>this.init()),5e3)})),this.start())},start:function(){this.connection.start().catch((t=>{console.warn("Notification connection failed to start; retrying in 5s.",t),this.connection=null,setTimeout((()=>this.init()),5e3)}))},ensureFrame:function(){$("#notification_frame").length<1&&$("",{id:"notification_frame"}).appendTo($("footer:first").length?"footer:first":"body")},push:function(t){this.ensureFrame(),t=t||{};let e=$("",{class:"notification_item"}).addClass((t.severity||"info").toLowerCase()).append($("",{type:"button",class:"notification_close",text:"×"})).append($("",{class:"notification_title",text:t.title||"Info"})).append($("",{class:"notification_message",text:t.message||""}));e.find(".notification_close").on("click",(function(){e.remove()})),$("#notification_frame").prepend(e),setTimeout((function(){e.fadeOut(150,(function(){e.remove()}))}),9e3)}},$fis.draft={connection:null,active:null,init:function(){"undefined"!=typeof signalR&&null===this.connection&&$ocms.auth.useraccount_id&&(this.connection=(new signalR.HubConnectionBuilder).withUrl("/draftpreview").withAutomaticReconnect().build(),this.connection.on("draftReady",(t=>this._dispatch("onReady",t,(t=>t.version)))),this.connection.on("draftExpiring",(t=>this._dispatch("onExpiring",t,(t=>t.secondsLeft)))),this.connection.on("draftClosed",(t=>this._dispatch("onClosed",t,(t=>t.reason)))),this.connection.onreconnected((()=>{this.active&&this._invoke("JoinDraft",this.active.token)})),this.connection.onclose((()=>{console.warn("Draft connection closed; retrying in 5s."),this.connection=null,setTimeout((()=>{this.init(),this.active&&this.bind(this.active.token,this.active)}),5e3)})),this.start())},start:function(){this.connection.start().then((()=>{this.active&&this._invoke("JoinDraft",this.active.token)})).catch((t=>{console.warn("Draft connection failed to start; retrying in 5s.",t),this.connection=null,setTimeout((()=>this.init()),5e3)}))},bind:function(t,e){t&&(this.active=$.extend({token:t},e||{}),null===this.connection&&this.init(),this._invoke("JoinDraft",t))},release:function(t){!this.active||t&&this.active.token!==t||(this.active=null),this._invoke("LeaveDraft",t)},_invoke:function(t,e){e&&this.connection&&"Connected"===this.connection.state&&this.connection.invoke(t,e).catch((e=>console.warn("Draft "+t+" failed",e)))},_dispatch:function(t,e,n){e=e||{},this.active&&this.active.token===e.token&&"function"==typeof this.active[t]&&this.active[t](n(e))}},Array.prototype.push.apply($ocms.ocmsmenu,[{lbl:$t.m_inv,id:"m_inv",fnc:"init:inv",ico:"glyphicon glyphicon-list-alt"},{lbl:$t.m_req,id:"m_req",fnc:"init:req",ico:"glyphicon glyphicon-eur"},{lbl:$t.m_bcd,id:"m_bcd",fnc:"init:bam",ico:"glyphicon glyphicon-indent-right"},{fnc:"separator"},{lbl:$t.m_rep,id:"m_rep",fnc:"init:rep",ico:"glyphicon glyphicon-dashboard"},{fnc:"separator"},{lbl:$t.m_todo,id:"m_todo",fnc:()=>{$("#contentframe").empty().load($ocms.url("todos")),$("#listframe").rC("fix").aC("hd")},ico:"glyphicon glyphicon-sunglasses"}]),$(document).ready((function(){$fis.notifications.init(),$fis.draft.init(),$fis.ov()}));
\ No newline at end of file
+function onloadCSS(t,e){e=e||{};let n=function(e){return new Promise(((n,i)=>{t.addEventListener?e.addEventListener("load",newcb):t.attachEvent&&e.attachEvent("onload",newcb),"isApplicationInstalled"in navigator&&"onloadcssdefined"in t&&e.onloadcssdefined(newcb)}))};if(Array.isArray(t)){let i=t.length;Promise.all(t.map(n)).then((function(t){var n=t.reduce(((t,e)=>t+(!0===e?1:0)));!async function(t){!0===t&&"function"==typeof e.success?e.success():!0===t&&"object"==typeof e.success&&e.success instanceof Promise&&await e.success(),e.complete()}(i===n)}))}else n(t)}!function(t){"use strict";var e=function(e,n,i,o){var r,s=t.document,a=s.createElement("link");if(n)r=n;else{var c=(s.body||s.getElementsByTagName("head")[0]).childNodes;r=c[c.length-1]}var l=s.styleSheets;if(o)for(var u in o)o.hasOwnProperty(u)&&a.setAttribute(u,o[u]);a.rel="stylesheet",a.href=e,a.media="only x",function t(e){if(s.body)return e();setTimeout((function(){t(e)}))}((function(){r.parentNode.insertBefore(a,n?r:r.nextSibling)}));var d=function(t){for(var e=a.href,n=l.length;n--;)if(l[n].href===e)return t();setTimeout((function(){d(t)}))};function h(){a.addEventListener&&a.removeEventListener("load",h),a.media=i||"all"}return a.addEventListener&&a.addEventListener("load",h),a.onloadcssdefined=d,d(h),a};"undefined"!=typeof exports?exports.loadCSS=e:t.loadCSS=e}("undefined"!=typeof global?global:this);const isIE=/MSIE\/|Trident/gi.test(window.navigator.userAgent)||void 0!==window.document.documentMode,isfileapi=!!(window.File&&window.FileReader&&window.FileList&&window.Blob);var $ocms={auth:{},no:function(t){t.stopPropagation()},vmin:function(t){var e=$(window).width*(t||1),n=$(window).height*(t||1);return e($ocms.baseurl+"/"+(t||"")).replace(/\/\//,"/"),cexi:null};function deepCopy(t){var e,n,i;if("object"!=typeof t||null===t)return t;for(i in e=Array.isArray(t)?[]:{},t)n=t[i],e[i]=deepCopy(n);return e}function fields_definition(t,e,n){this.label_sng=!0===Array.isArray(t)?"":t||"",this.label_pl=!0===Array.isArray(t)?"":e||"",this.fields=!0===Array.isArray(t)?t:n||[],this.itm=function(t){for(var e=0;e0)for(var n=0;nt||"")).filter(((t,e)=>""!==t)).join(e)}function parseDt(t,e,n){t=(t||"").substr(0,e.length);var i=e,o=t.length>0&&e.split(";").some((function(e){for(var n,o=/[^yMdhms0-9]/gi,r=!0;null!==(n=o.exec(e));)r=r&&e.substr(n.index,1)===t.substr(n.index,1);var s=t.length===e.length&&r;return!0===s&&(i=e),s}));if(!0===o){for(var r,s=[0,0,0,0,0,0,0],a=/(mm{1,2}|dd{1,2}|MM{1,2}|(yy){2,4}|ss{1,2}|hh{1,2})(?!\w)/g;null!==(r=a.exec(i));)s["yMdhms".indexOf(r[0].substr(0,1))]=parseInt(("yy"===r[0]?"20":"")+t.substr(r.index,r[0].length))-("M"===r[0].substr(0,1)?1:0);var c=new(Function.prototype.bind.apply(Date,[null].concat(s)));return"string"==typeof n?fdt(c,n):c}return!1}function bool(t,e){return"boolean"==typeof t?t:"boolean"==typeof e&&e}function booln(t,e){return"boolean"==typeof t?t:"number"==typeof t?1===t:"boolean"==typeof e&&e}Date.prototype.isValid=function(){return!isNaN(this)},Date.prototype.format=function(t){return fdt(this,t)},Date.prototype.addDays=function(t){return this.setDate(this.getDate()+t),this},Date.prototype.isBetween=function(t,e){return this>t&&this section");$(window).scroll((function(e){let n=$(window).scrollTop(),i=$("body");i.toggleClass("unfocus",n>vh()-1.2*t),i.toggleClass("btb",n>.5*vh()-t)}))},$ocms.cf_reset=function(){return $("#contentframe").empty()},function(t){t.fn.scrollTo=function(e){if(t(this).length>0){var n=t(this).offset().top||0;n>0&&t("html, body").animate({scrollTop:n-hh()},2e3)}},t.fn.ldng=function(e){var n=!0;return"boolean"==typeof e?n=e:"number"==typeof e&&(n=e>0),t(this).toggleClass("loading",n)},"function"!=typeof t.noop&&(t.noop=function(){}),t.fn.hasAttr=function(e){var n=t(this).attr(e);return void 0!==n&&!1!==n},t.fn.parseCssPx=function(e){try{return parseFloat(t(this).css(e).replace("px","")||0)}catch(t){return 0}},t.max=function(t,e){return isNaN(t)&&isNaN(e)?null:isNaN(t)&&!isNaN(e)?e:!isNaN(e)&&isNaN(e)||t>=e?t:e},t.min=function(t,e){return isNaN(t)&&isNaN(e)?null:isNaN(t)&&!isNaN(e)?e:!isNaN(e)&&isNaN(e)||t<=e?t:e},t.lim=function(t,e){return isNaN(t)?null:isNaN(e)?t:e<=t?e:t},t.fn.enterKey=function(e){return this.each((function(){t(this).keypress((function(t){"13"===(t.keyCode?t.keyCode:t.which).toString()&&e.call(this,t)}))}))}}(jQuery),$ocms.defaultTimeout=3e4,$ocms.AjaxEX=function(t){var e=this;e.responseText=e.responseText||"";var n=e.getResponseHeader("x-ocms-code")||"";e.internalCode=""!==n&&!1===isNaN(n)?parseInt(n):-1,e.isInternal=e.internalCode>-1,e.internalText=decodeURIComponent((e.getResponseHeader("x-ocms-desc")||"").replace(/\+/g,"%20")||"");var i=e.internalText||t,o=e.internalCode||e.status;e.logtext=i+" ("+o+")"},$ocms.postXTS=function(t){$ocms.postXT.call(this,$.extend(t,{sync:!0}))},$ocms.postXT=function(t){if((t=t||{}).trycount=t.trycount||0,""!==(t.url||"")){t.url=-1!==t.url.indexOf("&yy=")?t.url:t.url.indexOf("?")>-1?t.url+"&yy="+(new Date).getTime():t.url+"?yy="+(new Date).getTime();var e=t.context||this;switch(t.context=e,t.retryLimit=t.retryLimit||0,t.timeout=t.timeout||$ocms.defaultTimeout,t.timeout<100&&(t.timeout=1e3*t.timeout),t.data=t.data||{},t.contentType=t.contentType||"multipart/form-data; charset=UTF-8",t.islogin="boolean"==typeof t.islogin&&t.islogin,t.contentType){case"":case"json":t.contentType="application/json; charset=utf-8";break;case"form":t.contentType="application/x-www-form-urlencoded; charset=UTF-8";break;case"multi":t.contentType="multipart/form-data";break;case"text":t.contentType="text/plain; charset=UTF-8"}if(t.form instanceof jQuery?(t.data=t.form.serializeObject(),t.contentType="form-data"):t.lzw instanceof jQuery&&(t.data.lzw=$.ccLZW(t.lzw.serializeAnything(!0)).join(",")),"multipart/form-data"!==t.contentType.substr(0,19)&&"form-data"!==t.contentType.substr(0,9)||t.data instanceof FormData!=!1)t.data instanceof FormData&&(t.contentType=!1,t.processData=!1);else{t.contentType=!1;var n=new FormData;$.each(t.files||[],(function(t,e){n.append("upload_file",e)})),$.each(t.data||{},(function(t,e){n.append(t,e)})),t.data=n,t.processData=!1}var i={type:t.method||"post",url:t.url,data:t.data,processData:"boolean"!=typeof t.processData||t.processData,contentType:t.contentType,cache:t.cache||!1,timeout:t.timeout,beforeSend:function(n){$(t.loading).ldng(),$("body").addClass("ldng"),"function"==typeof t.beforesend&&t.beforesend.apply(e,[n])},success:function(n,i,o){"false"===n||"not authorized"===n?("function"==typeof t.error&&t.error.apply(e,[o,i,n]),"function"==typeof $.status&&$.status(i+" - "+n)):"function"==typeof t.success&&t.success.apply(e,[n,i,o])},error:function(n,i,o){if($ocms.AjaxEX.call(n,i),-1===t.url.indexOf("doc.ashx")||-1!==t.url.indexOf("ftest")){if(401===n.status&&111===n.internalCode&&!1===t.islogin&&"function"==typeof $ocms.login.dlg)$ocms.login.dlg({ajo:t});else if("timeout"===i||302===n.status)return t.tryCount++,t.tryCount<=t.retryLimit?void $ocms.postXT(t):void 0;"function"==typeof t.error?t.error.apply(e,[n,i,o]):"function"==typeof $ocms.failure?$ocms.failure.apply(e,[n]):"function"==typeof $.status&&$.status("Server error: "+i+" - "+o)}},dataType:t.datatype||"json",complete:function(n,i){"function"==typeof t.complete&&t.complete.apply(e,[n,i]),$(t.loading).ldng(0),$("body").removeClass("ldng");let o=$("body > .timer");if(o.length>0){let t=new Date(n.getResponseHeader("ocms_cec")||""),e=new Date(n.getResponseHeader("ocms_cex")||"");if(t.isValid()&&e.isValid()){let n=new Date,i=Math.abs(e-t);n.setMilliseconds(n.getMilliseconds()+i),o.data({cex:n,ctt:i}),$ocms.cex_timer()}}},context:e,async:!0};return"boolean"==typeof t.sync&&(i.async=!1===t.sync),!0==("boolean"==typeof t.contentType&&!1===t.contentType)&&(i.contentType=!1),$.ajax(i)}},$ocms.cex_timer=function(){$ocms.cexi||($ocms.cexi=setInterval($ocms.cex_timer,15e3));let t=$("body > .timer"),e=t.data("cex"),n=t.data("ctt"),i=new Date;if(e instanceof Date&&e.isValid()&&"number"==typeof n&&n>0&&e>i){let o=Math.abs(i-e)/n*100;t.css("width",o.toString()+"%"),o<98&&(!$ocms.cex_lp||Math.abs(i-$ocms.cex_lp)>6e5)&&$ocms.postXT({url:$ocms.url("ping"),success:()=>{$ocms.cex_lp=i},timeout:5e3,error:()=>{}})}},$ocms.vbl_send=function(t){var e=t.data||{};if(""!==(e.url||"")){var n=$("#contentframe form:first"),i={url:e.url,data:new FormData,success:function(t){"function"==typeof e.success?e.success(t):"string"==typeof e.success&&alert(e.success)},error:function(t,n,i){"function"==typeof e.error?e.error(i):"string"==typeof e.error&&alert(e.error)},complete:function(){n.ldng(0)}},o=!0;n.find("input").each((function(){var t=$(this),e=t.nza("name"),n=t.val(),r=$(this).prop("required")||!1;if(""!==e){var s=""!==n||!1===r;o=o&&s,!0===s?(i.data.append(e,n),t[0].setCustomValidity("")):""!==$(this).nza("ocms-nvnote")&&t[0].setCustomValidity($(this).nza("ocms-nvnote"))}})),!0===o&&(n.ldng(1),$ocms.postXT.call(this,i))}},function(t){t.fn.nza=function(e,n){var i=t(this).attr(e);return void 0!==i&&!1!==i?i:n||""},t.fn.serializeObject=function(e,n){var i=/\r?\n/g,o=/^(?:submit|button|image|reset|file)$/i,r=/^(?:input|select|textarea|keygen)/i,s=/^(?:checkbox|radio)$/i,a=bool((n=n||{}).typedvalues,!1),c={},l=t(this),u=l.find(':input:not([nosend],[type="file"])').addBack(":input"),d=!0;return t.each(u.not(".tinymce").get(),(function(n,l){var u=t(this),h=this,p=(this.type||"").toLowerCase(),f=u.prop("required")||!1;if(!0===(h.name&&!u.is(":disabled")&&r.test(h.nodeName)&&!o.test(p))){var m=u.val(),g=h.name,y=u.nza("data-format").split(":"),v=u.nza("pattern")||".*";if(!0===s.test(p)&&(m=h.checked?""!==m?m:"true":""),"date"===y[0].substr(0,4)&&y.length>1)"boolean"==typeof(m=parseDt(m,y.slice(1).join(":")))&&(m=null),null===m&&"date"===u.prop("type").substr(0,4)&&!1===isNaN(new Date(u.val()))&&(m=new Date(u.val())),m instanceof Date==!0&&"function"==typeof m.getMonth?!1===a&&(m=fdt(m,"date"===y[0]?"dts":"iso")):m=null;else if(("number"===p||"float"===y[0]||"integer"===y[0])&&!0===a){let t,e=String(m).replace(",",".");t="integer"===y[0]?parseInt(e):parseFloat(e),m=isNaN(t)?m:t}if(!0===f&&(""===m||null==m||"string"==typeof m&&null===m.match(v))?(!0===bool(e,!1)&&h.setCustomValidity(u.nza("ocms-nvnote",$ocms.t.inv||"Invalid field")),m=null):!0===bool(e,!1)&&h.setCustomValidity(""),null!=m&&"string"==typeof m){let t=c[g];null!=t?Array.isArray(t)?t.push(m.replace(i,"\r\n")):c[g]=[t,m.replace(i,"\r\n")]:c[g]=m.replace(i,"\r\n")}else if(null!=m){let t=c[g];null!=t?Array.isArray(t)?t.push(m):c[g]=[t,m]:c[g]=m}else d=!1}})),u.filter(".tinymce").each((function(e,n){var i=t(this),o=((this.type||"").toLowerCase(),i.prop("required")||!1);try{var r=tinymce.get(t(n).attr("id"));if(r){var s=t(n).attr("name"),a=r.getContent();!1===o||""!==(a||"")?c[s]=a:d=!1}}catch(e){t.noop()}})),l.toggleClass("invalid",!d),d?c:null},t.fn.sendForm=function(e,n,i){var o=t(this);i=i||{};var r={url:e,success:function(t){if(i.response=t,"function"==typeof n)n(t);o.closest("div.modal").remove()},error:function(t,e,n){"function"==typeof i.error?i.error.call(this,t):$ocms.failure.call(this,t)},complete:function(){o.ldng(0),"function"==typeof i.complete&&i.complete.call(this,jqXHR)}},s=o.find('input[type="file"]');r.data=new FormData,s.length>0&&t.each(s[0].files,(function(t,e){r.data.append(t,e),r.data.append("file_lastmodified",$ocms.isodt(e.lastModifiedDate))}));var a=o.serializeObject();t.each(a||{},(function(t,e){r.data.append(t,e)})),o.ldng(),$ocms.postXT.call(this,r)},t.fn.checkValidity=function(){var e=t(this),n=!0;return e.each((function(t,e){n=n&&e.checkValidity()})),n},t.fn.wrap=function(e,n){var i=t(this),o=$$.dc(e).attr(n||{}).insertAfter(i);return i.append(o),o}}(jQuery),$ocms.logout=function(){$ocms.postXT({url:$ocms.url("logout"),complete:function(){window.location.reload()}})},$ocms.login={send:function(t){t.preventDefault();var e=$(this);if(!0===e.find("#dbtn-confirm").hasClass("disabled"))return!1;var n=e.serializeObject();return n.loginaccount=ne(n.loginaccount,$ocms.auth.account||$ocms.auth.requestedaccount||""),n.loginaccount=ne(n.loginaccount,$ocms.auth.account||$ocms.auth.requestedaccount||""),""===ne(n.loginaccount)&&!0===bool($ocms.auth.accountrequired,!0)?(alert($t.l16),!1):($ocms.postXT({url:$ocms.url("login"),data:n,success:function(){window.location.reload()}}),!1)},uichange:function(){let t=$(this),e=t.closest("form"),n=bool($ocms.auth.accountrequired,!0),i=ne(e.find('[name="loginaccount"]').val(),$ocms.auth.account||$ocms.auth.requestedaccount||"");if(""!==i||!1===n){var o=e.find('[name="userlogin"]').empty().val(""),r=e.find('[name="username"]').empty().val(""),s=$("#dlg_userlogin_sel").empty().val(""),a=t.val()||"";if(!1===t.checkValidity()&&""===a)return;var c=t.closest("table").ldng();$ocms.postXT.call(this,{url:$ocms.url("auth"),data:{userinfo:a,account:i||""},success:function(t,e,n){if(1===t.length){var i=t[0];o.val(i.login).change().attr("required","").removeAttr("nosend"),r.val(i.name).change().attr("required","").show(),s.removeAttr("required").attr("nosend","").hide()}else t.length>0?(r.hide().removeAttr("required"),o.removeAttr("required").attr("nosend",""),0===s.length&&(s=$("").attr({name:"userlogin",size:t.length,id:"dlg_userlogin_sel",class:"form-control",required:""}).css({width:"100%","max-width":"100%",padding:"2px"}).insertAfter(r)),$.each(t,(function(t,e){var n=$("").attr({value:e.login,style:"padding-top: 2px; padding-bottom: 5px;","border-bottom":"1px solid #EEE;"}).text(e.name).appendTo(s);t%2==0&&n.css({"background-color":"#F9F9F9"})})),s.attr("required","").removeAttr("nosend")):(s.hide().attr("nosend",""),r.attr("required","").show(),o.attr("required","").removeAttr("nosend"),alert($t.l9))},error:function(t){$ocms.failure.call(this,t)},complete:function(){c.ldng(0)}})}else alert($t.l18)},sendpassword:function(t){var e=$(''),n=e.find(".form-body"),i=null;e.find("form").submit((function(t){t.preventDefault();var o=$(this).serializeObject(!0),r=null===i,s=r?"spwc":"spw";return $ocms.postXT.call(this,{url:$ocms.url(s),data:o,complete:function(){r?(n.append('Ihnen wurde ein Code per SMS zugesandt.
Bitte tragen Sie den hier ein:'),i=$('').appendTo(n)):(alert($t.l13),e.remove())},error:()=>{}}),!1})),e.find(".modal-close").click((function(){e.remove()}));var o=[];$.each($t.l7a.split("\n"),((t,e)=>{Array.prototype.push.apply(o,[$("
"),$("").text(e)])})),e.find(".modal-note").append($('').text($t.alert)).append(o),e.appendTo("body"),setTimeout((function(){$(".modal").find('input[name="lastname"]').focus()}),600)}};var $$={s:function(t){return $("").text(t)},br:function(){return $("
")},sc:function(t,e){return $("").addClass(t).text(e)},td:function(t,e){var n=$(" ");return t instanceof jQuery==!0?n.appendTo(t):"object"==typeof t?n.attr(t):"string"==typeof t&&n.text(t),"object"==typeof e?n.attr(e):"string"==typeof e&&n.text(e),n},th:function(t,e){var n=$(" ");return t instanceof jQuery==!0?n.appendTo(t):"object"==typeof t?n.attr(t):"string"==typeof t&&n.text(t),"object"==typeof e?n.attr(e):"string"==typeof e&&n.text(e),n},tdc:function(t,e,n){return $$.td(e,n).addClass(t)},td2:function(t){var e=$(' ');return"string"===$.type(t)?e.text(t):t instanceof jQuery?e.append(t):"function"==typeof t?t.call(e):e.html(" "),e},td3:function(t){var e=$(' ');return"string"===$.type(t)?e.text(t):t instanceof jQuery?e.append(t):"function"==typeof t?t.call(e):e.html(" "),e},tdtr:function(t,e){var n=$$.tr().appendTo(e);return t instanceof jQuery==!0||"string"==typeof t?t.appendTo($$.td().appendTo(n)):!0===Array.isArray(t)&&$.each(t,(function(t,e){$(e).appendTo($$.td().appendTo(n))})),n},tr:function(t,e){var n=$(" ");return t instanceof jQuery==!0?n.appendTo(t):"object"==typeof t&&n.attr(t),"object"==typeof e&&n.attr(e),n},trc:function(t,e){var n=$(" ").addClass(t);return e instanceof jQuery==!0?n.appendTo(e):"object"==typeof e&&n.attr(e),n},d:function(t){return $("").attr(t||{})},dc:function(t,e,n,i){var o=$("").addClass(t);return e instanceof jQuery==!0?o.appendTo(e):"object"==typeof e?o.attr(e):"function"==typeof e?o.click(e):"string"==typeof e&&o.text(e),"string"==typeof n?o.text(n):"object"==typeof n?o.attr(n):"function"==typeof n&&o.click(n),"string"==typeof i?o.text(i):"object"==typeof i?o.attr(i):"function"==typeof i&&o.click(i),o},df:function(t){return $(" ").attr(t||{})},opt:function(t,e,n){var i=$("");return"string"==typeof t?i.attr("value",t):"object"==typeof t&&i.attr(t),"string"==typeof e?i.text(e):"object"==typeof e&&i.attr(e),"object"==typeof n&&i.attr(n),i},eOpt:function(t){var e=$('');return t&&e.attr("selected","selected"),e},tbl:function(t){return $("
").attr(t||{})},tblc:function(t){return $("
").addClass(t)},thead:function(t){let e=$("");return t instanceof jQuery&&e.prependTo(t),e},tbody:function(t){let e=$("");return t instanceof jQuery&&e.appendTo(t),e},tblset:function(t,e){let n=$$.tbl(t||{});return e instanceof jQuery&&e.append(n),{tbl:n,hd:$$.thead().appendTo(n),bdy:$$.tbody().appendTo(n)}},i:function(t){return $("").attr(t||{})},img:function(t,e){return $("
").attr("src",t).attr(e||{})},sel:function(t){return $("").attr(t||{})},btn:function(t){return $("").attr(t||{})},a:function(t){return $("").attr(t||{})},li:function(t){return $("").attr(t||{})},ul:function(t){return $("
").attr(t||{})},nav:function(t){return $("").attr(t||{})},lbl:function(t,e){var n=$("");return"string"==typeof t&&n.text(t),"object"==typeof t?n.attr(t):"object"==typeof e&&n.attr(e),n},txt:function(t){return $("").attr(t||{})},0:function(t,e){return $("<"+t+">"+t+">").attr(e||{})},bbtn:function(t,e){return $$.btn({type:"button",class:"btn"}).addClass(e).text(t)},svg:t=>$(document.createElementNS("http://www.w3.org/2000/svg",t))};function getMonday(t){var e=(t=new Date(t)).getDay(),n=t.getDate()-e+(0==e?-6:1);return new Date(t.setDate(n))}function $lf(t){var e=void 0===t?null:"number"==typeof t&&1!==t||"boolean"==typeof cl&&!1===t;return $("#listframe").tC("hd",e).is(".hd")}function $nuf(t){if(t&&t.stopPropagation(),!$(this).is(".disabled")){var e=function(t){t.removeClass("vis").find("li.dropdown").removeClass("open").removeClass("vis").attr("aria-expanded","false")},n=$(this).parent("li.dropdown");if(n.length>0){n.tC("open"),navs=!0===n.is(".open")?"true":"false",n.attr("aria-expanded",navs);var i=n.closest("nav");i.find("li.dropdown").not(n.parentsUntil("nav")).not(n).removeClass("open").attr("aria-expanded","false"),!1===n.is(".open")&&n.find("li.dropdown").removeClass("open").attr("aria-expanded","false"),e($("nav").not(i))}else e($("nav"))}}function $tbr(){return $lf(0),$("#topbar").ocmsmenu([])}function $lfr(){return $("#sidebar").empty(),$("#listframe").removeClass("fix").addClass("hd").empty()}function $cfr(){return $tbr(),$("#contentframe").empty()}function jObj(t,e){let n={};if("{"===(t||"").substr(0,1))try{n=JSON.parse(t)}catch(t){n={}}return n[e]||""}function string(t,e){var n,i=t||"";return $.each(e||[],(function(t,e){n=new RegExp("\\{"+t.toString()+"\\}","ig"),i=i.replace(n,e)})),i}function init_tooltip(t){var e=!0===("boolean"==typeof t&&t)&&"mouse";$("[title]").qtip({position:{target:e,adjust:{x:2,y:2},viewport:!0},events:{hidden:$ocms.tooltip_hidden},effect:!1}),$("div.tooltiptext").each((function(){$(this).filter(":not(:empty)").parent().qtip({suppress:!1,content:{text:$(this).clone()},position:{target:e,adjust:{x:2,y:2},viewport:!0},events:{hidden:$ocms.tooltip_hidden}})}))}String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")},String.prototype.left=function(t){if("string"===$.type(t)){var e=this.indexOf(t);return e>0?this.slice(0,e):""}return this.substring(0,t)},String.prototype.right=function(t){if("string"===$.type(t)){var e=this.indexOf(t);return e>0?this.substring(this.length-e):""}return this.substring(this.length-t)},Array.prototype.move=function(t,e){if(e>=this.length)for(var n=e-this.length;1+n--;)this.push(void 0);return this.splice(e,0,this.splice(t,1)[0]),this},function(t){t.fn.appendToIf=function(e,n){var i=t(this),o="function"==typeof n?n(i):n;return!0===("boolean"!=typeof o||o)&&i.appendTo(e),i},t.fn.appendIf=function(e,n){var i=t(this),o="function"==typeof n?n(i):n;return!0===("boolean"!=typeof o||o)&&i.append(e),i},t.fn.rwText=function(e,n,i){var o=t(this).empty();i=t.extend({wrap:!0},i);var r=!0===Array.isArray(e)?e:(null==e?"":String(e)).split("\n");return t.each(r,(function(t,e){""!==(e||"")&&(t>0&&o.append($$.br()),o.append(!0===i.wrap?$$.s(e):e))})),n&&o.attr("title",n),o},t.fn.loadSel=function(e,n,i){if("SELECT"===t(this).prop("tagName").toUpperCase()){var o=t(this);$ocms.postXT.call(this,{url:e,data:n||{},success:function(e){t.each(e,(function(){o.append($$.opt(e.value,e.text))}))},complete:function(){o.ldng(0),"function"==typeof i&&i.call(o)}})}},t.fn.emptyWithEditors=function(e){var n=t(this);return n.find(":input.tinymce").each((function(e,n){try{var i=tinymce.get(t(n).attr("id"));i&&i.remove()}catch(e){t.noop()}})),n.empty()},t.fn.cssValue=function(t){if(this.length>0){var e=this.css(t)||"";if(""===e)return 0;var n=/(^[\d\.]*)(\D{1,3}$)/gi.exec(e);return null!==n?"rem"===n[2]?$ocms.rpx(parseFloat(n[1])):parseFloat(n[1]):!1===isNaN(e)?parseFloat(e):0}return 0},t.fn.veryInnerHeight=function(){let e=e=>t(this).cssValue(e);return t(this).innerHeight()-e("padding-top")-e("padding-bottom")},t.fn.veryInnerWidth=function(){let e=e=>t(this).cssValue(e);return t(this).innerWidth()-e("padding-left")-e("padding-right")},t.fn.marginWidth=function(){let e=e=>t(this).cssValue(e);return e("margin-left")+e("margin-right")},t.fn.marginHeight=function(){let e=e=>t(this).cssValue(e);return e("margin-top")+e("margin-bottom")},t.inArrayRegEx=function(e,n,i){var o="regexp"===t.type(e)?e:new RegExp(e);if(!n)return-1;for(var r=i=i||0;r7){i=e.split(","),o=(n||(t<0?"rgb(0,0,0)":"rgb(255,255,255)")).split(",");var c=a(i[0].slice(4)),l=a(i[1]),u=a(i[2]);return"rgb("+(s((a(o[0].slice(4))-c)*r)+c)+","+(s((a(o[1])-l)*r)+l)+","+(s((a(o[2])-u)*r)+u)+")"}var d=(i=a(e.slice(1),16))>>16,h=i>>8&255,p=255&i;return"#"+(16777216+65536*(s((((o=a((n||(t<0?"#000000":"#FFFFFF")).slice(1),16))>>16)-d)*r)+d)+256*(s(((o>>8&255)-h)*r)+h)+(s(((255&o)-p)*r)+p)).toString(16).slice(1)},t.fn.IN=function(e){return t(this).fadeIn(400,e),t(this)},t.fn.OUT=function(e){return t(this).fadeOut(400,e),t(this)},t.fn.tooltip=function(e,n){var i=!0===("boolean"==typeof e&&e)&&"mouse",o="boolean"==typeof n&&n,r=t(this);return r.each((function(){var e=o?t(this).find(".tooltiptext"):t(this).children(".tooltiptext");t(e).length>0?e.each((function(){var e=t(this);t(this).filter(":not(:empty)").parent().qtip({suppress:!1,content:{text:e.clone()},position:{target:i,adjust:{x:2,y:2},viewport:!0},events:{hidden:$ocms.tooltip_hidden},show:{effect:!1},hide:{effect:!1}}),e.remove()})):t(this).qtip({position:{target:i,adjust:{x:2,y:2},viewport:!0},events:{hidden:$ocms.tooltip_hidden},effect:!1})})),r},t.fn.rC=function(e){return t(this).removeClass(e)},t.fn.aC=function(e){return t(this).addClass(e)},t.fn.tC=function(e,n){return t(this).toggleClass(e,n)}}(jQuery),function(t){t.fn.ocmsmenu=function(e,n){var i=t(this);return $ocms.menu.call(i,e,n),i},t.fn.activatemenu=function(){var e=t(this).filter("nav");return e.find("a").not(".on").addClass("on").click($nuf),e.find(".nav-btn").not(".on").addClass("on").click((function(e){e.stopPropagation();var n=t(this);t(n.attr("data-target")).tC(n.attr("data-toggle"))})),e}}(jQuery);class ObjectArray extends Array{isEmpty(){return 0===this[0].length}static get[Symbol.species](){return Array}filter(t){return"function"==typeof t?new ObjectArray(this[0].filter(t)):this}remove(t){if("function"!=typeof t)return this;{let e=this[0].findIndex(t);for(;e>-1;)this[0].splice(e),e=this[0].findIndex(t)}}sortBy(t){return"function"==typeof t&&this[0].sort(t),this}sortString(t){return this[0].sort(((e,n)=>{let i=(e[t]||"").toString().toUpperCase(),o=(n[t]||"").toString().toUpperCase();return console.debug(i.localeCompare(o)),i.localeCompare(o)})),this}sortNum(t){return this[0].sort(((e,n)=>{let i=e[t],o=n[t];return!0===isNaN(o)&&!1===isNaN(i)||io?1:0})),this}sum(t){return this[0].reduce(((e,n)=>e+(!0===isNaN(n[t])?0:n[t])),0)}groupBy(t){return this[0].reduce((function(e,n){let i=n[t];return e[i]||(e[i]=[]),e[i].push(n),e}),{})}each(t){if("function"==typeof t){let e=!1;this[0].forEach(((n,i,o)=>{if(!1===e){let r=t(n,i,o);"boolean"==typeof r&&!1===r&&(e=!0)}}))}}get toArray(){return this[0]}}class NumArray extends Array{sum(){return this.reduce(((t,e)=>t+e))}first(){return this[0]}last(){return this[this.length-1]}average(){return this.sum()/this.length}range(){let t=this.map((t=>t)).sort();return{min:t[0],max:t[this.length-1]}}static get[Symbol.species](){return Array}}$ocms.ocmsmenu=[{lbl:"",id:"m_home",ico:"glyphicon glyphicon-home",fnc:"init:home"},{fnc:"separator"}],function(t){t.multline=function(t){let e=t.split("\n"),n=$$.d();return $.each(e,((t,e)=>{n.append($$.s(e))})),n.html()},t.tooltip_hidden=function(t,e){$(this).remove(),e.rendered=!1},t.isJSONDateString=function(t){return"string"==typeof t&&/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?)?$/.test(t)},t.failure=function(e){11110===(e.internalCode||-1)?t.login.dlg():alert($t.f1+"\n"+(e.internalText||""))},t.getScript=function(e,n){var i=[],o=[],r=function(t){return"string"==typeof t&&""!==(t||"")},s=function(t,e){!0===bool(e.condition,!0)&&(""!==(e.script||"")&&o.push({url:e.script,module:e.module||""}),!0===r(e.css||"")?i.push(e.css):!0===Array.isArray(e.css)&&Array.prototype.push.apply(i,e.css.filter(r)))};!0===r(e||"")?o.push(e):!0===Array.isArray(e)?$.each(e,s):"object"==typeof e&&""!==(e.script||"")&&s(0,e);let a=[];$.each(i,(function(t,e){""!==(e||"")&&a.push(loadCSS(e))}));let c=o.map((function(e,n){let i=e.url,r=e.module||"";if(""===r){let t=new Promise((function(t,e){try{!async function(){$.ajax({url:i,dataType:"script",success:function(){t(o)},error:function(){e(o)},timeout:3e4})}()}catch(t){console.debug(t.message+"%o",t)}}));return t}return t.loadmodule(r,i,e.alias)}));Promise.all(c).then(n)},t.loadmodule=function(e,n,i){let o=new Promise((function(o,r){!async function(){try{let s=(n.startsWith("/")||n.startsWith(".")?"":"/")+n;import(s).then((n=>{t[e]=n[i||"default"],o(e)})).catch((t=>{console.debug(t.message+"%o",t),r(e)}))}catch(t){console.debug(t.message+"%o",t)}}()}));return o},t.ocms_auth=function(e,n,i,o){!1===$.isPlainObject(t.auth.modules)&&(t.auth.modules={});var r=0;t.auth.modules[e+(i||"")]?((r=t.auth.modules[e+(i||"")])<2&&(i||"")===auth.guid&&(r=2),r>=(n||0)&&o(false)):t.postXT({url:t.url("auth"),data:{module:e,person_guid:i||""},success:function(s){r=s[e],t.auth.modules[e+(i||"")]=r,r<2&&(i||"")===t.auth.person_guid&&(r=2),r>=(n||0)&&o(false)},error:function(e){t.failure.call(this,e)}})},t.auth.locale="de",t.ocms_prepauth=function(e,n,i){t.postXT({url:t.url("auth"),data:{fn:"csv",modules:e,person_guid:n||""},success:function(e){t.ocms_regauth(e)},error:function(e){t.failure.call(this,e)},complete:function(){i()}})},t.ocms_regauth=function(t){$.each(t||{},(function(t,e){auth.modules[t]=parseInt(e)}))},t.init=function(e){var n="string"==typeof e?e:(e.data||{}).fn||"";""!==n&&("home"===n?($cfr(),$lfr(),$("#topbar").ocmsmenu([],!0),$("#activemodule").text($t.ov),t.ov.call($("#contentframe"))):($cfr(),$lfr(),$("#topbar").ocmsmenu([]),t.postXT({url:t.url(n+"/auth"),success:function(e){void 0===t[n]&&(t[n]={}),t[n].auth=e,e.manage>0&&t.getScript({module:n,script:["web/imdl",n,t.auth.locale||"de","js"].join("."),css:["web/imdl",n,"css"].join("."),condition:"function"!=typeof t[n].init2},(function(){t[n].init2()}))},error:function(){$("#contentframe").empty()}})))},t.menuarray=function(t){this.array=[],this.sep=function(){this.length>0&&"separator"!==this.array[array.length-1].fnc&&this.push({fnc:"separator"})},this.push=function(t){return void 0===t?null:(!0===Array.isArray(t)?Array.prototype.push.apply(this.array,t):"object"==typeof t&&this.array.push(t),t)},this.unshift=function(t){return void 0===t?null:(!0===Array.isArray(t)?Array.prototype.unshift.apply(this.array,t):"object"==typeof t&&this.array.unshift(t),t)},this.push(t)},t.menu=function(e,n){e=e||[];var i=$(this).removeClass("vis");if(!0===bool(n,!0)&&!1===i.is("#mainmenu")&&i.empty(),!1===bool(n,!1)&&i.is("#sidebar,#topbar")&&(e.unshift({id:"sbctrl",glyph:"glyphicon-th-list",aclass:"fbtn",fnc:function(){$lf()}}),$lf(0)),0===(e||[]).length)i.empty().addClass("hd");else{i.removeClass("hd");var o=!0===i.is("nav")?i:i.children("nav");1!==o.length&&(o=$("").tC("nv",i.is("#sidebar")).tC("ctxt",i.is("#topbar")).appendTo(i));var r,s=$$.ul().appendTo(o),a=function(t,e){var n=$(this).addClass("dropdown submenu");t.append($$.sc("caret dd")).addClass("dds dropdown-toggle").attr({"aria-expanded":"false"}),""!==(e.ico||"")&&t.prepend($$.sc("ico "+e.ico));var i=$$.ul({class:"dropdown-menu",role:"menu"}).appendTo(n);$.each(e.itm||[],(function(t,e){r.call(i,e)}))},c=function(t){$(this).tC("disabled","boolean"==typeof t.disabled?t.disabled:"string"==typeof t.disabled&&"subs"===t.disabled&&0===(t.itm||[]).length)};r=function(e){var n,i=$$.li({id:e.id}).attr(e.attr||{}).addClass(e.lclass).appendTo($(this)),o="string"==typeof e.fnc&&""!==e.fnc?e.fnc.split(":")[0]:"";""!==o&&"init"!==o?i.attr("role",o).appendIf($$.s(e.lbl),""!==ne(e.lbl)):(n=$$.a({class:"on",role:"button"}).addClass(e.aclass).appendTo(i).append($$.s(e.lbl)),c.call(n,e),(e.itm||[]).length>0&&a.call(i,n,e),n.click($nuf),"function"==typeof e.fnc?n.click(e.data||{},e.fnc):"init"===o&&n.click($.extend({},e.data||{},{fn:e.fnc.split(":")[1]}),t.init))},$.each(e,(function(e,n){var i,o=$$.li({id:n.id}).attr(n.attr||{}).addClass(n.lclass),a="string"==typeof n.fnc&&""!==n.fnc?n.fnc.split(":")[0]:"";if(""!==a&&"init"!==a)o.attr("role",a).appendIf($$.s(n.lbl),""!==ne(n.lbl));else{if(i=$$.a({class:"on",role:"button"}).addClass(n.aclass).appendTo(o),c.call(i,n),""!==(n.lbl||"")&&i.append($$.s(n.lbl)),""!==(n.ico||"")&&i.prepend($$.sc("ico "+n.ico)),""!==(n.glyph||"")&&i.prepend($$.sc("glyphicon "+n.glyph)),(n.itm||[]).length>0){o.addClass("dropdown"),i.append($$.sc("caret dd")).addClass("dds dropdown-toggle").attr({"aria-expanded":"false"});var l=$$.ul({class:"dropdown-menu",role:"menu"}).appendTo(o);$.each(n.itm||[],(function(t,e){r.call(l,e)}))}(n.sel||[]).length>0||(i.click($nuf),"function"==typeof n.fnc?i.click(n.data||{},n.fnc):"init"===a&&i.click($.extend({},n.data||{},{fn:n.fnc.split(":")[1]}),t.init))}o.appendTo(s)})),o.activatemenu()}},t.easytbl=(t,e)=>{e=e||{};let n=$$.tbl().addClass(e.class).css("border-collapse","collapse"),i=($$.tbody(n),!0===bool(e.frame,!1)?{padding:"5px",border:"1px solid #727272"}:{});if(!0===Array.isArray(e.header)){let t=$$.thead(n);$.each(e.header,((n,o)=>$$.th(t).css(e.cellcss||i).rwText(o)))}else if(!0===bool(e.header,!1)&&(t||[]).length>0){let o=$$.thead(n);$.each(Object.keys(t[0]),((t,n)=>$$.th(o).css(e.cellcss||i).rwText(n)))}return $.each(t||[],((t,o)=>{let r=$$.tr();$.each(o,((t,n)=>{n=n||"";let o=$$.td(r).css(e.cellcss||i);n instanceof jQuery?o.append(n):"string"==typeof n&&("<"===n.substring(0,1)?o.append(n):o.text(n))})),n.append(r)})),n},t.dlgtbl=(e,n,i)=>{i=i||{};let o=t.easytbl(e,i);t.dlg(o,$.extend({title:n},i))},t.dlg=function(t,n){n=n||{};let i=$("body > .modal").length>0,o=t=>typeof n[t],r=t=>"function"===o(t);if(!0===bool(n.exclusive,!0)&&!0===i)return void alert($t.dbldlg||"Es ist bereits ein Dialog geöffnet");let s=$$.dc("modal",$("body")),a=$$.dc("modal-dialog",s);!1===isNaN(n.zindex)?s.css("zIndex",n.zindex):!0===i&&s.css("zIndex",parseInt($("body > .modal:last").cssValue("zIndex"))+200),!1===isNaN(n.zindex_min)&&s.cssValue("zIndex")').appendTo(d)),""!==ne(n.title)&&(c=$$.dc("modal-header",d),$("").text(n.title).appendTo(c));let p=$$.dc("modal-body",d),f=$$.dc("modal-footer",d);t instanceof jQuery==!0&&p.append(t);let m=function(t){t&&"function"==typeof t.stopPropagation&&t.stopPropagation(),a.removeClass("in"),!0===r("closing")&&n.closing.call(d),p.hide().emptyWithEditors(),s.remove(),!0===r("close")&&n.close.call(d)};if(d.find(":input[required]").length>0&&($$.dc("note_required",f).append($$.sc("ind_required","*")).append($$.s($t.t1||"Eingabe erforderlich")),$$.dc("note_invalid",f).append($$.s($t.t2||"Bitte überprüfen Sie Ihre Eingaben im Formular."))),!0===r("cancel")){$$.bbtn(n.cancelbutton||"Abbrechen","cancel").attr({type:"button",role:"cancel"}).appendTo(f).click((function(t){n.cancel.call(d,t);t.stopPropagation(),m()}))}if(!0===r("confirm")){let t=$$.bbtn(n.button||"OK","confirm").attr({type:!0===bool(n.form,!1)?"submit":"button",role:"confirm"}).appendTo(f);!0===h?(d.submit((function(t){try{n.confirm.call(d,t)}finally{t.preventDefault()}return!1})),d.on("modal_submit",(function(){n.confirm.call(d,e)}))):(t.click((function(t){n.confirm.call(d,t);t.stopPropagation()})),d.on("modal_submit",(function(){t.click()})))}else!0===h&&d.submit((function(t){return t.preventDefault(),!1}));return d.on("modal_close",(function(){m()})),l.click(m),!0===r("opening")&&n.opening.call(d),a.addClass("in"),ne(n.mode).indexOf("maxbody")>-1&&p.css("min-height",(u.height()-c.outerHeight()-f.outerHeight()).toString()+"px"),!0===r("open")&&n.open.call(d),{hd:c,bdy:p,ft:f,ct:u,dlg:a,c:d}},t.mform=function(e){let n=$$.dc("form-body"),i=Array.isArray(e)?e:e instanceof fields_definition?e.fields:[];return $.each(i||[],(function(e,i){let o=i.type||"";if("ignore"===o)return!0;let r=$$.dc("form-group",n),s=i.id||"dlg_"+(i.name||"")+("html"===i.type?"_"+(65536*(1+Math.random())||0).toString(16).substr(9):""),a=$$.lbl(i.label||i.name,{for:s}).appendTo($$.dc("form-itm",r)),c=$$.dc("form-itm",r),l=$$.i({id:s,name:i.name,placeholder:i.placeholder,type:i.type});switch(o){case"email":i.pattern=ne(i.pattern,"[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$");break;case"url":i.pattern=ne(i.pattern,"https?://.+");break;case"number":i.pattern=ne(i.pattern,"[-+]?[0-9]*[.,]?[0-9]*"),l.attr("type","text"),l.attr("inputmode","decimal"),l.attr("step",i.precision||"any"),l.attr("data-format","float");break;case"integer":case"int":i.pattern=ne(i.pattern,"[-+]?[0-9]*"),l.attr("type","number"),l.attr("data-format","integer");break;case"date":if(""!==ne(i.pattern,$t.datepattern)&&(i.pattern=ne(i.pattern,"("+$t.datepattern+")|([0-9]{4}.(0[1-9]|1[012]).(0[1-9]|1[0-9]|2[0-9]|3[01]))")),""!==ne(i.placeholder,$t.dateplaceholder)&&l.attr("placeholder",ne(i.placeholder,$t.dateplaceholder)),"string"==typeof i.value){var u=i.value.substr(0,10);i.value="date"!==l.prop("type")?fdt(u+"T00:00:00",ne(i.dateformat,$t.dateformat)):u}l.attr("data-format","date:"+ne(i.dateformat,$t.dateformat)+";yyyy-MM-dd");break;case"datetime":l.attr("type","datetime-local"),""!==ne(i.pattern,$t.datetimepattern)&&(i.pattern=ne(i.pattern,"("+$t.datetimepattern+")|([0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])\\s([0-5][0-9]):([0-5][0-9]))")),""!==ne(i.placeholder,$t.datetimeplaceholder)&&l.attr("placeholder",ne(i.placeholder,$t.datetimeplaceholder)),"string"==typeof i.value&&"T"===i.value.substr(10,1)&&(i.value="datetime"!==l.prop("type").substr(0,8)?fdt(i.value,ne(i.datetimeformat,$t.datetimeformat)):i.value),l.attr("data-format","datetime:"+ne(i.datetimeformat,$t.datetimeformat)+";yyyy-MM-dd HH:mm:ss");break;case"hidden":r.addClass("hd");break;case"html":case"text":l=$$.txt({id:s,name:i.name,placeholder:i.placeholder,type:i.type}),l.tC("tinymce","html"===i.type);break;case"bool":case"boolean":i.url=[{value:"true",label:($t||{}).true||"Yes"},{value:"false",label:($t||{}).false||"No"}],"boolean"==typeof i.value&&(i.value=i.value?"true":"false");case"select":l=$$.sel({id:s,name:i.name,type:i.type}),!1===bool(i.required,!1)&&$$.eOpt().appendTo(l);try{var d=function(t){!0===Array.isArray(t)&&$.each(t,(function(t,e){"string"==typeof e?$$.opt(e,e).appendTo(l):!0===Array.isArray(e)?$$.opt(e[0],e[1]).appendTo(l):"object"==typeof e&&$$.opt(e.value,e.label||e.text).appendTo(l)}))};!0===Array.isArray(i.url)?d(i.url):"function"==typeof i.url?i.url.call(l):"string"==typeof i.url&&t.postXT({url:i.url,success:d})}catch(t){$.noop()}break;default:""!==ne(i["max-length"])&&l.attr("max-length",i["max-length"])}""!==ne(i.pattern)&&l.attr("pattern",i.pattern),l.val(i.value).change(),l.change((function(){$(this)[0].setCustomValidity("")})),l.addClass("form-control").prop("required",bool(i.required,!1)).prop("readonly",bool(i.readonly,!1)).appendTo(c),!0===bool(i.required,!1)&&a.append($$.sc("ind_required","*")),"object"==typeof i.attr&&l.attr(i.attr),"object"==typeof i.prop&&l.prop(i.prop),"string"==typeof i.class&&l.addClass(i.class),"function"==typeof i.change&&(l.change(i.change),!0===bool(i.applychange,!1)&&void 0!==i.value&&l.change()),""!==(i.note||"")&&$$.dc("form-note",c).rwText(i.note),"function"==typeof i.complete&&i.complete.call(l)})),n},t.initMCE=function(t,e){t=$(t),e=e||{};try{let n={target:t[0],inline:!1,width:e.width||"100%",statusbar:!1,document_base_url:window.location.origin+"/",content_style:"ph:before {content: '«'; color: #BBB; font-style:italic; } ph:after {content: '»'; color: #BBB; font-style:italic; } ph { color: #AAA; font-style:italic; }",relative_urls:!1,remove_script_host:!1};!0===bool(e.hidemenu,!1)&&(n.menubar=!1,n.menu={}),!0===bool(e.hidetoolbar,!1)&&(n.toolbar=!1),$.extend(n,e||{}),tinymce.init(n)}catch(t){alert(t.message)}},t.dlgform=function(e,n){n=n||{};let i,o=$$.dc("frm").append(t.mform(e||[]).addClass("stacked"));n.addcontent instanceof jQuery&&o.append(n.addcontent),"function"==typeof n.submit?i=n.submit:"function"==typeof n.success&&(i=function(e){var i=$(this).ldng(1),o=$.extend({loginaccount:t.auth.account||""},i.serializeObject(bool(n.checkvalidity,!0),{typedvalues:bool(n.typedvalues,!1)}));""!==(n.url||"")?t.postXT({url:n.url,data:o,success:function(t){n.success.call(this,t),i.trigger("modal_close")},error:function(){alert($t.l17)},complete:function(){i.ldng(0)},timeout:6e4}):(n.success.call(this,o),i.trigger("modal_close"))});let r={form:!0,title:n.title||"",button:n.button||$t.submit,confirm:i,size:n.size||[500,600],open:function(){let e=$(this).find(".tinymce");e.length>0&&t.initMCE(e,n.tinymce||{})}};return t.dlg.call(this,o,r)},t.login.dlg=function(e){e=e||{};let n=[{name:"userinfo",label:$t.l1,type:"string",value:t.auth.login,change:t.login.uichange,required:!0},{name:"userlogin",type:"hidden",required:!0,value:t.auth.login},{name:"username",type:"string",label:$t.l4,required:!0,readonly:!0,placeholder:$t.l5,value:t.auth.fullname_rev},{name:"userpass",type:"password",label:$t.l3,required:!0,placeholder:$t.l3}];""===(t.auth.account||"")&&n.unshift({id:"dlg_loginaccount",name:"loginaccount",type:"string",required:!0,value:t.auth.account});let i=$$.dc("frm").append(t.mform(n).addClass("stacked")),o=t.dlg.call(this,i,{form:!0,title:$t.l0,button:$t.submit,confirm:function(n){var i=$(this).ldng(1),o=$.extend({loginaccount:t.auth.account||""},i.serializeObject());t.postXT({url:"/vt/login",data:o,success:function(n){""!==((n||{}).login||"")&&(i.trigger("modal_close"),t.auth=n,"object"==typeof e.ajo&&(e.ajo.islogin,$.ajax(e.ajo)))},error:function(){alert($t.l17)},complete:function(){i.ldng(0)},timeout:6e4})},size:[500,600]}),r=$$.dc("modal-content").css("height","auto").attr("novalidate","true").append($$.dc("modal-header").appendIf($("").text(t.auth.accountname),""!==(t.auth.accountname||"")).append($("Vereinsmanager
")));o.dlg.prepend(r)},t.addNoEntryInfo=function(t){$(this).append($$.dc("noentryinfo").text(t||$t.t11))}}($ocms),Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector),Element.prototype.closest||(Element.prototype.closest=function(t){var e=this;do{if(Element.prototype.matches.call(e,t))return e;e=e.parentElement||e.parentNode}while(null!==e&&1===e.nodeType);return null}),function(t,e){var n,i;"object"==typeof window&&(window[t]=(n=function(t){var e=window,n=document.body,i=document.documentElement,o=Math.max(0,e.pageXOffset||i.scrollLeft||n.scrollLeft||0)-(i.clientLeft||0),r=Math.max(0,e.pageYOffset||i.scrollTop||n.scrollTop||0)-(i.clientTop||0);return{x:t?Math.max(0,t.pageX||t.clientX||0)-o:0,y:t?Math.max(0,t.pageY||t.clientY||0)-r:0}},(i=function(t,e){t&&t instanceof Element&&(this._container=t,this._options=e||{},this._clickItem=null,this._dragItem=null,this._showDragItem="boolean"!=typeof this._options.dragItem||!1!==this._options.dragItem,this._hovItem=null,this._sortLists=[],this._click={},this._dragging=!1,this._dragHandleClass=this._options.dragHandleClass||"",this._parentident=this._options.parentident||"",this._swapdone="function"==typeof this._options.swapdone?this._options.swapdone:null,this._onend="function"==typeof this._options.onend?this._options.onend:null,this._container.setAttribute("data-is-sortable",1),this._container.classList.add("sortable"),this._container.style.position="static",window.addEventListener("mousedown",this._onPress.bind(this),!0),window.addEventListener("touchstart",this._onPress.bind(this),!0),window.addEventListener("mouseup",this._onRelease.bind(this),!0),window.addEventListener("touchend",this._onRelease.bind(this),!0),window.addEventListener("mousemove",this._onMove.bind(this),!0),window.addEventListener("touchmove",this._onMove.bind(this),!0))}).prototype={constructor:i,toArray:function(t){t=t||"id";for(var e=[],n="",i=0;ii.left&&ei.top&&n0?a.mousedown(c).addClass("dctrl"):s.mousedown(c).addClass("dctrl"),t(this)}}(jQuery),$(document).ready((function(){$("html").click((function(t){$nuf()})),$("#listframe").click((function(t){t.stopPropagation(),$nuf()})),$("#mainmenu").ocmsmenu($ocms.ocmsmenu),$("#mainmenu").activatemenu()})),$.extend($t,{m_inv:"Rechnungen",m_req:"Aufträge",m_rep:"Berichte",m_todo:"ToDos",m_bcd:"BankBuchungen",rsp:"Passwort ändern",pnm:"Die Passwörter stimmen nicht überein",cps:"Das neue Passwort wurde gespeichert.",pwr:"Bitte wählen Sie ein starkes Passwort (min 8 Zeichen, davon jeweils min 2 Zahlen, kleine und große Buchstaben, Sonderzeichen sind optional).",smsc:"Sie beötigen für diese Funktion einen SMS-Code.\nSoll dieser nun versandt werden?",wdc:"Doppelt klicken, um die Box zu aktualisieren.",wdg:{}}),$t.rspf={sms:"Der SMS-Code konnte nicht bestätigt werden",valid:"Das alte Passwort ist nicht korrekt",requirements:"Das Passwort entspricht nicht den Anforderungen.\n"+$t.pwr},$fd={rsp:new fields_definition("","",[{name:"opw",label:"aktuelles Passwort",type:"password",required:!0,attr:{"auto-complete":"current-password"}},{name:"npw",label:"neues Passwort",type:"password",required:!0,pattern:"(.{6,})",attr:{"auto-complete":"new-password"}},{name:"npwc",label:"neues Passwort (Bestätigung)",type:"password",required:!0,attr:{"auto-complete":"new-password"},note:$t.pwr},{name:"code",label:"SMS-Code",type:"string",required:!0,attr:{"auto-complete":"one-time-code"}}])},$ocms.init=function(t){var e="string"==typeof t?t:(t.data||{}).fn||"";""!==e&&("home"===e?($cfr(),$lfr(),$("#topbar").ocmsmenu([],!0),$("#activemodule").text($t.ov),$fis.ov()):($cfr(),$lfr(),$("#topbar").ocmsmenu([]),$ocms.postXT({url:$ocms.url(e+"/auth"),success:function(t){void 0===$ocms[e]&&($ocms[e]={}),$ocms[e].auth=t,t.manage>0&&$ocms.getScript({module:e,script:["/web/fis",e,$ocms.auth.locale||"de","js"].join("."),css:["/web/fis",e,"css"].join("."),condition:"function"!=typeof $ocms[e].init2},(function(){$ocms[e].init2()}))},error:function(){$("#contentframe").empty()}})))};var $fis={auth:{},db:function(){$("#mainmenu_activemodule").text($t.ov);let t=$(this).empty(),e=$$.d({id:"dashboard_frame"}).appendTo(t);$ocms.postXT({url:$ocms.url("wdg/my"),success:function(t){$.each(t,(function(t,n){var i=$$.dc("wdg_frame",e,{"data-wdg":n}).ldng(1);$ocms.wdg.call(i,{wdg:n})}))},loading:e})},ValidateEmail:function(t){return!!/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(t)},cf:t=>{let e=$("#contentframe");return!0===bool(t,!1)&&e.empty().rC("hd"),e},lf:t=>{let e=$("#listframe");return!0===bool(t,!1)&&e.empty().aC("hd").rC("fix"),e},frm_edit:function(t){let e=$fis.cf(!1),n=e.children(".cfrm"),i=e.children(".edit_frm");return n.length<1?n=$$.dc("cfrm hd").prependTo(e):!0===bool(t,!1)&&n.empty(),i.length<1&&(i=$$.dc("edit_frm").insertAfter(n)),i.empty()},frm_list:function(t,e){let n=$fis.cf(!1),i=n.children(".cfrm"),o=n.children(".list_frm");return i.length<1?i=$$.dc("cfrm hd").prependTo(n):!0===bool(t,!1)&&i.empty(),!0===bool(e,!1)&&n.children(".edit_frm").remove(),o.length<1&&(o=$$.dc("list_frm").appendTo(n)),o.empty()},lfm:()=>{let t=$fis.lf(!1),e=t.children(".lfrm");return e.length<1&&(e=$$.dc("lfrm").prependTo(t)),e},getAuth:(t,e)=>new Promise(((n,i)=>{$fis.auth[t]&&!1===bool(e,!1)?n($fis.auth[t]||-1):$ocms.postXT({url:$ocms.url("auth"),data:{module:t},success:e=>{$fis.auth[t]=e.auth||-1,n($fis.auth[t]||-1)},error:()=>{i()}})})),prepAuth:t=>new Promise(((e,n)=>{$ocms.postXT({url:$ocms.url("auth"),data:{module:t,array:1},success:t=>{$.extend($fis.auth,t||{})},complete:()=>{e()}})})),isAuth:(t,e)=>($fis.auth[t]||-1)>=(e||1),resetPass:function(t,e){confirm($t.smsc)&&($ocms.postXT({url:$ocms.url("account/sms"),data:{fn:"pwc"}}),$ocms.dlgform($fd.rsp.clone(),{title:$t.rsp||"",submit:function(t){var e=$(this).ldng(1),n=$.extend({loginaccount:$ocms.auth.account||""},e.serializeObject(!0,{typedvalues:!0}));(n.npw||"")!==(n.npwc||"")?e.find('input[name="npw"]:first')[0].setCustomValidity($t.pnm):$ocms.postXT({url:$ocms.url("account/changepassword"),data:n,success:function(t){alert($t.cps),e.trigger("modal_close")},error:function(t){alert($t.rspf[t.getResponseHeader("x-ocms-std")])},complete:function(){e.ldng(0)},timeout:6e4})}}))},wdg:function(t){let e=$(this).empty();$ocms.postXT({url:$ocms.url("wdg/one"),data:{short_name:t.wdg},timeout:9e4,success:function(n,i,o){let r=t.wdg,s=n[r];if(!s)return void e.ldng(0);let a=$.inArrayRegEx("dblwidth",s.rendering_options)>-1,c=$.inArrayRegEx("tiny",s.rendering_options)>-1;e.toggleClass("dbl",a&&!c).toggleClass("tny",c);$$.dc("wdg_hd",e,{title:ne(s.description,$t.wdc)}).toggleClass("dbl",a).text(ne(s.name,t.wdg)).dblclick((function(t){t.stopPropagation(),$fis.wdg.call(e,{wdg:r})}));let l=$$.dc("wdg_cnt",e).toggleClass("dbl",a).hide(),u=$.inArrayRegEx("bgcolor",s.rendering_options);switch(u>-1&&l.css("backgroundColor",s.rendering_options[u].toString().right(":")),s.type){case"table":var d=$$.tblset({},l),h=$$.tr().appendTo(d.hd),p=$t.wdg[r.indexOf("wdg_ev_")>=0?"wdg_ev_":r]||{};$.each(s.columns,(function(t,e){var n=p[e]?p[e].label:e;$$.th().text(n).appendTo(h)})),$.each(s.data,(function(t,e){var n=$$.tr().appendTo(d.bdy);$.each(s.columns,(function(t,i){var o=$$.td().appendTo(n);e[i]instanceof Date||!0===$ocms.isJSONDateString(e[i])?o.text(fdt(e[i],$t.dateformat)):o.rwText(e[i])}))})),$.inArray("firstrow_bold",s.rendering_options)>-1&&h.nextAll("tr:first").css("font-weight","bold");break;case"ind":$$.dc("ind",l).addClass("sts_"+(s.data.status||"")).append([$$.dc("ind").text(s.data.value),$$.lbl(s.data.label)]);break;case"image_url":l.css("background","url('"+s.url+"') no-repeat center center transparent");break;case"image_base64":l.css("background","url('data:image/png;base64,"+s.image+"') no-repeat center center transparent");break;case"html":if(l.html(s.html),$.inArray("reload_10min",s.rendering_options)>-1){var f=l.find("iframe");setTimeout((function(){f.attr("src",(function(t,e){return e}))}),6e5)}}$.inArray("reload_30min",s.rendering_options)>-1&&"html"!==s.type&&setTimeout((function(){$fis.wdg.call(e,{wdg:r})}),18e5),l.slideDown(150)},error:function(t){e.slideUp(150),$fis.failure.call(this,t)},complete:function(){e.ldng(0)}})},ov:function(){$fis.lf(!0);let t=$("#contentframe").empty(),e=$$.d({id:"dashboard_frame"}).appendTo(t);$ocms.postXT({url:$ocms.url("wdg/my"),success:function(t){$.each(t,(function(t,n){var i=$$.dc("wdg_frame",e,{"data-wdg":n}).ldng(1);$fis.wdg.call(i,{wdg:n})}))},loading:e})}};$fis.notifications={connection:null,init:function(){"undefined"!=typeof signalR&&null===this.connection&&$ocms.auth.useraccount_id&&(this.ensureFrame(),this.connection=(new signalR.HubConnectionBuilder).withUrl("/notifications").withAutomaticReconnect().build(),this.connection.on("notification",(t=>{this.push(t)})),this.connection.onclose((()=>{console.warn("Notification connection closed; retrying in 5s."),this.connection=null,setTimeout((()=>this.init()),5e3)})),this.start())},start:function(){this.connection.start().catch((t=>{console.warn("Notification connection failed to start; retrying in 5s.",t),this.connection=null,setTimeout((()=>this.init()),5e3)}))},ensureFrame:function(){$("#notification_frame").length<1&&$("",{id:"notification_frame"}).appendTo($("footer:first").length?"footer:first":"body")},push:function(t){this.ensureFrame(),t=t||{};let e=$("",{class:"notification_item"}).addClass((t.severity||"info").toLowerCase()).append($("",{type:"button",class:"notification_close",text:"×"})).append($("",{class:"notification_title",text:t.title||"Info"})).append($("",{class:"notification_message",text:t.message||""}));e.find(".notification_close").on("click",(function(){e.remove()})),$("#notification_frame").prepend(e),setTimeout((function(){e.fadeOut(150,(function(){e.remove()}))}),9e3)}},$fis.draft={connection:null,active:null,init:function(){"undefined"!=typeof signalR&&null===this.connection&&$ocms.auth.useraccount_id&&(this.connection=(new signalR.HubConnectionBuilder).withUrl("/draftpreview").withAutomaticReconnect().build(),this.connection.on("draftReady",(t=>this._dispatch("onReady",t,(t=>t.version)))),this.connection.on("draftExpiring",(t=>this._dispatch("onExpiring",t,(t=>t.secondsLeft)))),this.connection.on("draftClosed",(t=>this._dispatch("onClosed",t,(t=>t.reason)))),this.connection.onreconnected((()=>{this.active&&this._invoke("JoinDraft",this.active.token)})),this.connection.onclose((()=>{console.warn("Draft connection closed; retrying in 5s."),this.connection=null,setTimeout((()=>{this.init(),this.active&&this.bind(this.active.token,this.active)}),5e3)})),this.start())},start:function(){this.connection.start().then((()=>{this.active&&this._invoke("JoinDraft",this.active.token)})).catch((t=>{console.warn("Draft connection failed to start; retrying in 5s.",t),this.connection=null,setTimeout((()=>this.init()),5e3)}))},bind:function(t,e){t&&(this.active=$.extend({token:t},e||{}),null===this.connection&&this.init(),this._invoke("JoinDraft",t))},release:function(t){!this.active||t&&this.active.token!==t||(this.active=null),this._invoke("LeaveDraft",t)},_invoke:function(t,e){e&&this.connection&&"Connected"===this.connection.state&&this.connection.invoke(t,e).catch((e=>console.warn("Draft "+t+" failed",e)))},_dispatch:function(t,e,n){e=e||{},this.active&&this.active.token===e.token&&"function"==typeof this.active[t]&&this.active[t](n(e))}},Array.prototype.push.apply($ocms.ocmsmenu,[{lbl:$t.m_inv,id:"m_inv",fnc:"init:inv",ico:"glyphicon glyphicon-list-alt"},{lbl:$t.m_req,id:"m_req",fnc:"init:req",ico:"glyphicon glyphicon-eur"},{lbl:$t.m_bcd,id:"m_bcd",fnc:"init:bam",ico:"glyphicon glyphicon-indent-right"},{fnc:"separator"},{lbl:$t.m_rep,id:"m_rep",fnc:"init:rep",ico:"glyphicon glyphicon-dashboard"},{fnc:"separator"},{lbl:$t.m_todo,id:"m_todo",fnc:()=>{$("#contentframe").empty().load($ocms.url("todos")),$("#listframe").rC("fix").aC("hd")},ico:"glyphicon glyphicon-sunglasses"}]),$(document).ready((function(){$fis.notifications.init(),$fis.draft.init(),$fis.ov()}));
\ No newline at end of file
diff --git a/Fuchs/wwwroot/web/fis.req.de.js b/Fuchs/wwwroot/web/fis.req.de.js
index 791bc2e..5fbd85d 100644
--- a/Fuchs/wwwroot/web/fis.req.de.js
+++ b/Fuchs/wwwroot/web/fis.req.de.js
@@ -36,6 +36,7 @@ let $rct = {
combP: 'Positionen zusammenfassen',
toSetP: 'Auf Setpreis umstellen (Positionen ohne Preis)',
toSetPc: 'Der Set-Preis wird auf die Summe seiner Positionen gesetzt und die Positionen selbst verlieren ihren Preis. Das ist nicht rückgängig zu machen (der Betrag kann danach nur noch manuell geändert werden). Fortfahren?',
+ toSetMc: 'Jeder Leistungsauftrag wird zu einer Set-Position mit der Summe als Preis zusammengefasst. Das ist nicht rückgängig zu machen (die Set-Preise können danach nur noch manuell geändert werden). Fortfahren?',
iSum: 'Zwischensumme',
dtRel: 'Freigegeben am: ',
dtCr: 'Erstellt am: ',
@@ -151,7 +152,6 @@ let $ict = {
setm: 'Set-Preisanzeige',
setmo: {
setprice: 'Set mit Preis – Positionen ohne Preis',
- itemprices: 'Positionen mit Preis – Set als Überschrift',
setonly: 'Nur Set mit Preis – Positionen ausgeblendet'
},
ctp: 'Ansprechpartner festlegen',
@@ -654,10 +654,13 @@ $inv.d = {
return h;
},
/* Seed the authoritative server session from the assembled editor payload. Called
- once from invSumUpdate on open; thereafter the backend is the source of truth. */
+ once from invSumUpdate on open; thereafter the backend is the source of truth.
+ The in-flight ajax promise is stashed on 'dseedpromise' so a delta sent (e.g. via
+ a context-menu action) before seeding has actually completed can wait for the token
+ instead of silently no-op'ing (see $inv.d.sync). */
seed: function (payload) {
let l = $inv.d.layout(); l.aC('freeze');
- $ocms.postXT({
+ let p = $ocms.postXT({
url: $ocms.url('inv/dopen'), data: { payload: JSON.stringify(payload) }, success: (r) => {
$inv.d.tbl().data('dtoken', r.token).data('dver', r.version).data('dhashes', $inv.d.hashes()).data('dorder', $inv.d.order());
$fis.draft.bind(r.token, {
@@ -666,8 +669,10 @@ $inv.d = {
onClosed: (reason) => $inv.d.closed(reason)
});
$inv.d.refresh();
- }, error: () => { l.rC('freeze'); }, complete: () => { $inv.d.tbl().removeData('dseeding'); }
+ }, error: () => { l.rC('freeze'); }, complete: () => { $inv.d.tbl().removeData('dseeding').removeData('dseedpromise'); }
});
+ $inv.d.tbl().data('dseedpromise', p);
+ return p;
},
/* Re-fetch the authoritative state and render the totals footer + validation from it. */
refresh: function (cb) {
@@ -681,11 +686,21 @@ $inv.d = {
},
applyState: function (state) {
let tbl = $inv.d.tbl(); if (tbl.length < 1) { return; }
+ /* Concurrent refreshes (one per flushed block plus one for a follow-up delta such as
+ item.setprice, and SignalR draftReady on top) can have their dstate responses arrive
+ out of order. Applying a response older than the version already rendered would
+ silently roll back a just-applied server-side mutation (e.g. a set-price conversion
+ reverting to its pre-conversion 0/individually-priced state) — so stale responses are
+ dropped here instead of rendered. */
+ let curVer = tbl.data('dver');
+ if (typeof curVer === 'number' && typeof state.version === 'number' && state.version < curVer) {
+ return;
+ }
tbl.data('dver', state.version).data('serverSums', state.sums);
$inv.d.footer(tbl, state.sums || {}, state.admin || {});
$inv.d.notes(state.notes || []);
$inv.d.validation(state.validation || []);
- $inv.d.applyPositions(tbl, state.req || []);
+ $inv.d.applyItems(tbl, state.req || []);
$inv.d.applySetDisplay(tbl, state.setDisplay || {});
/* Keep the menu's "Set-Preisanzeige" entry in sync with the authoritative admin.setmode:
hides it right after a mode switch, and restores it if a discard reverted the draft to
@@ -705,19 +720,60 @@ $inv.d = {
/* Push the server's authoritative position numbers back onto the rendered rows so the online
editor and the PDF preview always agree (the server numbers priced lines continuously; the
browser must not keep its own numbering). Only the position cell is touched — no re-render. */
- applyPositions: function (tbl, req) {
- (req || []).forEach((b) => (b && b.itm || []).forEach((co) => {
- if (!co || (co.id || '') === '') { return; }
- let cell = tbl.find('#itm' + co.id + ' td.keep').first();
- if (cell.length) { cell.text(co.p != null ? co.p : ''); }
- }));
+ /* Reconciles each block's rendered rows against the authoritative server line list
+ (`req[].itm`, the co shape). The server may not only change a line's values but also
+ ADD lines (the block set row inserted by "Set mit Preis"/block.setprice) and REMOVE lines
+ ("Nur Set mit Preis"/block.setonly), and reorder them — the browser never computes any of
+ that (ADR 0006/0008/0009), it just mirrors the server. For each server line: patch/insert
+ the matching row, preserving null price fields verbatim (ADR 0009: null = empty cell, kept
+ distinct from 0). Rows the server no longer lists are removed; order follows the server.
+ Position numbers, net/VAT and the set-row emphasis all come from rrw off the mirrored data. */
+ applyItems: function (tbl, req) {
+ let val = (x) => (x === undefined ? null : x); // JSON null stays null; absent -> null
+ (req || []).forEach((b) => {
+ if (!b) { return; }
+ let bid = (b.Id || '').toString(); if (bid === '') { return; }
+ let bdy = tbl.children('tbody').filter((i, e) => (($(e).data() || {}).Id || '').toString() === bid).first();
+ if (bdy.length < 1) { return; }
+ let itms = b.itm || [], serverIds = {};
+ let title = bdy.find('tr.title').first();
+ let prev = title.length ? title : null;
+ itms.forEach((co) => {
+ let id = (co.id || '').toString(); if (id === '') { return; }
+ serverIds[id] = true;
+ let rw = bdy.find('#itm' + id).first(), isNew = rw.length < 1;
+ if (isNew) { rw = $$.tr(bdy, { id: 'itm' + id, class: 'itm' }); }
+ let dta = rw.data() || {};
+ let changed = isNew || (dta.Type || '') !== (co.typ || '')
+ || dta.net !== val(co.v) || dta.net_val !== val(co.vt) || dta.vat_val !== val(co.vv)
+ || dta.svcnet_val !== val(co.vs) || dta.svcvat_val !== val(co.vsv)
+ || (dta.position || '') !== (co.p != null ? co.p : '');
+ $.extend(dta, {
+ Id: id, Type: co.typ,
+ net: val(co.v), net_val: val(co.vt), vat_val: val(co.vv),
+ svcnet_val: val(co.vs), svcvat_val: val(co.vsv),
+ vat: co.vat, position: (co.p != null ? co.p : ''),
+ SetItmId: (co.SetItmId != null ? co.SetItmId : null)
+ });
+ if (isNew) { $.extend(dta, { htmltext: co.t, quantity: co.q }); } // text only for server-created rows (e.g. the set row)
+ rw.data(dta);
+ if (prev) { if (rw.prev()[0] !== prev[0]) { rw.insertAfter(prev); } } // keep server order, but don't churn already-ordered rows
+ else if (bdy.children().first()[0] !== rw[0]) { bdy.prepend(rw); }
+ prev = rw;
+ if (changed) { $inv.rrw.call(rw); }
+ });
+ bdy.find('tr.itm').each((i, tr) => {
+ let id = (($(tr).data() || {}).Id || '').toString();
+ if (id !== '' && !serverIds[id]) { $(tr).remove(); } // dropped server-side (block.setonly)
+ });
+ });
},
/* Applies the backend-authoritative set-pricing display flags (see BuildSetDisplay /
InvoiceSetPricing) onto the rendered rows: blanks the price/total cells for lines the
- server says should show no price (set members in SetPrice mode, the set header in
- ItemPrices mode), and emphasises the set header line — so the online editor always
- shows exactly what the PDF will print, without duplicating the pricing rules client-side.
- Rows not present in the map (no set in that block, or standalone items) are left untouched. */
+ server says should show no price (set members in SetPrice/SetOnly mode), and emphasises
+ the set header line — so the online editor always shows exactly what the PDF will print,
+ without duplicating the pricing rules client-side. Rows not present in the map (no set in
+ that block, or standalone items) are left untouched. */
applySetDisplay: function (tbl, setDisplay) {
tbl.find('tr.itm').each((i, tr) => {
let rw = $(tr), dta = rw.data() || {}, id = (dta.Id || '').toString();
@@ -729,11 +785,23 @@ $inv.d = {
}
});
},
- /* Send one change to the server; the draftReady signal and this success both refresh. */
+ /* Send one change to the server; the draftReady signal and this success both refresh.
+ Returns the underlying ajax promise so callers that must not race a follow-up delta
+ against this one (e.g. $inv.toSetPrice after a flush) can chain on it.
+ If the initial seeding (inv/dopen) is still in flight (no token yet, but a
+ 'dseedpromise' is pending), the delta previously vanished silently — the user saw no
+ network activity at all when clicking a context-menu action right after opening the
+ editor. Now the delta waits for the seed to finish and retries against the freshly
+ issued token instead of being dropped. */
sync: function (delta) {
- let t = $inv.d.token(); if (t === '') { return; }
+ let t = $inv.d.token();
+ if (t === '') {
+ let seeding = $inv.d.tbl().data('dseedpromise');
+ if (seeding) { return $.when(seeding).then(() => $inv.d.sync(delta)); }
+ return $.when();
+ }
$inv.d.layout().aC('freeze');
- $ocms.postXT({
+ return $ocms.postXT({
url: $ocms.url('inv/dpatch'), data: { token: t, delta: JSON.stringify(delta) },
success: () => { $inv.d.refresh(); },
error: (xhr) => { $inv.d.layout().rC('freeze'); if (xhr && xhr.status === 410) { $inv.d.closed('expired'); } }
@@ -744,22 +812,29 @@ $inv.d = {
/* Diff the freshly-rebuilt blocks against the last-synced state and send only the
changed/removed blocks as granular block.replace / block.remove deltas. A pure section
reorder (same blocks, new sequence) changes no block hash, so it is sent separately as a
- block.order delta; the server reorders the cache, renumbers positions and pushes them back. */
+ block.order delta; the server reorders the cache, renumbers positions and pushes them back.
+ No early return on an empty token here: sync() itself waits for an in-flight seed
+ (dseedpromise) instead of silently dropping the delta, so edits made in the brief window
+ before seeding completes are not lost. */
syncChanged: function (tbl) {
- if (($inv.d.token()) === '') { return; }
- let bai = tbl.data('bai') || [], prev = tbl.data('dhashes') || {}, next = {}, changed = [], removed = [];
+ let bai = tbl.data('bai') || [], prev = tbl.data('dhashes') || {}, next = {}, changed = [], removed = [], pending = [];
$.each(bai, (i, b) => { let id = (b.Id || '').toString(), h = JSON.stringify(b); next[id] = h; if (prev[id] !== h) { changed.push(b); } });
$.each(prev, (id) => { if (next[id] === undefined) { removed.push(id); } });
let order = $inv.d.order(), prevOrder = tbl.data('dorder') || [];
tbl.data('dhashes', next).data('dorder', order);
- changed.forEach((b) => $inv.d.sync({ Target: 'block.replace', Ref: (b.Id || '').toString(), Value: b }));
- removed.forEach((id) => $inv.d.sync({ Target: 'block.remove', Ref: id }));
+ changed.forEach((b) => pending.push($inv.d.sync({ Target: 'block.replace', Ref: (b.Id || '').toString(), Value: b })));
+ removed.forEach((id) => pending.push($inv.d.sync({ Target: 'block.remove', Ref: id })));
let sameSet = prevOrder.length === order.length && prevOrder.slice().sort().join(',') === order.slice().sort().join(',');
- if (sameSet && prevOrder.join(',') !== order.join(',')) { $inv.d.sync({ Target: 'block.order', Value: order }); }
+ if (sameSet && prevOrder.join(',') !== order.join(',')) { pending.push($inv.d.sync({ Target: 'block.order', Value: order })); }
+ /* $.when(...pending) so a caller (e.g. toSetPrice) can wait until every flushed block
+ has actually reached the server before sending a further delta that depends on it —
+ otherwise a delayed block.replace carrying pre-conversion values can land after and
+ silently overwrite a just-applied server-side mutation (e.g. item.setprice). */
+ return $.when.apply($, pending).promise();
},
- /* Map an inline recipient field to its delta target and send it. */
+ /* Map an inline recipient field to its delta target and send it. No token-guard here for the
+ same reason as syncChanged: sync() waits for an in-flight seed instead of dropping the edit. */
syncField: function (nme, val) {
- if ($inv.d.token() === '') { return; }
let map = { invoicetitle: 'title', invoiceaddress: 'address', invoiceemail: 'email', loc: 'provisionlocation', provisionlocation: 'provisionlocation', provisionperiod: 'provisionperiod' };
let target = map[nme]; if (!target) { return; }
$inv.d.sync({ Target: target, Value: val });
@@ -914,6 +989,12 @@ $inv.rd = {
},
applyState: function (state) {
let tbl = $inv.rd.tbl(); if (tbl.length < 1) { return; }
+ /* See $inv.d.applyState — drop stale/out-of-order dstate responses so an older refresh
+ can never roll back a newer one's totals/validation. */
+ let curVer = tbl.data('rdver');
+ if (typeof curVer === 'number' && typeof state.version === 'number' && state.version < curVer) {
+ return;
+ }
tbl.data('rdver', state.version).data('serverSums', state.sums).data('remid', state.remid || '');
$inv.rd.footer(tbl, state.sums || {});
$inv.rd.notes(state.notes || {});
@@ -1473,6 +1554,8 @@ $inv.eHtml = function (ev) {
}
$ocms.dlgform(flds, sets);
};
+/* No client-side arithmetic (ADR 0006/0008): only the chosen VAT rate is stored on each row;
+ the server (InvoiceDraftCalculator.RecomputeLineValues) recomputes vat_val/svcvat_val from it. */
$inv.setVat = function (ev) {
let t = $(this), thisrow = ev.data;
let vat = prompt($rct.rqV);
@@ -1485,12 +1568,6 @@ $inv.setVat = function (ev) {
thisrow.siblings('.itm').each(function () {
let rwi = $(this), dta = rwi.data();
dta.vat = fnum(vat, { style: 'percent' }).replace(' ', '');
- if ((dta.net_val || 0) > 0) {
- dta.vat_val = dta.net_val * vat;
- }
- if ((dta.svcnet_val || 0) > 0) {
- dta.svcvat_val = dta.svcnet_val * vat;
- }
});
$inv.t_fds_inv();
}
@@ -1550,12 +1627,14 @@ $inv.rrw = function () {
if (ph === false) {
bc.unshift($$.dc('ibtn edit', { title: $rct.cP }).append(gi('pencil')).click(rw, $inv.eRow));
bc.push($$.dc('ibtn del', { title: $rct.dR }).append(gi('trash')).click(function (e) { if (confirm($rct.cD)) { rw.remove(); $inv.t_fds_inv(); } }));
- /* "Auf Setpreis umstellen": only offered on a Set header item that is not yet
- priced from its members (fds__prepInvoice's [SetItmId] is null exactly for a
- Set header — either already set-priced, or not yet converted). Irreversible:
- sets this row's price to the sum of its members (rows whose [SetItmId] equals
- this row's id) and clears each member's price. */
- if ((dta.Type || '').toLowerCase() === 'set' && (dta.SetItmId || '') === '') {
+ /* "Auf Setpreis umstellen": offered on a Set header item that does not yet carry a
+ price. fds__prepInvoice's [SetItmId] now anchors on the still-unconverted (price 0)
+ header, so the header row's own SetItmId self-references its own id rather than being
+ null — the real signal for showing this button is still the header's own price/net_val
+ being 0 (once converted it carries a nonzero price and the button disappears).
+ Irreversible: the actual sum/clear mutation happens server-side (backend-authoritative,
+ see InvoiceDraftEditService.ApplyItemSetPrice) via the "item.setprice" patch target. */
+ if ((dta.Type || '').toLowerCase() === 'set' && (dta.net_val || 0) === 0) {
bc.push($$.dc('ibtn tosetp', { title: $rct.toSetP }).append(gi('scale')).click(rw, $inv.toSetPrice));
}
}
@@ -1565,7 +1644,7 @@ $inv.rrw = function () {
} else if (rw.is('.itm.osum') === true) {
co = { invrqid: dta.InvRqId, id: 'osum' + rw.index(), typ: 'osum', p: '', q: null, t: oHtml(dta.tbl.tbl), tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: false };
} else {
- co = { invrqid: dta.InvRqId, id: dta.Id || '', typ: dta.Type || 'other', p: '', q: null, t: '', tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: (dta.Note || '') !== '' && hn === false };
+ co = { invrqid: dta.InvRqId, id: dta.Id || '', typ: dta.Type || 'other', p: '', q: null, t: '', tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: (dta.Note || '') !== '' && hn === false, SetItmId: dta.SetItmId || null };
$$.dc('ibtn ico move', axf, { title: $rct.mR }); /* should be the last added */
co.p = dta.position || (dta.SortOrder || '');
@@ -1575,7 +1654,7 @@ $inv.rrw = function () {
co.t = dta.htmltext || (((dta.NameOrNumber || '').substr(0, 1) !== '#' ? oHtml($$[0]('p').text(dta.NameOrNumber)) : '') + (dta.Note || ''));
} else {
co.tt = co.det ? '' : $$.s(dta.Note || '').text();
- co.q = dta.quantity || (fnum(dta.quantityhours) + ' ' + (dta.UnitString || ''));
+ co.q = dta.quantity || ((dta.quantityhours || 0) !== 0 ? (fnum(dta.quantityhours) + ' ' + (dta.UnitString || '')) : ''); /* guard: no quantityhours -> blank, not fnum(undefined)="NaN" (e.g. the block set row) */
co.t = dta.htmltext ||(co.det ? (oHtml($$.s(dta.NameOrNumber || '')) + oHtml($$.dc('desc').html(dta.Note))) : oHtml($$.s(dta.NameOrNumber || '')));
co.v = dta.net
co.vt = dta.net_val
@@ -1594,75 +1673,62 @@ $inv.rrw = function () {
tda.push($$.td(rw, { colspan: 4 }).append(co.t));
} else {
Array.prototype.push.apply(tda, co.q ? [$$.tdc('keep').text(co.q)] : []);
+ /* ADR 0009: a null/undefined price renders an EMPTY cell (block-mode "Set mit Preis"
+ members, and the set row's own unit-price), distinct from a real 0,00 €. */
+ let cur = (x) => (x == null ? '' : fnum(x, $rct.cst));
Array.prototype.push.apply(tda, [
$$.tdc('txt', { colspan: !co.q ? 2 : 1, title: co.tt }).append(co.t),
- $$.tdc('currency').text(fnum(co.v, $rct.cst)),
- $$.tdc('currency inetval').text(fnum(co.vt, $rct.cst)).attr('title', $rct.svcPart + ': ' + fnum(co.vs, $rct.cst))
+ $$.tdc('currency').text(cur(co.v)),
+ $$.tdc('currency inetval').text(cur(co.vt)).attr('title', $rct.svcPart + ': ' + cur(co.vs))
]);
}
- rw.empty().attr('class', ph ? 'placeholder' : 'itm').aC(co.Typ).tC('hidenote', hn).append(tda);
+ rw.empty().attr('class', ph ? 'placeholder' : 'itm').aC(co.Typ)
+ .tC('sethdr', (co.typ || '').toString().toLowerCase() === 'set') /* emphasise set rows (fn1 header + block set row) */
+ .tC('hidenote', hn).append(tda);
dta.co = co;
};
-/* "Auf Setpreis umstellen" (see $inv.rrw): sets this Set-header row's price to the sum of
- its member rows' totals (rows in the same block whose [SetItmId] equals this row's id,
- the authoritative grouping from fds__prepInvoice), then clears each member's price so the
- member items show without a price — matching the SetPrice presentation, but as an actual,
- irreversible data change instead of a display-mode toggle (INVOICE_SET_PRICING.md's
- setmode remains display-only and is unaffected by this). */
+/* "Auf Setpreis umstellen" (see $inv.rrw): backend-authoritative (ADR 0006) — the browser only
+ posts the target set-header item id; the server (InvoiceDraftEditService.ApplyItemSetPrice)
+ sums the member rows (same block, [SetItmId] equal to this row's id), writes that sum onto
+ the set header and clears each member's price, then the normal draftReady refresh re-renders
+ both the header and its members from the authoritative session state. This mirrors the PDF's
+ read of the same cached session, so the online editor and PDF can never drift apart. */
$inv.toSetPrice = function (ev) {
let rw = ev.data, dta = rw.data(), id = (dta.Id || '').toString();
if (id === '') { return; }
if (confirm($rct.toSetPc) === false) { return; }
- let bdy = rw.closest('tbody'), members = bdy.find('tr.itm').filter(function () {
- return (($(this).data('SetItmId') || '').toString()) === id;
- });
- let sum_net_val = 0, sum_vat_val = 0, sum_svcnet_val = 0, sum_svcvat_val = 0;
- members.each(function () {
- let m = $(this).data();
- sum_net_val += (m.net_val || 0);
- sum_vat_val += (m.vat_val || 0);
- sum_svcnet_val += (m.svcnet_val || 0);
- sum_svcvat_val += (m.svcvat_val || 0);
- $.extend(m, { net: 0, net_val: 0, vat_val: 0, svcnet_val: 0, svcvat_val: 0, Discount: 0 });
- $inv.rrw.call($(this));
- });
- $.extend(dta, {
- net: sum_net_val, quantityhours: 1, Discount: 0,
- net_val: sum_net_val, vat_val: sum_vat_val, svcnet_val: sum_svcnet_val, svcvat_val: sum_svcvat_val
- });
- $inv.rrw.call(rw);
- $inv.t_fds_inv();
+ /* Wait for the flush of any pending local edits to actually reach the server before sending
+ the conversion delta — sending both in parallel let a delayed block.replace (still carrying
+ the pre-conversion, zero member/header values) land after item.setprice and silently
+ overwrite the just-converted totals back to 0. */
+ $.when($inv.t_fds_inv()).done(() => { $inv.d.sync({ Target: 'item.setprice', Ref: id }); });
};
+/* No client-side totals/footer/tax computation (ADR 0006/0008): this only re-assembles each
+ block's row contract array (needed to post the "req" shape to the server) and, on the very
+ first pass, seeds the authoritative backend session. Footer, VAT breakdown, service-refund
+ note figures and the per-block sum cell are never computed here — they are rendered exclusively
+ from the server's `dstate` response by $inv.d.footer / $inv.d.applyState once the draft has a
+ token. Before a token exists the footer/notes/isum cells are simply left empty; there is no
+ local approximation to display. */
$inv.invSumUpdate = function () {
- let tbl = $(this), ft = tbl.children('tfoot').empty(), p13b = bool((tbl.data().admin || {}).p13b || '', false);
- tbl.nextAll('.fnote').remove();
- let sms = { ttn: 0, ttb: 0, ttvat: 0, tscn: 0, tscvat: 0, vat: {}, itmnet: {} }, ba = [];
- let rwcy = (lbl, val, cls) => $$.tdc('currency', $$.tr(ft, { class: cls || 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text(lbl)]), fnum(val, $rct.cst)), fn = (t) => $$.dc('fnote').insertAfter(tbl).rwText(t);
- let csms = function (rrx, sms, sid) {
- sms.tscn += (rrx.svcnet_val || 0);
- sms.tscvat += (rrx.svcvat_val || 0);
- sms.ttn += (rrx.net_val || 0);
- sms.ttvat += (rrx.vat_val || 0);
- sms.ttb += ((rrx.net_val || 0) + (rrx.vat_val || 0));
- if ((rrx.vat || '') !== '') {
- sms.vat[rrx.vat] = (sms.vat[rrx.vat] || 0) + (rrx.vat_val || 0);
- }
- //sms.itmnet[sid] = (sms.itmnet[sid] || 0) + (rrx.net_val || 0);
- };
+ let tbl = $(this);
+ let ba = [];
let bds = tbl.children('tbody');
bds.each((bi, bdy) => {
- let b = $(bdy), rx = b.data() || {}, i = [], citems = [], cset = null, bnet = 0, itm = b.find('tr.itm'), iso = 0, ipos = 0;
+ let b = $(bdy), rx = b.data() || {}, i = [], citems = [], itm = b.find('tr.itm'), iso = 0, ipos = 0;
b.tC('empty', itm.length < 1);
itm.each((ti, tx) => {
-
- let rrx = $(tx).data() || {}; csms(rrx, sms, rx.Id); bnet += (rrx.net_val || 0); i.push(rrx.co);
- //console.debug('rrx %o', rrx);
+ let rrx = $(tx).data() || {};
+ i.push(rrx.co);
/* backend item contract (title/desc/qty/price_net/total_net + set flags), see InvoiceSetPricing.
- Set grouping: an item of Type 'set' is a header that claims the following items in this
- block as its members until the next set header (mfr__items has no explicit member link). */
+ Set grouping: fds__prepInvoice computes [SetItmId] per item, anchored on the still-unconverted
+ (price 0) Set header that owns it — this is the authoritative membership signal (not row order),
+ so items not tagged with a SetItmId by the server are never swept into a preceding set. The
+ header row's own SetItmId self-references its own id, but it is never its own member (excluded
+ by the id !== '' && !== citem.id check below). */
let citem = $inv.itemToContract(rrx);
- if (citem.type === 'set' && citem.id !== '') { cset = citem.id; }
- else if (cset !== null && (citem.id || '') !== '') { citem.setId = cset; }
+ let sid = (rrx.SetItmId || '').toString();
+ if (citem.type !== 'set' && sid !== '' && sid !== citem.id) { citem.setId = sid; }
citems.push(citem);
if (((typeof rrx.SortOrder === 'undefined' || rrx.SortOrder === null) ? -1 : rrx.SortOrder) > -1) {
if (['text', 'title'].includes((rrx.Type || 'other').toLowerCase()) === false) { ipos++; }
@@ -1671,41 +1737,10 @@ $inv.invSumUpdate = function () {
$inv.rrw.call(tx);
}
});
- //console.debug('%o', {
- // f: b.find('tr.isum > td.isumval'), t: fnum(bnet, $rct.cst), n: bnet
- //});
- b.find('tr.isum > td.isumval').text(fnum(bnet, $rct.cst));
- ba.push({ Id: rx.Id, nme: rx.Name, text: rx.text, itm: i, items: citems, netval: bnet });
+ ba.push({ Id: rx.Id, nme: rx.Name, text: rx.text, itm: i, items: citems });
});
let nonempty = tbl.find('tbody:not(.empty)').length;
bds.find('tr.isum').tC('hidden', nonempty < 2);
- //let fnet = $$.tdc('currency', $$.tr(ft, { class: 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Netto')]), fnum(sms.ttn, $rct.cst));
- rwcy('Netto', sms.ttn);
- if (p13b === false) {
- $.each(sms.vat, (vi, vx) => {
- //$$.tdc('currency vat', $$.tr(ft, { class: 'tvat' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Umsatzsteuer ' + vi)]), fnum(vx, $rct.cst));
- rwcy($rct.vat + ' ' + vi, vx, 'tvat');
- });
- } else {
- sms.ttb = sms.ttn;
- }
- //let fsum = $$.tdc('currency', $$.tr(ft, { class: 'tsum' }).append([$$.tdc('aux'), $$.td({ colspan: 4 }).text('Summe')]), fnum(sms.ttb, $rct.cst));
- rwcy('Summe', sms.ttb);
- let itype = tbl.data().admin.type;
- if (itype === 'i') {
- fn($rct.note2);
- fn($rct.note4);
- } else if (itype === 'c') {
- fn($rct.note2);
- } else {
- fn(string($rct.note3, [fnum((sms.tscn + sms.tscvat) * (tbl.data().admin.tax_servicerefund || 0), $rct.cst)])).aC('ntax');
- fn($rct.note2);
- fn(string($rct.note1, [fnum(sms.tscn + sms.tscvat, $rct.cst), fnum(sms.tscn, $rct.cst), fnum(sms.tscvat, $rct.cst)]));
- }
- if (p13b === true) {
- fn($rct.note13b);
- }
- tbl.data('sms', sms);
tbl.data('bai', ba);
/* Backend-authoritative seeding (ADR 0006): on the first calculation of an invoice
draft (invSumUpdate is only bound for invoices, never reminders), hand the assembled
@@ -1805,8 +1840,16 @@ $inv.t_fds_inv = () => {
let tbl = $('div.invoice_layout table.invi');
tbl.trigger('fds.inv');
/* After any local item mutation, push the changed block(s) to the authoritative
- server session as granular deltas (invoice drafts only — reminders have no token). */
- if ((tbl.data('dtoken') || '') !== '') { $inv.d.syncChanged(tbl); }
+ server session as granular deltas (invoice drafts only — reminders have no token,
+ nor a 'dseedpromise', so they correctly fall through to the no-op). While the initial
+ seed (inv/dopen) is still in flight there is no token yet either, but a 'dseedpromise'
+ is pending — wait for it instead of skipping the flush, otherwise an edit made in that
+ brief window is silently never sent. Returns the flush promise so callers that must
+ sequence a follow-up server delta after this flush (e.g. $inv.toSetPrice) can wait for
+ it instead of racing it. */
+ if ((tbl.data('dtoken') || '') !== '') { return $inv.d.syncChanged(tbl); }
+ let seeding = tbl.data('dseedpromise');
+ return seeding ? $.when(seeding).then(() => $inv.d.syncChanged(tbl)) : $.when();
};
$inv.sedit = () => {
$inv.sprev(true);
@@ -1873,7 +1916,10 @@ $inv.itemToContract = function (rrx) {
rrx = rrx || {};
let oHtml = (e) => $$.d().append(e).html();
let type = (rrx.Type || '').toString().toLowerCase();
- let ci = { id: (rrx.Id || '').toString(), type: type, title: '', desc: '', qty: '', price_net: '', total_net: (rrx.net_val || 0), vat: rrx.vat || '' };
+ /* ADR 0009: preserve null prices verbatim (null = empty cell, kept distinct from a real 0) so
+ block-mode nulled members and the set row round-trip unchanged when the block is re-posted. */
+ let nz = (x) => (x == null ? null : x);
+ let ci = { id: (rrx.Id || '').toString(), type: type, title: '', desc: '', qty: '', price_net: '', total_net: nz(rrx.net_val), vat: rrx.vat || '' };
if (rrx.co && rrx.co.typ === 'osum') {
/* combined single-sum line — the on-screen "title" is an HTML sub-table; render it as desc */
ci.desc = rrx.co.t || '';
@@ -1894,30 +1940,35 @@ $inv.itemToContract = function (rrx) {
ci.desc = rrx.Note || '';
}
ci.qty = rrx.quantity || ((rrx.quantityhours || 0) !== 0 ? (fnum(rrx.quantityhours) + (rrx.UnitString ? ' ' + rrx.UnitString : '')) : '');
- ci.price_net = (rrx.net || 0);
- ci.total_net = (rrx.net_val || 0);
+ ci.price_net = nz(rrx.net);
+ ci.total_net = nz(rrx.net_val);
}
return ci;
};
-/* 3-way set-pricing display switch. Mirrors §13b: writes the choice onto admin.setmode,
- which BuildInvoiceParams turns into the "setmode:" InvoiceOptions token the PDF reads. */
+/* 2-way set-pricing display switch (SetPrice / SetOnly). Mirrors §13b: writes the choice onto
+ admin.setmode, which BuildInvoiceParams turns into the "setmode:" InvoiceOptions token
+ the PDF reads. ItemPrices ("Positionen mit Preis – Set als Überschrift") was removed: it was
+ always just the implicit pre-conversion default and is not a state the user can switch back to
+ once a set has been converted via the "Auf Setpreis umstellen" item switch (see $inv.toSetPrice /
+ InvoiceDraftEditService.ApplyItemSetPrice) — that conversion is one-way. */
$inv.ssetmode = () => {
let l = $('div.invoice_layout'), tbl = l.find('table.invi'), d = tbl.data();
d.admin = d.admin || {};
let cur = (d.admin.setmode || 'setprice'), o;
let btn = (mode) => $$.dc('btn', $ict.setmo[mode]).tC('selected', cur === mode).click(() => { o.c.trigger('modal_close'); $inv.setSetmode(mode); });
- let fr = $$.dc('choicefrm').append([btn('setprice'), btn('itemprices'), btn('setonly')]);
+ let fr = $$.dc('choicefrm').append([btn('setprice'), btn('setonly')]);
o = $ocms.dlg(fr, { width: 800 });
};
+/* "Set mit Preis" / "Nur Set mit Preis" (ADR 0009): NOT a display toggle — an irreversible,
+ backend-authoritative mutation grouped by service-request block. The server inserts a dedicated
+ set row per block (block sum) and either nulls each member's price (setprice) or removes the
+ members (setonly); the normal draftReady refresh re-renders both via $inv.d.applyItems. The
+ browser only posts the chosen mode. Flush pending local edits first so a delayed block.replace
+ can't land after the conversion and overwrite it (same race guard as $inv.toSetPrice). */
$inv.setSetmode = (mode) => {
- let l = $('div.invoice_layout'), tbl = l.find('table.invi'), d = tbl.data();
- d.admin = d.admin || {};
- d.admin.setmode = mode; /* posted in admin -> BuildInvoiceParams writes setmode: into InvoiceOptions */
- d.inv = d.inv || {}; /* keep a local InvoiceOptions reflection in sync (cosmetic) */
- let opts = (d.inv.InvoiceOptions || '').split(',').filter(x => x !== '' && x.indexOf('setmode:') !== 0);
- if (mode && mode !== 'setprice') { opts.push('setmode:' + mode); }
- d.inv.InvoiceOptions = opts.join(',');
- $inv.d.sync({ Target: 'setmode', Value: mode });
+ if (confirm($rct.toSetMc || $rct.toSetPc) === false) { return; }
+ let target = (mode === 'setonly') ? 'block.setonly' : 'block.setprice';
+ $.when($inv.t_fds_inv()).done(() => { $inv.d.sync({ Target: target }); });
};
$inv.sctp = () => {
let flds = $invcol.ctp;
@@ -1940,24 +1991,21 @@ $inv.sctp = () => {
});
};
/* Normalises the editor's working model into the exact field names the C# backend
- (FdsInvoiceData.BuildInvoiceParams) reads, then returns the `invc` payload:
- - balances/service sums come from `sms` (ttn/ttb), exposed on `new` as total_net/total_gross;
- - every VAT rate's net amount is exposed as new.vat__net (the backend reads the highest);
+ (FdsInvoiceData.BuildInvoiceParams) reads, then returns the `invc` payload. No totals/VAT
+ are computed here (ADR 0006/0008: the online editor performs no arithmetic at all) — the
+ backend session computes total_net/total_gross/vat itself (InvoiceDraftCalculator) once
+ opened from this payload, and BuildFdsData/BuildInvoiceParams reads them from there:
- new.invoicetitle -> new.title, new.loc -> new.provisionlocation, admin.paymentterms ->
new.paymentterm, admin.CustomerId -> admin.customerid.
Originals are kept alongside; the source objects are not mutated. */
$inv.invcPayload = function (d) {
d = d || {};
- let sms = d.sms || {}, nw = $.extend({}, d.new), adm = $.extend({}, d.admin);
- nw.total_net = sms.ttn || 0;
- nw.total_gross = sms.ttb || 0;
- /* VAT (rate + amount) is taken by the backend straight from the posted sms.vat map
- (FdsInvoiceData.HighestVat), so no per-rate new.vat_* keys are needed here. */
+ let nw = $.extend({}, d.new), adm = $.extend({}, d.admin);
nw.title = (nw.invoicetitle != null ? nw.invoicetitle : (nw.title || ''));
nw.provisionlocation = (nw.loc != null ? nw.loc : (nw.provisionlocation || ''));
nw.paymentterm = (adm.paymentterms != null ? adm.paymentterms : (nw.paymentterm || ''));
adm.customerid = (adm.customerid != null ? adm.customerid : adm.CustomerId);
- return { admin: adm, req: d.bai, sms: d.sms, new: nw };
+ return { admin: adm, req: d.bai, new: nw };
};
/* Zwischenspeichern and preview now run against the backend-authoritative session
(ADR 0006): no full-invoice re-upload — the cached draft is flushed / rendered by
@@ -1971,20 +2019,11 @@ $inv.rReload = () => {
$inv.cInv2({ id: s.search });
} catch (e) { }
};
-$inv.quantChange = function (i) {
- //console.debug({ t: this, i: i });
- let t = $(this), f = t.closest('form'), fi = {}, pf = (i) => parseFloat(i.toString().replace('%', '').replace(',', '.')), rtp = (num) => num.toFixed(2);
- f.find(':input').each((i, e) => { fi[$(e).attr('name')] = $(e); });
- let qv = parseInt(fi.quantityhours.val() || '0'), nv = pf(fi.net.val() || '0'), vat = pf(fi.vat.val()) * 0.01;
- if (qv > 0 && nv > 0) {
- fi.net_val.val(rtp(qv * nv));
- fi.vat_val.val(rtp(qv * nv * vat));
- if (['Service'].includes(fi.Type.val())) {
- fi.svcnet_val.val(rtp(qv * nv));
- fi.svcvat_val.val(rtp(qv * nv * vat));
- }
- }
-};
+/* No client-side arithmetic (ADR 0006/0008): quantity/price/VAT edits are posted as raw values
+ and the server (InvoiceDraftCalculator.RecomputeLineValues) computes net_val/vat_val/
+ svcnet_val/svcvat_val. The fields are left as entered here; the authoritative values are
+ pushed back onto the row by $inv.d.applyItems once the change reaches the backend. */
+$inv.quantChange = function (i) { };
$inv.storno = function (id, fds) {
let o, fr = $$.dc('choicefrm').append([
$$.dc('btn', 'Storno ohne Details').click({ id: id, mode: 'simple' }, (ev) => { o.c.trigger('modal_close'); $inv.cSt(ev.data); })
diff --git a/Fuchs/wwwroot/web/fis.req.de.min.js b/Fuchs/wwwroot/web/fis.req.de.min.js
index d9412c6..dfcc360 100644
--- a/Fuchs/wwwroot/web/fis.req.de.min.js
+++ b/Fuchs/wwwroot/web/fis.req.de.min.js
@@ -1 +1 @@
-let $rct={mdl:"Aufträge",or:"offene Aufträge",orr:"offene Aufträge (4 W)",rn:"Auftragsnummer",iov:{all:"Auftragsübersicht (alle)","":"Auftragsübersicht"},wk:"Woche",nd:"Keine Daten gefunden.",h:"Uhr",rq1:"Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",rq2:"Auftragsdaten werden geladen",rq1f:"Die Auftragsdaten von MFR konnten nicht oder nicht schnell genug abgerufen werde.\nMöchten Sie mit den bestehenden Daten trotzdem weitermachen?",note1:"Im Bruttobetrag sind {0} Lohnkosten enthalten (netto {1}). Die darin enthaltene Umsatzsteuer beträgt {2}.",note2:"Bitte beachten Sie, nach §14 Abs. 1 Umsatzsteuergesetz ist diese Rechnung ein Zahlungsbeleg oder eine andere beweiskräftige Unterlage für 2 Jahre nach Ablauf des Kalenderjahres der Ausstellung dieser Rechnung aufzubewahren, soweit nicht aufgrund anderer gesetzlicher Regelungen andere ggf.längere Aufbewahrungsfristen gelten.",note3:"Privathaushalten erstattet das Finanzamt bis zu {0} des Arbeitslohns mit der nächsten Steuererklärung.",note4:"Für bereits erbrachte Arbeiten, Dienstleistungen, Materiallieferungen und getätigte Bestellvorgänge zum oben genannten Bauvorhaben, die sich aus dem mit Ihnen geschlossenen Vertrag ergeben, stellen wir Ihnen vertragsgemäß unsere Akontozahlung in Rechnung. Eine Endabrechnung erhalten Sie als Schlussrechnung nach Abschluss des gesamten Bauvorhabens. Das Ausführungsdatum entnehmen Sie bitte dem Schlusstext dieser Rechnung. Wir danken Ihnen herzlich für das entgegengebrachte Vertrauen und bitten Sie um kurzfristigen Ausgleich der Akontorechnung.",note13b:"Gem. §13b Umsatzsteuergesetz unterliegen Sie der Steuerschuldnerschaft des Leistungsempfängers zur Umsatzsteuer aus dieser Rechnung mit einem Steuersatz von 19%.",crI:"Rechnung erstellen",crII:"Abschlagsrechnung erstellen",dII:"Für eine Abschlagsrechnung darf nur ein Auftrag gewählt werden.",dnS:"Für eine Rechnung muss mindestens ein Auftrag gewählt werden.",inv:"Rechnung",invs:"Rechnungen",req:"Auftrag",provP:"Leistungszeitraum",provD:"Leistungsdatum",cP:"Position ändern",iRb:"Zeile darunter einfügen",dR:"Zeile löschen",sV:"USt festlegen",cD:"Löschen?",mR:"Zeile verschieben",svcPart:"Service-Anteil",vat:"Umsatzsteuer",combP:"Positionen zusammenfassen",toSetP:"Auf Setpreis umstellen (Positionen ohne Preis)",toSetPc:"Der Set-Preis wird auf die Summe seiner Positionen gesetzt und die Positionen selbst verlieren ihren Preis. Das ist nicht rückgängig zu machen (der Betrag kann danach nur noch manuell geändert werden). Fortfahren?",iSum:"Zwischensumme",dtRel:"Freigegeben am: ",dtCr:"Erstellt am: ",rqV:"USt des Auftrags?",cthd:"wirklich aus-/einblenden ?",cst:{style:"currency",currency:"EUR"},sts:{IsWorkDone:"Arbeiten erledigt",Closed:"Auftrag geschlossen",SubcontractorPendingConfirmation:"Warten auf Bestätigung (Unterauftrag)",Scheduled:"Geplant",OfferIsRejected:"Angebot abgelehnt",OfferIsSend:"Offen (Angebot versandt)",CollaborationWaitingConfirmation:"Warten auf Bestätigung (Zusammenarbeit)",Released:"Freigegeben",OfferIsConfirmed:"Bestätigt",InProgress:"In Bearbeitung",ReadyForScheduling:"Zur Planung",Created:"Erstellt",Rejected:"Abgebrochen",Invoiced:"Rechnung gestellt","-":"-"},invHR:["Pos.","Menge","Artikelbezeichnung","VK","Summe"],frm:{invoiceaddress:"Adresse",loc:"Leistungsort / Lieferadresse",invoiceemail:"Email"}},$rcol={req:new fields_definition("Auftrag","Aufträge",[{name:"tags",label:"",type:"string",dfnc:function(e,t){""!==(e||"")&&($(this).aC("tags"),e.split(",").forEach((e=>{""!==e&&$(this).append($$.sc("tag "+e.replace(" ","_").replace("/","_").toLowerCase(),e))})))}},{name:"DateOfCreation",label:"Datum",type:"date",title:function(e){$(this).attr("title",$rct.dtCr+fdt(e.DateOfCreation).ne("-")+" \n"+$rct.dtRel+fdt(e.DateReleased).ne("-"))}},{name:"CustomerName",label:"Kunde (Firma)",type:"string"},{name:"Name",label:"Auftragsname",type:"string"},{name:"ExternalId",label:"Auftragsnummer",type:"string"},{name:"ParentExtenalId",label:"PAuftrag",type:"string"},{name:"InvoiceId",label:"RNummer",type:"string",dfnc:function(e,t){$(this).rwText(e," ").find("span").each((function(){$(this).aC("cla").click({id:$(this).text()},$inv.jdbn)}))}},{name:"State",label:"Status",type:"string"},{name:"WorkDoneAt",label:"Erledigt am",type:"date"},{name:"Description",label:"Beschreibung",type:"html"}]),itm:new fields_definition("Auftragsposition","Auftragspositionen",[{name:"NameOrNumber",label:"Bezeichnung",type:"string"},{name:"Type",label:"Typ",type:"select",required:!0,value:"Text",url:[{value:"Text",label:"Text"},{value:"Equipment",label:"Ausrüstung"},{value:"Material",label:"Material"},{value:"Service",label:"Arbeitsleistung"}],change:function(e){$req.quantChange.call(this,e)}},{name:"quantityhours",label:"Anzahl / Menge",type:"number",precision:"0.01",value:1,change:function(e){$inv.quantChange.call(this,e)}},{name:"UnitString",label:"Einheit",type:"select",url:["LFDM","Stck","Std.","QM","AW","Pauschal"],change:function(e){$inv.quantChange.call(this,e)}},{name:"net",label:"EinzelPreis netto",type:"number",precision:"0.01",value:0,change:function(e){$inv.quantChange.call(this,e)}},{name:"net_val",label:"GesamtPreis netto",type:"number",precision:"0.01",value:0},{name:"vat_val",label:"GesamtPreis USt",type:"number",precision:"0.01",value:0},{name:"svcnet_val",label:"Arbeitslohn netto",type:"number",precision:"0.01",value:0},{name:"svcvat_val",label:"Arbeitslohn USt",type:"number",precision:"0.01",value:0},{name:"net_pos",label:"Netto",type:"string"},{name:"bo_pos",label:"Brutto",type:"string"},{name:"vat",label:"USt",type:"string",value:"19,0%",change:function(e){$inv.quantChange.call(this,e)}},{name:"Note",label:"Details",type:"html",tinymce:!0}])},$ict={mdl:"Rechnungen",iov:{all:"Rechnungen (alle)","":"Rechnungen (nur fertige)","#d":"Rechnungen (nur Entwürfe)","#u":"Rechnungen (nur unbezahlt)","#r":"Rechnungen (nur angemahnt)","#a":"Rechnungen (nur Akonto)","#c":"Rechnungen (nur Storno)","#ru":"Rechnungen (nur angemahnt + unbez.)"},uba:", gesamter Zeitraum)",req:"Auftrag",inv:"Rechnung",rem:"Mahnung",in:"Rechnungsnummer",cc:"Kunde",wk:"Woche",nd:"Keine Daten gefunden.",dl:"Herunterladen",ed:"Bearbeiten",ced:"Bearbeitung fortsetzen",sItm:"Einzelheiten anzeigen",sPay:"Zahlungen anzeigen",cdI:"Entwurf der Rechnung löschen?",rel:"Neu Laden",relm:"Bitte laden Sie Liste manuell neu, um die Änderungen zu sehen.",dsp:"Rechnung anzeigen",storno:"Storno-Rechnung erstellen",credit:"Gutschrift erstellen",remd:"Mahnung erstellen",remdt:"Mahnung erstellen zur Rechnung {0}",remlst:"Mahnungen anzeigen",remdsp:"Mahnung anzeigen",remres:"Mahnung erneut senden",remresc:"Mahnung {0} wirklich erneut senden?",remresr:"Mahnung {0} wurde erfolgreich versandt.",setpyd:"Bezahlt markieren",cpyd:"Rechnung wirklich als bezahlt markieren?",setupd:"Bezahlt-Markierung aufheben",cupd:"Bezahlt-Markierung wirklich aufheben?",ivE:"Die Email-Adresse ist vermutlich nicht gültig.",ivEc:"\nMöchten Sie fortfahren?",pna:"Diese Seite ist in der Vorschau nicht verfügbar",tpe:"Die Anzahl von {0} Seiten wird aktuell nicht unterstützt",eis:"Der Rechnungsentwurf konnte nicht gespeichert werden.",iss:"Zwischenstand speichern.",p13b:"USt -> §13b",setm:"Set-Preisanzeige",setmo:{setprice:"Set mit Preis – Positionen ohne Preis",itemprices:"Positionen mit Preis – Set als Überschrift",setonly:"Nur Set mit Preis – Positionen ausgeblendet"},ctp:"Ansprechpartner festlegen",mfr:"Von MFR neu abrufen",rq1:"Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",rq2:"Auftragsdaten werden geladen",iq1:"Rechnungsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",iq2:"Rechnungsdaten werden geladen",sis:"Rechnung als versandt markieren",srs:"Mahnung als versandt markieren",sisc:"Rechnung wirklich als versandt markieren?",srsc:"Mahnung wirklich als versandt markieren?",iSt:{dft:"Entwurf",uns:"nicht versandt",pyd:"bezahlt",cc:"storniert",op:"offen",due:"fällig",ovd:"überfällig",rem:"angemahnt"},rSt:["","Überfällig","2. Mahnung","3. Stufe"],pSt:{a:"Vollst.",p:"Teilz."},ivT:{i:"AbschlagsR.",f:"SchlussR",r:"Rechnung",c:"StornoR."},rovlh:"Übersicht der bisherigen Mahnungen",rovl:["Betreff","Betrag","Betrag gezahlt","fertiggestellt am"],remHR:["Rechnung","vom","Rechnungsbetrag","bereits bezahlt","noch offen"],translatePaymentTerm:e=>(e||"").replace("wd"," Werktagen").replace("d"," Tagen").replace("wk"," Wochen")||"10 Tagen",payi:{account:"Konto",name:"Zahler",text:"Verw.Zweck",InvoiceID:"Rechnung",amount:"Betrag",date:"Datum",manual:"Typ"}},$invcol={datev:new fields_definition("Rechnung","Rechnungen",[{name:"Umsatz (ohne Soll/Haben-Kz)",label:"Umsatz (ohne Soll/Haben-Kz)",type:"string"},{name:"vf",label:"vf",type:"string"},{name:"Soll/Haben-Kennzeichen",label:"Soll/Haben-Kennzeichen",type:"string"},{name:"Konto",label:"Konto",type:"string"},{name:"Gegenkonto",label:"Gegenkonto",type:"string"},{name:"BU-Schlüssel",label:"BU-Schlüssel",type:"string"},{name:"Belegdatum",label:"Belegdatum",type:"string"},{name:"Belegfeld 1",label:"Belegfeld 1",type:"string"},{name:"Belegfeld 2",label:"Belegfeld 2",type:"string"},{name:"Buchungstext",label:"Buchungstext",type:"string"}]),inv:new fields_definition("Rechnung","Rechnungen",[{name:"invstatus",label:"Status",type:"select",url:$ict.iSt},{name:"balance",label:"Umsatz",type:"string",dtype:"currency"},{name:"CustomerName",label:"Kunde",type:"string"},{name:"InvoiceId",label:"RNummer",type:"string"},{name:"InvoiceType",label:"Typ",type:"select",url:$ict.ivT},{name:"request",label:"Auftrag",type:"string",dtype:"num"},{name:"vat",label:"MwSt",type:"string",dtype:"num"},{name:"deb_cred",label:"Soll/Haben",type:"string"},{name:"customer",label:"Konto",type:"string",dtype:"num"},{name:"contra_account",label:"Gegenkonto",type:"string",dtype:"num"},{name:"Belegdatum",label:"Belegdatum",type:"date"},{name:"reminderstatus",label:"MahnStatus",type:"select",url:$ict.rSt},{name:"reminder",label:"# Mahnungen",type:"integer"},{name:"Buchungstext",label:"Buchungstext",type:"string"},{name:"Payment",label:"Zahlung",type:"string"}]),rem:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"amount",label:"Rechnungsbetrag",type:"number",precision:"0.01",value:1},{name:"amount_payed",label:"bereits bezahlt",type:"number",precision:"0.01",value:1}]),rem2:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"DocumentName",label:"Name",type:"string"},{name:"subject",label:"Betreff",type:"string"},{name:"DateSent",label:"Versanddatum",type:"date"},{name:"status",label:"Status",type:"string"},{name:"amount_open",label:"offener Betrag",type:"number",precision:"0.01"},{name:"InvoiceId",label:"RNummer",type:"string"}]),rid:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"type",label:"Typ",type:"select",url:[["f","einfache Zahlungserinnerung"],["m","Mahnung"],["l","letzte Mahnung"]],required:!0},{name:"level",label:"Stufe",type:"select",url:[["1","Stufe 1"],["2","Stufe 2"],["3","Stufe 3"],["4","Stufe 4"],["5","Stufe 5"],["6","Stufe 6"]],required:!0}]),ctp:new fields_definition("Ansprechpartner","Ansprechpartner",[{name:"name",label:"Name",type:"string"},{name:"email",label:"Email",type:"string"}])},gi=(e,t)=>$$.sc("glyphicon glyphicon-"+e).aC(t),$inv={},$req={init2:function(e,t){e=e||"inv",t=t||{},$ocms.getScript([],(function(){$req.init3(e,t)}))},init3:async function(e,t){$fis.cf(!0);let n=$fis.lf(!0);$("#topbar").ocmsmenu([]),$("#activemodule").text($rct.mdl),await $fis.prepAuth("fds_req,fds_inv,fds_reminder");let i=[(async()=>{!0===$fis.isAuth("fds_req",1)&&($req.prepLst(""),n.aC("fix"))})(),new Promise(((e,t)=>{n.find("div.oreq2").aC("selected"),$req.renderreq(fdt(new Date,"yy-MM-dd"),"r"),e()}))];await Promise.all(i)},prepLst:function(e){let t=new Date,n=$fis.lf(!0).ldng(1),i=new Date("2021-01-01");$fis.frm_list().IN((function(){}));$$.dc("mth oreq",n).text($rct.or).click((function(e){let t=$(this);e.stopPropagation(),t.siblings().rC("selected"),!0===t.is(".selected")&&(t.tC("selected"),$req.renderreq(fdt(new Date,"yy-MM-dd"),"o")),t.aC("selected")})),$$.dc("mth oreq2",n).text($rct.orr).click((function(e){let t=$(this);e.stopPropagation(),t.siblings().rC("selected"),!0===t.is(".selected")&&(t.tC("selected"),$req.renderreq(fdt(new Date,"yy-MM-dd"),"r")),t.aC("selected")})),$$.i({placeholder:$rct.rn}).appendTo($$.dc("mth oreqn",n)).enterKey((function(e){let t=$(this),n=t.val()||"";e.stopPropagation(),t.parent().siblings().rC("selected"),n.length>3&&(t.parent().aC("selected"),$req.renderreq("n:"+n,"s"),t.val(""))}));n.append("
");let a=$$.dc("mthl",n),r=t.getFullYear(),l=t.getMonth()+1;for(let t=i.getFullYear();t<=r;t++){let n=$$.dc("yr").prependTo(a).text($rct.iov[e]+" - "+t.toString()).toggleClass("selected",t===r);n.click({yr:t},(function(e){e.stopPropagation(),n.siblings().rC("selected"),n.aC("selected")}));let d=$$.dc("mfrm",n);for(let n=0;n<(t!==r?12:l);n++){i=new Date(t,n,1);let a=$$.dc("mth").prependTo(d).text($rct.iov[e]+" - "+fdt(i,"MMM yyyy"));a.click({yr:t,mt:n},(function(e){if(e.stopPropagation(),a.siblings().rC("selected"),!0===a.is(".selected")){a.tC("selected");let t=fdt(new Date(e.data.yr,e.data.mt,1),"yy-MM-dd");$req.renderreq(t,"m")}a.aC("selected")}));let r=getMonday(i),l=new Date(i);l.setMonth(l.getMonth()+1),l.setDate(0),l=getMonday(l);let s=$$.dc("wfrm",a);for(;r<=l;){let e=$$.dc("wk",s).text(($rct.wk||"W")+" "+fdt(r,"dd.MM.yy"));e.click({rd:new Date(r)},(function(t){t.stopPropagation();let n=fdt(t.data.rd,"yy-MM-dd");$req.renderreq(n,"w"),a.siblings().rC("selected").find(".wk").rC("selected"),a.aC("selected").find(".wk").rC("selected"),e.aC("selected")}));let t=$$.dc("wkdl",e).append($$.sc("ico glyphicon glyphicon-compressed"));!0===$fis.isAuth("fds_inv",2)&&t.click({rd:new Date(r)},(function(e){e.stopPropagation();let t=fdt(e.data.rd,"yy-MM-dd");$req.downloadzip.call(t,"w")})),r.setDate(r.getDate()+7)}}}n.ldng(0)},renderreq:function(e,t){let n=$fis.frm_list().ldng(1),i=$$.dc("invfrm",n).aC("md"+t),a=$fis.lf();$ocms.postXT({url:$ocms.url("req/reql"),data:{mode:t,tgt:e},success:n=>{a.rC("fix").aC("hd"),$$.dc("ovhd",i).append($$.s(n.admin.title)).appendIf($$.sc("note",n.admin.note),""!==ne(n.admin.note,""));let r=$$.tblset({},i),l=$rcol.req,d=$$.tr(r.hd);$$.th(d);$.each(l.fields||[],((e,t)=>{$$.th(d).text(t.label),"vat"===t.name&&$$.th(d)}));let s=0,c=!1;$.each(n.requests||[],((n,d)=>{s>0&&s!==d.ParentServiceRequestId&&(c=!c);let o=$$.tr(r.bdy).tC("alt",c);s=d.ParentServiceRequestId,o.click((function(){a.rC("fix").aC("hd"),o.tC("selected").siblings().rC("selected").find("td.av").rC("av"),o.find("td.av").rC("av")})),o.tC("child",d.isChild);let u=$$.td(o,{class:"raux"});!0===bool(d.open,!1)&&$$.dc("ihd ilbtn",u).append(gi("eye-close","ico")).click({id:d.Id},$req.tHd),$$.dc("iitm ilbtn",u).append(gi("list","ico")).click({id:d.Id},$req.showitm),!0===$fis.isAuth("fds_inv",2)&&$$.dc("invc ilbtn",u).append(gi("edit","ico")).click({id:d.Id},$inv.cInv),$.each(l.fields||[],((n,a)=>{let r=$$.td(o).aC(a.dtype),l=d[a.name];if("function"==typeof a.dfnc)a.dfnc.call(r,l,d);else switch(a.type||""){case"date":r.text(fdt(d[a.name],"dd.MM.yy"));break;case"datetime":r.text(fdt(d[a.name]));break;case"html":r.append($$.dc("ctw").html(l)),r.append($$.dc("ttip").html(l));break;default:r.text(d[a.name])}switch(a.name||""){case"State":r.text($rct.sts[l||"-"]);break;case"Name":r.aC(a.name.toLowerCase());break;case"vat":$$.sel().appendTo($$.td(o,{class:"vsel"})).click((function(e){e.stopPropagation()})).append([$$.opt("19,0 %","19,0 %"),$$.opt("16,0 %","16,0 %"),$$.opt("0,0 %","0,0 %")]).val(d[a.name]).change().change({frm:i,tgt:e,mode:t,id:d.Id,td:r},$req.setvat),r.tC("hl","19"!==d[a.name].substr(0,2)).click((function(e){e.stopPropagation(),$(this).tC("av")}));break;case"balance":r.aC("sh_"+(d.SollHaben||"").toLowerCase());break;case"InvoiceId":r.aC("keep")}switch(typeof a.title){case"function":a.title.call(r,d);break;case"string":r.attr("title",cs.title)}}))}))},complete:()=>{n.ldng(0)}})},tHd:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&confirm($rct.cthd)&&$ocms.postXT({url:$ocms.url("req/rthd"),data:{id:e.data.id},success:n=>{n.id===e.data.id&&!1===bool(n.visible,!0)?(!1===t.is(".tbhd")&&setTimeout((()=>{t.filter(".tbhd").remove()}),15e3),t.aC("tbhd")):n.id===e.data.id&&t.rC("tbhd")}})},showitm:function(e){let t=$(this).closest("tr");if(e.stopPropagation(),!1===t.is(".selected"))return;let n=$$.dc("rfrm").ldng(1);$ocms.postXT({url:$ocms.url("req/pget"),data:{id:e.data.id},success:t=>{$ocms.postXT({url:$ocms.url("req/get"),data:{id:e.data.id,mode:"ful"},success:e=>{if((e.requests||[]).length<1)n.text($rct.nd);else{let t=$$.dc("srq",n),i=$$.tblset({class:"if"},t);$.each(e.requests||[],(function(e,t){e>0&&$$.tr(i.bdy).aC("sep").append($$.td({colspan:6}));let n=$$.tr(i.bdy).aC("title"),a=$rcol.itm.lbl(),r=$inv.worknotes(t);$$.td(n,{colspan:6}).append([$$.s($rcol.req.label_sng),$$.sc("eid",t.ExternalId),$$.sc("nme",fdt(t.WorkDoneAt,"dd.MM.yy")+": "+r.ne(t.Name))]);$$.tr(i.bdy).aC("shd").append([$$.td(),$$.td(a.NameOrNumber),$$.td(a.Type),$$.td(a.net_pos),$$.td(a.bo_pos),$$.td(a.vat)]);$.each(t.items||[],((e,t)=>{t.ServiceRequestId;let n=$$.tr(i.bdy,{id:"itm"+t.Id}).aC(t.Type);$$.td(n).aC("ico"),$$.td(n).text(t.NameOrNumber),$$.td(n).text(t.Type),$$.td(n).aC("currency").text(t.net_pos),$$.td(n).aC("currency").text(t.bo_pos),$$.td(n).aC("num").text(t.vat)}))}))}},error:()=>{n.text($t.t12)},complete:()=>{n.ldng(0)}})},error:()=>{n.text($t.t12),n.ldng(0)}}),$ocms.dlg(n,{width:1e3})}},$$req={init2:$req.init2,auth:{}};export default $$req;$inv.cInv=function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&!1!==$fis.isAuth("fds_inv",2)&&$inv.cInv2({id:e.data.id})},$inv.rMn=e=>{let t=[{lbl:$ict.req,itm:[]}];return!0===bool(e,!1)&&!0===$fis.isAuth("fds_inv",2)&&Array.prototype.push.apply(t[0].itm,[{lbl:$rct.crI,fnc:$inv.ccInv,data:{typ:"r"}},{lbl:$rct.crII,fnc:$inv.ccInv,data:{typ:"i"}}]),t.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(t)},$inv.iMnr=e=>{let t=booln(e.isFinal,!0),n=e.Id,i=booln(e.fds,!1),a=[{glyph:"glyphicon-menu-left",fnc:()=>{$fis.frm_edit().remove()}},{lbl:$ict.inv,itm:[]},{lbl:$ict.rem,itm:[]}];return!1===t&&!0===$fis.isAuth("fds_inv",2)?a[1].itm.push({lbl:$ict.ced,fnc:$inv.clCntInv}):!0===$fis.isAuth("fds_inv",1)&&a[1].itm.push({lbl:$ict.dsp,fnc:()=>$inv.disp(n,"inv")}),!0===i&&!0===t&&!0===$fis.isAuth("fds_inv",2)&&(a[1].itm.push({lbl:$ict.storno,fnc:()=>$inv.storno(n,i)}),a[1].itm.push({lbl:$ict.credit,fnc:()=>$inv.credit(n,i)})),!0===t&&!0===$fis.isAuth("fds_reminder",2)&&(a[2].itm.push({lbl:$ict.remd,fnc:()=>$inv.ccRem(n,e.InvoiceId)}),a[2].itm.push({lbl:$ict.remlst,fnc:()=>$inv.dspRem(n)})),!0===t&&!0===$fis.isAuth("fds_reminder",2)&&!1===booln(e.IsSent,!1)&&a[2].itm.push({lbl:$ict.srs,fnc:()=>$inv.srs(n)}),a.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(a)},$inv.iMn=e=>{let t=booln(e.isFinal,!0),n=e.Id,i=booln(e.fds,!1),a=[{glyph:"glyphicon-menu-left",fnc:()=>{$fis.frm_edit().remove()}},{lbl:$ict.inv,itm:[]},{lbl:$ict.rem,itm:[]}];return!1===t&&!0===$fis.isAuth("fds_inv",2)?a[1].itm.push({lbl:$ict.ced,fnc:()=>{$inv.cntInv({id:n})}}):!0===$fis.isAuth("fds_inv",1)&&a[1].itm.push({lbl:$ict.dsp,fnc:()=>$inv.disp(n,"inv")}),!0===$fis.isAuth("fds_inv",2)&&(a[1].itm.push({lbl:$ict.storno,fnc:()=>$inv.storno(n,i)}),a[1].itm.push({lbl:$ict.credit,fnc:()=>$inv.credit(n,i)})),!0===t&&!1===booln(e.IsPayed,!1)?(!0===$fis.isAuth("fds_reminder",2)&&a[2].itm.push({lbl:$ict.remd,fnc:()=>$inv.ccRem(n,e.InvoiceId)}),!0===$fis.isAuth("fds_inv",2)&&a[1].itm.push({lbl:$ict.setpyd,fnc:()=>$inv.setPyd(n)})):!0===t&&!0===booln(e.IsPayed,!1)&&"m"===(e.PaymentStatus||"")&&!0===$fis.isAuth("fds_inv",2)&&a[1].itm.push({lbl:$ict.setupd,fnc:()=>$inv.setUpd(n)}),!0===$fis.isAuth("fds_reminder",2)&&a[2].itm.push({lbl:$ict.remlst,fnc:()=>$inv.dspRem(n)}),!0===t&&!0===$fis.isAuth("fds_inv",2)&&!1===booln(e.IsSent,!1)&&a[1].itm.push({lbl:$ict.sis,fnc:()=>$inv.sis(n)}),!1===i&&a[1].itm.push({lbl:$ict.mfr,fnc:()=>$inv.mfrrel(n)}),$("#topbar").ocmsmenu(a)},$inv.emOpt=e=>"iss,p13b,ctp"+(""===((e||{}).setmode||"")?",setm":""),$inv.eM=(e,t,n)=>{let i=[];return!0!==booln(e,!1)&&!0!==booln(t,!1)||i.push({glyph:"glyphicon-menu-left",fnc:()=>{$fis.lf(!0),$fis.frm_edit().remove()}}),!0===(n||"").split(",").includes("iss")&&i.push({lbl:$ict.iss,fnc:$inv.ssave}),!0===(n||"").split(",").includes("ctp")&&i.push({lbl:$ict.ctp,fnc:$inv.sctp}),!0===(n||"").split(",").includes("p13b")&&i.push({lbl:$ict.p13b,fnc:$inv.sp13b}),!0===(n||"").split(",").includes("setm")&&i.push({lbl:$ict.setm,fnc:$inv.ssetmode}),!0===(n||"").split(",").includes("iss")&&(i.push({lbl:"Änderungshistorie",fnc:()=>$inv.d.history()}),i.push({lbl:"Änderungen verwerfen",fnc:()=>$inv.d.discard()})),!0===booln(e,!1)&&i.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(i)},$inv.d={tbl:()=>$("div.invoice_layout table.invi"),layout:()=>$("div.invoice_layout"),token:function(){return $inv.d.tbl().data("dtoken")||""},hashes:function(){let e=$inv.d.tbl().data("bai")||[],t={};return $.each(e,((e,n)=>{t[(n.Id||"").toString()]=JSON.stringify(n)})),t},seed:function(e){let t=$inv.d.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dopen"),data:{payload:JSON.stringify(e)},success:e=>{$inv.d.tbl().data("dtoken",e.token).data("dver",e.version).data("dhashes",$inv.d.hashes()).data("dorder",$inv.d.order()),$fis.draft.bind(e.token,{onReady:()=>$inv.d.refresh(),onExpiring:e=>$inv.d.warnExpiry(e),onClosed:e=>$inv.d.closed(e)}),$inv.d.refresh()},error:()=>{t.rC("freeze")},complete:()=>{$inv.d.tbl().removeData("dseeding")}})},refresh:function(e){let t=$inv.d.token();""!==t&&$ocms.postXT({url:$ocms.url("inv/dstate"),data:{token:t},success:t=>{$inv.d.applyState(t),"function"==typeof e&&e(t)},error:e=>{e&&410===e.status&&$inv.d.closed("expired")},complete:()=>{$inv.d.layout().rC("freeze")}})},applyState:function(e){let t=$inv.d.tbl();t.length<1||(t.data("dver",e.version).data("serverSums",e.sums),$inv.d.footer(t,e.sums||{},e.admin||{}),$inv.d.notes(e.notes||[]),$inv.d.validation(e.validation||[]),$inv.d.applyPositions(t,e.req||[]),$inv.d.applySetDisplay(t,e.setDisplay||{}),$inv.eM(!1,!0,$inv.emOpt(e.admin||{})))},notes:function(e){let t=$inv.d.layout();if(t.length<1)return;let n=t.children(".dnotes");n.length<1&&(n=$$.dc("dnotes"),t.append(n)),n.empty(),(e||[]).forEach((e=>$$.dc("dnote").aC(e.style||"InvoiceNotes").text(e.text)))},applyPositions:function(e,t){(t||[]).forEach((t=>(t&&t.itm||[]).forEach((t=>{if(!t||""===(t.id||""))return;let n=e.find("#itm"+t.id+" td.keep").first();n.length&&n.text(null!=t.p?t.p:"")}))))},applySetDisplay:function(e,t){e.find("tr.itm").each(((e,n)=>{let i=$(n),a=((i.data()||{}).Id||"").toString();if(""===a||!Object.prototype.hasOwnProperty.call(t,a))return;let r=t[a]||{};i.tC("sethdr",bool(r.h,!1)),!1===bool(r.p,!0)&&i.find("td.currency").text("")}))},sync:function(e){let t=$inv.d.token();""!==t&&($inv.d.layout().aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dpatch"),data:{token:t,delta:JSON.stringify(e)},success:()=>{$inv.d.refresh()},error:e=>{$inv.d.layout().rC("freeze"),e&&410===e.status&&$inv.d.closed("expired")}}))},order:function(){return($inv.d.tbl().data("bai")||[]).map((e=>(e.Id||"").toString()))},syncChanged:function(e){if(""===$inv.d.token())return;let t=e.data("bai")||[],n=e.data("dhashes")||{},i={},a=[],r=[];$.each(t,((e,t)=>{let r=(t.Id||"").toString(),l=JSON.stringify(t);i[r]=l,n[r]!==l&&a.push(t)})),$.each(n,(e=>{void 0===i[e]&&r.push(e)}));let l=$inv.d.order(),d=e.data("dorder")||[];e.data("dhashes",i).data("dorder",l),a.forEach((e=>$inv.d.sync({Target:"block.replace",Ref:(e.Id||"").toString(),Value:e}))),r.forEach((e=>$inv.d.sync({Target:"block.remove",Ref:e}))),d.length===l.length&&d.slice().sort().join(",")===l.slice().sort().join(",")&&d.join(",")!==l.join(",")&&$inv.d.sync({Target:"block.order",Value:l})},syncField:function(e,t){if(""===$inv.d.token())return;let n={invoicetitle:"title",invoiceaddress:"address",invoiceemail:"email",loc:"provisionlocation",provisionlocation:"provisionlocation",provisionperiod:"provisionperiod"}[e];n&&$inv.d.sync({Target:n,Value:t})},footer:function(e,t,n){let i=e.children("tfoot").empty();e.nextAll(".fnote").remove();let a=bool(n.p13b,!1),r=(e,t,n)=>$$.tdc("currency",$$.tr(i,{class:n||"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text(e)]),fnum(t,$rct.cst)),l=t=>$$.dc("fnote").insertAfter(e).rwText(t);r("Netto",t.total_net||0),!1===a&&$.each(t.vat||{},((e,t)=>r($rct.vat+" "+e+"%",t,"tvat"))),r("Summe",t.total_gross||0);let d=n.type||"";"i"===d?(l($rct.note2),l($rct.note4)):"c"===d?l($rct.note2):(l(string($rct.note3,[fnum(((t.service_net||0)+(t.service_vat||0))*(n.tax_servicerefund||0),$rct.cst)])).aC("ntax"),l($rct.note2),l(string($rct.note1,[fnum((t.service_net||0)+(t.service_vat||0),$rct.cst),fnum(t.service_net||0,$rct.cst),fnum(t.service_vat||0,$rct.cst)]))),!0===a&&l($rct.note13b)},validation:function(e){let t=$("div.invoice_layout");if(t.length<1)return;let n=t.children(".dvalidation");n.length<1&&(n=$$.dc("dvalidation"),t.prepend(n)),n.empty().tC("hidden",(e||[]).length<1),$.each(e||[],((e,t)=>$$.dc("dvmsg",n).aC(t.severity).text(t.message)))},preview:function(){let e=$inv.d.token();if(""===e)return;let t=$inv.d.layout(),n=($inv.d.tbl().data("new")||{}).invoiceemail||"";!1===$fis.ValidateEmail(n)&&!1===bool(confirm($ict.ivE+$ict.ivEc),!1)||(t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dpreview"),data:{token:e},success:n=>{t.rC("freeze");let i=$$.dc("imagecollection pdfpreview"),a=Math.round(.88*vh()),r=n.total;r>10&&$$.dc("note warn",i).text($ict.tpe),$.each(n.img||[],((e,t)=>{$$.dc("pdfp",i).append($$.img(t).css("max-height",(a-rpx(6)).toString()+"px"))}));for(let e=(n.img||[]).length+1;e<=r;e++)$$.dc("pdfp ph",i).append($$.dc("note",$ict.pna));$ocms.dlg(i,{size:[a,Math.round(.88*vw())],zindex:50,form:!1,button:$rct.crI,confirm:function(n){let i=$(this);t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dsave"),data:{token:e},success:e=>{$ocms.postXT({url:$ocms.url("req/sconf"),data:{id:e.invid},success:t=>{i.trigger("modal_close"),!0===t.hasFile&&window.open($ocms.url("req/idoc")+"?id="+e.invid,"_blank"),$inv.d.close(),$ocms.init("req"),$inv.rReload()},error:()=>{alert($t.f1),i.trigger("modal_close")},complete:()=>{t.rC("freeze")}})},error:()=>{t.rC("freeze"),alert($ict.eis)}})},cancel:function(e){confirm($ict.cdI)&&($inv.d.close(),$inv.rReload())}})},error:()=>{t.rC("freeze"),alert($ict.eis)}}))},save:function(){let e=$inv.d.token();if(""===e)return;let t=$inv.d.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dsave"),data:{token:e},success:e=>{$inv.d.tbl().data("invid",e.invid)},error:()=>{alert($ict.eis)},complete:()=>{t.rC("freeze")}})},history:function(){let e=$inv.d.token();""!==e&&$ocms.postXT({url:$ocms.url("inv/dhistory"),data:{token:e},success:e=>{let t=$$.dc("dhist");if((e.history||[]).length<1)$$.dc("note",t).text("Noch keine Änderungen erfasst.");else{let n=$$.tblset({class:"invtbl fullwidth"},t);$$.tr(n.hd).append([$$.th().text("Zeit"),$$.th().text("Feld"),$$.th().text("Alt"),$$.th().text("Neu")]),$.each(e.history,((e,t)=>$$.tr(n.bdy).append([$$.tdc("keep",fdt(t.timestamp)),$$.td().text(t.target),$$.td().text(t.oldValue),$$.td().text(t.newValue)])))}$ocms.dlg(t,{width:800,form:!1})}})},discard:function(){let e=$inv.d.tbl().data("invid")||"";""!==e?!1!==confirm("Alle Änderungen verwerfen und den zuletzt gespeicherten Stand neu laden?")&&($inv.d.close(),$inv.cntInv({id:e})):alert("Es wurde noch kein Zwischenstand gespeichert, der wiederhergestellt werden könnte.")},warnExpiry:function(e){let t=Math.max(1,Math.round((e||0)/60));$fis.notifications.push({severity:"info",title:"Entwurf läuft ab",message:"Der Rechnungsentwurf läuft in etwa "+t+" Minute(n) ab. Bitte zwischenspeichern, sonst gehen die Änderungen verloren."})},closed:function(e){let t=$inv.d.token();$inv.d.tbl().removeData("dtoken"),""!==t&&$fis.draft.release(t),$fis.frm_edit().remove(),$fis.lf(!0),$fis.notifications.push({severity:"error",title:"Entwurf geschlossen",message:"expired"===e?"Der Rechnungsentwurf ist wegen Inaktivität abgelaufen. Nicht gespeicherte Änderungen sind verloren.":"Der Rechnungsentwurf wurde geschlossen."});try{$inv.rReload()}catch(e){}},close:function(){let e=$inv.d.token();""!==e&&($ocms.postXT({url:$ocms.url("inv/dclose"),data:{token:e}}),$fis.draft.release(e)),$inv.d.tbl().removeData("dtoken")}},$inv.rd={tbl:()=>$("div.invoice_layout table.invi"),layout:()=>$("div.invoice_layout"),token:function(){return $inv.rd.tbl().data("rdtoken")||""},seed:function(e){let t=$inv.rd.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dopen"),data:{payload:JSON.stringify(e)},success:e=>{$inv.rd.tbl().data("rdtoken",e.token).data("rdver",e.version),$fis.draft.bind(e.token,{onReady:()=>$inv.rd.refresh(),onExpiring:e=>$inv.rd.warnExpiry(e),onClosed:e=>$inv.rd.closed(e)}),$inv.rd.refresh()},error:()=>{t.rC("freeze")}})},refresh:function(e){let t=$inv.rd.token();""!==t&&$ocms.postXT({url:$ocms.url("rem/dstate"),data:{token:t},success:t=>{$inv.rd.applyState(t),"function"==typeof e&&e(t)},error:e=>{e&&410===e.status&&$inv.rd.closed("expired")},complete:()=>{$inv.rd.layout().rC("freeze")}})},applyState:function(e){let t=$inv.rd.tbl();t.length<1||(t.data("rdver",e.version).data("serverSums",e.sums).data("remid",e.remid||""),$inv.rd.footer(t,e.sums||{}),$inv.rd.notes(e.notes||{}),$inv.rd.validation(e.validation||[]))},notes:function(e){let t=$inv.rd.layout();if(t.length<1)return;let n=t.find(".srq");if(n.length<1)return;n.children(".dnote").remove();let i=(e||{}).intro||[],a=n.children().first();i.slice().reverse().forEach((e=>{let t=$$[0]("p").aC("dnote intro").rwText(e);a.length?t.insertBefore(a):t.appendTo(n)})),((e||{}).closing||[]).forEach((e=>$$[0]("p").aC("dnote closing").rwText(e).appendTo(n)))},sync:function(e){let t=$inv.rd.token();""!==t&&($inv.rd.layout().aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dpatch"),data:{token:t,delta:JSON.stringify(e)},success:()=>{$inv.rd.refresh()},error:e=>{$inv.rd.layout().rC("freeze"),e&&410===e.status&&$inv.rd.closed("expired")}}))},syncField:function(e,t){if(""===$inv.rd.token())return;let n={subject:"subject",invoiceaddress:"address",invoiceemail:"email",text:"text"}[e];n&&$inv.rd.sync({Target:n,Value:t})},syncAmount:function(e,t){""!==$inv.rd.token()&&($inv.rd.sync({Target:"amount",Value:(null!=e?e:0).toString()}),$inv.rd.sync({Target:"amount_payed",Value:(null!=t?t:0).toString()}))},footer:function(e,t){let n=e.children("tfoot").empty(),i=$$.tr(n,{class:"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text("Offener Betrag")]);$$.tdc("currency",i,fnum(t.amount_open||0,$rct.cst))},validation:function(e){let t=$inv.rd.layout();if(t.length<1)return;let n=t.children(".dvalidation");n.length<1&&(n=$$.dc("dvalidation"),t.prepend(n)),n.empty().tC("hidden",(e||[]).length<1),$.each(e||[],((e,t)=>$$.dc("dvmsg",n).aC(t.severity).text(t.message)))},preview:function(){let e=$inv.rd.token();if(""===e)return;let t=$inv.rd.layout(),n=($inv.rd.tbl().data("new")||{}).invoiceemail||"";!1===$fis.ValidateEmail(n)&&!1===bool(confirm($ict.ivE+$ict.ivEc),!1)||(t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dpreview"),data:{token:e},success:n=>{t.rC("freeze");let i=$$.dc("imagecollection pdfpreview"),a=Math.round(.88*vh());$.each(n.img||[],((e,t)=>{$$.dc("pdfp",i).append($$.img(t).css("max-height",(a-rpx(6)).toString()+"px"))})),$ocms.dlg(i,{size:[a,Math.round(.88*vw())],zindex:50,form:!1,button:$ict.remd,confirm:function(n){let i=$(this);t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dsave"),data:{token:e},success:e=>{$ocms.postXT({url:$ocms.url("rem/conf"),data:{id:e.remid},success:()=>{i.trigger("modal_close"),window.open($ocms.url("rem/idoc")+"?id="+e.remid,"_blank"),$inv.rd.close(),$ocms.init("req"),$inv.rReload()},error:()=>{alert($t.f1),i.trigger("modal_close")},complete:()=>{t.rC("freeze")}})},error:()=>{t.rC("freeze"),alert($t.f1)}})},cancel:function(e){confirm($ict.cdI)&&($inv.rd.close(),$inv.rReload())}})},error:()=>{t.rC("freeze"),alert($t.f1)}}))},save:function(){let e=$inv.rd.token();if(""===e)return;let t=$inv.rd.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dsave"),data:{token:e},success:e=>{$inv.rd.tbl().data("remid",e.remid)},error:()=>{alert($t.f1)},complete:()=>{t.rC("freeze")}})},history:function(){let e=$inv.rd.token();""!==e&&$ocms.postXT({url:$ocms.url("rem/dhistory"),data:{token:e},success:e=>{let t=$$.dc("dhist");if((e.history||[]).length<1)$$.dc("note",t).text("Noch keine Änderungen erfasst.");else{let n=$$.tblset({class:"invtbl fullwidth"},t);$$.tr(n.hd).append([$$.th().text("Zeit"),$$.th().text("Feld"),$$.th().text("Alt"),$$.th().text("Neu")]),$.each(e.history,((e,t)=>$$.tr(n.bdy).append([$$.tdc("keep",fdt(t.timestamp)),$$.td().text(t.target),$$.td().text(t.oldValue),$$.td().text(t.newValue)])))}$ocms.dlg(t,{width:800,form:!1})}})},warnExpiry:function(e){let t=Math.max(1,Math.round((e||0)/60));$fis.notifications.push({severity:"info",title:"Entwurf läuft ab",message:"Der Mahnentwurf läuft in etwa "+t+" Minute(n) ab. Bitte zwischenspeichern, sonst gehen die Änderungen verloren."})},closed:function(e){let t=$inv.rd.token();$inv.rd.tbl().removeData("rdtoken"),""!==t&&$fis.draft.release(t),$fis.frm_edit().remove(),$fis.lf(!0),$fis.notifications.push({severity:"error",title:"Entwurf geschlossen",message:"expired"===e?"Der Mahnentwurf ist wegen Inaktivität abgelaufen. Nicht gespeicherte Änderungen sind verloren.":"Der Mahnentwurf wurde geschlossen."});try{$inv.rReload()}catch(e){}},close:function(){let e=$inv.rd.token();""!==e&&($ocms.postXT({url:$ocms.url("rem/dclose"),data:{token:e}}),$fis.draft.release(e)),$inv.rd.tbl().removeData("rdtoken")}},$inv.cInv2=function(e){let t=$$.dc("rfrm").ldng(1),n=$ocms.dlg(t,{width:1e3});n&&n.ft.rwText($rct.rq1);let i=()=>{$ocms.postXT({url:$ocms.url("req/get"),timeout:60,data:{id:e.id,mode:"r"},success:t=>{t.admin=t.admin||{};let n=$fis.lf(!0).aC("fix").rC("hd");if($fis.frm_edit().IN(),$inv.eM(!0,!0),(t.requests||[]).length<1)n.aC("fix").text($rct.nd);else{$$.dc("lh",n,$rct.mdl);let i=$$.d(),a=$$.ul({class:"rql"}).data({search:e.id,parent:t.admin.parent}).appendTo(n),r={},l=$rcol.req.lbl();$.each(t.requests||[],(function(e,t){let n=$$.li({class:"cli rli"}).data($.extend({},t)).appendTo(a),d=$$.dc("lihd",n).addClass(t.state);!0===booln(t.open,!1)&&d.append($$.sc("cbox").click((()=>{n.tC("checked"),i.find("li").rC("checked"),!0===n.is(".checked")?$inv.rMn(t.open):$inv.eM(!0)}))),d.append([$$.sc("eid",t.ExternalId),$$.sc("nme",t.Name)]),$$.dc("lidt",n).append([$$.dc("rqs").append([$$.s(l.State+": "),$$.s($rct.sts[t.State||"-"])]),$$.dc("ivn").append([$$.s(l.InvoiceId+": "),$$.s(t.InvoiceId||"- -")]),$$.dc("wda").append([$$.s(l.WorkDoneAt+": "),$$.s(fdt(t.WorkDoneAt,"dd.MM.yyyy"))])]),r[t.Id]=n})),(t.inv||[]).length>0&&($$.dc("lh",n,$rct.invs),i=$$.ul({class:"ivl"}).appendTo(n),$.each(t.inv||[],((e,t)=>{let n=$$.li({class:"cli ili"}).data($.extend({},t)).appendTo(i),r=$$.dc("lihd",n).addClass(t.invstatus);!1===booln(t.isFinal,!0)?r.append($$.sc("cbox").click((()=>{""!==(t.Id||"")&&(n.tC("checked").siblings().rC("checked"),a.find("li").rC("checked"),!0===n.is(".checked")?$inv.iMnr(t):$inv.eM(!0))}))):["","dft"].indexOf(t.invstatus)<0&&r.append($$.sc("dli").click((function(){$inv.disp(t.Id,"inv")}))),r.append($$.sc("nme",t.DocumentName||t.Id)),$$.dc("lidt",n).append([$$.dc("wda").append([$$.s(fdt(t.DateCreated,"dd.MM.yyyy"))]),$$.d().text($ict.iSt[t.invstatus]||t.invstatus)])})))}},complete:()=>{n&&n.c.trigger("modal_close")}})};$ocms.postXT({url:$ocms.url("req/pget"),timeout:90,data:{id:e.id},success:e=>{n&&n.ft.rwText($rct.rq2),i()},error:()=>{confirm($rct.rq1f)?(n&&n.ft.rwText($rct.rq2),i()):n&&n.c.trigger("modal_close")}})},$inv.ccInv=function(e){let t=(e.data||{}).typ||"r",n=$fis.lf(),i=n.children("ul.rql"),a=i.data("parent"),r=[];if(i.find("li.rli.checked").each((function(){r.push($(this).data("Id"))})),r.length<1)return void alert($rct.dnS);if("i"===t&&r.length>1)return void alert($rct.dII);let l=$fis.frm_edit(),d=$$.dc("invoice_layout",l).append($$.dc("btn sprev").click($inv.sprev)),s=$fis.cf().width()>d.width()+n.width()+20;n.tC("fix",s).tC("hd",!s),$inv.eM(!1,!0);let c=$$.dc("rfrm").ldng(1),o=$ocms.dlg(c,{width:1e3});o.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("req/iget"),timeout:60,data:{id:a,mode:"ful",typ:t,sel:r.join(",")},success:e=>{let t=$$.dc("srq",d),n=$$.tblset({class:"invi"},t);n.bdy.remove(),n.ft=$$[0]("tfoot"),e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b")),n.tbl.data($.extend({new:{},sms:{},itm:{}},{admin:e.admin,companies:e.companies,locations:e.locations}));let i=$$.tr(n.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(i,e))),n.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.requests||[],(function(t,i){if(0!==(i.Id||0)){let t=$inv.worknotes(i);i.text="i"===e.admin.type?$rct.req+jine([i.ExternalId,i.Name],": ").eine(" ",""):jine([jine([fdt(i.WorkDoneAt,"dd.MM.yy"),i.ExternalId]," - "+$rct.req+" "),t.ne(i.Name)],": \n");let a=$$.tbody(n.tbl).data($.extend({},i));$inv.rendersrq.call(a)}}));let a=$$.tr($$.tbody(n.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(a),n.ft.appendTo(n.tbl);let r,l,s=e.admin||{},c=(e,t,i,a,r)=>{let l=$$.dc("inpfrm",d).aC(e).append("string"==typeof a?$$.dc("ahd",a):a>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",l).rwText(t);$$.dc("axf",l).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{n.tbl.data("new")[i]=e}},r),$inv.eHtml)),n.tbl.data("new")[i]=t};c("tfrm",s.invoicetitle,"invoicetitle",0,null),c("adrfrm",s.invoiceaddress,"invoiceaddress",0,null),c("locfrm","","loc",1,{list:deepCopy(e.locations),lbl:"ref",property:"address"}),c("emailfrm",s.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",d).append($$.dc("content").text(s.sender)),s.provisionend&&(l=s.provisionstart?$rct.provP:$rct.provD,r=s.provisionstart?fdt(s.provisionstart,"dd.MM.yyyy")+" - "+fdt(s.provisionend,"dd.MM.yyyy"):fdt(s.provisionend,"dd.MM.yyyy")),c("admfrm",r,"provisionperiod",l,1),n.tbl.data("new").CustomValues=s.CustomValues||"",$$.dc("inpfrm ctpfrm",d).text(jObj(s.CustomValues,"contactName")),n.tbl.children("tbody").each($inv.bdysort),n.tbl.trigger("fds.inv"),$inv.eM(!1,!0,$inv.emOpt(s))},complete:()=>{o.c.trigger("modal_close")}})},$inv.ccStInv=function(e){let t=e.data||{},n=$fis.lf(),i=t.id,a=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sprev)),r=$fis.cf().width()>a.width()+n.width()+20;n.tC("fix",r).tC("hd",!r),$inv.eM(!1,!0);let l=$$.dc("rfrm").ldng(1),d=$ocms.dlg(l,{width:1e3});d.ft.rwText($ict.iq1),$ocms.postXT({url:$ocms.url("inv/pget"),timeout:90,data:{id:t.id},success:e=>{d&&d.ft.rwText($ict.iq2),$ocms.postXT({url:$ocms.url("inv/icget"),timeout:60,data:{id:i},success:e=>{let t=$$.dc("srq",a),n=$$.tblset({class:"invi"},t);n.bdy.remove(),n.ft=$$[0]("tfoot"),e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b")),n.tbl.data($.extend({new:{},sms:{},itm:{}},{admin:e.admin,companies:e.companies,locations:e.locations}));let i=$$.tr(n.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(i,e))),n.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.requests||[],(function(t,i){if(0!==(i.Id||0)){let t=$inv.worknotes(i);i.text="i"===e.admin.type?$rct.req+jine([i.ExternalId,i.Name],": ").eine(" ",""):jine([fdt(i.WorkDoneAt,"dd.MM.yy")+t.ne(i.Name)],": ");let a=$$.tbody(n.tbl).data($.extend({},i));$inv.rendersrq.call(a)}}));let r=$$.tr($$.tbody(n.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(r),n.ft.appendTo(n.tbl);let l,d,s=e.admin||{},c=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",a).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{n.tbl.data("new")[i]=e}},l),$inv.eHtml)),n.tbl.data("new")[i]=t};c("tfrm",s.invoicetitle,"invoicetitle",0,null),c("adrfrm",s.invoiceaddress,"invoiceaddress",0,null),c("locfrm",s.provisionlocation,"loc",1,{list:deepCopy(e.locations),lbl:"ref",property:"address"}),c("emailfrm",s.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",a).append($$.dc("content").text(s.sender)),s.provisionend&&(d=s.provisionstart?$rct.provP:$rct.provD,l=s.provisionstart?fdt(s.provisionstart,"dd.MM.yyyy")+" - "+fdt(s.provisionend,"dd.MM.yyyy"):fdt(s.provisionend,"dd.MM.yyyy")),c("admfrm",l,"provisionperiod",d,1),n.tbl.data("new").CustomValues=s.CustomValues||"",$$.dc("inpfrm ctpfrm",a).text(jObj(s.CustomValues,"contactName")),n.tbl.children("tbody").each($inv.bdysort),n.tbl.trigger("fds.inv")},complete:()=>{d.c.trigger("modal_close")}})},error:()=>{d&&d.c.trigger("modal_close")}})},$inv.clCntInv=function(e){let t=$fis.lf(!1),n=[];t.find("li.ili.checked").each((function(){n.push($(this).data("Id"))})),1===n.length&&$inv.cntInv({id:n[0]})},$inv.cntInv=function(e){e=e||{};$fis.lf(!1).rC("fix").aC("hd");let t=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sedit));$inv.eM(!1,!0);let n=$$.dc("rfrm").ldng(1),i=$ocms.dlg(n,{width:1e3});i.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("inv/get"),timeout:60,data:{id:e.id},success:e=>{e.admin=e.admin||{};let n=e.inv||{},i=$$.dc("srq",t),a=$$.tblset({class:"invi"},i);a.bdy.remove(),a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:n.Id,new:{},sms:{},itm:{},bai:[]},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(r,e))),a.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.req||[],(function(e,t){let n=$$.tbody(a.tbl).data($.extend({},t));$inv.rendersrq.call(n)}));let l=$$.tr($$.tbody(a.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(l),a.ft.appendTo(a.tbl);let d=(e,n,i,r,l)=>{let d=$$.dc("inpfrm",t).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(n);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=n};d("tfrm",n.InvoiceTitle,"invoicetitle",0,null),d("adrfrm",n.SendToAddress,"invoiceaddress",0,null),d("locfrm",n.ProvisionLocation,"loc",1,null),d("emailfrm",n.SendToEmail,"invoiceemail",0,null),$$.dc("sndfrm",t).append($$.dc("content").text(e.admin.sender)),d("admfrm",n.ProvisionPeriod,"provisionperiod",!0===(n.ProvisionPeriod||"").includes("-")?$rct.provP:$rct.provD,1),a.tbl.data("new").CustomValues=n.CustomValues||"",$$.dc("inpfrm ctpfrm",t).text(jObj(n.CustomValues,"contactName")),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv"),$inv.eM(!1,!0,$inv.emOpt(e.admin))},complete:()=>{i.c.trigger("modal_close")}})},$inv.cSt=function(e){e=e||{};let t=$fis.lf(),n=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sedit)),i=$fis.cf().width()>n.width()+t.width()+20;t.tC("fix",i).tC("hd",!i),$inv.eM(!1,!0);let a=$$.dc("rfrm").ldng(1),r=$ocms.dlg(a,{width:1e3});r.ft.rwText($ict.iq1),$ocms.postXT({url:$ocms.url("inv/pget"),data:{id:e.id},success:t=>{r&&r.ft.rwText($ict.iq2),$ocms.postXT({url:$ocms.url("inv/storno"),data:{id:e.id,mode:e.mode},success:e=>{e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b"));let t=e.inv||{},i=$$.dc("srq",n),a=$$.tblset({class:"invi"},i);a.bdy.remove(),a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:t.Id,new:{},sms:{},itm:{},bai:[]},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(r,e))),a.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.req||[],(function(e,t){let n=$$.tbody(a.tbl).data($.extend({},t));$inv.rendersrq.call(n)}));let l=$$.tr($$.tbody(a.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(l),a.ft.appendTo(a.tbl);let d=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",n).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=t};d("tfrm",t.InvoiceTitle,"invoicetitle",0,null),d("adrfrm",t.SendToAddress,"invoiceaddress",0,null),d("locfrm",t.ProvisionLocation,"loc",1,null),d("emailfrm",t.SendToEmail,"invoiceemail",0,null),$$.dc("sndfrm",n).append($$.dc("content").text(e.admin.sender)),d("admfrm",t.ProvisionPeriod,"provisionperiod",!0===(t.ProvisionPeriod||"").includes("-")?$rct.provP:$rct.provD,1),a.tbl.data("new").CustomValues=t.CustomValues||"",$$.dc("inpfrm ctpfrm",n).text(jObj(t.CustomValues,"contactName")),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv")},complete:()=>{r.c.trigger("modal_close")}})},error:()=>{r&&r.c.trigger("modal_close")}})},$inv.eHtml=function(e){let t=$(this),n=e.data instanceof jQuery?e.data:e.data.t,i=["invoiceemail","provisionperiod","invoicetitle"].includes(e.data.nme),a=i?[{name:"txt",label:"Text",type:"text",value:n.text()}]:[{name:"txt",label:"Text",type:"html",value:n.html(),tinymce:!0,attr:{style:"height: 300px"}}],r=e.data.change||null,l={title:t.data("dialog")||"",success:function(t){i?n.text(t.txt||""):n.html(t.txt),"function"==typeof r&&r(t.txt),$inv.d.syncField(e.data.nme,i?t.txt||"":t.txt),$inv.rd.syncField(e.data.nme,i?t.txt||"":t.txt)},tinymce:{valid_elements:"br",hidemenu:!0,hidetoolbar:!0}};if(Array.isArray(e.data.list)){let t=$$.dc("lstfrm");$.each(e.data.list,((n,i)=>{let a=$$.dc("li",t).append(""!==(e.data.lbl||"")?$$.dc("lbl").rwText(i[e.data.lbl]):null);$$.dc("adr",a).rwText(i[e.data.property]).data("val",i[e.data.property]).click((function(){let e=$(this),t=e.closest(".modal-body").find(':input[name="txt"]');t.is(".tinymce")?tinymce.get(t.attr("id")).setContent($$.s().rwText(e.data("val")).html()):"TEXTAREA"===t.prop("tagName")?t.val(e.data("val")).change():t.rwText(e.data("val"))}))})),l.addcontent=t}$ocms.dlgform(a,l)},$inv.setVat=function(e){$(this);let t=e.data,n=prompt($rct.rqV);n&&(n=parseFloat(n.replace("%","")),n>1&&(n*=.01),!1===isNaN(n)&&(t.siblings(".itm").each((function(){let e=$(this).data();e.vat=fnum(n,{style:"percent"}).replace(" ",""),(e.net_val||0)>0&&(e.vat_val=e.net_val*n),(e.svcnet_val||0)>0&&(e.svcvat_val=e.svcnet_val*n)})),$inv.t_fds_inv()))},$inv.inRow=function(e){let t=$(this),n=e.data,i={},a=$rcol.itm.clone(["SortOrder","NameOrNumber","Type","quantityhours","UnitString","net","svcnet_val","svcvat_val","net_val","vat_val","vat","Note"]),r="N"+(65536*(1+Math.random())||0).toString(16).substr(6),l=$$.tr({id:"itm_"+r.toString(),class:"itm"});$ocms.dlgform(a,{title:t.data("dialog")||"",success:function(e){l.data($.extend({Id:r},i,e)),$inv.rrw.call(l),l.insertAfter(n),$inv.t_fds_inv()},typedvalues:!0})},$inv.eRow=function(e){let t=$(this),n=e.data,i=n.data()||{},a=["SortOrder","NameOrNumber","Type","quantityhours","UnitString","net","svcnet_val","svcvat_val","net_val","vat_val","vat","Note"];i.id||""!==(i.Type||"")||a.unshift("Type");let r=$rcol.itm.clone(a).applyValues(i);r.set("Type","hidden","type"),$inv.eRw.call(t,n,i,r)},$inv.eRw=function(e,t,n){let i=$(this);$ocms.dlgform(n,{title:i.data("dialog")||"",success:function(n){let i={};""===(t.Id||"")&&(i.Id="N"+(65536*(1+Math.random())||0).toString(16).substr(6),e.attr("id","itm_"+i.Id.toString())),i.quantity=((n.quantityhours||"").toString()+" "+(n.UnitString||"").toString()).trimEnd(),e.data($.extend({},t,n,i)),console.debug("eRw success %o",e.data()),$inv.rrw.call(e),$inv.t_fds_inv()},typedvalues:!0})},$inv.bdysort=(e,t)=>{$(t).Sortable({dragItem:!1,dragHandleClass:"ico",parentident:"tr",onend:()=>{$inv.t_fds_inv()}})},$inv.rrw=function(){let e=$(this),t=e.data(),n={},i=e.is(".placeholder"),a=e.is(".hidenote"),r=e=>$$.d().append(e).html(),l=[$$.dc("ibtn insb",{title:$rct.iRb}).append(gi("indent-left")).click(e,$inv.inRow)];!1===i&&(l.unshift($$.dc("ibtn edit",{title:$rct.cP}).append(gi("pencil")).click(e,$inv.eRow)),l.push($$.dc("ibtn del",{title:$rct.dR}).append(gi("trash")).click((function(t){confirm($rct.cD)&&(e.remove(),$inv.t_fds_inv())}))),"set"===(t.Type||"").toLowerCase()&&""===(t.SetItmId||"")&&l.push($$.dc("ibtn tosetp",{title:$rct.toSetP}).append(gi("scale")).click(e,$inv.toSetPrice)));let d=$$.dc("axf").append(l);!0===i?n={id:"",typ:"placeholder"}:!0===e.is(".itm.osum")?n={invrqid:t.InvRqId,id:"osum"+e.index(),typ:"osum",p:"",q:null,t:r(t.tbl.tbl),tt:null,v:null,vt:t.net_val,vs:t.svcnet_val,vat:t.vat,vv:t.vat_val,vsv:t.svcvat_val,det:!1}:(n={invrqid:t.InvRqId,id:t.Id||"",typ:t.Type||"other",p:"",q:null,t:"",tt:null,v:null,vt:t.net_val,vs:t.svcnet_val,vat:t.vat,vv:t.vat_val,vsv:t.svcvat_val,det:""!==(t.Note||"")&&!1===a},$$.dc("ibtn ico move",d,{title:$rct.mR}),n.p=t.position||t.SortOrder||"",""===n.id?n.t="":["Text","Title"].includes(n.typ)&&0===(t.net_val||0)?n.t=t.htmltext||("#"!==(t.NameOrNumber||"").substr(0,1)?r($$[0]("p").text(t.NameOrNumber)):"")+(t.Note||""):(n.tt=n.det?"":$$.s(t.Note||"").text(),n.q=t.quantity||fnum(t.quantityhours)+" "+(t.UnitString||""),n.t=t.htmltext||(n.det?r($$.s(t.NameOrNumber||""))+r($$.dc("desc").html(t.Note)):r($$.s(t.NameOrNumber||""))),n.v=t.net,n.vt=t.net_val)),""!==(t.Note||"")&&$$.dc("ibtn add",d).append(gi("object-align-left")).click((function(t){$inv.rrw.call(e.tC("hidenote"))}));let s=[$$.tdc("aux").append(d),$$.tdc("keep").text(n.p)];""===n.id?s.push($$.td(e,{colspan:4}).append(n.t)):(Array.prototype.push.apply(s,n.q?[$$.tdc("keep").text(n.q)]:[]),Array.prototype.push.apply(s,[$$.tdc("txt",{colspan:n.q?1:2,title:n.tt}).append(n.t),$$.tdc("currency").text(fnum(n.v,$rct.cst)),$$.tdc("currency inetval").text(fnum(n.vt,$rct.cst)).attr("title",$rct.svcPart+": "+fnum(n.vs,$rct.cst))])),e.empty().attr("class",i?"placeholder":"itm").aC(n.Typ).tC("hidenote",a).append(s),t.co=n},$inv.toSetPrice=function(e){let t=e.data,n=t.data(),i=(n.Id||"").toString();if(""===i)return;if(!1===confirm($rct.toSetPc))return;let a=t.closest("tbody").find("tr.itm").filter((function(){return($(this).data("SetItmId")||"").toString()===i})),r=0,l=0,d=0,s=0;a.each((function(){let e=$(this).data();r+=e.net_val||0,l+=e.vat_val||0,d+=e.svcnet_val||0,s+=e.svcvat_val||0,$.extend(e,{net:0,net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,Discount:0}),$inv.rrw.call($(this))})),$.extend(n,{net:r,quantityhours:1,Discount:0,net_val:r,vat_val:l,svcnet_val:d,svcvat_val:s}),$inv.rrw.call(t),$inv.t_fds_inv()},$inv.invSumUpdate=function(){let e=$(this),t=e.children("tfoot").empty(),n=bool((e.data().admin||{}).p13b||"",!1);e.nextAll(".fnote").remove();let i={ttn:0,ttb:0,ttvat:0,tscn:0,tscvat:0,vat:{},itmnet:{}},a=[],r=(e,n,i)=>$$.tdc("currency",$$.tr(t,{class:i||"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text(e)]),fnum(n,$rct.cst)),l=t=>$$.dc("fnote").insertAfter(e).rwText(t),d=e.children("tbody");d.each(((e,t)=>{let n=$(t),r=n.data()||{},l=[],d=[],s=null,c=0,o=n.find("tr.itm"),u=0;n.tC("empty",o.length<1),o.each(((e,t)=>{let n=$(t).data()||{};!function(e,t,n){t.tscn+=e.svcnet_val||0,t.tscvat+=e.svcvat_val||0,t.ttn+=e.net_val||0,t.ttvat+=e.vat_val||0,t.ttb+=(e.net_val||0)+(e.vat_val||0),""!==(e.vat||"")&&(t.vat[e.vat]=(t.vat[e.vat]||0)+(e.vat_val||0))}(n,i,r.Id),c+=n.net_val||0,l.push(n.co);let a=$inv.itemToContract(n);"set"===a.type&&""!==a.id?s=a.id:null!==s&&""!==(a.id||"")&&(a.setId=s),d.push(a),(void 0===n.SortOrder||null===n.SortOrder?-1:n.SortOrder)>-1&&(!1===["text","title"].includes((n.Type||"other").toLowerCase())&&u++,n.SortOrder=0,n.position=u,$inv.rrw.call(t))})),n.find("tr.isum > td.isumval").text(fnum(c,$rct.cst)),a.push({Id:r.Id,nme:r.Name,text:r.text,itm:l,items:d,netval:c})}));let s=e.find("tbody:not(.empty)").length;d.find("tr.isum").tC("hidden",s<2),r("Netto",i.ttn),!1===n?$.each(i.vat,((e,t)=>{r($rct.vat+" "+e,t,"tvat")})):i.ttb=i.ttn,r("Summe",i.ttb);let c=e.data().admin.type;"i"===c?(l($rct.note2),l($rct.note4)):"c"===c?l($rct.note2):(l(string($rct.note3,[fnum((i.tscn+i.tscvat)*(e.data().admin.tax_servicerefund||0),$rct.cst)])).aC("ntax"),l($rct.note2),l(string($rct.note1,[fnum(i.tscn+i.tscvat,$rct.cst),fnum(i.tscn,$rct.cst),fnum(i.tscvat,$rct.cst)]))),!0===n&&l($rct.note13b),e.data("sms",i),e.data("bai",a),""===(e.data("dtoken")||"")&&!1===bool(e.data("dseeding"),!1)&&null!=(e.data("admin")||{}).type&&(e.data("dseeding",!0),$inv.d.seed($.extend($inv.invcPayload(e.data()),{invid:e.data("invid")||""})))},$inv.worknotes=function(e){let t="";return e.steps.forEach(((e,n)=>{let i;try{i=JSON.parse(e.Data||{}).fields||[]}catch(e){console.debug(e),i=[]}!0!==Array.isArray(i||"")&&(i="object"==typeof i&&!0===Array.isArray(i.field||"")?i.field:[]),i.forEach(((e,n)=>{"Ausgeführte Arbeiten"===e.name&&(t=e.result||"")}))})),t},$inv.rendersrq=function(){let e=$(this).empty(),t=e.is(".onesum"),n=e.data(),i=$$.tr(e,{id:"srq"+n.Id}).aC("title nosort"),a=($rcol.itm.lbl(),$$.dc("axf").appendTo($$.tdc("aux",i)));$$.dc("ibtn osum",a,{title:$rct.combP}).append(gi("euro")).click((function(t){e.tC("onesum"),$inv.rendersrq.call(e),$inv.t_fds_inv()})),$$.dc("ibtn setvat",a,{title:$rct.sV}).append(gi("gbp")).click(i,$inv.setVat),$$.dc("ibtn insb",a,{title:$rct.iRb}).append(gi("indent-left")).click(i,$inv.inRow);let r,l=$$.sc("text",n.text),d=($$.td(i,{colspan:t?4:5}).append(l),["net_val","vat_val","svcnet_val","svcvat_val","net"]);if($$.dc("ibtn edit",a).data("dialog",$rcol.req.lbl().Name).append(gi("pencil")).click({t:l,change:e=>{n.text=e,$inv.t_fds_inv()}},$inv.eHtml),t&&($$.tdc("currency isumval",i),r={Id:n.Id.toString()+"_osum",net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0},r.tbl=$$.tblset({class:"stbl"})),$.each(n.items||[],((n,i)=>{let a,l={Id:i.Id,net_val:i.net_val||0,vat_val:i.vat_val||0,svcnet_val:0,svcvat_val:0,net:i.net||0,Note:i.Note||""};if("service"===i.Type.toLowerCase())l.svcnet_val=i.net_val||0,l.svcvat_val=i.vat_val||0;t?(a=$$.tr(r.tbl.bdy,{id:"itm"+i.Id,class:"sitm"}).aC(i.Type),"Text"===i.Type||"Title"===i.Type?$$.td(a,{colspan:2}).html(i.htmltext||i.Note):($$.tdc("keep",a).text(i.quantity||((i.quantityhours||0)>0?fnum(i.quantityhours)+(i.UnitString||"").eine(" ",""):"")),i.htmltext?$$.tdc("txt",a).html(i.htmltext):$$.tdc("txt",a).text(i.NameOrNumber).attr("title",i.Note)),$.each(d,((e,t)=>{r[t]+=l[t]})),a.data(l)):($.extend(l,i),a=$$.tr(e,{id:"itm"+i.Id,class:"itm"}),a.data(l),$inv.rrw.call(a))})),t){let t=$$.tr(e,{id:"itmsq"+n.Id,class:"itm osum"}).data(r);$inv.rrw.call(t)}else{let t=$$.tr(e).aC("isum nosort");$$.tdc("aux",t),$$.td(t,{colspan:4}).text($rct.iSum),$$.tdc("currency isumval",t)}},$inv.t_fds_inv=()=>{let e=$("div.invoice_layout table.invi");e.trigger("fds.inv"),""!==(e.data("dtoken")||"")&&$inv.d.syncChanged(e)},$inv.sedit=()=>{$inv.sprev(!0)},$inv.jdisp=function(e){e.stopPropagation(),e.data.id&&$inv.disp(e.data.id,e.data.typ||"")},$inv.disp=(e,t)=>{let n="";switch(t){case"inv":n="inv/rdoc";break;case"rem":n="rem/rdoc"}""!==n&&$ocms.postXT({url:$ocms.url(n),data:{id:e||"",typ:"img"},success:e=>{let t=$$.dc("imagecollection pdfpreview"),n=Math.round(.88*vh());e.id;$.each(e.img||[],(function(e,i){$$.dc("pdfp",t).append($$.img(i).css("max-height",(n-rpx(6)).toString()+"px"))})),$ocms.dlg(t,{size:[n,Math.round(.88*vw())],zindex_min:50,form:!1,exclusive:!1})}})},$inv.jdbn=function(e){$ocms.postXT({url:$ocms.url("inv/rdocn"),data:{name:e.data.id||"",typ:"img"},success:e=>{let t=$$.dc("imagecollection pdfpreview"),n=Math.round(.88*vh());e.id;$.each(e.img||[],(function(e,i){$$.dc("pdfp",t).append($$.img(i).css("max-height",(n-rpx(6)).toString()+"px"))})),$ocms.dlg(t,{size:[n,Math.round(.88*vw())],zindex:50,form:!1})}})},$inv.sp13b=()=>{var e=$("div.invoice_layout").find("table.invi"),t=e.data();t.admin.p13b=!0,!1===(t.inv.InvoiceOptions||"").split(",").includes("§13b")&&(t.inv.InvoiceOptions+=",§13b"),e.trigger("fds.inv"),$inv.d.sync({Target:"p13b",Value:t.admin.p13b})},$inv.itemToContract=function(e){let t=((e=e||{}).Type||"").toString().toLowerCase(),n={id:(e.Id||"").toString(),type:t,title:"",desc:"",qty:"",price_net:"",total_net:e.net_val||0,vat:e.vat||""};var i;return e.co&&"osum"===e.co.typ?(n.desc=e.co.t||"",n.total_net=e.net_val||0):["text","title"].includes(t)&&0===(e.net_val||0)?(n.desc=e.htmltext||("#"!==(e.NameOrNumber||"").substr(0,1)?(i=$$[0]("p").text(e.NameOrNumber||""),$$.d().append(i).html()):"")+(e.Note||""),n.total_net=""):(e.htmltext?n.desc=e.htmltext:(n.title=e.NameOrNumber||"",n.desc=e.Note||""),n.qty=e.quantity||(0!==(e.quantityhours||0)?fnum(e.quantityhours)+(e.UnitString?" "+e.UnitString:""):""),n.price_net=e.net||0,n.total_net=e.net_val||0),n},$inv.ssetmode=()=>{let e=$("div.invoice_layout").find("table.invi").data();e.admin=e.admin||{};let t,n=e.admin.setmode||"setprice",i=e=>$$.dc("btn",$ict.setmo[e]).tC("selected",n===e).click((()=>{t.c.trigger("modal_close"),$inv.setSetmode(e)})),a=$$.dc("choicefrm").append([i("setprice"),i("itemprices"),i("setonly")]);t=$ocms.dlg(a,{width:800})},$inv.setSetmode=e=>{let t=$("div.invoice_layout").find("table.invi").data();t.admin=t.admin||{},t.admin.setmode=e,t.inv=t.inv||{};let n=(t.inv.InvoiceOptions||"").split(",").filter((e=>""!==e&&0!==e.indexOf("setmode:")));e&&"setprice"!==e&&n.push("setmode:"+e),t.inv.InvoiceOptions=n.join(","),$inv.d.sync({Target:"setmode",Value:e})},$inv.sctp=()=>{let e=$invcol.ctp;$ocms.dlgform(e,{title:$ict.ctp,success:function(e){var t=$("div.invoice_layout"),n=t.find("table.invi").data();let i={};void 0!==n.new&&"{"===(n.new.CustomValues||"").substr(0,1)&&(i=JSON.parse(n.inv.CustomValues)),i.contactName=e.name,i.contactEmail=e.email,n.new.CustomValues=JSON.stringify(i),t.find(".ctpfrm").text(ne(e.name,e.email)),$inv.d.sync({Target:"contact",Value:{name:e.name,email:e.email}})},typedvalues:!0})},$inv.invcPayload=function(e){let t=(e=e||{}).sms||{},n=$.extend({},e.new),i=$.extend({},e.admin);return n.total_net=t.ttn||0,n.total_gross=t.ttb||0,n.title=null!=n.invoicetitle?n.invoicetitle:n.title||"",n.provisionlocation=null!=n.loc?n.loc:n.provisionlocation||"",n.paymentterm=null!=i.paymentterms?i.paymentterms:n.paymentterm||"",i.customerid=null!=i.customerid?i.customerid:i.CustomerId,{admin:i,req:e.bai,sms:e.sms,new:n}},$inv.ssave=()=>{$inv.d.save()},$inv.sprev=e=>{$inv.d.preview()},$inv.rReload=()=>{try{let e=$("#listframe ul.rql:first").data();$inv.cInv2({id:e.search})}catch(e){}},$inv.quantChange=function(e){let t=$(this).closest("form"),n={},i=e=>parseFloat(e.toString().replace("%","").replace(",",".")),a=e=>e.toFixed(2);t.find(":input").each(((e,t)=>{n[$(t).attr("name")]=$(t)}));let r=parseInt(n.quantityhours.val()||"0"),l=i(n.net.val()||"0"),d=.01*i(n.vat.val());r>0&&l>0&&(n.net_val.val(a(r*l)),n.vat_val.val(a(r*l*d)),["Service"].includes(n.Type.val())&&(n.svcnet_val.val(a(r*l)),n.svcvat_val.val(a(r*l*d))))},$inv.storno=function(e,t){let n,i=$$.dc("choicefrm").append([$$.dc("btn","Storno ohne Details").click({id:e,mode:"simple"},(e=>{n.c.trigger("modal_close"),$inv.cSt(e.data)})),$$.dc("btn","Storno mit neuer Rechnung").click({id:e},(e=>{n.c.trigger("modal_close"),$inv.ccStInv(e)})),$$.dc("btn","Storno mit best. Rechnung").tC("inactive",!1===bool(t,!1)).click({id:e,mode:"copy"},(e=>{!0===bool(t,!1)&&(n.c.trigger("modal_close"),$inv.cSt(e.data))}))]);n=$ocms.dlg(i,{width:1e3})},$inv.credit=function(e,t){let n,i=$$.dc("choicefrm").append([$$.dc("btn","Gutschrift").click({id:e,mode:"credit"},(e=>{n.c.trigger("modal_close"),$inv.cSt(e.data)}))]);n=$ocms.dlg(i,{width:1e3})},$inv.setPyd=function(e){confirm($ict.cpyd)&&$ocms.postXT({url:$ocms.url("inv/setpyd"),timeout:60,data:{id:e},success:e=>{alert($ict.relm)},error:()=>{alert($t.f1)}})},$inv.setUpd=function(e){confirm($ict.cupd)&&$ocms.postXT({url:$ocms.url("inv/setupd"),timeout:60,data:{id:e},success:e=>{alert($ict.relm)},error:()=>{alert($t.f1)}})},$inv.resendRem=function(e){e.stopPropagation(),e.data.id&&confirm(string($ict.remresc,[e.data.name]))&&$ocms.postXT({url:$ocms.url("rem/resend"),timeout:60,data:{id:e.data.id},success:t=>{alert(string($ict.remresr,[e.data.name]))},error:()=>{alert($t.f1)}})},$inv.dspRem=function(e){let t=$$.dc("rfrm").ldng(1),n=$ocms.dlg(t,{width:1e3});n.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("inv/getrem"),timeout:60,data:{id:e,drafts:!1},success:e=>{n.ft.empty();let i=$$.tblset({class:"invtbl"},t.empty()),a=$invcol.rem2,r=$$.tr(i.hd);$$.th(r);$.each(a.fields||[],((e,t)=>{$$.th(r).text(t.label)}));let l=!1;$.each(e,((e,t)=>{l=!l;let n=$$.tr(i.bdy).tC("alt",l),r=$$.td(n);n.click((function(){n.tC("selected").siblings().rC("selected")})),!0===bool(t.hasFile,!1)&&($$.dc("idl ilbtn",r,{title:$ict.dl+"\n"+t.DocumentName}).append(gi("save-file","ico")).click({id:t.Id},$inv.downloadrem),$$.dc("idl ilbtn",r,{title:$ict.remdsp+"\n"+t.DocumentName}).append(gi("eye-open","ico")).click({id:t.Id,typ:"rem"},$inv.jdisp),$$.dc("idl ilbtn",r,{title:$ict.remres+"\n"+t.DocumentName}).append(gi("refresh","ico")).click({id:t.Id,typ:"rem",name:t.DocumentName},$inv.resendRem)),$.each(a.fields||[],((e,i)=>{let a=$$.td(n).aC(i.dtype),r=t[i.name];if("function"==typeof i.dfnc)i.dfnc.call(a,r,t);else switch(i.type||""){case"date":a.text(fdt(t[i.name],"dd.MM.yy"));break;case"datetime":a.text(fdt(t[i.name]));break;case"html":a.append($$.dc("ctw").html(r)),a.append($$.dc("ttip").html(r));break;default:a.text(t[i.name])}if("InvoiceId"===(i.name||""))a.aC("keep");switch(typeof i.title){case"function":i.title.call(a,t);break;case"string":a.attr("title",cs.title)}}))}))},error:()=>{t.empty(),n.ft.rwText($t.f1)},complete:()=>{t.ldng(0)}})},$inv.ccRem=function(e,t){$(this);$ocms.postXT({url:$ocms.url("rem/lrem"),timeout:60,data:{id:e},success:n=>{let i=$invcol.rid.clone();i.applyValues(n.ov);let a=$$.dc("ac"),r=$$.tblset({class:"fullgrid fullwidth"},a);if((n.lst||[]).length>0){$$.d({style:"margin: 1.5rem 0 1rem 0;font-size: 110%;text-decoration: underline;"}).prependTo(a).text($ict.rovlh);let e=$$.tr(r.hd);$ict.rovl.forEach(((t,n)=>$$.th(e,t))),$.each(n.lst,((e,t)=>{$$.tr(r.bdy).append([$$.tdc("keep",t.subject),$$.tdc("currency",fnum(t.amount,$rct.cst)),$$.tdc("currency",fnum(t.amount_payed,$rct.cst)),$$.tdc("keep",fdt(t.DateFinalized,"dd.MM.yy"))])}))}else $$.td($$.tr(r.bdy),$ict.nd);$ocms.dlgform(i,{addcontent:a,title:string($ict.remdt,[t||"?"]),success:function(t){$inv.ccRem_s2(e,t)},typedvalues:!0})}})},$inv.rRemRw=function(e){let t=$(this),n=e.rm||{};t.empty().data({invoiceid:n.invoiceid,invoicedate:n.invoicedate,amount:n.amount,amount_payed:n.amount_payed});let i=$$.dc("axf").append($$.dc("ibtn edit",{title:$rct.cP}).append(gi("pencil")).click(t,$inv.eRowR));t.append([$$.tdc("aux").append(i),$$.tdc("keep",n.invoiceid),$$.tdc("keep",fdt(n.invoicedate,"dd.MM.yy")),$$.tdc("currency",fnum(n.amount,$rct.cst)),$$.tdc("currency",fnum(n.amount_payed,$rct.cst)),$$.tdc("currency",fnum(n.amount-n.amount_payed,$rct.cst))])},$inv.eRowR=function(e){let t=$(this),n=e.data,i=n.data()||{},a=$invcol.rem.clone().applyValues(i);$ocms.dlgform(a,{title:t.data("dialog")||"",success:function(e){let i=t.closest("table"),a=i.data();$.extend(a.rm,e),i.data(a),$inv.rRemRw.call(n,a),$inv.rd.syncAmount(a.rm.amount,a.rm.amount_payed)},typedvalues:!0})},$inv.ccRem_s2=function(e,t){$fis.lf(!1).rC("fix").aC("hd");let n=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.rprev));$inv.eM(!1,!0);$$.dc("rfrm").ldng(1);$ocms.postXT({url:$ocms.url("rem/get"),timeout:60,data:$.extend({id:e},t),success:e=>{let t=e.rm||{},i=$$.dc("srq",n),a=$$.tblset({class:"invi"},i);a.ft=$$[0]("tfoot"),a.tbl.data($.extend({invid:t.invid,new:{}},e));let r=$$.tr(a.hd).aC("shd").append([$$.th().aC("aux")]);$ict.remHR.forEach((e=>$$.th(r,e))),$inv.rRemRw.call($$.tr(a.bdy),a.tbl.data()),a.ft.appendTo(a.tbl);let l=(e,t,i,r,l)=>{let d=$$.dc("inpfrm",n).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{a.tbl.data("new")[i]=e}},l),$inv.eHtml)),a.tbl.data("new")[i]=t};l("tfrm",t.subject,"subject",0,null),l("adrfrm",t.invoiceaddress,"invoiceaddress",0,null),l("emailfrm",t.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",n).append($$.dc("content").text(t.sender)),a.tbl.children("tbody").each($inv.bdysort),a.tbl.trigger("fds.inv");let d=a.tbl.data("new");d.amount=t.amount,d.amount_payed=t.amount_payed,$inv.rd.seed({rem:{invid:t.invid,type:t.type,invoiceid:t.invoiceid,invoicedate:t.invoicedate},new:d})},complete:()=>{}})},$inv.rprev=()=>{$inv.rd.preview()},$inv.sis=e=>{confirm($ict.sisc)&&$ocms.postXT({url:$ocms.url("inv/sis"),data:{id:e||""},success:e=>{}})},$inv.srs=e=>{confirm($ict.srsc)&&$ocms.postXT({url:$ocms.url("rem/srs"),data:{id:e||""},success:e=>{}})},$inv.mfrrel=e=>{$("#contentframe").ldng(),$ocms.postXT({url:$ocms.url("inv/mfrrel"),data:{id:e||""},success:e=>{$inv.rerenderinv()},complete:()=>{$("#contentframe").ldng(0)}})};
\ No newline at end of file
+let $rct={mdl:"Aufträge",or:"offene Aufträge",orr:"offene Aufträge (4 W)",rn:"Auftragsnummer",iov:{all:"Auftragsübersicht (alle)","":"Auftragsübersicht"},wk:"Woche",nd:"Keine Daten gefunden.",h:"Uhr",rq1:"Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",rq2:"Auftragsdaten werden geladen",rq1f:"Die Auftragsdaten von MFR konnten nicht oder nicht schnell genug abgerufen werde.\nMöchten Sie mit den bestehenden Daten trotzdem weitermachen?",note1:"Im Bruttobetrag sind {0} Lohnkosten enthalten (netto {1}). Die darin enthaltene Umsatzsteuer beträgt {2}.",note2:"Bitte beachten Sie, nach §14 Abs. 1 Umsatzsteuergesetz ist diese Rechnung ein Zahlungsbeleg oder eine andere beweiskräftige Unterlage für 2 Jahre nach Ablauf des Kalenderjahres der Ausstellung dieser Rechnung aufzubewahren, soweit nicht aufgrund anderer gesetzlicher Regelungen andere ggf.längere Aufbewahrungsfristen gelten.",note3:"Privathaushalten erstattet das Finanzamt bis zu {0} des Arbeitslohns mit der nächsten Steuererklärung.",note4:"Für bereits erbrachte Arbeiten, Dienstleistungen, Materiallieferungen und getätigte Bestellvorgänge zum oben genannten Bauvorhaben, die sich aus dem mit Ihnen geschlossenen Vertrag ergeben, stellen wir Ihnen vertragsgemäß unsere Akontozahlung in Rechnung. Eine Endabrechnung erhalten Sie als Schlussrechnung nach Abschluss des gesamten Bauvorhabens. Das Ausführungsdatum entnehmen Sie bitte dem Schlusstext dieser Rechnung. Wir danken Ihnen herzlich für das entgegengebrachte Vertrauen und bitten Sie um kurzfristigen Ausgleich der Akontorechnung.",note13b:"Gem. §13b Umsatzsteuergesetz unterliegen Sie der Steuerschuldnerschaft des Leistungsempfängers zur Umsatzsteuer aus dieser Rechnung mit einem Steuersatz von 19%.",crI:"Rechnung erstellen",crII:"Abschlagsrechnung erstellen",dII:"Für eine Abschlagsrechnung darf nur ein Auftrag gewählt werden.",dnS:"Für eine Rechnung muss mindestens ein Auftrag gewählt werden.",inv:"Rechnung",invs:"Rechnungen",req:"Auftrag",provP:"Leistungszeitraum",provD:"Leistungsdatum",cP:"Position ändern",iRb:"Zeile darunter einfügen",dR:"Zeile löschen",sV:"USt festlegen",cD:"Löschen?",mR:"Zeile verschieben",svcPart:"Service-Anteil",vat:"Umsatzsteuer",combP:"Positionen zusammenfassen",toSetP:"Auf Setpreis umstellen (Positionen ohne Preis)",toSetPc:"Der Set-Preis wird auf die Summe seiner Positionen gesetzt und die Positionen selbst verlieren ihren Preis. Das ist nicht rückgängig zu machen (der Betrag kann danach nur noch manuell geändert werden). Fortfahren?",toSetMc:"Jeder Leistungsauftrag wird zu einer Set-Position mit der Summe als Preis zusammengefasst. Das ist nicht rückgängig zu machen (die Set-Preise können danach nur noch manuell geändert werden). Fortfahren?",iSum:"Zwischensumme",dtRel:"Freigegeben am: ",dtCr:"Erstellt am: ",rqV:"USt des Auftrags?",cthd:"wirklich aus-/einblenden ?",cst:{style:"currency",currency:"EUR"},sts:{IsWorkDone:"Arbeiten erledigt",Closed:"Auftrag geschlossen",SubcontractorPendingConfirmation:"Warten auf Bestätigung (Unterauftrag)",Scheduled:"Geplant",OfferIsRejected:"Angebot abgelehnt",OfferIsSend:"Offen (Angebot versandt)",CollaborationWaitingConfirmation:"Warten auf Bestätigung (Zusammenarbeit)",Released:"Freigegeben",OfferIsConfirmed:"Bestätigt",InProgress:"In Bearbeitung",ReadyForScheduling:"Zur Planung",Created:"Erstellt",Rejected:"Abgebrochen",Invoiced:"Rechnung gestellt","-":"-"},invHR:["Pos.","Menge","Artikelbezeichnung","VK","Summe"],frm:{invoiceaddress:"Adresse",loc:"Leistungsort / Lieferadresse",invoiceemail:"Email"}},$rcol={req:new fields_definition("Auftrag","Aufträge",[{name:"tags",label:"",type:"string",dfnc:function(e,t){""!==(e||"")&&($(this).aC("tags"),e.split(",").forEach((e=>{""!==e&&$(this).append($$.sc("tag "+e.replace(" ","_").replace("/","_").toLowerCase(),e))})))}},{name:"DateOfCreation",label:"Datum",type:"date",title:function(e){$(this).attr("title",$rct.dtCr+fdt(e.DateOfCreation).ne("-")+" \n"+$rct.dtRel+fdt(e.DateReleased).ne("-"))}},{name:"CustomerName",label:"Kunde (Firma)",type:"string"},{name:"Name",label:"Auftragsname",type:"string"},{name:"ExternalId",label:"Auftragsnummer",type:"string"},{name:"ParentExtenalId",label:"PAuftrag",type:"string"},{name:"InvoiceId",label:"RNummer",type:"string",dfnc:function(e,t){$(this).rwText(e," ").find("span").each((function(){$(this).aC("cla").click({id:$(this).text()},$inv.jdbn)}))}},{name:"State",label:"Status",type:"string"},{name:"WorkDoneAt",label:"Erledigt am",type:"date"},{name:"Description",label:"Beschreibung",type:"html"}]),itm:new fields_definition("Auftragsposition","Auftragspositionen",[{name:"NameOrNumber",label:"Bezeichnung",type:"string"},{name:"Type",label:"Typ",type:"select",required:!0,value:"Text",url:[{value:"Text",label:"Text"},{value:"Equipment",label:"Ausrüstung"},{value:"Material",label:"Material"},{value:"Service",label:"Arbeitsleistung"}],change:function(e){$req.quantChange.call(this,e)}},{name:"quantityhours",label:"Anzahl / Menge",type:"number",precision:"0.01",value:1,change:function(e){$inv.quantChange.call(this,e)}},{name:"UnitString",label:"Einheit",type:"select",url:["LFDM","Stck","Std.","QM","AW","Pauschal"],change:function(e){$inv.quantChange.call(this,e)}},{name:"net",label:"EinzelPreis netto",type:"number",precision:"0.01",value:0,change:function(e){$inv.quantChange.call(this,e)}},{name:"net_val",label:"GesamtPreis netto",type:"number",precision:"0.01",value:0},{name:"vat_val",label:"GesamtPreis USt",type:"number",precision:"0.01",value:0},{name:"svcnet_val",label:"Arbeitslohn netto",type:"number",precision:"0.01",value:0},{name:"svcvat_val",label:"Arbeitslohn USt",type:"number",precision:"0.01",value:0},{name:"net_pos",label:"Netto",type:"string"},{name:"bo_pos",label:"Brutto",type:"string"},{name:"vat",label:"USt",type:"string",value:"19,0%",change:function(e){$inv.quantChange.call(this,e)}},{name:"Note",label:"Details",type:"html",tinymce:!0}])},$ict={mdl:"Rechnungen",iov:{all:"Rechnungen (alle)","":"Rechnungen (nur fertige)","#d":"Rechnungen (nur Entwürfe)","#u":"Rechnungen (nur unbezahlt)","#r":"Rechnungen (nur angemahnt)","#a":"Rechnungen (nur Akonto)","#c":"Rechnungen (nur Storno)","#ru":"Rechnungen (nur angemahnt + unbez.)"},uba:", gesamter Zeitraum)",req:"Auftrag",inv:"Rechnung",rem:"Mahnung",in:"Rechnungsnummer",cc:"Kunde",wk:"Woche",nd:"Keine Daten gefunden.",dl:"Herunterladen",ed:"Bearbeiten",ced:"Bearbeitung fortsetzen",sItm:"Einzelheiten anzeigen",sPay:"Zahlungen anzeigen",cdI:"Entwurf der Rechnung löschen?",rel:"Neu Laden",relm:"Bitte laden Sie Liste manuell neu, um die Änderungen zu sehen.",dsp:"Rechnung anzeigen",storno:"Storno-Rechnung erstellen",credit:"Gutschrift erstellen",remd:"Mahnung erstellen",remdt:"Mahnung erstellen zur Rechnung {0}",remlst:"Mahnungen anzeigen",remdsp:"Mahnung anzeigen",remres:"Mahnung erneut senden",remresc:"Mahnung {0} wirklich erneut senden?",remresr:"Mahnung {0} wurde erfolgreich versandt.",setpyd:"Bezahlt markieren",cpyd:"Rechnung wirklich als bezahlt markieren?",setupd:"Bezahlt-Markierung aufheben",cupd:"Bezahlt-Markierung wirklich aufheben?",ivE:"Die Email-Adresse ist vermutlich nicht gültig.",ivEc:"\nMöchten Sie fortfahren?",pna:"Diese Seite ist in der Vorschau nicht verfügbar",tpe:"Die Anzahl von {0} Seiten wird aktuell nicht unterstützt",eis:"Der Rechnungsentwurf konnte nicht gespeichert werden.",iss:"Zwischenstand speichern.",p13b:"USt -> §13b",setm:"Set-Preisanzeige",setmo:{setprice:"Set mit Preis – Positionen ohne Preis",setonly:"Nur Set mit Preis – Positionen ausgeblendet"},ctp:"Ansprechpartner festlegen",mfr:"Von MFR neu abrufen",rq1:"Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",rq2:"Auftragsdaten werden geladen",iq1:"Rechnungsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.",iq2:"Rechnungsdaten werden geladen",sis:"Rechnung als versandt markieren",srs:"Mahnung als versandt markieren",sisc:"Rechnung wirklich als versandt markieren?",srsc:"Mahnung wirklich als versandt markieren?",iSt:{dft:"Entwurf",uns:"nicht versandt",pyd:"bezahlt",cc:"storniert",op:"offen",due:"fällig",ovd:"überfällig",rem:"angemahnt"},rSt:["","Überfällig","2. Mahnung","3. Stufe"],pSt:{a:"Vollst.",p:"Teilz."},ivT:{i:"AbschlagsR.",f:"SchlussR",r:"Rechnung",c:"StornoR."},rovlh:"Übersicht der bisherigen Mahnungen",rovl:["Betreff","Betrag","Betrag gezahlt","fertiggestellt am"],remHR:["Rechnung","vom","Rechnungsbetrag","bereits bezahlt","noch offen"],translatePaymentTerm:e=>(e||"").replace("wd"," Werktagen").replace("d"," Tagen").replace("wk"," Wochen")||"10 Tagen",payi:{account:"Konto",name:"Zahler",text:"Verw.Zweck",InvoiceID:"Rechnung",amount:"Betrag",date:"Datum",manual:"Typ"}},$invcol={datev:new fields_definition("Rechnung","Rechnungen",[{name:"Umsatz (ohne Soll/Haben-Kz)",label:"Umsatz (ohne Soll/Haben-Kz)",type:"string"},{name:"vf",label:"vf",type:"string"},{name:"Soll/Haben-Kennzeichen",label:"Soll/Haben-Kennzeichen",type:"string"},{name:"Konto",label:"Konto",type:"string"},{name:"Gegenkonto",label:"Gegenkonto",type:"string"},{name:"BU-Schlüssel",label:"BU-Schlüssel",type:"string"},{name:"Belegdatum",label:"Belegdatum",type:"string"},{name:"Belegfeld 1",label:"Belegfeld 1",type:"string"},{name:"Belegfeld 2",label:"Belegfeld 2",type:"string"},{name:"Buchungstext",label:"Buchungstext",type:"string"}]),inv:new fields_definition("Rechnung","Rechnungen",[{name:"invstatus",label:"Status",type:"select",url:$ict.iSt},{name:"balance",label:"Umsatz",type:"string",dtype:"currency"},{name:"CustomerName",label:"Kunde",type:"string"},{name:"InvoiceId",label:"RNummer",type:"string"},{name:"InvoiceType",label:"Typ",type:"select",url:$ict.ivT},{name:"request",label:"Auftrag",type:"string",dtype:"num"},{name:"vat",label:"MwSt",type:"string",dtype:"num"},{name:"deb_cred",label:"Soll/Haben",type:"string"},{name:"customer",label:"Konto",type:"string",dtype:"num"},{name:"contra_account",label:"Gegenkonto",type:"string",dtype:"num"},{name:"Belegdatum",label:"Belegdatum",type:"date"},{name:"reminderstatus",label:"MahnStatus",type:"select",url:$ict.rSt},{name:"reminder",label:"# Mahnungen",type:"integer"},{name:"Buchungstext",label:"Buchungstext",type:"string"},{name:"Payment",label:"Zahlung",type:"string"}]),rem:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"amount",label:"Rechnungsbetrag",type:"number",precision:"0.01",value:1},{name:"amount_payed",label:"bereits bezahlt",type:"number",precision:"0.01",value:1}]),rem2:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"DocumentName",label:"Name",type:"string"},{name:"subject",label:"Betreff",type:"string"},{name:"DateSent",label:"Versanddatum",type:"date"},{name:"status",label:"Status",type:"string"},{name:"amount_open",label:"offener Betrag",type:"number",precision:"0.01"},{name:"InvoiceId",label:"RNummer",type:"string"}]),rid:new fields_definition("Zahlungserinnerung","Zahlungserinnerung",[{name:"type",label:"Typ",type:"select",url:[["f","einfache Zahlungserinnerung"],["m","Mahnung"],["l","letzte Mahnung"]],required:!0},{name:"level",label:"Stufe",type:"select",url:[["1","Stufe 1"],["2","Stufe 2"],["3","Stufe 3"],["4","Stufe 4"],["5","Stufe 5"],["6","Stufe 6"]],required:!0}]),ctp:new fields_definition("Ansprechpartner","Ansprechpartner",[{name:"name",label:"Name",type:"string"},{name:"email",label:"Email",type:"string"}])},gi=(e,t)=>$$.sc("glyphicon glyphicon-"+e).aC(t),$inv={},$req={init2:function(e,t){e=e||"inv",t=t||{},$ocms.getScript([],(function(){$req.init3(e,t)}))},init3:async function(e,t){$fis.cf(!0);let n=$fis.lf(!0);$("#topbar").ocmsmenu([]),$("#activemodule").text($rct.mdl),await $fis.prepAuth("fds_req,fds_inv,fds_reminder");let i=[(async()=>{!0===$fis.isAuth("fds_req",1)&&($req.prepLst(""),n.aC("fix"))})(),new Promise(((e,t)=>{n.find("div.oreq2").aC("selected"),$req.renderreq(fdt(new Date,"yy-MM-dd"),"r"),e()}))];await Promise.all(i)},prepLst:function(e){let t=new Date,n=$fis.lf(!0).ldng(1),i=new Date("2021-01-01");$fis.frm_list().IN((function(){}));$$.dc("mth oreq",n).text($rct.or).click((function(e){let t=$(this);e.stopPropagation(),t.siblings().rC("selected"),!0===t.is(".selected")&&(t.tC("selected"),$req.renderreq(fdt(new Date,"yy-MM-dd"),"o")),t.aC("selected")})),$$.dc("mth oreq2",n).text($rct.orr).click((function(e){let t=$(this);e.stopPropagation(),t.siblings().rC("selected"),!0===t.is(".selected")&&(t.tC("selected"),$req.renderreq(fdt(new Date,"yy-MM-dd"),"r")),t.aC("selected")})),$$.i({placeholder:$rct.rn}).appendTo($$.dc("mth oreqn",n)).enterKey((function(e){let t=$(this),n=t.val()||"";e.stopPropagation(),t.parent().siblings().rC("selected"),n.length>3&&(t.parent().aC("selected"),$req.renderreq("n:"+n,"s"),t.val(""))}));n.append("
");let r=$$.dc("mthl",n),a=t.getFullYear(),d=t.getMonth()+1;for(let t=i.getFullYear();t<=a;t++){let n=$$.dc("yr").prependTo(r).text($rct.iov[e]+" - "+t.toString()).toggleClass("selected",t===a);n.click({yr:t},(function(e){e.stopPropagation(),n.siblings().rC("selected"),n.aC("selected")}));let l=$$.dc("mfrm",n);for(let n=0;n<(t!==a?12:d);n++){i=new Date(t,n,1);let r=$$.dc("mth").prependTo(l).text($rct.iov[e]+" - "+fdt(i,"MMM yyyy"));r.click({yr:t,mt:n},(function(e){if(e.stopPropagation(),r.siblings().rC("selected"),!0===r.is(".selected")){r.tC("selected");let t=fdt(new Date(e.data.yr,e.data.mt,1),"yy-MM-dd");$req.renderreq(t,"m")}r.aC("selected")}));let a=getMonday(i),d=new Date(i);d.setMonth(d.getMonth()+1),d.setDate(0),d=getMonday(d);let s=$$.dc("wfrm",r);for(;a<=d;){let e=$$.dc("wk",s).text(($rct.wk||"W")+" "+fdt(a,"dd.MM.yy"));e.click({rd:new Date(a)},(function(t){t.stopPropagation();let n=fdt(t.data.rd,"yy-MM-dd");$req.renderreq(n,"w"),r.siblings().rC("selected").find(".wk").rC("selected"),r.aC("selected").find(".wk").rC("selected"),e.aC("selected")}));let t=$$.dc("wkdl",e).append($$.sc("ico glyphicon glyphicon-compressed"));!0===$fis.isAuth("fds_inv",2)&&t.click({rd:new Date(a)},(function(e){e.stopPropagation();let t=fdt(e.data.rd,"yy-MM-dd");$req.downloadzip.call(t,"w")})),a.setDate(a.getDate()+7)}}}n.ldng(0)},renderreq:function(e,t){let n=$fis.frm_list().ldng(1),i=$$.dc("invfrm",n).aC("md"+t),r=$fis.lf();$ocms.postXT({url:$ocms.url("req/reql"),data:{mode:t,tgt:e},success:n=>{r.rC("fix").aC("hd"),$$.dc("ovhd",i).append($$.s(n.admin.title)).appendIf($$.sc("note",n.admin.note),""!==ne(n.admin.note,""));let a=$$.tblset({},i),d=$rcol.req,l=$$.tr(a.hd);$$.th(l);$.each(d.fields||[],((e,t)=>{$$.th(l).text(t.label),"vat"===t.name&&$$.th(l)}));let s=0,c=!1;$.each(n.requests||[],((n,l)=>{s>0&&s!==l.ParentServiceRequestId&&(c=!c);let o=$$.tr(a.bdy).tC("alt",c);s=l.ParentServiceRequestId,o.click((function(){r.rC("fix").aC("hd"),o.tC("selected").siblings().rC("selected").find("td.av").rC("av"),o.find("td.av").rC("av")})),o.tC("child",l.isChild);let u=$$.td(o,{class:"raux"});!0===bool(l.open,!1)&&$$.dc("ihd ilbtn",u).append(gi("eye-close","ico")).click({id:l.Id},$req.tHd),$$.dc("iitm ilbtn",u).append(gi("list","ico")).click({id:l.Id},$req.showitm),!0===$fis.isAuth("fds_inv",2)&&$$.dc("invc ilbtn",u).append(gi("edit","ico")).click({id:l.Id},$inv.cInv),$.each(d.fields||[],((n,r)=>{let a=$$.td(o).aC(r.dtype),d=l[r.name];if("function"==typeof r.dfnc)r.dfnc.call(a,d,l);else switch(r.type||""){case"date":a.text(fdt(l[r.name],"dd.MM.yy"));break;case"datetime":a.text(fdt(l[r.name]));break;case"html":a.append($$.dc("ctw").html(d)),a.append($$.dc("ttip").html(d));break;default:a.text(l[r.name])}switch(r.name||""){case"State":a.text($rct.sts[d||"-"]);break;case"Name":a.aC(r.name.toLowerCase());break;case"vat":$$.sel().appendTo($$.td(o,{class:"vsel"})).click((function(e){e.stopPropagation()})).append([$$.opt("19,0 %","19,0 %"),$$.opt("16,0 %","16,0 %"),$$.opt("0,0 %","0,0 %")]).val(l[r.name]).change().change({frm:i,tgt:e,mode:t,id:l.Id,td:a},$req.setvat),a.tC("hl","19"!==l[r.name].substr(0,2)).click((function(e){e.stopPropagation(),$(this).tC("av")}));break;case"balance":a.aC("sh_"+(l.SollHaben||"").toLowerCase());break;case"InvoiceId":a.aC("keep")}switch(typeof r.title){case"function":r.title.call(a,l);break;case"string":a.attr("title",cs.title)}}))}))},complete:()=>{n.ldng(0)}})},tHd:function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&confirm($rct.cthd)&&$ocms.postXT({url:$ocms.url("req/rthd"),data:{id:e.data.id},success:n=>{n.id===e.data.id&&!1===bool(n.visible,!0)?(!1===t.is(".tbhd")&&setTimeout((()=>{t.filter(".tbhd").remove()}),15e3),t.aC("tbhd")):n.id===e.data.id&&t.rC("tbhd")}})},showitm:function(e){let t=$(this).closest("tr");if(e.stopPropagation(),!1===t.is(".selected"))return;let n=$$.dc("rfrm").ldng(1);$ocms.postXT({url:$ocms.url("req/pget"),data:{id:e.data.id},success:t=>{$ocms.postXT({url:$ocms.url("req/get"),data:{id:e.data.id,mode:"ful"},success:e=>{if((e.requests||[]).length<1)n.text($rct.nd);else{let t=$$.dc("srq",n),i=$$.tblset({class:"if"},t);$.each(e.requests||[],(function(e,t){e>0&&$$.tr(i.bdy).aC("sep").append($$.td({colspan:6}));let n=$$.tr(i.bdy).aC("title"),r=$rcol.itm.lbl(),a=$inv.worknotes(t);$$.td(n,{colspan:6}).append([$$.s($rcol.req.label_sng),$$.sc("eid",t.ExternalId),$$.sc("nme",fdt(t.WorkDoneAt,"dd.MM.yy")+": "+a.ne(t.Name))]);$$.tr(i.bdy).aC("shd").append([$$.td(),$$.td(r.NameOrNumber),$$.td(r.Type),$$.td(r.net_pos),$$.td(r.bo_pos),$$.td(r.vat)]);$.each(t.items||[],((e,t)=>{t.ServiceRequestId;let n=$$.tr(i.bdy,{id:"itm"+t.Id}).aC(t.Type);$$.td(n).aC("ico"),$$.td(n).text(t.NameOrNumber),$$.td(n).text(t.Type),$$.td(n).aC("currency").text(t.net_pos),$$.td(n).aC("currency").text(t.bo_pos),$$.td(n).aC("num").text(t.vat)}))}))}},error:()=>{n.text($t.t12)},complete:()=>{n.ldng(0)}})},error:()=>{n.text($t.t12),n.ldng(0)}}),$ocms.dlg(n,{width:1e3})}},$$req={init2:$req.init2,auth:{}};export default $$req;$inv.cInv=function(e){let t=$(this).closest("tr");e.stopPropagation(),!1!==t.is(".selected")&&!1!==$fis.isAuth("fds_inv",2)&&$inv.cInv2({id:e.data.id})},$inv.rMn=e=>{let t=[{lbl:$ict.req,itm:[]}];return!0===bool(e,!1)&&!0===$fis.isAuth("fds_inv",2)&&Array.prototype.push.apply(t[0].itm,[{lbl:$rct.crI,fnc:$inv.ccInv,data:{typ:"r"}},{lbl:$rct.crII,fnc:$inv.ccInv,data:{typ:"i"}}]),t.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(t)},$inv.iMnr=e=>{let t=booln(e.isFinal,!0),n=e.Id,i=booln(e.fds,!1),r=[{glyph:"glyphicon-menu-left",fnc:()=>{$fis.frm_edit().remove()}},{lbl:$ict.inv,itm:[]},{lbl:$ict.rem,itm:[]}];return!1===t&&!0===$fis.isAuth("fds_inv",2)?r[1].itm.push({lbl:$ict.ced,fnc:$inv.clCntInv}):!0===$fis.isAuth("fds_inv",1)&&r[1].itm.push({lbl:$ict.dsp,fnc:()=>$inv.disp(n,"inv")}),!0===i&&!0===t&&!0===$fis.isAuth("fds_inv",2)&&(r[1].itm.push({lbl:$ict.storno,fnc:()=>$inv.storno(n,i)}),r[1].itm.push({lbl:$ict.credit,fnc:()=>$inv.credit(n,i)})),!0===t&&!0===$fis.isAuth("fds_reminder",2)&&(r[2].itm.push({lbl:$ict.remd,fnc:()=>$inv.ccRem(n,e.InvoiceId)}),r[2].itm.push({lbl:$ict.remlst,fnc:()=>$inv.dspRem(n)})),!0===t&&!0===$fis.isAuth("fds_reminder",2)&&!1===booln(e.IsSent,!1)&&r[2].itm.push({lbl:$ict.srs,fnc:()=>$inv.srs(n)}),r.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(r)},$inv.iMn=e=>{let t=booln(e.isFinal,!0),n=e.Id,i=booln(e.fds,!1),r=[{glyph:"glyphicon-menu-left",fnc:()=>{$fis.frm_edit().remove()}},{lbl:$ict.inv,itm:[]},{lbl:$ict.rem,itm:[]}];return!1===t&&!0===$fis.isAuth("fds_inv",2)?r[1].itm.push({lbl:$ict.ced,fnc:()=>{$inv.cntInv({id:n})}}):!0===$fis.isAuth("fds_inv",1)&&r[1].itm.push({lbl:$ict.dsp,fnc:()=>$inv.disp(n,"inv")}),!0===$fis.isAuth("fds_inv",2)&&(r[1].itm.push({lbl:$ict.storno,fnc:()=>$inv.storno(n,i)}),r[1].itm.push({lbl:$ict.credit,fnc:()=>$inv.credit(n,i)})),!0===t&&!1===booln(e.IsPayed,!1)?(!0===$fis.isAuth("fds_reminder",2)&&r[2].itm.push({lbl:$ict.remd,fnc:()=>$inv.ccRem(n,e.InvoiceId)}),!0===$fis.isAuth("fds_inv",2)&&r[1].itm.push({lbl:$ict.setpyd,fnc:()=>$inv.setPyd(n)})):!0===t&&!0===booln(e.IsPayed,!1)&&"m"===(e.PaymentStatus||"")&&!0===$fis.isAuth("fds_inv",2)&&r[1].itm.push({lbl:$ict.setupd,fnc:()=>$inv.setUpd(n)}),!0===$fis.isAuth("fds_reminder",2)&&r[2].itm.push({lbl:$ict.remlst,fnc:()=>$inv.dspRem(n)}),!0===t&&!0===$fis.isAuth("fds_inv",2)&&!1===booln(e.IsSent,!1)&&r[1].itm.push({lbl:$ict.sis,fnc:()=>$inv.sis(n)}),!1===i&&r[1].itm.push({lbl:$ict.mfr,fnc:()=>$inv.mfrrel(n)}),$("#topbar").ocmsmenu(r)},$inv.emOpt=e=>"iss,p13b,ctp"+(""===((e||{}).setmode||"")?",setm":""),$inv.eM=(e,t,n)=>{let i=[];return!0!==booln(e,!1)&&!0!==booln(t,!1)||i.push({glyph:"glyphicon-menu-left",fnc:()=>{$fis.lf(!0),$fis.frm_edit().remove()}}),!0===(n||"").split(",").includes("iss")&&i.push({lbl:$ict.iss,fnc:$inv.ssave}),!0===(n||"").split(",").includes("ctp")&&i.push({lbl:$ict.ctp,fnc:$inv.sctp}),!0===(n||"").split(",").includes("p13b")&&i.push({lbl:$ict.p13b,fnc:$inv.sp13b}),!0===(n||"").split(",").includes("setm")&&i.push({lbl:$ict.setm,fnc:$inv.ssetmode}),!0===(n||"").split(",").includes("iss")&&(i.push({lbl:"Änderungshistorie",fnc:()=>$inv.d.history()}),i.push({lbl:"Änderungen verwerfen",fnc:()=>$inv.d.discard()})),!0===booln(e,!1)&&i.push({lbl:$ict.rel,fnc:$inv.rReload}),$("#topbar").ocmsmenu(i)},$inv.d={tbl:()=>$("div.invoice_layout table.invi"),layout:()=>$("div.invoice_layout"),token:function(){return $inv.d.tbl().data("dtoken")||""},hashes:function(){let e=$inv.d.tbl().data("bai")||[],t={};return $.each(e,((e,n)=>{t[(n.Id||"").toString()]=JSON.stringify(n)})),t},seed:function(e){let t=$inv.d.layout();t.aC("freeze");let n=$ocms.postXT({url:$ocms.url("inv/dopen"),data:{payload:JSON.stringify(e)},success:e=>{$inv.d.tbl().data("dtoken",e.token).data("dver",e.version).data("dhashes",$inv.d.hashes()).data("dorder",$inv.d.order()),$fis.draft.bind(e.token,{onReady:()=>$inv.d.refresh(),onExpiring:e=>$inv.d.warnExpiry(e),onClosed:e=>$inv.d.closed(e)}),$inv.d.refresh()},error:()=>{t.rC("freeze")},complete:()=>{$inv.d.tbl().removeData("dseeding").removeData("dseedpromise")}});return $inv.d.tbl().data("dseedpromise",n),n},refresh:function(e){let t=$inv.d.token();""!==t&&$ocms.postXT({url:$ocms.url("inv/dstate"),data:{token:t},success:t=>{$inv.d.applyState(t),"function"==typeof e&&e(t)},error:e=>{e&&410===e.status&&$inv.d.closed("expired")},complete:()=>{$inv.d.layout().rC("freeze")}})},applyState:function(e){let t=$inv.d.tbl();if(t.length<1)return;let n=t.data("dver");"number"==typeof n&&"number"==typeof e.version&&e.version$$.dc("dnote").aC(e.style||"InvoiceNotes").text(e.text)))},applyItems:function(e,t){let n=e=>void 0===e?null:e;(t||[]).forEach((t=>{if(!t)return;let i=(t.Id||"").toString();if(""===i)return;let r=e.children("tbody").filter(((e,t)=>(($(t).data()||{}).Id||"").toString()===i)).first();if(r.length<1)return;let a=t.itm||[],d={},l=r.find("tr.title").first(),s=l.length?l:null;a.forEach((e=>{let t=(e.id||"").toString();if(""===t)return;d[t]=!0;let i=r.find("#itm"+t).first(),a=i.length<1;a&&(i=$$.tr(r,{id:"itm"+t,class:"itm"}));let l=i.data()||{},c=a||(l.Type||"")!==(e.typ||"")||l.net!==n(e.v)||l.net_val!==n(e.vt)||l.vat_val!==n(e.vv)||l.svcnet_val!==n(e.vs)||l.svcvat_val!==n(e.vsv)||(l.position||"")!==(null!=e.p?e.p:"");$.extend(l,{Id:t,Type:e.typ,net:n(e.v),net_val:n(e.vt),vat_val:n(e.vv),svcnet_val:n(e.vs),svcvat_val:n(e.vsv),vat:e.vat,position:null!=e.p?e.p:"",SetItmId:null!=e.SetItmId?e.SetItmId:null}),a&&$.extend(l,{htmltext:e.t,quantity:e.q}),i.data(l),s?i.prev()[0]!==s[0]&&i.insertAfter(s):r.children().first()[0]!==i[0]&&r.prepend(i),s=i,c&&$inv.rrw.call(i)})),r.find("tr.itm").each(((e,t)=>{let n=(($(t).data()||{}).Id||"").toString();""===n||d[n]||$(t).remove()}))}))},applySetDisplay:function(e,t){e.find("tr.itm").each(((e,n)=>{let i=$(n),r=((i.data()||{}).Id||"").toString();if(""===r||!Object.prototype.hasOwnProperty.call(t,r))return;let a=t[r]||{};i.tC("sethdr",bool(a.h,!1)),!1===bool(a.p,!0)&&i.find("td.currency").text("")}))},sync:function(e){let t=$inv.d.token();if(""===t){let t=$inv.d.tbl().data("dseedpromise");return t?$.when(t).then((()=>$inv.d.sync(e))):$.when()}return $inv.d.layout().aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dpatch"),data:{token:t,delta:JSON.stringify(e)},success:()=>{$inv.d.refresh()},error:e=>{$inv.d.layout().rC("freeze"),e&&410===e.status&&$inv.d.closed("expired")}})},order:function(){return($inv.d.tbl().data("bai")||[]).map((e=>(e.Id||"").toString()))},syncChanged:function(e){let t=e.data("bai")||[],n=e.data("dhashes")||{},i={},r=[],a=[],d=[];$.each(t,((e,t)=>{let a=(t.Id||"").toString(),d=JSON.stringify(t);i[a]=d,n[a]!==d&&r.push(t)})),$.each(n,(e=>{void 0===i[e]&&a.push(e)}));let l=$inv.d.order(),s=e.data("dorder")||[];return e.data("dhashes",i).data("dorder",l),r.forEach((e=>d.push($inv.d.sync({Target:"block.replace",Ref:(e.Id||"").toString(),Value:e})))),a.forEach((e=>d.push($inv.d.sync({Target:"block.remove",Ref:e})))),s.length===l.length&&s.slice().sort().join(",")===l.slice().sort().join(",")&&s.join(",")!==l.join(",")&&d.push($inv.d.sync({Target:"block.order",Value:l})),$.when.apply($,d).promise()},syncField:function(e,t){let n={invoicetitle:"title",invoiceaddress:"address",invoiceemail:"email",loc:"provisionlocation",provisionlocation:"provisionlocation",provisionperiod:"provisionperiod"}[e];n&&$inv.d.sync({Target:n,Value:t})},footer:function(e,t,n){let i=e.children("tfoot").empty();e.nextAll(".fnote").remove();let r=bool(n.p13b,!1),a=(e,t,n)=>$$.tdc("currency",$$.tr(i,{class:n||"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text(e)]),fnum(t,$rct.cst)),d=t=>$$.dc("fnote").insertAfter(e).rwText(t);a("Netto",t.total_net||0),!1===r&&$.each(t.vat||{},((e,t)=>a($rct.vat+" "+e+"%",t,"tvat"))),a("Summe",t.total_gross||0);let l=n.type||"";"i"===l?(d($rct.note2),d($rct.note4)):"c"===l?d($rct.note2):(d(string($rct.note3,[fnum(((t.service_net||0)+(t.service_vat||0))*(n.tax_servicerefund||0),$rct.cst)])).aC("ntax"),d($rct.note2),d(string($rct.note1,[fnum((t.service_net||0)+(t.service_vat||0),$rct.cst),fnum(t.service_net||0,$rct.cst),fnum(t.service_vat||0,$rct.cst)]))),!0===r&&d($rct.note13b)},validation:function(e){let t=$("div.invoice_layout");if(t.length<1)return;let n=t.children(".dvalidation");n.length<1&&(n=$$.dc("dvalidation"),t.prepend(n)),n.empty().tC("hidden",(e||[]).length<1),$.each(e||[],((e,t)=>$$.dc("dvmsg",n).aC(t.severity).text(t.message)))},preview:function(){let e=$inv.d.token();if(""===e)return;let t=$inv.d.layout(),n=($inv.d.tbl().data("new")||{}).invoiceemail||"";!1===$fis.ValidateEmail(n)&&!1===bool(confirm($ict.ivE+$ict.ivEc),!1)||(t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dpreview"),data:{token:e},success:n=>{t.rC("freeze");let i=$$.dc("imagecollection pdfpreview"),r=Math.round(.88*vh()),a=n.total;a>10&&$$.dc("note warn",i).text($ict.tpe),$.each(n.img||[],((e,t)=>{$$.dc("pdfp",i).append($$.img(t).css("max-height",(r-rpx(6)).toString()+"px"))}));for(let e=(n.img||[]).length+1;e<=a;e++)$$.dc("pdfp ph",i).append($$.dc("note",$ict.pna));$ocms.dlg(i,{size:[r,Math.round(.88*vw())],zindex:50,form:!1,button:$rct.crI,confirm:function(n){let i=$(this);t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dsave"),data:{token:e},success:e=>{$ocms.postXT({url:$ocms.url("req/sconf"),data:{id:e.invid},success:t=>{i.trigger("modal_close"),!0===t.hasFile&&window.open($ocms.url("req/idoc")+"?id="+e.invid,"_blank"),$inv.d.close(),$ocms.init("req"),$inv.rReload()},error:()=>{alert($t.f1),i.trigger("modal_close")},complete:()=>{t.rC("freeze")}})},error:()=>{t.rC("freeze"),alert($ict.eis)}})},cancel:function(e){confirm($ict.cdI)&&($inv.d.close(),$inv.rReload())}})},error:()=>{t.rC("freeze"),alert($ict.eis)}}))},save:function(){let e=$inv.d.token();if(""===e)return;let t=$inv.d.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("inv/dsave"),data:{token:e},success:e=>{$inv.d.tbl().data("invid",e.invid)},error:()=>{alert($ict.eis)},complete:()=>{t.rC("freeze")}})},history:function(){let e=$inv.d.token();""!==e&&$ocms.postXT({url:$ocms.url("inv/dhistory"),data:{token:e},success:e=>{let t=$$.dc("dhist");if((e.history||[]).length<1)$$.dc("note",t).text("Noch keine Änderungen erfasst.");else{let n=$$.tblset({class:"invtbl fullwidth"},t);$$.tr(n.hd).append([$$.th().text("Zeit"),$$.th().text("Feld"),$$.th().text("Alt"),$$.th().text("Neu")]),$.each(e.history,((e,t)=>$$.tr(n.bdy).append([$$.tdc("keep",fdt(t.timestamp)),$$.td().text(t.target),$$.td().text(t.oldValue),$$.td().text(t.newValue)])))}$ocms.dlg(t,{width:800,form:!1})}})},discard:function(){let e=$inv.d.tbl().data("invid")||"";""!==e?!1!==confirm("Alle Änderungen verwerfen und den zuletzt gespeicherten Stand neu laden?")&&($inv.d.close(),$inv.cntInv({id:e})):alert("Es wurde noch kein Zwischenstand gespeichert, der wiederhergestellt werden könnte.")},warnExpiry:function(e){let t=Math.max(1,Math.round((e||0)/60));$fis.notifications.push({severity:"info",title:"Entwurf läuft ab",message:"Der Rechnungsentwurf läuft in etwa "+t+" Minute(n) ab. Bitte zwischenspeichern, sonst gehen die Änderungen verloren."})},closed:function(e){let t=$inv.d.token();$inv.d.tbl().removeData("dtoken"),""!==t&&$fis.draft.release(t),$fis.frm_edit().remove(),$fis.lf(!0),$fis.notifications.push({severity:"error",title:"Entwurf geschlossen",message:"expired"===e?"Der Rechnungsentwurf ist wegen Inaktivität abgelaufen. Nicht gespeicherte Änderungen sind verloren.":"Der Rechnungsentwurf wurde geschlossen."});try{$inv.rReload()}catch(e){}},close:function(){let e=$inv.d.token();""!==e&&($ocms.postXT({url:$ocms.url("inv/dclose"),data:{token:e}}),$fis.draft.release(e)),$inv.d.tbl().removeData("dtoken")}},$inv.rd={tbl:()=>$("div.invoice_layout table.invi"),layout:()=>$("div.invoice_layout"),token:function(){return $inv.rd.tbl().data("rdtoken")||""},seed:function(e){let t=$inv.rd.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dopen"),data:{payload:JSON.stringify(e)},success:e=>{$inv.rd.tbl().data("rdtoken",e.token).data("rdver",e.version),$fis.draft.bind(e.token,{onReady:()=>$inv.rd.refresh(),onExpiring:e=>$inv.rd.warnExpiry(e),onClosed:e=>$inv.rd.closed(e)}),$inv.rd.refresh()},error:()=>{t.rC("freeze")}})},refresh:function(e){let t=$inv.rd.token();""!==t&&$ocms.postXT({url:$ocms.url("rem/dstate"),data:{token:t},success:t=>{$inv.rd.applyState(t),"function"==typeof e&&e(t)},error:e=>{e&&410===e.status&&$inv.rd.closed("expired")},complete:()=>{$inv.rd.layout().rC("freeze")}})},applyState:function(e){let t=$inv.rd.tbl();if(t.length<1)return;let n=t.data("rdver");"number"==typeof n&&"number"==typeof e.version&&e.version{let t=$$[0]("p").aC("dnote intro").rwText(e);r.length?t.insertBefore(r):t.appendTo(n)})),((e||{}).closing||[]).forEach((e=>$$[0]("p").aC("dnote closing").rwText(e).appendTo(n)))},sync:function(e){let t=$inv.rd.token();""!==t&&($inv.rd.layout().aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dpatch"),data:{token:t,delta:JSON.stringify(e)},success:()=>{$inv.rd.refresh()},error:e=>{$inv.rd.layout().rC("freeze"),e&&410===e.status&&$inv.rd.closed("expired")}}))},syncField:function(e,t){if(""===$inv.rd.token())return;let n={subject:"subject",invoiceaddress:"address",invoiceemail:"email",text:"text"}[e];n&&$inv.rd.sync({Target:n,Value:t})},syncAmount:function(e,t){""!==$inv.rd.token()&&($inv.rd.sync({Target:"amount",Value:(null!=e?e:0).toString()}),$inv.rd.sync({Target:"amount_payed",Value:(null!=t?t:0).toString()}))},footer:function(e,t){let n=e.children("tfoot").empty(),i=$$.tr(n,{class:"tsum"}).append([$$.tdc("aux"),$$.td({colspan:4}).text("Offener Betrag")]);$$.tdc("currency",i,fnum(t.amount_open||0,$rct.cst))},validation:function(e){let t=$inv.rd.layout();if(t.length<1)return;let n=t.children(".dvalidation");n.length<1&&(n=$$.dc("dvalidation"),t.prepend(n)),n.empty().tC("hidden",(e||[]).length<1),$.each(e||[],((e,t)=>$$.dc("dvmsg",n).aC(t.severity).text(t.message)))},preview:function(){let e=$inv.rd.token();if(""===e)return;let t=$inv.rd.layout(),n=($inv.rd.tbl().data("new")||{}).invoiceemail||"";!1===$fis.ValidateEmail(n)&&!1===bool(confirm($ict.ivE+$ict.ivEc),!1)||(t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dpreview"),data:{token:e},success:n=>{t.rC("freeze");let i=$$.dc("imagecollection pdfpreview"),r=Math.round(.88*vh());$.each(n.img||[],((e,t)=>{$$.dc("pdfp",i).append($$.img(t).css("max-height",(r-rpx(6)).toString()+"px"))})),$ocms.dlg(i,{size:[r,Math.round(.88*vw())],zindex:50,form:!1,button:$ict.remd,confirm:function(n){let i=$(this);t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dsave"),data:{token:e},success:e=>{$ocms.postXT({url:$ocms.url("rem/conf"),data:{id:e.remid},success:()=>{i.trigger("modal_close"),window.open($ocms.url("rem/idoc")+"?id="+e.remid,"_blank"),$inv.rd.close(),$ocms.init("req"),$inv.rReload()},error:()=>{alert($t.f1),i.trigger("modal_close")},complete:()=>{t.rC("freeze")}})},error:()=>{t.rC("freeze"),alert($t.f1)}})},cancel:function(e){confirm($ict.cdI)&&($inv.rd.close(),$inv.rReload())}})},error:()=>{t.rC("freeze"),alert($t.f1)}}))},save:function(){let e=$inv.rd.token();if(""===e)return;let t=$inv.rd.layout();t.aC("freeze"),$ocms.postXT({url:$ocms.url("rem/dsave"),data:{token:e},success:e=>{$inv.rd.tbl().data("remid",e.remid)},error:()=>{alert($t.f1)},complete:()=>{t.rC("freeze")}})},history:function(){let e=$inv.rd.token();""!==e&&$ocms.postXT({url:$ocms.url("rem/dhistory"),data:{token:e},success:e=>{let t=$$.dc("dhist");if((e.history||[]).length<1)$$.dc("note",t).text("Noch keine Änderungen erfasst.");else{let n=$$.tblset({class:"invtbl fullwidth"},t);$$.tr(n.hd).append([$$.th().text("Zeit"),$$.th().text("Feld"),$$.th().text("Alt"),$$.th().text("Neu")]),$.each(e.history,((e,t)=>$$.tr(n.bdy).append([$$.tdc("keep",fdt(t.timestamp)),$$.td().text(t.target),$$.td().text(t.oldValue),$$.td().text(t.newValue)])))}$ocms.dlg(t,{width:800,form:!1})}})},warnExpiry:function(e){let t=Math.max(1,Math.round((e||0)/60));$fis.notifications.push({severity:"info",title:"Entwurf läuft ab",message:"Der Mahnentwurf läuft in etwa "+t+" Minute(n) ab. Bitte zwischenspeichern, sonst gehen die Änderungen verloren."})},closed:function(e){let t=$inv.rd.token();$inv.rd.tbl().removeData("rdtoken"),""!==t&&$fis.draft.release(t),$fis.frm_edit().remove(),$fis.lf(!0),$fis.notifications.push({severity:"error",title:"Entwurf geschlossen",message:"expired"===e?"Der Mahnentwurf ist wegen Inaktivität abgelaufen. Nicht gespeicherte Änderungen sind verloren.":"Der Mahnentwurf wurde geschlossen."});try{$inv.rReload()}catch(e){}},close:function(){let e=$inv.rd.token();""!==e&&($ocms.postXT({url:$ocms.url("rem/dclose"),data:{token:e}}),$fis.draft.release(e)),$inv.rd.tbl().removeData("rdtoken")}},$inv.cInv2=function(e){let t=$$.dc("rfrm").ldng(1),n=$ocms.dlg(t,{width:1e3});n&&n.ft.rwText($rct.rq1);let i=()=>{$ocms.postXT({url:$ocms.url("req/get"),timeout:60,data:{id:e.id,mode:"r"},success:t=>{t.admin=t.admin||{};let n=$fis.lf(!0).aC("fix").rC("hd");if($fis.frm_edit().IN(),$inv.eM(!0,!0),(t.requests||[]).length<1)n.aC("fix").text($rct.nd);else{$$.dc("lh",n,$rct.mdl);let i=$$.d(),r=$$.ul({class:"rql"}).data({search:e.id,parent:t.admin.parent}).appendTo(n),a={},d=$rcol.req.lbl();$.each(t.requests||[],(function(e,t){let n=$$.li({class:"cli rli"}).data($.extend({},t)).appendTo(r),l=$$.dc("lihd",n).addClass(t.state);!0===booln(t.open,!1)&&l.append($$.sc("cbox").click((()=>{n.tC("checked"),i.find("li").rC("checked"),!0===n.is(".checked")?$inv.rMn(t.open):$inv.eM(!0)}))),l.append([$$.sc("eid",t.ExternalId),$$.sc("nme",t.Name)]),$$.dc("lidt",n).append([$$.dc("rqs").append([$$.s(d.State+": "),$$.s($rct.sts[t.State||"-"])]),$$.dc("ivn").append([$$.s(d.InvoiceId+": "),$$.s(t.InvoiceId||"- -")]),$$.dc("wda").append([$$.s(d.WorkDoneAt+": "),$$.s(fdt(t.WorkDoneAt,"dd.MM.yyyy"))])]),a[t.Id]=n})),(t.inv||[]).length>0&&($$.dc("lh",n,$rct.invs),i=$$.ul({class:"ivl"}).appendTo(n),$.each(t.inv||[],((e,t)=>{let n=$$.li({class:"cli ili"}).data($.extend({},t)).appendTo(i),a=$$.dc("lihd",n).addClass(t.invstatus);!1===booln(t.isFinal,!0)?a.append($$.sc("cbox").click((()=>{""!==(t.Id||"")&&(n.tC("checked").siblings().rC("checked"),r.find("li").rC("checked"),!0===n.is(".checked")?$inv.iMnr(t):$inv.eM(!0))}))):["","dft"].indexOf(t.invstatus)<0&&a.append($$.sc("dli").click((function(){$inv.disp(t.Id,"inv")}))),a.append($$.sc("nme",t.DocumentName||t.Id)),$$.dc("lidt",n).append([$$.dc("wda").append([$$.s(fdt(t.DateCreated,"dd.MM.yyyy"))]),$$.d().text($ict.iSt[t.invstatus]||t.invstatus)])})))}},complete:()=>{n&&n.c.trigger("modal_close")}})};$ocms.postXT({url:$ocms.url("req/pget"),timeout:90,data:{id:e.id},success:e=>{n&&n.ft.rwText($rct.rq2),i()},error:()=>{confirm($rct.rq1f)?(n&&n.ft.rwText($rct.rq2),i()):n&&n.c.trigger("modal_close")}})},$inv.ccInv=function(e){let t=(e.data||{}).typ||"r",n=$fis.lf(),i=n.children("ul.rql"),r=i.data("parent"),a=[];if(i.find("li.rli.checked").each((function(){a.push($(this).data("Id"))})),a.length<1)return void alert($rct.dnS);if("i"===t&&a.length>1)return void alert($rct.dII);let d=$fis.frm_edit(),l=$$.dc("invoice_layout",d).append($$.dc("btn sprev").click($inv.sprev)),s=$fis.cf().width()>l.width()+n.width()+20;n.tC("fix",s).tC("hd",!s),$inv.eM(!1,!0);let c=$$.dc("rfrm").ldng(1),o=$ocms.dlg(c,{width:1e3});o.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("req/iget"),timeout:60,data:{id:r,mode:"ful",typ:t,sel:a.join(",")},success:e=>{let t=$$.dc("srq",l),n=$$.tblset({class:"invi"},t);n.bdy.remove(),n.ft=$$[0]("tfoot"),e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b")),n.tbl.data($.extend({new:{},sms:{},itm:{}},{admin:e.admin,companies:e.companies,locations:e.locations}));let i=$$.tr(n.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(i,e))),n.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.requests||[],(function(t,i){if(0!==(i.Id||0)){let t=$inv.worknotes(i);i.text="i"===e.admin.type?$rct.req+jine([i.ExternalId,i.Name],": ").eine(" ",""):jine([jine([fdt(i.WorkDoneAt,"dd.MM.yy"),i.ExternalId]," - "+$rct.req+" "),t.ne(i.Name)],": \n");let r=$$.tbody(n.tbl).data($.extend({},i));$inv.rendersrq.call(r)}}));let r=$$.tr($$.tbody(n.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(r),n.ft.appendTo(n.tbl);let a,d,s=e.admin||{},c=(e,t,i,r,a)=>{let d=$$.dc("inpfrm",l).aC(e).append("string"==typeof r?$$.dc("ahd",r):r>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",d).rwText(t);$$.dc("axf",d).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{n.tbl.data("new")[i]=e}},a),$inv.eHtml)),n.tbl.data("new")[i]=t};c("tfrm",s.invoicetitle,"invoicetitle",0,null),c("adrfrm",s.invoiceaddress,"invoiceaddress",0,null),c("locfrm","","loc",1,{list:deepCopy(e.locations),lbl:"ref",property:"address"}),c("emailfrm",s.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",l).append($$.dc("content").text(s.sender)),s.provisionend&&(d=s.provisionstart?$rct.provP:$rct.provD,a=s.provisionstart?fdt(s.provisionstart,"dd.MM.yyyy")+" - "+fdt(s.provisionend,"dd.MM.yyyy"):fdt(s.provisionend,"dd.MM.yyyy")),c("admfrm",a,"provisionperiod",d,1),n.tbl.data("new").CustomValues=s.CustomValues||"",$$.dc("inpfrm ctpfrm",l).text(jObj(s.CustomValues,"contactName")),n.tbl.children("tbody").each($inv.bdysort),n.tbl.trigger("fds.inv"),$inv.eM(!1,!0,$inv.emOpt(s))},complete:()=>{o.c.trigger("modal_close")}})},$inv.ccStInv=function(e){let t=e.data||{},n=$fis.lf(),i=t.id,r=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sprev)),a=$fis.cf().width()>r.width()+n.width()+20;n.tC("fix",a).tC("hd",!a),$inv.eM(!1,!0);let d=$$.dc("rfrm").ldng(1),l=$ocms.dlg(d,{width:1e3});l.ft.rwText($ict.iq1),$ocms.postXT({url:$ocms.url("inv/pget"),timeout:90,data:{id:t.id},success:e=>{l&&l.ft.rwText($ict.iq2),$ocms.postXT({url:$ocms.url("inv/icget"),timeout:60,data:{id:i},success:e=>{let t=$$.dc("srq",r),n=$$.tblset({class:"invi"},t);n.bdy.remove(),n.ft=$$[0]("tfoot"),e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b")),n.tbl.data($.extend({new:{},sms:{},itm:{}},{admin:e.admin,companies:e.companies,locations:e.locations}));let i=$$.tr(n.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(i,e))),n.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.requests||[],(function(t,i){if(0!==(i.Id||0)){let t=$inv.worknotes(i);i.text="i"===e.admin.type?$rct.req+jine([i.ExternalId,i.Name],": ").eine(" ",""):jine([fdt(i.WorkDoneAt,"dd.MM.yy")+t.ne(i.Name)],": ");let r=$$.tbody(n.tbl).data($.extend({},i));$inv.rendersrq.call(r)}}));let a=$$.tr($$.tbody(n.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(a),n.ft.appendTo(n.tbl);let d,l,s=e.admin||{},c=(e,t,i,a,d)=>{let l=$$.dc("inpfrm",r).aC(e).append("string"==typeof a?$$.dc("ahd",a):a>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",l).rwText(t);$$.dc("axf",l).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{n.tbl.data("new")[i]=e}},d),$inv.eHtml)),n.tbl.data("new")[i]=t};c("tfrm",s.invoicetitle,"invoicetitle",0,null),c("adrfrm",s.invoiceaddress,"invoiceaddress",0,null),c("locfrm",s.provisionlocation,"loc",1,{list:deepCopy(e.locations),lbl:"ref",property:"address"}),c("emailfrm",s.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",r).append($$.dc("content").text(s.sender)),s.provisionend&&(l=s.provisionstart?$rct.provP:$rct.provD,d=s.provisionstart?fdt(s.provisionstart,"dd.MM.yyyy")+" - "+fdt(s.provisionend,"dd.MM.yyyy"):fdt(s.provisionend,"dd.MM.yyyy")),c("admfrm",d,"provisionperiod",l,1),n.tbl.data("new").CustomValues=s.CustomValues||"",$$.dc("inpfrm ctpfrm",r).text(jObj(s.CustomValues,"contactName")),n.tbl.children("tbody").each($inv.bdysort),n.tbl.trigger("fds.inv")},complete:()=>{l.c.trigger("modal_close")}})},error:()=>{l&&l.c.trigger("modal_close")}})},$inv.clCntInv=function(e){let t=$fis.lf(!1),n=[];t.find("li.ili.checked").each((function(){n.push($(this).data("Id"))})),1===n.length&&$inv.cntInv({id:n[0]})},$inv.cntInv=function(e){e=e||{};$fis.lf(!1).rC("fix").aC("hd");let t=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sedit));$inv.eM(!1,!0);let n=$$.dc("rfrm").ldng(1),i=$ocms.dlg(n,{width:1e3});i.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("inv/get"),timeout:60,data:{id:e.id},success:e=>{e.admin=e.admin||{};let n=e.inv||{},i=$$.dc("srq",t),r=$$.tblset({class:"invi"},i);r.bdy.remove(),r.ft=$$[0]("tfoot"),r.tbl.data($.extend({invid:n.Id,new:{},sms:{},itm:{},bai:[]},e));let a=$$.tr(r.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(a,e))),r.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.req||[],(function(e,t){let n=$$.tbody(r.tbl).data($.extend({},t));$inv.rendersrq.call(n)}));let d=$$.tr($$.tbody(r.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(d),r.ft.appendTo(r.tbl);let l=(e,n,i,a,d)=>{let l=$$.dc("inpfrm",t).aC(e).append("string"==typeof a?$$.dc("ahd",a):a>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",l).rwText(n);$$.dc("axf",l).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{r.tbl.data("new")[i]=e}},d),$inv.eHtml)),r.tbl.data("new")[i]=n};l("tfrm",n.InvoiceTitle,"invoicetitle",0,null),l("adrfrm",n.SendToAddress,"invoiceaddress",0,null),l("locfrm",n.ProvisionLocation,"loc",1,null),l("emailfrm",n.SendToEmail,"invoiceemail",0,null),$$.dc("sndfrm",t).append($$.dc("content").text(e.admin.sender)),l("admfrm",n.ProvisionPeriod,"provisionperiod",!0===(n.ProvisionPeriod||"").includes("-")?$rct.provP:$rct.provD,1),r.tbl.data("new").CustomValues=n.CustomValues||"",$$.dc("inpfrm ctpfrm",t).text(jObj(n.CustomValues,"contactName")),r.tbl.children("tbody").each($inv.bdysort),r.tbl.trigger("fds.inv"),$inv.eM(!1,!0,$inv.emOpt(e.admin))},complete:()=>{i.c.trigger("modal_close")}})},$inv.cSt=function(e){e=e||{};let t=$fis.lf(),n=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.sedit)),i=$fis.cf().width()>n.width()+t.width()+20;t.tC("fix",i).tC("hd",!i),$inv.eM(!1,!0);let r=$$.dc("rfrm").ldng(1),a=$ocms.dlg(r,{width:1e3});a.ft.rwText($ict.iq1),$ocms.postXT({url:$ocms.url("inv/pget"),data:{id:e.id},success:t=>{a&&a.ft.rwText($ict.iq2),$ocms.postXT({url:$ocms.url("inv/storno"),data:{id:e.id,mode:e.mode},success:e=>{e.admin=e.admin||{},e.admin.p13b=bool(e.admin.p13b||"",!0===((e.inv||{}).InvoiceOptions||"").split(",").includes("§13b"));let t=e.inv||{},i=$$.dc("srq",n),r=$$.tblset({class:"invi"},i);r.bdy.remove(),r.ft=$$[0]("tfoot"),r.tbl.data($.extend({invid:t.Id,new:{},sms:{},itm:{},bai:[]},e));let a=$$.tr(r.hd).aC("shd").append([$$.th().aC("aux")]);$rct.invHR.forEach((e=>$$.th(a,e))),r.tbl.on("fds.inv",$inv.invSumUpdate),$.each(e.req||[],(function(e,t){let n=$$.tbody(r.tbl).data($.extend({},t));$inv.rendersrq.call(n)}));let d=$$.tr($$.tbody(r.tbl),{class:"placeholder"}).data({net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0});$inv.rrw.call(d),r.ft.appendTo(r.tbl);let l=(e,t,i,a,d)=>{let l=$$.dc("inpfrm",n).aC(e).append("string"==typeof a?$$.dc("ahd",a):a>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",l).rwText(t);$$.dc("axf",l).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{r.tbl.data("new")[i]=e}},d),$inv.eHtml)),r.tbl.data("new")[i]=t};l("tfrm",t.InvoiceTitle,"invoicetitle",0,null),l("adrfrm",t.SendToAddress,"invoiceaddress",0,null),l("locfrm",t.ProvisionLocation,"loc",1,null),l("emailfrm",t.SendToEmail,"invoiceemail",0,null),$$.dc("sndfrm",n).append($$.dc("content").text(e.admin.sender)),l("admfrm",t.ProvisionPeriod,"provisionperiod",!0===(t.ProvisionPeriod||"").includes("-")?$rct.provP:$rct.provD,1),r.tbl.data("new").CustomValues=t.CustomValues||"",$$.dc("inpfrm ctpfrm",n).text(jObj(t.CustomValues,"contactName")),r.tbl.children("tbody").each($inv.bdysort),r.tbl.trigger("fds.inv")},complete:()=>{a.c.trigger("modal_close")}})},error:()=>{a&&a.c.trigger("modal_close")}})},$inv.eHtml=function(e){let t=$(this),n=e.data instanceof jQuery?e.data:e.data.t,i=["invoiceemail","provisionperiod","invoicetitle"].includes(e.data.nme),r=i?[{name:"txt",label:"Text",type:"text",value:n.text()}]:[{name:"txt",label:"Text",type:"html",value:n.html(),tinymce:!0,attr:{style:"height: 300px"}}],a=e.data.change||null,d={title:t.data("dialog")||"",success:function(t){i?n.text(t.txt||""):n.html(t.txt),"function"==typeof a&&a(t.txt),$inv.d.syncField(e.data.nme,i?t.txt||"":t.txt),$inv.rd.syncField(e.data.nme,i?t.txt||"":t.txt)},tinymce:{valid_elements:"br",hidemenu:!0,hidetoolbar:!0}};if(Array.isArray(e.data.list)){let t=$$.dc("lstfrm");$.each(e.data.list,((n,i)=>{let r=$$.dc("li",t).append(""!==(e.data.lbl||"")?$$.dc("lbl").rwText(i[e.data.lbl]):null);$$.dc("adr",r).rwText(i[e.data.property]).data("val",i[e.data.property]).click((function(){let e=$(this),t=e.closest(".modal-body").find(':input[name="txt"]');t.is(".tinymce")?tinymce.get(t.attr("id")).setContent($$.s().rwText(e.data("val")).html()):"TEXTAREA"===t.prop("tagName")?t.val(e.data("val")).change():t.rwText(e.data("val"))}))})),d.addcontent=t}$ocms.dlgform(r,d)},$inv.setVat=function(e){$(this);let t=e.data,n=prompt($rct.rqV);n&&(n=parseFloat(n.replace("%","")),n>1&&(n*=.01),!1===isNaN(n)&&(t.siblings(".itm").each((function(){$(this).data().vat=fnum(n,{style:"percent"}).replace(" ","")})),$inv.t_fds_inv()))},$inv.inRow=function(e){let t=$(this),n=e.data,i={},r=$rcol.itm.clone(["SortOrder","NameOrNumber","Type","quantityhours","UnitString","net","svcnet_val","svcvat_val","net_val","vat_val","vat","Note"]),a="N"+(65536*(1+Math.random())||0).toString(16).substr(6),d=$$.tr({id:"itm_"+a.toString(),class:"itm"});$ocms.dlgform(r,{title:t.data("dialog")||"",success:function(e){d.data($.extend({Id:a},i,e)),$inv.rrw.call(d),d.insertAfter(n),$inv.t_fds_inv()},typedvalues:!0})},$inv.eRow=function(e){let t=$(this),n=e.data,i=n.data()||{},r=["SortOrder","NameOrNumber","Type","quantityhours","UnitString","net","svcnet_val","svcvat_val","net_val","vat_val","vat","Note"];i.id||""!==(i.Type||"")||r.unshift("Type");let a=$rcol.itm.clone(r).applyValues(i);a.set("Type","hidden","type"),$inv.eRw.call(t,n,i,a)},$inv.eRw=function(e,t,n){let i=$(this);$ocms.dlgform(n,{title:i.data("dialog")||"",success:function(n){let i={};""===(t.Id||"")&&(i.Id="N"+(65536*(1+Math.random())||0).toString(16).substr(6),e.attr("id","itm_"+i.Id.toString())),i.quantity=((n.quantityhours||"").toString()+" "+(n.UnitString||"").toString()).trimEnd(),e.data($.extend({},t,n,i)),console.debug("eRw success %o",e.data()),$inv.rrw.call(e),$inv.t_fds_inv()},typedvalues:!0})},$inv.bdysort=(e,t)=>{$(t).Sortable({dragItem:!1,dragHandleClass:"ico",parentident:"tr",onend:()=>{$inv.t_fds_inv()}})},$inv.rrw=function(){let e=$(this),t=e.data(),n={},i=e.is(".placeholder"),r=e.is(".hidenote"),a=e=>$$.d().append(e).html(),d=[$$.dc("ibtn insb",{title:$rct.iRb}).append(gi("indent-left")).click(e,$inv.inRow)];!1===i&&(d.unshift($$.dc("ibtn edit",{title:$rct.cP}).append(gi("pencil")).click(e,$inv.eRow)),d.push($$.dc("ibtn del",{title:$rct.dR}).append(gi("trash")).click((function(t){confirm($rct.cD)&&(e.remove(),$inv.t_fds_inv())}))),"set"===(t.Type||"").toLowerCase()&&0===(t.net_val||0)&&d.push($$.dc("ibtn tosetp",{title:$rct.toSetP}).append(gi("scale")).click(e,$inv.toSetPrice)));let l=$$.dc("axf").append(d);!0===i?n={id:"",typ:"placeholder"}:!0===e.is(".itm.osum")?n={invrqid:t.InvRqId,id:"osum"+e.index(),typ:"osum",p:"",q:null,t:a(t.tbl.tbl),tt:null,v:null,vt:t.net_val,vs:t.svcnet_val,vat:t.vat,vv:t.vat_val,vsv:t.svcvat_val,det:!1}:(n={invrqid:t.InvRqId,id:t.Id||"",typ:t.Type||"other",p:"",q:null,t:"",tt:null,v:null,vt:t.net_val,vs:t.svcnet_val,vat:t.vat,vv:t.vat_val,vsv:t.svcvat_val,det:""!==(t.Note||"")&&!1===r,SetItmId:t.SetItmId||null},$$.dc("ibtn ico move",l,{title:$rct.mR}),n.p=t.position||t.SortOrder||"",""===n.id?n.t="":["Text","Title"].includes(n.typ)&&0===(t.net_val||0)?n.t=t.htmltext||("#"!==(t.NameOrNumber||"").substr(0,1)?a($$[0]("p").text(t.NameOrNumber)):"")+(t.Note||""):(n.tt=n.det?"":$$.s(t.Note||"").text(),n.q=t.quantity||(0!==(t.quantityhours||0)?fnum(t.quantityhours)+" "+(t.UnitString||""):""),n.t=t.htmltext||(n.det?a($$.s(t.NameOrNumber||""))+a($$.dc("desc").html(t.Note)):a($$.s(t.NameOrNumber||""))),n.v=t.net,n.vt=t.net_val)),""!==(t.Note||"")&&$$.dc("ibtn add",l).append(gi("object-align-left")).click((function(t){$inv.rrw.call(e.tC("hidenote"))}));let s=[$$.tdc("aux").append(l),$$.tdc("keep").text(n.p)];if(""===n.id)s.push($$.td(e,{colspan:4}).append(n.t));else{Array.prototype.push.apply(s,n.q?[$$.tdc("keep").text(n.q)]:[]);let e=e=>null==e?"":fnum(e,$rct.cst);Array.prototype.push.apply(s,[$$.tdc("txt",{colspan:n.q?1:2,title:n.tt}).append(n.t),$$.tdc("currency").text(e(n.v)),$$.tdc("currency inetval").text(e(n.vt)).attr("title",$rct.svcPart+": "+e(n.vs))])}e.empty().attr("class",i?"placeholder":"itm").aC(n.Typ).tC("sethdr","set"===(n.typ||"").toString().toLowerCase()).tC("hidenote",r).append(s),t.co=n},$inv.toSetPrice=function(e){let t=(e.data.data().Id||"").toString();""!==t&&!1!==confirm($rct.toSetPc)&&$.when($inv.t_fds_inv()).done((()=>{$inv.d.sync({Target:"item.setprice",Ref:t})}))},$inv.invSumUpdate=function(){let e=$(this),t=[],n=e.children("tbody");n.each(((e,n)=>{let i=$(n),r=i.data()||{},a=[],d=[],l=i.find("tr.itm"),s=0;i.tC("empty",l.length<1),l.each(((e,t)=>{let n=$(t).data()||{};a.push(n.co);let i=$inv.itemToContract(n),r=(n.SetItmId||"").toString();"set"!==i.type&&""!==r&&r!==i.id&&(i.setId=r),d.push(i),(void 0===n.SortOrder||null===n.SortOrder?-1:n.SortOrder)>-1&&(!1===["text","title"].includes((n.Type||"other").toLowerCase())&&s++,n.SortOrder=0,n.position=s,$inv.rrw.call(t))})),t.push({Id:r.Id,nme:r.Name,text:r.text,itm:a,items:d})}));let i=e.find("tbody:not(.empty)").length;n.find("tr.isum").tC("hidden",i<2),e.data("bai",t),""===(e.data("dtoken")||"")&&!1===bool(e.data("dseeding"),!1)&&null!=(e.data("admin")||{}).type&&(e.data("dseeding",!0),$inv.d.seed($.extend($inv.invcPayload(e.data()),{invid:e.data("invid")||""})))},$inv.worknotes=function(e){let t="";return e.steps.forEach(((e,n)=>{let i;try{i=JSON.parse(e.Data||{}).fields||[]}catch(e){console.debug(e),i=[]}!0!==Array.isArray(i||"")&&(i="object"==typeof i&&!0===Array.isArray(i.field||"")?i.field:[]),i.forEach(((e,n)=>{"Ausgeführte Arbeiten"===e.name&&(t=e.result||"")}))})),t},$inv.rendersrq=function(){let e=$(this).empty(),t=e.is(".onesum"),n=e.data(),i=$$.tr(e,{id:"srq"+n.Id}).aC("title nosort"),r=($rcol.itm.lbl(),$$.dc("axf").appendTo($$.tdc("aux",i)));$$.dc("ibtn osum",r,{title:$rct.combP}).append(gi("euro")).click((function(t){e.tC("onesum"),$inv.rendersrq.call(e),$inv.t_fds_inv()})),$$.dc("ibtn setvat",r,{title:$rct.sV}).append(gi("gbp")).click(i,$inv.setVat),$$.dc("ibtn insb",r,{title:$rct.iRb}).append(gi("indent-left")).click(i,$inv.inRow);let a,d=$$.sc("text",n.text),l=($$.td(i,{colspan:t?4:5}).append(d),["net_val","vat_val","svcnet_val","svcvat_val","net"]);if($$.dc("ibtn edit",r).data("dialog",$rcol.req.lbl().Name).append(gi("pencil")).click({t:d,change:e=>{n.text=e,$inv.t_fds_inv()}},$inv.eHtml),t&&($$.tdc("currency isumval",i),a={Id:n.Id.toString()+"_osum",net_val:0,vat_val:0,svcnet_val:0,svcvat_val:0,net:0},a.tbl=$$.tblset({class:"stbl"})),$.each(n.items||[],((n,i)=>{let r,d={Id:i.Id,net_val:i.net_val||0,vat_val:i.vat_val||0,svcnet_val:0,svcvat_val:0,net:i.net||0,Note:i.Note||""};if("service"===i.Type.toLowerCase())d.svcnet_val=i.net_val||0,d.svcvat_val=i.vat_val||0;t?(r=$$.tr(a.tbl.bdy,{id:"itm"+i.Id,class:"sitm"}).aC(i.Type),"Text"===i.Type||"Title"===i.Type?$$.td(r,{colspan:2}).html(i.htmltext||i.Note):($$.tdc("keep",r).text(i.quantity||((i.quantityhours||0)>0?fnum(i.quantityhours)+(i.UnitString||"").eine(" ",""):"")),i.htmltext?$$.tdc("txt",r).html(i.htmltext):$$.tdc("txt",r).text(i.NameOrNumber).attr("title",i.Note)),$.each(l,((e,t)=>{a[t]+=d[t]})),r.data(d)):($.extend(d,i),r=$$.tr(e,{id:"itm"+i.Id,class:"itm"}),r.data(d),$inv.rrw.call(r))})),t){let t=$$.tr(e,{id:"itmsq"+n.Id,class:"itm osum"}).data(a);$inv.rrw.call(t)}else{let t=$$.tr(e).aC("isum nosort");$$.tdc("aux",t),$$.td(t,{colspan:4}).text($rct.iSum),$$.tdc("currency isumval",t)}},$inv.t_fds_inv=()=>{let e=$("div.invoice_layout table.invi");if(e.trigger("fds.inv"),""!==(e.data("dtoken")||""))return $inv.d.syncChanged(e);let t=e.data("dseedpromise");return t?$.when(t).then((()=>$inv.d.syncChanged(e))):$.when()},$inv.sedit=()=>{$inv.sprev(!0)},$inv.jdisp=function(e){e.stopPropagation(),e.data.id&&$inv.disp(e.data.id,e.data.typ||"")},$inv.disp=(e,t)=>{let n="";switch(t){case"inv":n="inv/rdoc";break;case"rem":n="rem/rdoc"}""!==n&&$ocms.postXT({url:$ocms.url(n),data:{id:e||"",typ:"img"},success:e=>{let t=$$.dc("imagecollection pdfpreview"),n=Math.round(.88*vh());e.id;$.each(e.img||[],(function(e,i){$$.dc("pdfp",t).append($$.img(i).css("max-height",(n-rpx(6)).toString()+"px"))})),$ocms.dlg(t,{size:[n,Math.round(.88*vw())],zindex_min:50,form:!1,exclusive:!1})}})},$inv.jdbn=function(e){$ocms.postXT({url:$ocms.url("inv/rdocn"),data:{name:e.data.id||"",typ:"img"},success:e=>{let t=$$.dc("imagecollection pdfpreview"),n=Math.round(.88*vh());e.id;$.each(e.img||[],(function(e,i){$$.dc("pdfp",t).append($$.img(i).css("max-height",(n-rpx(6)).toString()+"px"))})),$ocms.dlg(t,{size:[n,Math.round(.88*vw())],zindex:50,form:!1})}})},$inv.sp13b=()=>{var e=$("div.invoice_layout").find("table.invi"),t=e.data();t.admin.p13b=!0,!1===(t.inv.InvoiceOptions||"").split(",").includes("§13b")&&(t.inv.InvoiceOptions+=",§13b"),e.trigger("fds.inv"),$inv.d.sync({Target:"p13b",Value:t.admin.p13b})},$inv.itemToContract=function(e){let t=((e=e||{}).Type||"").toString().toLowerCase(),n=e=>e??null,i={id:(e.Id||"").toString(),type:t,title:"",desc:"",qty:"",price_net:"",total_net:n(e.net_val),vat:e.vat||""};var r;return e.co&&"osum"===e.co.typ?(i.desc=e.co.t||"",i.total_net=e.net_val||0):["text","title"].includes(t)&&0===(e.net_val||0)?(i.desc=e.htmltext||("#"!==(e.NameOrNumber||"").substr(0,1)?(r=$$[0]("p").text(e.NameOrNumber||""),$$.d().append(r).html()):"")+(e.Note||""),i.total_net=""):(e.htmltext?i.desc=e.htmltext:(i.title=e.NameOrNumber||"",i.desc=e.Note||""),i.qty=e.quantity||(0!==(e.quantityhours||0)?fnum(e.quantityhours)+(e.UnitString?" "+e.UnitString:""):""),i.price_net=n(e.net),i.total_net=n(e.net_val)),i},$inv.ssetmode=()=>{let e=$("div.invoice_layout").find("table.invi").data();e.admin=e.admin||{};let t,n=e.admin.setmode||"setprice",i=e=>$$.dc("btn",$ict.setmo[e]).tC("selected",n===e).click((()=>{t.c.trigger("modal_close"),$inv.setSetmode(e)})),r=$$.dc("choicefrm").append([i("setprice"),i("setonly")]);t=$ocms.dlg(r,{width:800})},$inv.setSetmode=e=>{if(!1===confirm($rct.toSetMc||$rct.toSetPc))return;let t="setonly"===e?"block.setonly":"block.setprice";$.when($inv.t_fds_inv()).done((()=>{$inv.d.sync({Target:t})}))},$inv.sctp=()=>{let e=$invcol.ctp;$ocms.dlgform(e,{title:$ict.ctp,success:function(e){var t=$("div.invoice_layout"),n=t.find("table.invi").data();let i={};void 0!==n.new&&"{"===(n.new.CustomValues||"").substr(0,1)&&(i=JSON.parse(n.inv.CustomValues)),i.contactName=e.name,i.contactEmail=e.email,n.new.CustomValues=JSON.stringify(i),t.find(".ctpfrm").text(ne(e.name,e.email)),$inv.d.sync({Target:"contact",Value:{name:e.name,email:e.email}})},typedvalues:!0})},$inv.invcPayload=function(e){e=e||{};let t=$.extend({},e.new),n=$.extend({},e.admin);return t.title=null!=t.invoicetitle?t.invoicetitle:t.title||"",t.provisionlocation=null!=t.loc?t.loc:t.provisionlocation||"",t.paymentterm=null!=n.paymentterms?n.paymentterms:t.paymentterm||"",n.customerid=null!=n.customerid?n.customerid:n.CustomerId,{admin:n,req:e.bai,new:t}},$inv.ssave=()=>{$inv.d.save()},$inv.sprev=e=>{$inv.d.preview()},$inv.rReload=()=>{try{let e=$("#listframe ul.rql:first").data();$inv.cInv2({id:e.search})}catch(e){}},$inv.quantChange=function(e){},$inv.storno=function(e,t){let n,i=$$.dc("choicefrm").append([$$.dc("btn","Storno ohne Details").click({id:e,mode:"simple"},(e=>{n.c.trigger("modal_close"),$inv.cSt(e.data)})),$$.dc("btn","Storno mit neuer Rechnung").click({id:e},(e=>{n.c.trigger("modal_close"),$inv.ccStInv(e)})),$$.dc("btn","Storno mit best. Rechnung").tC("inactive",!1===bool(t,!1)).click({id:e,mode:"copy"},(e=>{!0===bool(t,!1)&&(n.c.trigger("modal_close"),$inv.cSt(e.data))}))]);n=$ocms.dlg(i,{width:1e3})},$inv.credit=function(e,t){let n,i=$$.dc("choicefrm").append([$$.dc("btn","Gutschrift").click({id:e,mode:"credit"},(e=>{n.c.trigger("modal_close"),$inv.cSt(e.data)}))]);n=$ocms.dlg(i,{width:1e3})},$inv.setPyd=function(e){confirm($ict.cpyd)&&$ocms.postXT({url:$ocms.url("inv/setpyd"),timeout:60,data:{id:e},success:e=>{alert($ict.relm)},error:()=>{alert($t.f1)}})},$inv.setUpd=function(e){confirm($ict.cupd)&&$ocms.postXT({url:$ocms.url("inv/setupd"),timeout:60,data:{id:e},success:e=>{alert($ict.relm)},error:()=>{alert($t.f1)}})},$inv.resendRem=function(e){e.stopPropagation(),e.data.id&&confirm(string($ict.remresc,[e.data.name]))&&$ocms.postXT({url:$ocms.url("rem/resend"),timeout:60,data:{id:e.data.id},success:t=>{alert(string($ict.remresr,[e.data.name]))},error:()=>{alert($t.f1)}})},$inv.dspRem=function(e){let t=$$.dc("rfrm").ldng(1),n=$ocms.dlg(t,{width:1e3});n.ft.rwText($rct.rq2),$ocms.postXT({url:$ocms.url("inv/getrem"),timeout:60,data:{id:e,drafts:!1},success:e=>{n.ft.empty();let i=$$.tblset({class:"invtbl"},t.empty()),r=$invcol.rem2,a=$$.tr(i.hd);$$.th(a);$.each(r.fields||[],((e,t)=>{$$.th(a).text(t.label)}));let d=!1;$.each(e,((e,t)=>{d=!d;let n=$$.tr(i.bdy).tC("alt",d),a=$$.td(n);n.click((function(){n.tC("selected").siblings().rC("selected")})),!0===bool(t.hasFile,!1)&&($$.dc("idl ilbtn",a,{title:$ict.dl+"\n"+t.DocumentName}).append(gi("save-file","ico")).click({id:t.Id},$inv.downloadrem),$$.dc("idl ilbtn",a,{title:$ict.remdsp+"\n"+t.DocumentName}).append(gi("eye-open","ico")).click({id:t.Id,typ:"rem"},$inv.jdisp),$$.dc("idl ilbtn",a,{title:$ict.remres+"\n"+t.DocumentName}).append(gi("refresh","ico")).click({id:t.Id,typ:"rem",name:t.DocumentName},$inv.resendRem)),$.each(r.fields||[],((e,i)=>{let r=$$.td(n).aC(i.dtype),a=t[i.name];if("function"==typeof i.dfnc)i.dfnc.call(r,a,t);else switch(i.type||""){case"date":r.text(fdt(t[i.name],"dd.MM.yy"));break;case"datetime":r.text(fdt(t[i.name]));break;case"html":r.append($$.dc("ctw").html(a)),r.append($$.dc("ttip").html(a));break;default:r.text(t[i.name])}if("InvoiceId"===(i.name||""))r.aC("keep");switch(typeof i.title){case"function":i.title.call(r,t);break;case"string":r.attr("title",cs.title)}}))}))},error:()=>{t.empty(),n.ft.rwText($t.f1)},complete:()=>{t.ldng(0)}})},$inv.ccRem=function(e,t){$(this);$ocms.postXT({url:$ocms.url("rem/lrem"),timeout:60,data:{id:e},success:n=>{let i=$invcol.rid.clone();i.applyValues(n.ov);let r=$$.dc("ac"),a=$$.tblset({class:"fullgrid fullwidth"},r);if((n.lst||[]).length>0){$$.d({style:"margin: 1.5rem 0 1rem 0;font-size: 110%;text-decoration: underline;"}).prependTo(r).text($ict.rovlh);let e=$$.tr(a.hd);$ict.rovl.forEach(((t,n)=>$$.th(e,t))),$.each(n.lst,((e,t)=>{$$.tr(a.bdy).append([$$.tdc("keep",t.subject),$$.tdc("currency",fnum(t.amount,$rct.cst)),$$.tdc("currency",fnum(t.amount_payed,$rct.cst)),$$.tdc("keep",fdt(t.DateFinalized,"dd.MM.yy"))])}))}else $$.td($$.tr(a.bdy),$ict.nd);$ocms.dlgform(i,{addcontent:r,title:string($ict.remdt,[t||"?"]),success:function(t){$inv.ccRem_s2(e,t)},typedvalues:!0})}})},$inv.rRemRw=function(e){let t=$(this),n=e.rm||{};t.empty().data({invoiceid:n.invoiceid,invoicedate:n.invoicedate,amount:n.amount,amount_payed:n.amount_payed});let i=$$.dc("axf").append($$.dc("ibtn edit",{title:$rct.cP}).append(gi("pencil")).click(t,$inv.eRowR));t.append([$$.tdc("aux").append(i),$$.tdc("keep",n.invoiceid),$$.tdc("keep",fdt(n.invoicedate,"dd.MM.yy")),$$.tdc("currency",fnum(n.amount,$rct.cst)),$$.tdc("currency",fnum(n.amount_payed,$rct.cst)),$$.tdc("currency",fnum(n.amount-n.amount_payed,$rct.cst))])},$inv.eRowR=function(e){let t=$(this),n=e.data,i=n.data()||{},r=$invcol.rem.clone().applyValues(i);$ocms.dlgform(r,{title:t.data("dialog")||"",success:function(e){let i=t.closest("table"),r=i.data();$.extend(r.rm,e),i.data(r),$inv.rRemRw.call(n,r),$inv.rd.syncAmount(r.rm.amount,r.rm.amount_payed)},typedvalues:!0})},$inv.ccRem_s2=function(e,t){$fis.lf(!1).rC("fix").aC("hd");let n=$$.dc("invoice_layout",$fis.frm_edit()).append($$.dc("btn sprev").click($inv.rprev));$inv.eM(!1,!0);$$.dc("rfrm").ldng(1);$ocms.postXT({url:$ocms.url("rem/get"),timeout:60,data:$.extend({id:e},t),success:e=>{let t=e.rm||{},i=$$.dc("srq",n),r=$$.tblset({class:"invi"},i);r.ft=$$[0]("tfoot"),r.tbl.data($.extend({invid:t.invid,new:{}},e));let a=$$.tr(r.hd).aC("shd").append([$$.th().aC("aux")]);$ict.remHR.forEach((e=>$$.th(a,e))),$inv.rRemRw.call($$.tr(r.bdy),r.tbl.data()),r.ft.appendTo(r.tbl);let d=(e,t,i,a,d)=>{let l=$$.dc("inpfrm",n).aC(e).append("string"==typeof a?$$.dc("ahd",a):a>0?$$.dc("ahd",$rct.frm[i]):null),s=$$.dc("content",l).rwText(t);$$.dc("axf",l).append($$.dc("ibtn edit").data("dialog",$rct.frm[i]).append(gi("pencil")).click($.extend({t:s,nme:i,change:e=>{r.tbl.data("new")[i]=e}},d),$inv.eHtml)),r.tbl.data("new")[i]=t};d("tfrm",t.subject,"subject",0,null),d("adrfrm",t.invoiceaddress,"invoiceaddress",0,null),d("emailfrm",t.invoiceemail,"invoiceemail",0,null),$$.dc("sndfrm",n).append($$.dc("content").text(t.sender)),r.tbl.children("tbody").each($inv.bdysort),r.tbl.trigger("fds.inv");let l=r.tbl.data("new");l.amount=t.amount,l.amount_payed=t.amount_payed,$inv.rd.seed({rem:{invid:t.invid,type:t.type,invoiceid:t.invoiceid,invoicedate:t.invoicedate},new:l})},complete:()=>{}})},$inv.rprev=()=>{$inv.rd.preview()},$inv.sis=e=>{confirm($ict.sisc)&&$ocms.postXT({url:$ocms.url("inv/sis"),data:{id:e||""},success:e=>{}})},$inv.srs=e=>{confirm($ict.srsc)&&$ocms.postXT({url:$ocms.url("rem/srs"),data:{id:e||""},success:e=>{}})},$inv.mfrrel=e=>{$("#contentframe").ldng(),$ocms.postXT({url:$ocms.url("inv/mfrrel"),data:{id:e||""},success:e=>{$inv.rerenderinv()},complete:()=>{$("#contentframe").ldng(0)}})};
\ No newline at end of file
diff --git a/Fuchs/wwwroot/web/fisb.js b/Fuchs/wwwroot/web/fisb.js
index 3a4b550..d4068c2 100644
--- a/Fuchs/wwwroot/web/fisb.js
+++ b/Fuchs/wwwroot/web/fisb.js
@@ -631,7 +631,7 @@ $ocms.postXT = function (options) {
if ((typeof options.contentType === 'boolean' ? options.contentType === false : false) === true) {
ajo.contentType = false; /* needed for file uploads */
}
- $.ajax(ajo);
+ return $.ajax(ajo);
};
$ocms.cex_timer = function () {
if (!$ocms.cexi) {
diff --git a/Fuchs/wwwroot/web/fisb.min.js b/Fuchs/wwwroot/web/fisb.min.js
index e2338c0..b966fac 100644
--- a/Fuchs/wwwroot/web/fisb.min.js
+++ b/Fuchs/wwwroot/web/fisb.min.js
@@ -1 +1 @@
-var $t={lng:"de-DE",dn:["So","Mo","Di","Mi","Do","Fr","Sa"],mn:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],ma:["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],datepattern:"(0[1-9]|1[0-9]|2[0-9]|3[01]).(0[1-9]|1[012]).[0-9]{4}",datetimepattern:"(0[1-9]|1[0-9]|2[0-9]|3[01]).(0[1-9]|1[012]).[0-9]{4}\\s([0-5][0-9]):([0-5][0-9])",dateplaceholder:"dd.MM.yyyy",datetimeplaceholder:"dd.MM.yyyy HH:mm",dateformat:"dd.MM.yyyy",datetimeformat:"dd.MM.yyyy HH:mm",f1:"Der Server hat einen Fehler gemeldet: \n",f2:"Bitte versuchen Sie es erneut.",m0:"Diese Internet-Seite benötigt einen html5-kompatiblen Browser.",m0b:"Unterstützt werden bspw: Internet Explorer ab Version 10, Firefox ab Version 31, Chrome ab Version 31, Safari ab Version 7, Opera ab Version 27",m1:"Dieser Datensatz ist momentan von jemand anderem zur Bearbeitung gesperrt.",m2:"Diese Funktion ist zur Zeit nicht verfügbar",t1:"Eingabe erforderlich.",t2:"Eingabe ist nicht erforderlich.",true:"Ja",false:"Nein",alert:"Hinweis",confirm:"Bestätigen",open:"Öffnen","not implemented":"Diese Funktion in zur Zeit noch nicht verfügbar.",l0:"Anmeldung",l1:"Email / Anmeldename",l2:"Email-Adresse / Anmeldename",l3:"Passwort",l4:"Benutzer",l5:"Wird vom System ermittelt...",l6:"Anmelden",l7:"Passwort vergessen?",l7a:'Die "Passwort vergessen"-Funktion läuft in zwei Schritten ab:\n \nIm ersten Schritt wird eine SMS mit einem Code an die hinterlegte Mobilfunk-Nummer versandt.\nIm zweiten Schritt geben Sie bitte diesen Code in das Formular ein und übermitteln es erneut.\n \nIn beiden Schritten wird aus Sicherheitsgründen kein Fehler angezeigt und auch dann ein erfolgreicher Versand bestätigt, wenn die Kombination aus Email-Adresse und Nachname nicht gefunden wurde und/oder der code falsch ist.',l8:"Keinen Account?",l9:"Anmeldenamen der Email-Adresse wurde nicht erkannt.",l10:"Nachname",l11:"Email-Adresse",l12:"Passwort zusenden",l13:"Das Passwort wurde erfolgreich verschickt",l14:"Das Passwort konnte nicht verschickt werden",l15:"Sie sind nicht berechtigt, diese Funktion auszuführen.",l16:"Sie müssen zunächst einen Account angeben.",l17:"Die Kombination aus Anmeldenamen und Passwort konnte nicht bestätigt werden.",l18:"Es gibt ein Problem mit dem Formular.\nEs kann momentan nicht verarbeitet und versendet werden.",name:"Name",submit:"Senden",cancel:"Abbrechen",noop:"Diese Funktion is noch nicht verfügar."};const isIE=/MSIE\/|Trident/gi.test(window.navigator.userAgent)||void 0!==window.document.documentMode,isfileapi=!!(window.File&&window.FileReader&&window.FileList&&window.Blob);var $ocms={auth:{},no:function(e){e.stopPropagation()},vmin:function(e){var t=$(window).width*(e||1),n=$(window).height*(e||1);return t($ocms.baseurl+"/"+(e||"")).replace(/\/\//,"/"),cexi:null};function deepCopy(e){var t,n,i;if("object"!=typeof e||null===e)return e;for(i in t=Array.isArray(e)?[]:{},e)n=e[i],t[i]=deepCopy(n);return t}function fields_definition(e,t,n){this.label_sng=!0===Array.isArray(e)?"":e||"",this.label_pl=!0===Array.isArray(e)?"":t||"",this.fields=!0===Array.isArray(e)?e:n||[],this.itm=function(e){for(var t=0;t0)for(var n=0;ne||"")).filter(((e,t)=>""!==e)).join(t)}function parseDt(e,t,n){e=(e||"").substr(0,t.length);var i=t,r=e.length>0&&t.split(";").some((function(t){for(var n,r=/[^yMdhms0-9]/gi,o=!0;null!==(n=r.exec(t));)o=o&&t.substr(n.index,1)===e.substr(n.index,1);var a=e.length===t.length&&o;return!0===a&&(i=t),a}));if(!0===r){for(var o,a=[0,0,0,0,0,0,0],s=/(mm{1,2}|dd{1,2}|MM{1,2}|(yy){2,4}|ss{1,2}|hh{1,2})(?!\w)/g;null!==(o=s.exec(i));)a["yMdhms".indexOf(o[0].substr(0,1))]=parseInt(("yy"===o[0]?"20":"")+e.substr(o.index,o[0].length))-("M"===o[0].substr(0,1)?1:0);var l=new(Function.prototype.bind.apply(Date,[null].concat(a)));return"string"==typeof n?fdt(l,n):l}return!1}function bool(e,t){return"boolean"==typeof e?e:"boolean"==typeof t&&t}function booln(e,t){return"boolean"==typeof e?e:"number"==typeof e?1===e:"boolean"==typeof t&&t}Date.prototype.isValid=function(){return!isNaN(this)},Date.prototype.format=function(e){return fdt(this,e)},Date.prototype.addDays=function(e){return this.setDate(this.getDate()+e),this},Date.prototype.isBetween=function(e,t){return this>e&&this section");$(window).scroll((function(t){let n=$(window).scrollTop(),i=$("body");i.toggleClass("unfocus",n>vh()-1.2*e),i.toggleClass("btb",n>.5*vh()-e)}))},$ocms.cf_reset=function(){return $("#contentframe").empty()},function(e){e.fn.scrollTo=function(t){if(e(this).length>0){var n=e(this).offset().top||0;n>0&&e("html, body").animate({scrollTop:n-hh()},2e3)}},e.fn.ldng=function(t){var n=!0;return"boolean"==typeof t?n=t:"number"==typeof t&&(n=t>0),e(this).toggleClass("loading",n)},"function"!=typeof e.noop&&(e.noop=function(){}),e.fn.hasAttr=function(t){var n=e(this).attr(t);return void 0!==n&&!1!==n},e.fn.parseCssPx=function(t){try{return parseFloat(e(this).css(t).replace("px","")||0)}catch(e){return 0}},e.max=function(e,t){return isNaN(e)&&isNaN(t)?null:isNaN(e)&&!isNaN(t)?t:!isNaN(t)&&isNaN(t)||e>=t?e:t},e.min=function(e,t){return isNaN(e)&&isNaN(t)?null:isNaN(e)&&!isNaN(t)?t:!isNaN(t)&&isNaN(t)||e<=t?e:t},e.lim=function(e,t){return isNaN(e)?null:isNaN(t)?e:t<=e?t:e},e.fn.enterKey=function(t){return this.each((function(){e(this).keypress((function(e){"13"===(e.keyCode?e.keyCode:e.which).toString()&&t.call(this,e)}))}))}}(jQuery),$ocms.defaultTimeout=3e4,$ocms.AjaxEX=function(e){var t=this;t.responseText=t.responseText||"";var n=t.getResponseHeader("x-ocms-code")||"";t.internalCode=""!==n&&!1===isNaN(n)?parseInt(n):-1,t.isInternal=t.internalCode>-1,t.internalText=decodeURIComponent((t.getResponseHeader("x-ocms-desc")||"").replace(/\+/g,"%20")||"");var i=t.internalText||e,r=t.internalCode||t.status;t.logtext=i+" ("+r+")"},$ocms.postXTS=function(e){$ocms.postXT.call(this,$.extend(e,{sync:!0}))},$ocms.postXT=function(e){if((e=e||{}).trycount=e.trycount||0,""!==(e.url||"")){e.url=-1!==e.url.indexOf("&yy=")?e.url:e.url.indexOf("?")>-1?e.url+"&yy="+(new Date).getTime():e.url+"?yy="+(new Date).getTime();var t=e.context||this;switch(e.context=t,e.retryLimit=e.retryLimit||0,e.timeout=e.timeout||$ocms.defaultTimeout,e.timeout<100&&(e.timeout=1e3*e.timeout),e.data=e.data||{},e.contentType=e.contentType||"multipart/form-data; charset=UTF-8",e.islogin="boolean"==typeof e.islogin&&e.islogin,e.contentType){case"":case"json":e.contentType="application/json; charset=utf-8";break;case"form":e.contentType="application/x-www-form-urlencoded; charset=UTF-8";break;case"multi":e.contentType="multipart/form-data";break;case"text":e.contentType="text/plain; charset=UTF-8"}if(e.form instanceof jQuery?(e.data=e.form.serializeObject(),e.contentType="form-data"):e.lzw instanceof jQuery&&(e.data.lzw=$.ccLZW(e.lzw.serializeAnything(!0)).join(",")),"multipart/form-data"!==e.contentType.substr(0,19)&&"form-data"!==e.contentType.substr(0,9)||e.data instanceof FormData!=!1)e.data instanceof FormData&&(e.contentType=!1,e.processData=!1);else{e.contentType=!1;var n=new FormData;$.each(e.files||[],(function(e,t){n.append("upload_file",t)})),$.each(e.data||{},(function(e,t){n.append(e,t)})),e.data=n,e.processData=!1}var i={type:e.method||"post",url:e.url,data:e.data,processData:"boolean"!=typeof e.processData||e.processData,contentType:e.contentType,cache:e.cache||!1,timeout:e.timeout,beforeSend:function(n){$(e.loading).ldng(),$("body").addClass("ldng"),"function"==typeof e.beforesend&&e.beforesend.apply(t,[n])},success:function(n,i,r){"false"===n||"not authorized"===n?("function"==typeof e.error&&e.error.apply(t,[r,i,n]),"function"==typeof $.status&&$.status(i+" - "+n)):"function"==typeof e.success&&e.success.apply(t,[n,i,r])},error:function(n,i,r){if($ocms.AjaxEX.call(n,i),-1===e.url.indexOf("doc.ashx")||-1!==e.url.indexOf("ftest")){if(401===n.status&&111===n.internalCode&&!1===e.islogin&&"function"==typeof $ocms.login.dlg)$ocms.login.dlg({ajo:e});else if("timeout"===i||302===n.status)return e.tryCount++,e.tryCount<=e.retryLimit?void $ocms.postXT(e):void 0;"function"==typeof e.error?e.error.apply(t,[n,i,r]):"function"==typeof $ocms.failure?$ocms.failure.apply(t,[n]):"function"==typeof $.status&&$.status("Server error: "+i+" - "+r)}},dataType:e.datatype||"json",complete:function(n,i){"function"==typeof e.complete&&e.complete.apply(t,[n,i]),$(e.loading).ldng(0),$("body").removeClass("ldng");let r=$("body > .timer");if(r.length>0){let e=new Date(n.getResponseHeader("ocms_cec")||""),t=new Date(n.getResponseHeader("ocms_cex")||"");if(e.isValid()&&t.isValid()){let n=new Date,i=Math.abs(t-e);n.setMilliseconds(n.getMilliseconds()+i),r.data({cex:n,ctt:i}),$ocms.cex_timer()}}},context:t,async:!0};"boolean"==typeof e.sync&&(i.async=!1===e.sync),!0==("boolean"==typeof e.contentType&&!1===e.contentType)&&(i.contentType=!1),$.ajax(i)}},$ocms.cex_timer=function(){$ocms.cexi||($ocms.cexi=setInterval($ocms.cex_timer,15e3));let e=$("body > .timer"),t=e.data("cex"),n=e.data("ctt"),i=new Date;if(t instanceof Date&&t.isValid()&&"number"==typeof n&&n>0&&t>i){let r=Math.abs(i-t)/n*100;e.css("width",r.toString()+"%"),r<98&&(!$ocms.cex_lp||Math.abs(i-$ocms.cex_lp)>6e5)&&$ocms.postXT({url:$ocms.url("ping"),success:()=>{$ocms.cex_lp=i},timeout:5e3,error:()=>{}})}},$ocms.vbl_send=function(e){var t=e.data||{};if(""!==(t.url||"")){var n=$("#contentframe form:first"),i={url:t.url,data:new FormData,success:function(e){"function"==typeof t.success?t.success(e):"string"==typeof t.success&&alert(t.success)},error:function(e,n,i){"function"==typeof t.error?t.error(i):"string"==typeof t.error&&alert(t.error)},complete:function(){n.ldng(0)}},r=!0;n.find("input").each((function(){var e=$(this),t=e.nza("name"),n=e.val(),o=$(this).prop("required")||!1;if(""!==t){var a=""!==n||!1===o;r=r&&a,!0===a?(i.data.append(t,n),e[0].setCustomValidity("")):""!==$(this).nza("ocms-nvnote")&&e[0].setCustomValidity($(this).nza("ocms-nvnote"))}})),!0===r&&(n.ldng(1),$ocms.postXT.call(this,i))}},function(e){e.fn.nza=function(t,n){var i=e(this).attr(t);return void 0!==i&&!1!==i?i:n||""},e.fn.serializeObject=function(t,n){var i=/\r?\n/g,r=/^(?:submit|button|image|reset|file)$/i,o=/^(?:input|select|textarea|keygen)/i,a=/^(?:checkbox|radio)$/i,s=bool((n=n||{}).typedvalues,!1),l={},c=e(this),u=c.find(':input:not([nosend],[type="file"])').addBack(":input"),d=!0;return e.each(u.not(".tinymce").get(),(function(n,c){var u=e(this),f=this,m=(this.type||"").toLowerCase(),p=u.prop("required")||!1;if(!0===(f.name&&!u.is(":disabled")&&o.test(f.nodeName)&&!r.test(m))){var h=u.val(),g=f.name,y=u.nza("data-format").split(":"),v=u.nza("pattern")||".*";if(!0===a.test(m)&&(h=f.checked?""!==h?h:"true":""),"date"===y[0].substr(0,4)&&y.length>1)"boolean"==typeof(h=parseDt(h,y.slice(1).join(":")))&&(h=null),null===h&&"date"===u.prop("type").substr(0,4)&&!1===isNaN(new Date(u.val()))&&(h=new Date(u.val())),h instanceof Date==!0&&"function"==typeof h.getMonth?!1===s&&(h=fdt(h,"date"===y[0]?"dts":"iso")):h=null;else if(("number"===m||"float"===y[0]||"integer"===y[0])&&!0===s){let e,t=String(h).replace(",",".");e="integer"===y[0]?parseInt(t):parseFloat(t),h=isNaN(e)?h:e}if(!0===p&&(""===h||null==h||"string"==typeof h&&null===h.match(v))?(!0===bool(t,!1)&&f.setCustomValidity(u.nza("ocms-nvnote",$ocms.t.inv||"Invalid field")),h=null):!0===bool(t,!1)&&f.setCustomValidity(""),null!=h&&"string"==typeof h){let e=l[g];null!=e?Array.isArray(e)?e.push(h.replace(i,"\r\n")):l[g]=[e,h.replace(i,"\r\n")]:l[g]=h.replace(i,"\r\n")}else if(null!=h){let e=l[g];null!=e?Array.isArray(e)?e.push(h):l[g]=[e,h]:l[g]=h}else d=!1}})),u.filter(".tinymce").each((function(t,n){var i=e(this),r=((this.type||"").toLowerCase(),i.prop("required")||!1);try{var o=tinymce.get(e(n).attr("id"));if(o){var a=e(n).attr("name"),s=o.getContent();!1===r||""!==(s||"")?l[a]=s:d=!1}}catch(t){e.noop()}})),c.toggleClass("invalid",!d),d?l:null},e.fn.sendForm=function(t,n,i){var r=e(this);i=i||{};var o={url:t,success:function(e){if(i.response=e,"function"==typeof n)n(e);r.closest("div.modal").remove()},error:function(e,t,n){"function"==typeof i.error?i.error.call(this,e):$ocms.failure.call(this,e)},complete:function(){r.ldng(0),"function"==typeof i.complete&&i.complete.call(this,jqXHR)}},a=r.find('input[type="file"]');o.data=new FormData,a.length>0&&e.each(a[0].files,(function(e,t){o.data.append(e,t),o.data.append("file_lastmodified",$ocms.isodt(t.lastModifiedDate))}));var s=r.serializeObject();e.each(s||{},(function(e,t){o.data.append(e,t)})),r.ldng(),$ocms.postXT.call(this,o)},e.fn.checkValidity=function(){var t=e(this),n=!0;return t.each((function(e,t){n=n&&t.checkValidity()})),n},e.fn.wrap=function(t,n){var i=e(this),r=$$.dc(t).attr(n||{}).insertAfter(i);return i.append(r),r}}(jQuery),$ocms.logout=function(){$ocms.postXT({url:$ocms.url("logout"),complete:function(){window.location.reload()}})},$ocms.login={send:function(e){e.preventDefault();var t=$(this);if(!0===t.find("#dbtn-confirm").hasClass("disabled"))return!1;var n=t.serializeObject();return n.loginaccount=ne(n.loginaccount,$ocms.auth.account||$ocms.auth.requestedaccount||""),n.loginaccount=ne(n.loginaccount,$ocms.auth.account||$ocms.auth.requestedaccount||""),""===ne(n.loginaccount)&&!0===bool($ocms.auth.accountrequired,!0)?(alert($t.l16),!1):($ocms.postXT({url:$ocms.url("login"),data:n,success:function(){window.location.reload()}}),!1)},uichange:function(){let e=$(this),t=e.closest("form"),n=bool($ocms.auth.accountrequired,!0),i=ne(t.find('[name="loginaccount"]').val(),$ocms.auth.account||$ocms.auth.requestedaccount||"");if(""!==i||!1===n){var r=t.find('[name="userlogin"]').empty().val(""),o=t.find('[name="username"]').empty().val(""),a=$("#dlg_userlogin_sel").empty().val(""),s=e.val()||"";if(!1===e.checkValidity()&&""===s)return;var l=e.closest("table").ldng();$ocms.postXT.call(this,{url:$ocms.url("auth"),data:{userinfo:s,account:i||""},success:function(e,t,n){if(1===e.length){var i=e[0];r.val(i.login).change().attr("required","").removeAttr("nosend"),o.val(i.name).change().attr("required","").show(),a.removeAttr("required").attr("nosend","").hide()}else e.length>0?(o.hide().removeAttr("required"),r.removeAttr("required").attr("nosend",""),0===a.length&&(a=$("").attr({name:"userlogin",size:e.length,id:"dlg_userlogin_sel",class:"form-control",required:""}).css({width:"100%","max-width":"100%",padding:"2px"}).insertAfter(o)),$.each(e,(function(e,t){var n=$("").attr({value:t.login,style:"padding-top: 2px; padding-bottom: 5px;","border-bottom":"1px solid #EEE;"}).text(t.name).appendTo(a);e%2==0&&n.css({"background-color":"#F9F9F9"})})),a.attr("required","").removeAttr("nosend")):(a.hide().attr("nosend",""),o.attr("required","").show(),r.attr("required","").removeAttr("nosend"),alert($t.l9))},error:function(e){$ocms.failure.call(this,e)},complete:function(){l.ldng(0)}})}else alert($t.l18)},sendpassword:function(e){var t=$(''),n=t.find(".form-body"),i=null;t.find("form").submit((function(e){e.preventDefault();var r=$(this).serializeObject(!0),o=null===i,a=o?"spwc":"spw";return $ocms.postXT.call(this,{url:$ocms.url(a),data:r,complete:function(){o?(n.append('Ihnen wurde ein Code per SMS zugesandt.
Bitte tragen Sie den hier ein:'),i=$('').appendTo(n)):(alert($t.l13),t.remove())},error:()=>{}}),!1})),t.find(".modal-close").click((function(){t.remove()}));var r=[];$.each($t.l7a.split("\n"),((e,t)=>{Array.prototype.push.apply(r,[$("
"),$("").text(t)])})),t.find(".modal-note").append($('').text($t.alert)).append(r),t.appendTo("body"),setTimeout((function(){$(".modal").find('input[name="lastname"]').focus()}),600)}},$(document).ready((function(){$("#loginform").submit($ocms.login.send)}));
\ No newline at end of file
+var $t={lng:"de-DE",dn:["So","Mo","Di","Mi","Do","Fr","Sa"],mn:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],ma:["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],datepattern:"(0[1-9]|1[0-9]|2[0-9]|3[01]).(0[1-9]|1[012]).[0-9]{4}",datetimepattern:"(0[1-9]|1[0-9]|2[0-9]|3[01]).(0[1-9]|1[012]).[0-9]{4}\\s([0-5][0-9]):([0-5][0-9])",dateplaceholder:"dd.MM.yyyy",datetimeplaceholder:"dd.MM.yyyy HH:mm",dateformat:"dd.MM.yyyy",datetimeformat:"dd.MM.yyyy HH:mm",f1:"Der Server hat einen Fehler gemeldet: \n",f2:"Bitte versuchen Sie es erneut.",m0:"Diese Internet-Seite benötigt einen html5-kompatiblen Browser.",m0b:"Unterstützt werden bspw: Internet Explorer ab Version 10, Firefox ab Version 31, Chrome ab Version 31, Safari ab Version 7, Opera ab Version 27",m1:"Dieser Datensatz ist momentan von jemand anderem zur Bearbeitung gesperrt.",m2:"Diese Funktion ist zur Zeit nicht verfügbar",t1:"Eingabe erforderlich.",t2:"Eingabe ist nicht erforderlich.",true:"Ja",false:"Nein",alert:"Hinweis",confirm:"Bestätigen",open:"Öffnen","not implemented":"Diese Funktion in zur Zeit noch nicht verfügbar.",l0:"Anmeldung",l1:"Email / Anmeldename",l2:"Email-Adresse / Anmeldename",l3:"Passwort",l4:"Benutzer",l5:"Wird vom System ermittelt...",l6:"Anmelden",l7:"Passwort vergessen?",l7a:'Die "Passwort vergessen"-Funktion läuft in zwei Schritten ab:\n \nIm ersten Schritt wird eine SMS mit einem Code an die hinterlegte Mobilfunk-Nummer versandt.\nIm zweiten Schritt geben Sie bitte diesen Code in das Formular ein und übermitteln es erneut.\n \nIn beiden Schritten wird aus Sicherheitsgründen kein Fehler angezeigt und auch dann ein erfolgreicher Versand bestätigt, wenn die Kombination aus Email-Adresse und Nachname nicht gefunden wurde und/oder der code falsch ist.',l8:"Keinen Account?",l9:"Anmeldenamen der Email-Adresse wurde nicht erkannt.",l10:"Nachname",l11:"Email-Adresse",l12:"Passwort zusenden",l13:"Das Passwort wurde erfolgreich verschickt",l14:"Das Passwort konnte nicht verschickt werden",l15:"Sie sind nicht berechtigt, diese Funktion auszuführen.",l16:"Sie müssen zunächst einen Account angeben.",l17:"Die Kombination aus Anmeldenamen und Passwort konnte nicht bestätigt werden.",l18:"Es gibt ein Problem mit dem Formular.\nEs kann momentan nicht verarbeitet und versendet werden.",name:"Name",submit:"Senden",cancel:"Abbrechen",noop:"Diese Funktion is noch nicht verfügar."};const isIE=/MSIE\/|Trident/gi.test(window.navigator.userAgent)||void 0!==window.document.documentMode,isfileapi=!!(window.File&&window.FileReader&&window.FileList&&window.Blob);var $ocms={auth:{},no:function(e){e.stopPropagation()},vmin:function(e){var t=$(window).width*(e||1),n=$(window).height*(e||1);return t($ocms.baseurl+"/"+(e||"")).replace(/\/\//,"/"),cexi:null};function deepCopy(e){var t,n,i;if("object"!=typeof e||null===e)return e;for(i in t=Array.isArray(e)?[]:{},e)n=e[i],t[i]=deepCopy(n);return t}function fields_definition(e,t,n){this.label_sng=!0===Array.isArray(e)?"":e||"",this.label_pl=!0===Array.isArray(e)?"":t||"",this.fields=!0===Array.isArray(e)?e:n||[],this.itm=function(e){for(var t=0;t0)for(var n=0;ne||"")).filter(((e,t)=>""!==e)).join(t)}function parseDt(e,t,n){e=(e||"").substr(0,t.length);var i=t,r=e.length>0&&t.split(";").some((function(t){for(var n,r=/[^yMdhms0-9]/gi,o=!0;null!==(n=r.exec(t));)o=o&&t.substr(n.index,1)===e.substr(n.index,1);var a=e.length===t.length&&o;return!0===a&&(i=t),a}));if(!0===r){for(var o,a=[0,0,0,0,0,0,0],s=/(mm{1,2}|dd{1,2}|MM{1,2}|(yy){2,4}|ss{1,2}|hh{1,2})(?!\w)/g;null!==(o=s.exec(i));)a["yMdhms".indexOf(o[0].substr(0,1))]=parseInt(("yy"===o[0]?"20":"")+e.substr(o.index,o[0].length))-("M"===o[0].substr(0,1)?1:0);var l=new(Function.prototype.bind.apply(Date,[null].concat(a)));return"string"==typeof n?fdt(l,n):l}return!1}function bool(e,t){return"boolean"==typeof e?e:"boolean"==typeof t&&t}function booln(e,t){return"boolean"==typeof e?e:"number"==typeof e?1===e:"boolean"==typeof t&&t}Date.prototype.isValid=function(){return!isNaN(this)},Date.prototype.format=function(e){return fdt(this,e)},Date.prototype.addDays=function(e){return this.setDate(this.getDate()+e),this},Date.prototype.isBetween=function(e,t){return this>e&&this section");$(window).scroll((function(t){let n=$(window).scrollTop(),i=$("body");i.toggleClass("unfocus",n>vh()-1.2*e),i.toggleClass("btb",n>.5*vh()-e)}))},$ocms.cf_reset=function(){return $("#contentframe").empty()},function(e){e.fn.scrollTo=function(t){if(e(this).length>0){var n=e(this).offset().top||0;n>0&&e("html, body").animate({scrollTop:n-hh()},2e3)}},e.fn.ldng=function(t){var n=!0;return"boolean"==typeof t?n=t:"number"==typeof t&&(n=t>0),e(this).toggleClass("loading",n)},"function"!=typeof e.noop&&(e.noop=function(){}),e.fn.hasAttr=function(t){var n=e(this).attr(t);return void 0!==n&&!1!==n},e.fn.parseCssPx=function(t){try{return parseFloat(e(this).css(t).replace("px","")||0)}catch(e){return 0}},e.max=function(e,t){return isNaN(e)&&isNaN(t)?null:isNaN(e)&&!isNaN(t)?t:!isNaN(t)&&isNaN(t)||e>=t?e:t},e.min=function(e,t){return isNaN(e)&&isNaN(t)?null:isNaN(e)&&!isNaN(t)?t:!isNaN(t)&&isNaN(t)||e<=t?e:t},e.lim=function(e,t){return isNaN(e)?null:isNaN(t)?e:t<=e?t:e},e.fn.enterKey=function(t){return this.each((function(){e(this).keypress((function(e){"13"===(e.keyCode?e.keyCode:e.which).toString()&&t.call(this,e)}))}))}}(jQuery),$ocms.defaultTimeout=3e4,$ocms.AjaxEX=function(e){var t=this;t.responseText=t.responseText||"";var n=t.getResponseHeader("x-ocms-code")||"";t.internalCode=""!==n&&!1===isNaN(n)?parseInt(n):-1,t.isInternal=t.internalCode>-1,t.internalText=decodeURIComponent((t.getResponseHeader("x-ocms-desc")||"").replace(/\+/g,"%20")||"");var i=t.internalText||e,r=t.internalCode||t.status;t.logtext=i+" ("+r+")"},$ocms.postXTS=function(e){$ocms.postXT.call(this,$.extend(e,{sync:!0}))},$ocms.postXT=function(e){if((e=e||{}).trycount=e.trycount||0,""!==(e.url||"")){e.url=-1!==e.url.indexOf("&yy=")?e.url:e.url.indexOf("?")>-1?e.url+"&yy="+(new Date).getTime():e.url+"?yy="+(new Date).getTime();var t=e.context||this;switch(e.context=t,e.retryLimit=e.retryLimit||0,e.timeout=e.timeout||$ocms.defaultTimeout,e.timeout<100&&(e.timeout=1e3*e.timeout),e.data=e.data||{},e.contentType=e.contentType||"multipart/form-data; charset=UTF-8",e.islogin="boolean"==typeof e.islogin&&e.islogin,e.contentType){case"":case"json":e.contentType="application/json; charset=utf-8";break;case"form":e.contentType="application/x-www-form-urlencoded; charset=UTF-8";break;case"multi":e.contentType="multipart/form-data";break;case"text":e.contentType="text/plain; charset=UTF-8"}if(e.form instanceof jQuery?(e.data=e.form.serializeObject(),e.contentType="form-data"):e.lzw instanceof jQuery&&(e.data.lzw=$.ccLZW(e.lzw.serializeAnything(!0)).join(",")),"multipart/form-data"!==e.contentType.substr(0,19)&&"form-data"!==e.contentType.substr(0,9)||e.data instanceof FormData!=!1)e.data instanceof FormData&&(e.contentType=!1,e.processData=!1);else{e.contentType=!1;var n=new FormData;$.each(e.files||[],(function(e,t){n.append("upload_file",t)})),$.each(e.data||{},(function(e,t){n.append(e,t)})),e.data=n,e.processData=!1}var i={type:e.method||"post",url:e.url,data:e.data,processData:"boolean"!=typeof e.processData||e.processData,contentType:e.contentType,cache:e.cache||!1,timeout:e.timeout,beforeSend:function(n){$(e.loading).ldng(),$("body").addClass("ldng"),"function"==typeof e.beforesend&&e.beforesend.apply(t,[n])},success:function(n,i,r){"false"===n||"not authorized"===n?("function"==typeof e.error&&e.error.apply(t,[r,i,n]),"function"==typeof $.status&&$.status(i+" - "+n)):"function"==typeof e.success&&e.success.apply(t,[n,i,r])},error:function(n,i,r){if($ocms.AjaxEX.call(n,i),-1===e.url.indexOf("doc.ashx")||-1!==e.url.indexOf("ftest")){if(401===n.status&&111===n.internalCode&&!1===e.islogin&&"function"==typeof $ocms.login.dlg)$ocms.login.dlg({ajo:e});else if("timeout"===i||302===n.status)return e.tryCount++,e.tryCount<=e.retryLimit?void $ocms.postXT(e):void 0;"function"==typeof e.error?e.error.apply(t,[n,i,r]):"function"==typeof $ocms.failure?$ocms.failure.apply(t,[n]):"function"==typeof $.status&&$.status("Server error: "+i+" - "+r)}},dataType:e.datatype||"json",complete:function(n,i){"function"==typeof e.complete&&e.complete.apply(t,[n,i]),$(e.loading).ldng(0),$("body").removeClass("ldng");let r=$("body > .timer");if(r.length>0){let e=new Date(n.getResponseHeader("ocms_cec")||""),t=new Date(n.getResponseHeader("ocms_cex")||"");if(e.isValid()&&t.isValid()){let n=new Date,i=Math.abs(t-e);n.setMilliseconds(n.getMilliseconds()+i),r.data({cex:n,ctt:i}),$ocms.cex_timer()}}},context:t,async:!0};return"boolean"==typeof e.sync&&(i.async=!1===e.sync),!0==("boolean"==typeof e.contentType&&!1===e.contentType)&&(i.contentType=!1),$.ajax(i)}},$ocms.cex_timer=function(){$ocms.cexi||($ocms.cexi=setInterval($ocms.cex_timer,15e3));let e=$("body > .timer"),t=e.data("cex"),n=e.data("ctt"),i=new Date;if(t instanceof Date&&t.isValid()&&"number"==typeof n&&n>0&&t>i){let r=Math.abs(i-t)/n*100;e.css("width",r.toString()+"%"),r<98&&(!$ocms.cex_lp||Math.abs(i-$ocms.cex_lp)>6e5)&&$ocms.postXT({url:$ocms.url("ping"),success:()=>{$ocms.cex_lp=i},timeout:5e3,error:()=>{}})}},$ocms.vbl_send=function(e){var t=e.data||{};if(""!==(t.url||"")){var n=$("#contentframe form:first"),i={url:t.url,data:new FormData,success:function(e){"function"==typeof t.success?t.success(e):"string"==typeof t.success&&alert(t.success)},error:function(e,n,i){"function"==typeof t.error?t.error(i):"string"==typeof t.error&&alert(t.error)},complete:function(){n.ldng(0)}},r=!0;n.find("input").each((function(){var e=$(this),t=e.nza("name"),n=e.val(),o=$(this).prop("required")||!1;if(""!==t){var a=""!==n||!1===o;r=r&&a,!0===a?(i.data.append(t,n),e[0].setCustomValidity("")):""!==$(this).nza("ocms-nvnote")&&e[0].setCustomValidity($(this).nza("ocms-nvnote"))}})),!0===r&&(n.ldng(1),$ocms.postXT.call(this,i))}},function(e){e.fn.nza=function(t,n){var i=e(this).attr(t);return void 0!==i&&!1!==i?i:n||""},e.fn.serializeObject=function(t,n){var i=/\r?\n/g,r=/^(?:submit|button|image|reset|file)$/i,o=/^(?:input|select|textarea|keygen)/i,a=/^(?:checkbox|radio)$/i,s=bool((n=n||{}).typedvalues,!1),l={},c=e(this),u=c.find(':input:not([nosend],[type="file"])').addBack(":input"),d=!0;return e.each(u.not(".tinymce").get(),(function(n,c){var u=e(this),f=this,m=(this.type||"").toLowerCase(),p=u.prop("required")||!1;if(!0===(f.name&&!u.is(":disabled")&&o.test(f.nodeName)&&!r.test(m))){var h=u.val(),g=f.name,y=u.nza("data-format").split(":"),v=u.nza("pattern")||".*";if(!0===a.test(m)&&(h=f.checked?""!==h?h:"true":""),"date"===y[0].substr(0,4)&&y.length>1)"boolean"==typeof(h=parseDt(h,y.slice(1).join(":")))&&(h=null),null===h&&"date"===u.prop("type").substr(0,4)&&!1===isNaN(new Date(u.val()))&&(h=new Date(u.val())),h instanceof Date==!0&&"function"==typeof h.getMonth?!1===s&&(h=fdt(h,"date"===y[0]?"dts":"iso")):h=null;else if(("number"===m||"float"===y[0]||"integer"===y[0])&&!0===s){let e,t=String(h).replace(",",".");e="integer"===y[0]?parseInt(t):parseFloat(t),h=isNaN(e)?h:e}if(!0===p&&(""===h||null==h||"string"==typeof h&&null===h.match(v))?(!0===bool(t,!1)&&f.setCustomValidity(u.nza("ocms-nvnote",$ocms.t.inv||"Invalid field")),h=null):!0===bool(t,!1)&&f.setCustomValidity(""),null!=h&&"string"==typeof h){let e=l[g];null!=e?Array.isArray(e)?e.push(h.replace(i,"\r\n")):l[g]=[e,h.replace(i,"\r\n")]:l[g]=h.replace(i,"\r\n")}else if(null!=h){let e=l[g];null!=e?Array.isArray(e)?e.push(h):l[g]=[e,h]:l[g]=h}else d=!1}})),u.filter(".tinymce").each((function(t,n){var i=e(this),r=((this.type||"").toLowerCase(),i.prop("required")||!1);try{var o=tinymce.get(e(n).attr("id"));if(o){var a=e(n).attr("name"),s=o.getContent();!1===r||""!==(s||"")?l[a]=s:d=!1}}catch(t){e.noop()}})),c.toggleClass("invalid",!d),d?l:null},e.fn.sendForm=function(t,n,i){var r=e(this);i=i||{};var o={url:t,success:function(e){if(i.response=e,"function"==typeof n)n(e);r.closest("div.modal").remove()},error:function(e,t,n){"function"==typeof i.error?i.error.call(this,e):$ocms.failure.call(this,e)},complete:function(){r.ldng(0),"function"==typeof i.complete&&i.complete.call(this,jqXHR)}},a=r.find('input[type="file"]');o.data=new FormData,a.length>0&&e.each(a[0].files,(function(e,t){o.data.append(e,t),o.data.append("file_lastmodified",$ocms.isodt(t.lastModifiedDate))}));var s=r.serializeObject();e.each(s||{},(function(e,t){o.data.append(e,t)})),r.ldng(),$ocms.postXT.call(this,o)},e.fn.checkValidity=function(){var t=e(this),n=!0;return t.each((function(e,t){n=n&&t.checkValidity()})),n},e.fn.wrap=function(t,n){var i=e(this),r=$$.dc(t).attr(n||{}).insertAfter(i);return i.append(r),r}}(jQuery),$ocms.logout=function(){$ocms.postXT({url:$ocms.url("logout"),complete:function(){window.location.reload()}})},$ocms.login={send:function(e){e.preventDefault();var t=$(this);if(!0===t.find("#dbtn-confirm").hasClass("disabled"))return!1;var n=t.serializeObject();return n.loginaccount=ne(n.loginaccount,$ocms.auth.account||$ocms.auth.requestedaccount||""),n.loginaccount=ne(n.loginaccount,$ocms.auth.account||$ocms.auth.requestedaccount||""),""===ne(n.loginaccount)&&!0===bool($ocms.auth.accountrequired,!0)?(alert($t.l16),!1):($ocms.postXT({url:$ocms.url("login"),data:n,success:function(){window.location.reload()}}),!1)},uichange:function(){let e=$(this),t=e.closest("form"),n=bool($ocms.auth.accountrequired,!0),i=ne(t.find('[name="loginaccount"]').val(),$ocms.auth.account||$ocms.auth.requestedaccount||"");if(""!==i||!1===n){var r=t.find('[name="userlogin"]').empty().val(""),o=t.find('[name="username"]').empty().val(""),a=$("#dlg_userlogin_sel").empty().val(""),s=e.val()||"";if(!1===e.checkValidity()&&""===s)return;var l=e.closest("table").ldng();$ocms.postXT.call(this,{url:$ocms.url("auth"),data:{userinfo:s,account:i||""},success:function(e,t,n){if(1===e.length){var i=e[0];r.val(i.login).change().attr("required","").removeAttr("nosend"),o.val(i.name).change().attr("required","").show(),a.removeAttr("required").attr("nosend","").hide()}else e.length>0?(o.hide().removeAttr("required"),r.removeAttr("required").attr("nosend",""),0===a.length&&(a=$("").attr({name:"userlogin",size:e.length,id:"dlg_userlogin_sel",class:"form-control",required:""}).css({width:"100%","max-width":"100%",padding:"2px"}).insertAfter(o)),$.each(e,(function(e,t){var n=$("").attr({value:t.login,style:"padding-top: 2px; padding-bottom: 5px;","border-bottom":"1px solid #EEE;"}).text(t.name).appendTo(a);e%2==0&&n.css({"background-color":"#F9F9F9"})})),a.attr("required","").removeAttr("nosend")):(a.hide().attr("nosend",""),o.attr("required","").show(),r.attr("required","").removeAttr("nosend"),alert($t.l9))},error:function(e){$ocms.failure.call(this,e)},complete:function(){l.ldng(0)}})}else alert($t.l18)},sendpassword:function(e){var t=$(''),n=t.find(".form-body"),i=null;t.find("form").submit((function(e){e.preventDefault();var r=$(this).serializeObject(!0),o=null===i,a=o?"spwc":"spw";return $ocms.postXT.call(this,{url:$ocms.url(a),data:r,complete:function(){o?(n.append('Ihnen wurde ein Code per SMS zugesandt.
Bitte tragen Sie den hier ein:'),i=$('').appendTo(n)):(alert($t.l13),t.remove())},error:()=>{}}),!1})),t.find(".modal-close").click((function(){t.remove()}));var r=[];$.each($t.l7a.split("\n"),((e,t)=>{Array.prototype.push.apply(r,[$("
"),$("").text(t)])})),t.find(".modal-note").append($('').text($t.alert)).append(r),t.appendTo("body"),setTimeout((function(){$(".modal").find('input[name="lastname"]').focus()}),600)}},$(document).ready((function(){$("#loginform").submit($ocms.login.send)}));
\ No newline at end of file
diff --git a/Fuchs/wwwroot/web/tools.js b/Fuchs/wwwroot/web/tools.js
index f36c9c0..ceb47a5 100644
--- a/Fuchs/wwwroot/web/tools.js
+++ b/Fuchs/wwwroot/web/tools.js
@@ -1,5 +1,4 @@
+/*! js-cookie v3.0.1 | MIT */
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self,function(){var n=e.Cookies,o=e.Cookies=t();o.noConflict=function(){return e.Cookies=n,o}}())}(this,(function(){"use strict";function e(e){for(var t=1;t+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0
- b.SetMinimumLevel(LogLevel.Debug).AddFdsLogging());
-
- var mfr = new FdsMfr(
- loggerFactory.CreateLogger(),
- loggerFactory);
- var interval = TimeSpan.FromMinutes(FdsConfig.ExecutionFrequency_Minutes);
- var jobs = new[]
- {
- new PeriodicJobDefinition("MfrSync", interval, async ct =>
- {
- bool debug = FdsConfig.DebugDetails;
- await mfr.UpdateIfNecessary_async(debug, ct);
- await mfr.UpdateRequested_async(debug, ct);
- await mfr.GetInvoiceFiles_async(debug, ct);
- })
- };
-
- var logger = loggerFactory.CreateLogger();
- _hostedService = new PeriodicHostedService(jobs, logger);
- }
-
- public bool Start(HostControl hostControl)
- {
- _ = _hostedService.StartAsync(_cts.Token);
- return true;
- }
-
- public bool Stop(HostControl hostControl)
- {
- _cts.Cancel();
- _hostedService.StopAsync(CancellationToken.None).GetAwaiter().GetResult();
- return true;
- }
-}
-
-public static class FdsMainModule
-{
- public static void Main(string[] args)
- {
- FdsConfig.Initialize();
-
- string machineName = Environment.MachineName.ToLower();
- if (!new[] { "digital-pc", "digital-dpc" }.Contains(machineName))
- {
- HostFactory.Run(x =>
- {
- x.Service(s =>
- {
- s.ConstructUsing(name => new FdsService());
- s.WhenStarted((tc, host) => tc.Start(host));
- s.WhenStopped((tc, host) => tc.Stop(host));
- s.BeforeStoppingService(ctx =>
- {
- if (FdsConfig.DebugDetails) Task.Run(() => FdsDebug.DebugToFile("fds__data_service - beforestop", filename: "DebugDetail.txt"));
- });
- s.WhenPaused((tc, host) => tc.Stop(host));
- s.WhenContinued((tc, host) => tc.Start(host));
- });
- x.EnablePauseAndContinue();
- x.StartAutomatically();
- x.RunAsLocalSystem();
- x.SetDescription("MFR Data Sync");
- x.SetDisplayName("MFR Data Sync");
- x.SetServiceName("MFR Data Sync");
- });
- }
- else
- {
- var svc = new FdsService();
- svc.Start(null!);
- Console.WriteLine("Running locally — press any key to stop.");
- Console.ReadKey();
- svc.Stop(null!);
- }
- }
-}
diff --git a/Fuchs_DataService/FdsMfr.cs b/Fuchs_DataService/FdsMfr.cs
index 0b47cfd..1e15426 100644
--- a/Fuchs_DataService/FdsMfr.cs
+++ b/Fuchs_DataService/FdsMfr.cs
@@ -319,16 +319,13 @@ public class FdsMfr : IFdsMfr
var archiveFile = new FileInfo(Path.GetTempPath() + $"DatevUpload_AR {startdate:yyyyMM}_{admin["mode"]}.zip");
try
{
- using var archive = new Archive(archiveFile, type: SevenZip.OutArchiveFormat.Zip,
- logger: _loggerFactory.CreateLogger());
- if (archive.CompressToStream(fls, targetstream: stream!))
- {
- stream!.Position = 0;
- return archiveFile;
- }
- _logger.LogError(
- "getDatevZip: CompressToStream returned false — archiveFile={ArchiveFile} fileCount={FileCount}",
- archiveFile.FullName, fls.Count);
+ // Native .NET zip via the OCORE helper (System.IO.Compression) — no external
+ // 7-Zip dependency. The DATEV export is a plain, unencrypted zip, so ZipArchive
+ // covers it fully. filesToZipArchive skips null/empty entries.
+ var zipBytes = Task.Run(async () => await OCORE.zip.filesToZipArchive(fls)).Result;
+ stream!.Write(zipBytes, 0, zipBytes.Length);
+ stream.Position = 0;
+ return archiveFile;
}
catch (Exception ex)
{
diff --git a/Fuchs_DataService/FdsShared.cs b/Fuchs_DataService/FdsShared.cs
index 3bae247..4d8c095 100644
--- a/Fuchs_DataService/FdsShared.cs
+++ b/Fuchs_DataService/FdsShared.cs
@@ -2,29 +2,22 @@
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
-using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
namespace fds;
///
-/// Holds the application built from appsettings.json.
-/// Call once at startup before accessing .
+/// Holds the application supplied by the host (the Fuchs web app).
+/// Fuchs_DataService is a library — it has no configuration of its own; the host owns the
+/// connection strings and MFR credentials and injects them via ,
+/// which Program.cs calls once at startup before any use.
///
public static class FdsConfig
{
private static IConfiguration? _config;
internal static IConfiguration Current =>
- _config ?? throw new InvalidOperationException("FdsConfig has not been initialized. Call FdsConfig.Initialize() in Main().");
-
- public static void Initialize()
- {
- _config = new ConfigurationBuilder()
- .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
- .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
- .Build();
- }
+ _config ?? throw new InvalidOperationException("FdsConfig has not been initialized. Call FdsConfig.Initialize(configuration) at host startup.");
public static void Initialize(IConfiguration configuration)
{
@@ -32,21 +25,11 @@ public static class FdsConfig
}
// -- Connection strings ---------------------------------------------------
- internal static string SQLConnectionString() =>
- Current.GetConnectionString("fuchs_ConnectionString")
- ?? throw new InvalidOperationException("Missing connection string: fuchs_ConnectionString");
-
internal static string FDSConnectionString() =>
Current.GetConnectionString("fuchs_fds_ConnectionString")
?? throw new InvalidOperationException("Missing connection string: fuchs_fds_ConnectionString");
- // -- App settings ---------------------------------------------------------
- internal static double ExecutionFrequency_Minutes =>
- Current.GetValue("Fds:ExecutionFrequency_Minutes", 15);
-
- internal static bool DebugDetails =>
- Current.GetValue("Fds:DebugDetails");
-
+ // -- MFR credentials (supplied by the host from Key Vault / appsettings) --
internal static string MFR_UserName =>
Current["Fds:MFR_UserName"] ?? "";
@@ -59,12 +42,8 @@ public static class FdsConfig
internal static class FdsShared
{
- internal static string SQLConnectionString() => FdsConfig.SQLConnectionString();
internal static string FDSConnectionString() => FdsConfig.FDSConnectionString();
- internal static SqlConnection SqlCon() =>
- new(FdsConfig.SQLConnectionString());
-
public static string RandomString(byte length)
{
var r = new Random();
diff --git a/Fuchs_DataService/FdsZip.cs b/Fuchs_DataService/FdsZip.cs
deleted file mode 100644
index c2a316c..0000000
--- a/Fuchs_DataService/FdsZip.cs
+++ /dev/null
@@ -1,243 +0,0 @@
-using Microsoft.Extensions.Logging;
-using SevenZip;
-
-namespace fds;
-
-public class Archive : IDisposable
-{
- public event Action? FileSaved;
- public event Action? FileStreamCreated;
-
- private FileInfo _archiveFile;
- private string _archivePassword;
- private OutArchiveFormat _archiveFormat;
- private readonly ILogger _logger;
- public string TempPath { get; set; } = AppDomain.CurrentDomain.BaseDirectory;
- public Stream? ArchiveFileStream { get; set; }
-
- private SevenZipExtractor? _zipOut;
- private SevenZipCompressor? _zipIn;
- public bool ZipAppend { get; set; } = true;
- public bool ExitOK { get; set; }
- public bool ZipInOK { get; set; }
-
- public Archive(FileInfo archiveFile, string archivePassword = "", bool init = true,
- OutArchiveFormat type = OutArchiveFormat.SevenZip, ILogger? logger = null)
- {
- _logger = logger ?? Microsoft.Extensions.Logging.Abstractions.NullLogger.Instance;
- _archiveFormat = type;
- _archiveFile = new FileInfo(archiveFile.FullName.Replace(archiveFile.Extension,
- type == OutArchiveFormat.SevenZip ? ".7z" : archiveFile.Extension));
- _archivePassword = archivePassword;
- if (init) InitZipIn(type);
- }
-
- private void InitZipIn(OutArchiveFormat type)
- {
- if (string.IsNullOrEmpty(Zipping.SevenZipPath))
- {
- try
- {
- var assemblyDir = new DirectoryInfo(
- new Uri(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)!).LocalPath);
- var zip = assemblyDir.GetFiles("7z.dll", SearchOption.AllDirectories).FirstOrDefault();
- Zipping.SevenZipPath = zip?.FullName ?? "";
- }
- finally
- {
- if (string.IsNullOrEmpty(Zipping.SevenZipPath))
- {
- var assemblyDir = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
- var zip = assemblyDir.GetFiles("7z.dll", SearchOption.AllDirectories).FirstOrDefault();
- Zipping.SevenZipPath = zip?.FullName ?? "";
- }
- }
- if (string.IsNullOrEmpty(Zipping.SevenZipPath))
- _logger.LogError("SevenZipPath not found — 7z.dll is missing from the output directory.");
- }
- SevenZipCompressor.SetLibraryPath(Zipping.SevenZipPath);
-
- _zipIn = new SevenZipCompressor
- {
- ArchiveFormat = (type == OutArchiveFormat.SevenZip && _archiveFile.Extension.Contains("7z", StringComparison.OrdinalIgnoreCase))
- ? OutArchiveFormat.SevenZip : type,
- CompressionLevel = SevenZip.CompressionLevel.Ultra,
- CompressionMode = ZipAppend ? SevenZip.CompressionMode.Append : SevenZip.CompressionMode.Create,
- DirectoryStructure = false
- };
-
- _zipIn.CompressionMethod = _zipIn.ArchiveFormat switch
- {
- OutArchiveFormat.SevenZip => CompressionMethod.Lzma2,
- OutArchiveFormat.Zip or OutArchiveFormat.GZip => CompressionMethod.Deflate,
- _ => CompressionMethod.Default
- };
-
- ZipInOK = true;
- }
-
- public void Extract(FileInfo dataArchiveFilePath, DirectoryInfo tgtDirectory, OutArchiveFormat type = default)
- {
- if (!dataArchiveFilePath.Exists) return;
-
- if (type == default)
- type = dataArchiveFilePath.Extension.Contains("7z", StringComparison.OrdinalIgnoreCase)
- ? OutArchiveFormat.SevenZip : OutArchiveFormat.Zip;
-
- if (!ZipInOK) InitZipIn(type);
-
- _zipOut = string.IsNullOrEmpty(_archivePassword)
- ? new SevenZipExtractor(dataArchiveFilePath.FullName)
- : new SevenZipExtractor(dataArchiveFilePath.FullName, _archivePassword);
-
- try
- {
- if (!_zipOut.ArchiveFileData[0].Encrypted && !string.IsNullOrEmpty(_archivePassword))
- _archivePassword = "";
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Archive.Extract failed — path={Path}, target={Target}",
- dataArchiveFilePath.FullName, tgtDirectory.FullName);
- return;
- }
-
- _zipOut.ExtractArchive(tgtDirectory.FullName);
- _zipOut.Dispose();
- }
-
- public bool Compress(List files, FileInfo? archiveFile = null, string? archivePass = null, OutArchiveFormat type = OutArchiveFormat.SevenZip)
- {
- if (files.Count == 0) return true;
- if (!ZipInOK) InitZipIn(type);
-
- archiveFile ??= _archiveFile;
- archivePass = string.IsNullOrEmpty(archivePass) ? _archivePassword : archivePass;
-
- if (archiveFile.Exists && ZipAppend)
- _zipIn!.CompressionMode = CompressionMode.Append;
- else
- {
- if (archiveFile.Exists) archiveFile.Delete();
- _zipIn!.CompressionMode = CompressionMode.Create;
- }
-
- try
- {
- var filesVerified = files.Where(f => f.Exists).ToArray();
- var filePaths = filesVerified.Select(f => f.FullName).ToArray();
- if (string.IsNullOrEmpty(archivePass))
- _zipIn.CompressFiles(archiveFile.FullName, filePaths);
- else
- {
- _zipIn.EncryptHeaders = true;
- _zipIn.ZipEncryptionMethod = ZipEncryptionMethod.Aes256;
- _zipIn.CompressFilesEncrypted(archiveFile.FullName, archivePass, filePaths);
- }
- FileSaved?.Invoke();
- ExitOK = true;
- _zipIn = null;
- ZipInOK = false;
- }
- catch (Exception ex)
- {
- // Previously silent: callers (e.g. HandleDatevZip) saw only a bare failed result
- // with no way to tell a compression error from any other reason ExitOK is false.
- _logger.LogError(ex, "Archive.Compress failed — archiveFile={ArchiveFile} fileCount={FileCount}",
- archiveFile.FullName, files.Count);
- ExitOK = false;
- }
- archiveFile.Refresh();
- return ExitOK && archiveFile.Exists;
- }
-
- public bool CompressToStream(Dictionary files, Stream? targetstream = null)
- {
- if (files.Count == 0) return true;
- if (!ZipInOK) InitZipIn(_archiveFormat);
-
- if (ArchiveFileStream == null)
- {
- _zipIn!.CompressionMode = CompressionMode.Create;
- ArchiveFileStream = new MemoryStream();
- }
- else
- _zipIn!.CompressionMode = CompressionMode.Append;
-
- try
- {
- var filesStreams = files.ToDictionary(kv => kv.Key, kv => (Stream)new MemoryStream(kv.Value));
- var target = targetstream ?? ArchiveFileStream;
- if (string.IsNullOrEmpty(_archivePassword))
- _zipIn.CompressStreamDictionary(filesStreams, target);
- else
- {
- _zipIn.EncryptHeaders = true;
- _zipIn.ZipEncryptionMethod = ZipEncryptionMethod.Aes256;
- _zipIn.CompressStreamDictionary(filesStreams, target, _archivePassword);
- }
- ArchiveFileStream.Seek(0, SeekOrigin.Begin);
- FileStreamCreated?.Invoke();
- ExitOK = true;
- _zipIn = null;
- ZipInOK = false;
- }
- catch (Exception ex)
- {
- // Previously silent: the DATEV export ZIP-to-stream path failed with no
- // trace anywhere, only a bare false return.
- _logger.LogError(ex, "Archive.CompressToStream failed — fileCount={FileCount}", files.Count);
- ExitOK = false;
- }
- return ExitOK;
- }
-
- public bool WriteArchiveStreamToDisk(FileInfo? archiveFile = null)
- {
- try { if (_archiveFile.Exists) _archiveFile.Delete(); } catch { }
- FdsShared.WriteStreamToDisk(ArchiveFileStream!, (archiveFile ?? _archiveFile).FullName);
- _archiveFile.Refresh();
- return _archiveFile.Exists;
- }
-
- #region IDisposable
- private bool _disposed;
- protected virtual void Dispose(bool disposing)
- {
- if (!_disposed)
- {
- if (disposing)
- {
- try
- {
- ArchiveFileStream?.Dispose();
- _zipOut?.Dispose();
- _zipIn = null;
- }
- catch { }
- }
- _disposed = true;
- }
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- #endregion
-}
-
-public static class Zipping
-{
- public static string SevenZipPath = "";
-
- public static void FastAppend(FileInfo fileToZip, FileInfo archiveFile)
- {
- if (fileToZip.Exists && archiveFile?.Exists == true)
- {
- using var zip = new Archive(archiveFile) { ZipAppend = true };
- zip.Compress(new List { fileToZip });
- }
- }
-}
diff --git a/Fuchs_DataService/Fuchs_DataService.csproj b/Fuchs_DataService/Fuchs_DataService.csproj
index 65c3478..72fcb9d 100644
--- a/Fuchs_DataService/Fuchs_DataService.csproj
+++ b/Fuchs_DataService/Fuchs_DataService.csproj
@@ -1,7 +1,6 @@
-
+
net10.0
- Exe
fds
enable
enable
@@ -19,29 +18,18 @@
1591;NU1608
-
- PreserveNewest
-
-
-
+
+
-
-
- Always
-
-
-
-
-
-
-
+
+
diff --git a/Fuchs_DataService/Fuchs_DataService.vbproj b/Fuchs_DataService/Fuchs_DataService.vbproj
deleted file mode 100644
index a3f6532..0000000
--- a/Fuchs_DataService/Fuchs_DataService.vbproj
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
- net10.0
- Exe
- Sub Main
- fds
- Empty
- false
- db-dev.processweb.de;Debug;Release;server02.processweb.de
-
-
-
-
-
-
-
-
- x64
- Fuchs_DataService.xml
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
-
-
- false
- Fuchs_DataService.xml
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
-
-
-
- True
- Application.myapp
- True
-
-
- True
- True
- Resources.resx
-
-
- True
- Settings.settings
- True
-
-
-
-
-
- MyApplicationCodeGenerator
- Application.Designer.vb
-
-
-
-
-
-
-
-
-
-
-
- Always
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Fuchs_DataService/Fuchs_DataService.xml b/Fuchs_DataService/Fuchs_DataService.xml
index 4f31510..ed2c211 100644
--- a/Fuchs_DataService/Fuchs_DataService.xml
+++ b/Fuchs_DataService/Fuchs_DataService.xml
@@ -18,38 +18,10 @@
- Holds the application built from appsettings.json.
- Call once at startup before accessing .
-
-
-
-
- Writes log entries to Debug output and a rolling file.
- Database logging is wired up but disabled — set to true to activate.
-
-
-
- Set to true to activate database logging via fds__admin_logdebug.
-
-
-
- Prepared DB logging via fds__admin_logdebug.
- Enable by setting = true.
-
-
-
-
- Defines a named job with its own execution schedule for use with .
-
-
-
-
- Defines a named job with its own execution schedule for use with .
-
-
-
-
- A that runs multiple independent jobs, each on its own .
+ Holds the application supplied by the host (the Fuchs web app).
+ Fuchs_DataService is a library — it has no configuration of its own; the host owns the
+ connection strings and MFR credentials and injects them via ,
+ which Program.cs calls once at startup before any use.
diff --git a/Fuchs_DataService/Logging/FdsLoggerProvider.cs b/Fuchs_DataService/Logging/FdsLoggerProvider.cs
deleted file mode 100644
index 429dcc9..0000000
--- a/Fuchs_DataService/Logging/FdsLoggerProvider.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using Microsoft.Extensions.Logging;
-using System.Diagnostics;
-
-namespace fds.Logging;
-
-///
-/// Writes log entries to Debug output and a rolling file.
-/// Database logging is wired up but disabled — set to true to activate.
-///
-public sealed class FdsLoggerProvider : ILoggerProvider
-{
- private readonly string _logDirectory;
-
- /// Set to true to activate database logging via fds__admin_logdebug.
- public static bool DatabaseLoggingEnabled { get; set; } = false;
-
- public FdsLoggerProvider(string? logDirectory = null)
- {
- _logDirectory = logDirectory
- ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp");
- Directory.CreateDirectory(_logDirectory);
- }
-
- public ILogger CreateLogger(string categoryName) =>
- new FdsLogger(categoryName, _logDirectory);
-
- public void Dispose() { }
-}
-
-internal sealed class FdsLogger : ILogger
-{
- private readonly string _categoryName;
- private readonly string _logDirectory;
- private static readonly Lock _fileLock = new();
-
- internal FdsLogger(string categoryName, string logDirectory)
- {
- _categoryName = categoryName;
- _logDirectory = logDirectory;
- }
-
- public IDisposable? BeginScope(TState state) where TState : notnull => null;
-
- public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
-
- public void Log(LogLevel logLevel, EventId eventId, TState state,
- Exception? exception, Func formatter)
- {
- if (!IsEnabled(logLevel)) return;
-
- string message = formatter(state, exception);
- string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- string levelTag = logLevel switch
- {
- LogLevel.Trace => "TRC",
- LogLevel.Debug => "DBG",
- LogLevel.Information => "INF",
- LogLevel.Warning => "WRN",
- LogLevel.Error => "ERR",
- LogLevel.Critical => "CRT",
- _ => "???"
- };
-
- string line = $"{timestamp} [{levelTag}] {_categoryName}: {message}";
- if (exception != null)
- line += $"\r\n Exception: {exception.Message}\r\n Stack: {exception.StackTrace}";
-
- // Always emit to Debug output
- Debug.WriteLine(line);
-
- // Always write to file
- string filename = logLevel >= LogLevel.Error ? "ErrorLog.txt" : "DebugLog.txt";
- AppendToFile(filename, line);
-
- // Database logging — prepared, not activated
- if (FdsLoggerProvider.DatabaseLoggingEnabled)
- WriteToDatabase(_categoryName, message, exception);
- }
-
- private void AppendToFile(string filename, string line)
- {
- try
- {
- lock (_fileLock)
- File.AppendAllText(Path.Combine(_logDirectory, filename), line + "\r\n");
- }
- catch { /* never throw from logger */ }
- }
-
- ///
- /// Prepared DB logging via fds__admin_logdebug.
- /// Enable by setting = true.
- ///
- private static void WriteToDatabase(string codeReference, string message, Exception? exception)
- {
- // Activate by setting FdsLoggerProvider.DatabaseLoggingEnabled = true in appsettings / startup.
- //
- // using var con = new Microsoft.Data.SqlClient.SqlConnection(FdsConfig.FDSConnectionString());
- // using var cmd = new Microsoft.Data.SqlClient.SqlCommand(
- // "EXECUTE [dbo].[fds__admin_logdebug] @CodeReference, @ExceptionMessage, @StackTrace, @Data;", con);
- // cmd.Parameters.AddWithValue("@CodeReference", codeReference);
- // cmd.Parameters.AddWithValue("@ExceptionMessage", (object?)exception?.Message ?? DBNull.Value);
- // cmd.Parameters.AddWithValue("@StackTrace", (object?)exception?.StackTrace ?? DBNull.Value);
- // cmd.Parameters.AddWithValue("@Data", message);
- // con.Open();
- // cmd.ExecuteNonQuery();
- }
-}
-
-public static class FdsLoggingExtensions
-{
- public static ILoggingBuilder AddFdsLogging(this ILoggingBuilder builder, string? logDirectory = null)
- {
- builder.AddProvider(new FdsLoggerProvider(logDirectory));
- return builder;
- }
-}
diff --git a/Fuchs_DataService/appsettings.json b/Fuchs_DataService/appsettings.json
deleted file mode 100644
index 7a7f01c..0000000
--- a/Fuchs_DataService/appsettings.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "ConnectionStrings": {
- "fuchs_ConnectionString": "Data Source=MSSQL4.NBG4.DOMAINXYZ.DE,10439;Initial Catalog=site_fuchs_dev;Persist Security Info=False;TrustServerCertificate=true;Encrypt=true;User ID=fuchs_web;password='Bt5pL/cJg9oxb5';Connect Timeout=60;Load Balance Timeout=240;Max Pool Size=500;",
- "fuchs_fds_ConnectionString": "Data Source=MSSQL4.NBG4.DOMAINXYZ.DE,10439;Initial Catalog=site_fuchs_dev;Persist Security Info=False;TrustServerCertificate=true;Encrypt=true;User ID=fuchs_fds;password='!Po@cGZ5bUn37khO';Connect Timeout=60;Load Balance Timeout=240;Max Pool Size=500;"
- },
- "Fds": {
- "ExecutionFrequency_Minutes": 15,
- "DebugDetails": true,
- "MFR_UserName": "system@sebastian-fuchs---bad-und-heizung-gmbh-und-co-kg.com",
- "MFR_Password": "0oT4G3H2",
- "MFR_host": "portal.mobilefieldreport.com"
- }
-}
\ No newline at end of file
diff --git a/Fuchs_DataService/install.bat b/Fuchs_DataService/install.bat
deleted file mode 100644
index bd9c444..0000000
--- a/Fuchs_DataService/install.bat
+++ /dev/null
@@ -1 +0,0 @@
-Fuchs_Dataservice.exe install --autostart
\ No newline at end of file
diff --git a/Fuchs_DataService/un-install.bat b/Fuchs_DataService/un-install.bat
deleted file mode 100644
index 1312ccc..0000000
--- a/Fuchs_DataService/un-install.bat
+++ /dev/null
@@ -1 +0,0 @@
-Fuchs_Dataservice.exe uninstall
\ No newline at end of file
diff --git a/Fuchs_Database/FuchsDatabase.sqlproj b/Fuchs_Database/FuchsDatabase.sqlproj
index d621631..d5b509d 100644
--- a/Fuchs_Database/FuchsDatabase.sqlproj
+++ b/Fuchs_Database/FuchsDatabase.sqlproj
@@ -357,31 +357,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__createCredit_simple.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__createCredit_simple.sql
deleted file mode 100644
index 92d34c5..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__createCredit_simple.sql
+++ /dev/null
@@ -1,264 +0,0 @@
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__createCredit_simple]
- @InvId varchar(20)
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- IF [dbo].[fis_getModuleAuth]('fds_inv', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__createCredit_simple' ,@authuser , 'invid: ' + ISNULL(@InvId, ''));
-
- DECLARE @now datetime = GETDATE();
- DECLARE @today date = CAST(@now as date);
-
- DECLARE @newid varchar(10) = [dbo].[fds__fn_invoice_id]();
-
-
- DECLARE @inv_DocumentName varchar(50), @inv_DateFinalized datetime, @inv_vat numeric(5,2), @inv_net numeric(10,3);
-
- IF EXISTS (SELECT 0 FROM [dbo].[fds__invoices] WHERE [id] = @InvId AND ISNULL([isfinal],0) = 1)
- BEGIN
-
- SELECT @inv_DocumentName = [documentname], @inv_DateFinalized = [DateFinalized], @inv_vat = [InvoiceVAT_1], @inv_net = 1
- FROM [dbo].[fds__invoices] WHERE [id] = @InvId
-
- INSERT INTO [dbo].[fds__invoices]
- ([Id]
- ,[Version]
- ,[InvoiceId]
- ,[InvoiceType]
- ,[InvoiceTitle]
- ,[DocumentName]
- ,[InvoiceBalance]
- ,[InvoiceBalance_net]
- ,[InvoiceVAT_net1]
- ,[InvoiceVAT_1]
- ,[InvoiceVAT_net2]
- ,[InvoiceVAT_2]
- ,[PaymentTerm]
- ,[DueDate]
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[ProvisionPeriod]
- ,[ProvisionLocation]
- ,[PaymentStatus]
- ,[IsPayed]
- ,[IsSent]
- ,[Replaces_InvId]
- ,[CustomValues]
- ,[DateSent]
- ,[UserSent]
- ,[DateFinalized]
- ,[UserFinalized]
- ,[DateCancelled]
- ,[UserCancelled]
- ,[DateCreated]
- ,[UserCreated]
- ,[DateModified]
- ,[UserModified])
- SELECT
- [Id] = @newid
- ,[Version] = 0
- ,[InvoiceId] = NULL
- ,[InvoiceType] = 'g'
- ,[InvoiceTitle] = 'Gutschrift'
- ,[DocumentName] = NULL
- ,[InvoiceBalance] = (@inv_net * -1) * (1 + 0.01 * ISNULL(@inv_vat,19))
- ,[InvoiceBalance_net] = (@inv_net * -1)
- ,[InvoiceVAT_net1] = (@inv_net * -1) * (0.01 * ISNULL(@inv_vat,19))
- ,[InvoiceVAT_1] = @inv_net
- ,[InvoiceVAT_net2] = null
- ,[InvoiceVAT_2] = null
- ,[PaymentTerm]
- ,[DueDate] = @today
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[ProvisionPeriod]
- ,[ProvisionLocation]
- ,[PaymentStatus] = NULL
- ,[IsPayed] = 0
- ,[IsSent] = 0
- ,[Replaces_InvId] = @InvId
- ,[CustomValues]
- ,[DateSent] = NULL
- ,[UserSent] = @authuser
- ,[DateFinalized] = NULL
- ,[UserFinalized] = NULL
- ,[DateCancelled] = NULL
- ,[UserCancelled] = NULL
- ,[DateCreated] = @now
- ,[UserCreated] = @authuser
- ,[DateModified] = @now
- ,[UserModified] = @authuser
- FROM [dbo].[fds__invoices] WHERE [id] = @InvId AND ISNULL([isfinal],0) = 1;
- END
- ELSE IF EXISTS (SELECT 0 FROM [dbo].[mfr__invoices] as _i where TRY_CAST(_i.[Id] as varchar(20)) = @InvId AND [FileType] in ('PdfInvoice','PdfPartialInvoice'))
- BEGIN
-
- SELECT @inv_DocumentName = [documentname], @inv_DateFinalized = [DateOfCreation]
- , @inv_vat = CASE WHEN ISNULL([InvoiceBalanceNetto], 0) <> 0 THEN (([InvoiceBalance] / [InvoiceBalanceNetto]) - 1)*100 ELSE (SELECT TOP(1) TRY_CAST([value] as numeric(5,2)) FROM [dbo].[fds__admin_settings] as st where st.[type] = 'defaults' and st.[key] = 'vat') END
- , @inv_net = 1 --[InvoiceBalanceNetto]
- FROM [dbo].[mfr__invoices] as _i where TRY_CAST(_i.[Id] as varchar(20)) = @InvId AND [FileType] in ('PdfInvoice','PdfPartialInvoice');
-
- INSERT INTO [dbo].[fds__invoices]
- ([Id]
- ,[Version]
- ,[InvoiceId]
- ,[InvoiceType]
- ,[InvoiceTitle]
- ,[DocumentName]
- ,[InvoiceBalance]
- ,[InvoiceBalance_net]
- ,[InvoiceVAT_net1]
- ,[InvoiceVAT_1]
- ,[InvoiceVAT_net2]
- ,[InvoiceVAT_2]
- ,[PaymentTerm]
- ,[DueDate]
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[ProvisionPeriod]
- ,[ProvisionLocation]
- ,[PaymentStatus]
- ,[IsPayed]
- ,[IsSent]
- ,[Replaces_InvId]
- ,[CustomValues]
- ,[DateSent]
- ,[UserSent]
- ,[DateFinalized]
- ,[UserFinalized]
- ,[DateCancelled]
- ,[UserCancelled]
- ,[DateCreated]
- ,[UserCreated]
- ,[DateModified]
- ,[UserModified])
- SELECT
- [Id] = @newid
- ,[Version] = 0
- ,[InvoiceId] = NULL
- ,[InvoiceType] = 'g'
- ,[InvoiceTitle] = 'Gutschrift'
- ,[DocumentName] = NULL
- ,[InvoiceBalance] = (@inv_net * -1) * (1 + 0.01 * ISNULL(@inv_vat,19))
- ,[InvoiceBalance_net] = (@inv_net * -1)
- ,[InvoiceVAT_net1] = (@inv_net * -1) * (0.01 * ISNULL(@inv_vat,19))
- ,[InvoiceVAT_1] = @inv_vat
- ,[InvoiceVAT_net2] = NULL
- ,[InvoiceVAT_2] = NULL
- ,[PaymentTerm] = '10wd'
- ,[DueDate] = _i.DueDate
- ,[CustomerId] = (SELECT TOP(1) [partnerid] from [mfr__*PartnerSet] as ps where ps.[Property] = 'Invoice:Customer' and ps.[EntityId] = _i.[id])
- ,[SendToAddress] = NULL
- ,[SendToEmail] = NULL
- ,[ProvisionPeriod] = null
- ,[ProvisionLocation] = NULL
- ,[PaymentStatus] = NULL
- ,[IsPayed] = 0
- ,[IsSent] = 0
- ,[Replaces_InvId] = @InvId
- ,[CustomValues] = null
- ,[DateSent] = NULL
- ,[UserSent] = @authuser
- ,[DateFinalized] = NULL
- ,[UserFinalized] = NULL
- ,[DateCancelled] = NULL
- ,[UserCancelled] = NULL
- ,[DateCreated] = @now
- ,[UserCreated] = @authuser
- ,[DateModified] = @now
- ,[UserModified] = @authuser
- FROM [dbo].[mfr__invoices] as _i where TRY_CAST(_i.[Id] as varchar(20)) = @InvId AND [FileType] in ('PdfInvoice','PdfPartialInvoice');
- UPDATE [dbo].[fds__invoices]
- SET [SendToAddress] = [dbo].[fds__getCompanyNameAddress]([CustomerId]), [SendToEmail] = [dbo].[fds__getCompanyEmail]([CustomerId])
- WHERE [Id] = @newid;
-
- END
-
-
-
- -- continue creating storno
-
- DECLARE @inv_srq [dbo].[fds__tt__invoice_servicerequests];
- INSERT INTO [dbo].[fds__invoice_servicerequests]
- ([InvId]
- ,[mfr__servicerequest]
- ,[title]
- ,[value_net]
- ,[SortOrder])
- OUTPUT
- inserted.* INTO @inv_srq
- SELECT
- [InvId] = [id]
- ,NULL --
- ,'Gutschrift'
- ,(@inv_net * -1)
- ,0
- FROM [dbo].[fds__invoices] WHERE [id] = @newid;
-
-
- INSERT INTO [dbo].[fds__invoice_items]
- ([InvId]
- ,[InvRqId]
- ,[mfr__item]
- ,[reference_InvId]
- ,[Type]
- ,[Position]
- ,[Quantity]
- ,[Text]
- ,[value]
- ,[value_total]
- ,[vat]
- ,[value_service]
- ,[det]
- ,[SortOrder])
- SELECT
- @newid --
- ,[id]--
- ,NULL --
- ,@InvId --
- ,'CreditInvoice' --
- ,NULL --
- ,'1' ---
- ,[Text] = '' + 'Gutschrift zu der ' + REPLACE(@inv_DocumentName, '.pdf','') + ' vom ' + FORMAT(@inv_dateFinalized, 'dd.MM.yyyy', 'de-de') + '
'
- ,[value] = (@inv_net * -1)
- ,[value_total] = (@inv_net * -1)
- ,[vat] = @inv_vat
- ,0 --
- ,1 --
- ,1 --)
- FROM @inv_srq;
-
-
- INSERT INTO [dbo].[fds__invoice_details]
- ([InvId]
- ,[InvoiceService_net]
- ,[InvoiceService_VAT]
- ,[AllocatedTo_InvId]
- ,[StornoTo_InvId])
- VALUES(
- @newid
- ,NULL --[InvoiceService_net]
- ,NULL --[InvoiceService_VAT]
- ,NULL --[AllocatedTo_InvId]
- ,@InvId --[StornoTo_InvId]
- );
-
- EXECUTE [dbo].[fds__getInvoice] @newid, @authuser;
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__createReminder.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__createReminder.sql
deleted file mode 100644
index b16b388..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__createReminder.sql
+++ /dev/null
@@ -1,120 +0,0 @@
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__createReminder]
- @InvId varchar(15)
- , @type varchar(3)
- , @amount numeric(10,3)
- , @amount_payed numeric(10,3)
- , @SendToAddress [nvarchar](1000)
- , @SendToEmail [nvarchar](255)
- , @subject nvarchar(255)
- , @text nvarchar(2000)
- , @authuser varchar(25)
- , @Id varchar(10) OUT
-
-AS
-BEGIN
- SET NOCOUNT ON;
-
-
- IF [dbo].[fis_getModuleAuth]('fds_reminder', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__createReminder' ,@authuser , 'invid: ' + ISNULL(@invid, ''));
-
- DECLARE @now datetime = GETUTCDATE();
- DECLARE @today date = @now;
-
-
- DECLARE @newid varchar(10) = [dbo].[fds__fn_reminder_id]();
-
- DECLARE @OUT [dbo].[fds__tt__reminder_core];
- DECLARE @CustomerId bigint = dbo.fds__fn_invoice_customerid(@InvId);
-
- INSERT INTO [dbo].[fds__reminder]
- ([Id]
- ,[version]
- ,[InvId]
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[type]
- ,[amount]
- ,[amount_payed]
- ,[subject]
- ,[text]
- ,[IsSent]
- ,[CustomValues]
- ,[DateSent]
- ,[UserSent]
- ,[DateFinalized]
- ,[UserFinalized]
- ,[DateCreated]
- ,[UserCreated]
- ,[DateModified]
- ,[UserModified]
- ,[file])
- OUTPUT inserted.*
- INTO @OUT
- VALUES
- (@newid
- ,0 --version
- ,@InvId
- ,@CustomerId
- ,@SendToAddress
- ,@SendToEmail
- ,@type
- ,@amount
- ,@amount_payed
- ,@subject
- ,@text
- ,0 --IsSent, bit,>
- ,null --
- ,NULL --
- ,NULL --[UserSent]
- ,NULL --
- ,NULL --
- ,@now
- ,@authuser
- ,@now
- ,@authuser
- ,NULL);
-
-
- SELECT TOP(1) @Id = [id] FROM @out;
-
-
- With inv1 as(
- select TOP(1) * FROM [dbo].[fds__invoices] WHERE [id] = @InvId
- ), inv as(
- SELECT [Id] = cast([id] as varchar(15))
- ,[Invoiceid]
- ,[DateFinalized]
- ,[InvoiceBalance]
- FROM inv1
- UNION
- SELECT [Id] = cast([id] as varchar(15))
- ,[Invoiceid]
- ,[DateFinalized] = [DateOfCreation]
- ,[InvoiceBalance]
- FROM [dbo].[mfr__invoices] as mfri
- WHERE [id] = TRY_CAST(@invId as bigint) AND NOT EXISTS( SELECT 0 FROM inv1 ) --will only be used, if id not present in fds__invoices
- )
- SELECT TOP(1)
- o.*
- , [InvoiceId] = inv.[InvoiceId]
- , [InvoiceDate] = inv.[DateFinalized]
- , [hasFile] = CAST ( CASE WHEN o.[file] is null THEN 0 ELSE 1 END as bit)
- , [UserNameFinalized] = [dbo].[fis_admin_getUserName_byID](o.[UserFinalized])
- , [UserEmailFinalized] = [dbo].[fis_admin_getUserEmail_byID](o.[UserFinalized])
- from @out as o
- join inv on o.[invid] = inv.[id];
-
-
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__createStorno_simple.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__createStorno_simple.sql
deleted file mode 100644
index 7eb58b0..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__createStorno_simple.sql
+++ /dev/null
@@ -1,263 +0,0 @@
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__createStorno_simple]
- @InvId varchar(20)
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- IF [dbo].[fis_getModuleAuth]('fds_inv', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__createStorno_simple' ,@authuser , 'invid: ' + ISNULL(@InvId, ''));
-
- DECLARE @now datetime = GETDATE();
- DECLARE @today date = CAST(@now as date);
-
- DECLARE @newid varchar(10) = [dbo].[fds__fn_invoice_id]();
-
-
- DECLARE @inv_DocumentName varchar(50), @inv_DateFinalized datetime, @inv_vat numeric(5,2), @inv_net numeric(10,3);
-
- IF EXISTS (SELECT 0 FROM [dbo].[fds__invoices] WHERE [id] = @InvId AND ISNULL([isfinal],0) = 1)
- BEGIN
-
- SELECT @inv_DocumentName = [documentname], @inv_DateFinalized = [DateFinalized], @inv_vat = [InvoiceVAT_1], @inv_net = [invoicebalance_net] FROM [dbo].[fds__invoices] WHERE [id] = @InvId
-
- INSERT INTO [dbo].[fds__invoices]
- ([Id]
- ,[Version]
- ,[InvoiceId]
- ,[InvoiceType]
- ,[InvoiceTitle]
- ,[DocumentName]
- ,[InvoiceBalance]
- ,[InvoiceBalance_net]
- ,[InvoiceVAT_net1]
- ,[InvoiceVAT_1]
- ,[InvoiceVAT_net2]
- ,[InvoiceVAT_2]
- ,[PaymentTerm]
- ,[DueDate]
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[ProvisionPeriod]
- ,[ProvisionLocation]
- ,[PaymentStatus]
- ,[IsPayed]
- ,[IsSent]
- ,[Replaces_InvId]
- ,[CustomValues]
- ,[DateSent]
- ,[UserSent]
- ,[DateFinalized]
- ,[UserFinalized]
- ,[DateCancelled]
- ,[UserCancelled]
- ,[DateCreated]
- ,[UserCreated]
- ,[DateModified]
- ,[UserModified])
- SELECT
- [Id] = @newid
- ,[Version] = 0
- ,[InvoiceId] = NULL
- ,[InvoiceType] = 'c'
- ,[InvoiceTitle] = 'Stornorechnung'
- ,[DocumentName] = NULL
- ,[InvoiceBalance] = ([InvoiceBalance] * -1)
- ,[InvoiceBalance_net] = ([InvoiceBalance_net] *-1)
- ,[InvoiceVAT_net1] = ([InvoiceVAT_net1] * -1)
- ,[InvoiceVAT_1]
- ,[InvoiceVAT_net2] = ([InvoiceVAT_net2] * -1)
- ,[InvoiceVAT_2]
- ,[PaymentTerm]
- ,[DueDate] = @today
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[ProvisionPeriod]
- ,[ProvisionLocation]
- ,[PaymentStatus] = NULL
- ,[IsPayed] = 0
- ,[IsSent] = 0
- ,[Replaces_InvId] = @InvId
- ,[CustomValues]
- ,[DateSent] = NULL
- ,[UserSent] = NULL
- ,[DateFinalized] = NULL
- ,[UserFinalized] = NULL
- ,[DateCancelled] = NULL
- ,[UserCancelled] = NULL
- ,[DateCreated] = @now
- ,[UserCreated] = @authuser
- ,[DateModified] = @now
- ,[UserModified] = @authuser
- FROM [dbo].[fds__invoices] WHERE [id] = @InvId AND ISNULL([isfinal],0) = 1;
- END
- ELSE IF EXISTS (SELECT 0 FROM [dbo].[mfr__invoices] as _i where TRY_CAST(_i.[Id] as varchar(20)) = @InvId AND [FileType] in ('PdfInvoice','PdfPartialInvoice'))
- BEGIN
-
- SELECT @inv_DocumentName = [documentname], @inv_DateFinalized = [DateOfCreation]
- , @inv_vat = CASE WHEN ISNULL([InvoiceBalanceNetto], 0) <> 0 THEN (([InvoiceBalance] / [InvoiceBalanceNetto]) - 1)*100 ELSE (SELECT TOP(1) TRY_CAST([value] as numeric(5,2)) FROM [dbo].[fds__admin_settings] as st where st.[type] = 'defaults' and st.[key] = 'vat') END
- , @inv_net = [InvoiceBalanceNetto]
- FROM [dbo].[mfr__invoices] as _i where TRY_CAST(_i.[Id] as varchar(20)) = @InvId AND [FileType] in ('PdfInvoice','PdfPartialInvoice');
-
- INSERT INTO [dbo].[fds__invoices]
- ([Id]
- ,[Version]
- ,[InvoiceId]
- ,[InvoiceType]
- ,[InvoiceTitle]
- ,[DocumentName]
- ,[InvoiceBalance]
- ,[InvoiceBalance_net]
- ,[InvoiceVAT_net1]
- ,[InvoiceVAT_1]
- ,[InvoiceVAT_net2]
- ,[InvoiceVAT_2]
- ,[PaymentTerm]
- ,[DueDate]
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[ProvisionPeriod]
- ,[ProvisionLocation]
- ,[PaymentStatus]
- ,[IsPayed]
- ,[IsSent]
- ,[Replaces_InvId]
- ,[CustomValues]
- ,[DateSent]
- ,[UserSent]
- ,[DateFinalized]
- ,[UserFinalized]
- ,[DateCancelled]
- ,[UserCancelled]
- ,[DateCreated]
- ,[UserCreated]
- ,[DateModified]
- ,[UserModified])
- SELECT
- [Id] = @newid
- ,[Version] = 0
- ,[InvoiceId] = NULL
- ,[InvoiceType] = 'c'
- ,[InvoiceTitle] = 'Stornorechnung'
- ,[DocumentName] = NULL
- ,[InvoiceBalance] = ([InvoiceBalance] * -1)
- ,[InvoiceBalance_net] = ([InvoiceBalanceNetto] *-1)
- ,[InvoiceVAT_net1] = ((ISNULL([InvoiceBalance],0) - ISNULL([InvoiceBalanceNetto],0)) * -1)
- ,[InvoiceVAT_1] = @inv_vat
- ,[InvoiceVAT_net2] = NULL
- ,[InvoiceVAT_2] = NULL
- ,[PaymentTerm] = '10wd'
- ,[DueDate] = _i.DueDate
- ,[CustomerId] = (SELECT TOP(1) [partnerid] from [mfr__*PartnerSet] as ps where ps.[Property] = 'Invoice:Customer' and ps.[EntityId] = _i.[id])
- ,[SendToAddress] = NULL
- ,[SendToEmail] = NULL
- ,[ProvisionPeriod] = null
- ,[ProvisionLocation] = NULL
- ,[PaymentStatus] = NULL
- ,[IsPayed] = 0
- ,[IsSent] = 0
- ,[Replaces_InvId] = @InvId
- ,[CustomValues] = null
- ,[DateSent] = NULL
- ,[UserSent] = NULL
- ,[DateFinalized] = NULL
- ,[UserFinalized] = NULL
- ,[DateCancelled] = NULL
- ,[UserCancelled] = NULL
- ,[DateCreated] = @now
- ,[UserCreated] = @authuser
- ,[DateModified] = @now
- ,[UserModified] = @authuser
- FROM [dbo].[mfr__invoices] as _i where TRY_CAST(_i.[Id] as varchar(20)) = @InvId AND [FileType] in ('PdfInvoice','PdfPartialInvoice');
- UPDATE [dbo].[fds__invoices]
- SET [SendToAddress] = [dbo].[fds__getCompanyNameAddress]([CustomerId]), [SendToEmail] = [dbo].[fds__getCompanyEmail]([CustomerId])
- WHERE [Id] = @newid;
-
- END
-
-
-
- -- continue creating storno
-
- DECLARE @inv_srq [dbo].[fds__tt__invoice_servicerequests];
- INSERT INTO [dbo].[fds__invoice_servicerequests]
- ([InvId]
- ,[mfr__servicerequest]
- ,[title]
- ,[value_net]
- ,[SortOrder])
- OUTPUT
- inserted.* INTO @inv_srq
- SELECT TOP(1)
- [InvId] = [id]
- ,NULL --
- ,'Storno'
- ,0
- ,0
- FROM [dbo].[fds__invoices] WHERE [id] = @newid;
-
-
- INSERT INTO [dbo].[fds__invoice_items]
- ([InvId]
- ,[InvRqId]
- ,[mfr__item]
- ,[reference_InvId]
- ,[Type]
- ,[Position]
- ,[Quantity]
- ,[Text]
- ,[value]
- ,[value_total]
- ,[vat]
- ,[value_service]
- ,[det]
- ,[SortOrder])
- SELECT
- @newid --
- ,[id]--
- ,NULL --
- ,@InvId --
- ,'CanceledInvoice' --
- ,NULL --
- ,'1' ---
- ,[Text] = '' + 'Storno der ' + REPLACE(@inv_DocumentName, '.pdf','') + ' vom ' + FORMAT(@inv_dateFinalized, 'dd.MM.yyyy', 'de-de') + '
'
- ,[value] = (@inv_net * -1)
- ,[value_total] = (@inv_net * -1)
- ,[vat] = @inv_vat
- ,0 --
- ,1 --
- ,1 --)
- FROM @inv_srq;
-
-
- INSERT INTO [dbo].[fds__invoice_details]
- ([InvId]
- ,[InvoiceService_net]
- ,[InvoiceService_VAT]
- ,[AllocatedTo_InvId]
- ,[StornoTo_InvId])
- VALUES(
- @newid
- ,NULL --[InvoiceService_net]
- ,NULL --[InvoiceService_VAT]
- ,NULL --[AllocatedTo_InvId]
- ,@InvId --[StornoTo_InvId]
- );
-
- EXECUTE [dbo].[fds__getInvoice] @newid, @authuser;
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getBankingtransfers.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getBankingtransfers.sql
deleted file mode 100644
index 21dfadb..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getBankingtransfers.sql
+++ /dev/null
@@ -1,51 +0,0 @@
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getBankingtransfers]
- @mode varchar(1) = 'm'
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_bam', @authuser) < 1
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__getBankingtransfers_questionable' ,@authuser , '');
-
- DECLARE @startdate date, @enddate date, @today date = GETDATE();
- DECLARE @true bit = 1, @false bit = 0;
- SET @mode = LOWER(@mode);
-
- DECLARE @invidlist [dbo].[fds__tt__idlist_vchar];
-
- --output admin
- SELECT [startdate] = @startdate, [enddate] = @enddate, [mode] = @mode, [title] = 'Zahlungen (neueste zuerst)'
- ,[note] = 'Letzes Buchungsdatum: ' + FORMAT((SELECT MAX([valuedate]) from [fds__bankingtransactions]), 'dd.MM.yy');
-
-
- select
- ic.[taID]
- --inv.InvoiceId,
- --[IsPayed],
- , ic.fds
- , InvoiceId = ISNULL(fi.[invoiceid], mi.[invoiceid])
- , [ValueDate] = FORMAT(ic.[ValueDate], 'dd.MM.yy')
- , [InvoiceBalance] = FORMAT((ISNULL(fi.[InvoiceBalance],0.0) + ISNULL(mi.[InvoiceBalance],0.0)), '0.00€', 'de')
- , [Amount] = FORMAT(ic.[amount], '0.00€', 'de')
- , [Skonto] = CAST(CASE WHEN ic.[amount] between (0.965 * (ISNULL(fi.[InvoiceBalance],0.0) + ISNULL(mi.[InvoiceBalance],0.0))) and (0.975 * (ISNULL(fi.[InvoiceBalance],0.0) + ISNULL(mi.[InvoiceBalance],0.0))) THEN 1 ELSE 0 END as bit)
- , [Deviation] = FORMAT(CASE WHEN ISNULL((ISNULL(fi.[InvoiceBalance],0.0) + ISNULL(mi.[InvoiceBalance],0.0)),0) > 9 THEN ic.[amount] / (ISNULL(fi.[InvoiceBalance],0.0) + ISNULL(mi.[InvoiceBalance],0.0)) ELSE NULL END , '0.00%')
- --, ic.*
- ,ic.AccountNumberOfPayer
- ,ic.NameOfPayer
- ,ic.SepaRemittanceInformation
- ,ic.EndToEndReference
- , [order] = ROW_NUMBER() OVER (ORDER BY [valuedate] DESC)
- FROM
- [dbo].[fds__fn_bankingtransactions](null, null, @startdate, @enddate, @invidlist) as ic
- LEFT JOIN [dbo].[fds__invoices] as fi on ic.[fds] = 1 and ic.[invid] = fi.id
- LEFT JOIN [dbo].[mfr__invoices] as mi on ic.[fds] = 0 and ic.[invid] = mi.id
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getBankingtransfers_questionable.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getBankingtransfers_questionable.sql
deleted file mode 100644
index aa74767..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getBankingtransfers_questionable.sql
+++ /dev/null
@@ -1,60 +0,0 @@
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getBankingtransfers_questionable]
- @mode varchar(1) = 'm'
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_bam', @authuser) < 1
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__getBankingtransfers_questionable' ,@authuser , '');
-
- DECLARE @startdate date, @enddate date, @today date = GETDATE();
- DECLARE @true bit = 1, @false bit = 0;
- SET @mode = LOWER(@mode);
-
-
- --output admin
- SELECT [startdate] = @startdate, [enddate] = @enddate, [mode] = @mode, [title] = 'Auffällige Zahlungen (neueste zuerst)'
- ,[note] = 'Letzes Buchungsdatum: ' + FORMAT((SELECT MAX([valuedate]) from [fds__bankingtransactions]), 'dd.MM.yy');
-
-
- with inv as (
- SELECT [fds] = CAST(1 as bit), [InvId] = CAST([Id] as varchar(25)), [InvoiceId], [InvoiceBalance] = CAST([InvoiceBalance] as numeric(10,2)), [ispayed] FROM [dbo].[fds__invoices] as i
- UNION
- SELECT [fds] = CAST(0 as bit), [InvId] = CAST([Id] as varchar(25)), [InvoiceId], [InvoiceBalance] = CAST([InvoiceBalance] as numeric(10,2)), [ispayed] = CAST(CASE WHEN [InvoiceState] = 'eIsCancelled' THEN 1 WHEN [InvoiceState] = 'eIsPaid' THEN 1 ELSE 0 END as bit) FROM [dbo].[mfr__invoices] as i
- )
- select
- ic.[taID]
- --inv.InvoiceId,
- --[IsPayed],
- , inv.fds
- , ic.InvoiceId
- , [ValueDate] = FORMAT(ic.[ValueDate], 'dd.MM.yy')
- , [InvoiceBalance] = FORMAT(inv.[InvoiceBalance], '0.00€', 'de') + ISNULL( CASE WHEN id2.[invid] is not null then (SELECT TOP(1) FORMAT(inv2.[InvoiceBalance], '0.00€', 'de') FROM [dbo].[fds__invoices] as inv2 where inv2.Id = id2.[invid]) ELSE '' END ,'')
- , [Amount] = FORMAT(ic.[amount], '0.00€', 'de')
- , [Skonto] = CAST(CASE WHEN ic.[amount] between (0.965 * inv.[InvoiceBalance]) and (0.975 * inv.[InvoiceBalance]) THEN 1 ELSE 0 END as bit)
- , [Deviation] = FORMAT(CASE WHEN ISNULL(inv.[InvoiceBalance],0) > 9 THEN ic.[amount] / inv.[InvoiceBalance] ELSE NULL END , '0.00%')
- --, ic.*
- ,ic.AccountNumberOfPayer
- ,ic.NameOfPayer
- ,ic.SepaRemittanceInformation
- ,ic.EndToEndReference
- , [order] = ROW_NUMBER() OVER (ORDER BY [valuedate] DESC)
- FROM
- [dbo].[fds__getInvoiceCredits] (null, null) as ic
- LEFT JOIN inv on inv.[InvoiceId] = ic.[invoiceid]
- LEFT JOIN [dbo].[fds__invoice_details] as id2 ON inv.InvId = id2.[stornoto_invid]
- WHERE
- ((ISNULL(inv.ispayed,0) = 0 and fds = 1) OR
- ic.[amount] not between (inv.InvoiceBalance - 0.99) and (inv.InvoiceBalance + 0.99) OR
- ic.invoiceid is null oR
- inv.invoiceid is null
- ) AND NOT EXISTS (SELECT 0 FROM [dbo].[fds__bankingtransactions_settings] as bs WHERE bs.[taID] = ic.[taID] AND (ISNULL(bs.[done_manually],'') <> '' OR ISNULL(bs.[assigned_invoice_id],'') <> ''))
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getDatevExports.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getDatevExports.sql
deleted file mode 100644
index e748ef3..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getDatevExports.sql
+++ /dev/null
@@ -1,634 +0,0 @@
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getDatevExports]
- @tgtdate date
- ,@mode varchar(1) = 'm'
- ,@files bit
- ,@authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- IF [dbo].[fis_getModuleAuth]('fds_reports', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
-
-
- DECLARE @startdate date, @enddate date;
- SET @mode = LOWER(@mode);
- If @mode = 'm'
- BEGIN
- SELECT @startdate = [dbo].[date_monthfirst](@tgtdate)
- ,@enddate = [dbo].[date_monthend](@tgtdate);
- END
- ELSE If @mode = 'w'
- BEGIN
- SELECT @startdate = [dbo].[date_weekfirst](@tgtdate)
- ,@enddate = [dbo].[date_weekend](@tgtdate);
- END
-
- DECLARE @contraaccounts as table([account] varchar(10), [vat] numeric(5,2));
- insert into @contraaccounts
- SELECT [account] = [key], [vat] = TRY_PARSE([value2] as numeric(5,2) USING 'en-US') FROM [dbo].[fds__admin_settings] WHERE [type] = 'contra_account'
-
- SELECT [startdate] = @startdate, [enddate] = @enddate, [mode] = @mode
- , [beraternummer] = 11653
- , [mandantennummer] = 62321
- , [WJ-Beginn] = DATEFROMPARTS(YEAR(@tgtDate), 1, 1)
- , [Sachkontenlänge] = ISNULL((SELECT MAX(LEN([account])) FROM @contraaccounts), 4)
- ;
-
-
- DECLARE @inv TABLE([Id] varchar(20), [InvoiceID] varchar(255), [URI] nvarchar(255), [DocumentName] nvarchar(255), [DateOfCreation] date, [fds] bit, [file_guid] varchar(36));
- --INSERT INTO @inv SELECT [Id],[invoiceid],[URI],[DocumentName],[DateOfCreation],[fds] = 0 FROM [dbo].[mfr__reports] where [IsInvoice] = 1 AND CAST([DateOfCreation] as date) between @startdate AND @enddate;
- INSERT INTO @inv SELECT [Id],[invoiceid],[URI],[DocumentName],[DateOfCreation],[fds] = 0, [file_guid] FROM [dbo].[mfr__invoices] where CAST([DateOfCreation] as date) between @startdate AND @enddate and [FileType] in( 'PdfInvoice','PdfCancelInvoice','PdfPartialInvoice') and ISNULL(InvoiceId,'') not in ('Preview','') ;
- INSERT INTO @inv SELECT [Id],[invoiceid],[URI] = null,[DocumentName],[DateOfCreation] = [DateCreated],[fds] = 1, [file_guid] FROM [dbo].[fds__invoices] where CAST([DateCreated] as date) between @startdate AND @enddate and [isfinal] = 1;
-
- SELECT
- inv.[Id],inv.[InvoiceID],inv.[URI],inv.[DocumentName],inv.[fds]
- , [file] = CASE WHEN @files = 1 then finv.[file] ELSE NULL END
- , inv.[file_guid], [DateOfCreation]
- --,[order] = ROW_NUMBER() OVER (ORDER BY [DateOfCreation] ASC)
- FROM @inv as inv LEFT JOIN [dbo].[fds__invoices] as finv on inv.[id] = finv.[id];
-
- DECLARE @SReq TABLE ([id] bigint, [DateOfCreation] datetime, [name] nvarchar(255), [invoice.Id] varchar(15), [customer.ExternalId] bigint, [customer.Id] bigint, [ExternalId] nvarchar(255), [fds] bit);
- INSERT INTO @SReq
- SELECT s.[Id], s.[DateOfCreation], s.[name], [invoice.Id] = i.[Id], [customer.ExternalId] = cy.ExternalId , [customer.Id] = cy.[id], s.[ExternalId], [fds]
- FROM [dbo].[mfr__servicerequests] as s JOIN @inv as i on s.[InvoiceId] like ('%' + i.[InvoiceId] + '%') LEFT JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- WHERE i.fds = 0;
- INSERT INTO @SReq
- SELECT s.[Id], s.[DateOfCreation], s.[name], [invoice.Id] = i.[Id], [customer.ExternalId] = cy.ExternalId , [customer.Id] = cy.[id], s.[ExternalId], [fds]
- FROM [dbo].[fds__invoice_servicerequests] as irq
- JOIN @inv as i on irq.[InvId] = i.[Id]
- LEFT JOIN [dbo].[mfr__servicerequests] as s ON irq.[mfr__servicerequest] = s.[id]
- LEFT JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- WHERE i.fds = 1;
-
-
-
- With itm as (
- SELECT
- [net_itemsum] = CAST( SUM((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) as numeric(12,2))
- , [bo_itemsum] = CAST( SUM( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * (1 + (ISNULL(vat.[vat], 19.0) * 0.01))) as numeric(12,2))
- , [vf] = MAX(1 + (ISNULL(vat.[vat], 19.0) * 0.01))
- , sreq.[invoice.Id]
- ,[fds] = 0
- FROM [dbo].[mfr__items] as itm
- JOIN @sreq as sreq ON itm.[ServiceRequestId] = SReq.[id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item'
- WHERE [fds] = 0
- GROUP BY sreq.[invoice.Id]
- UNION
- SELECT
- [net_itemsum] = CAST( SUM(ISNULL([value_total],0)) as numeric(12,2))
- , [bo_itemsum] = CAST( SUM(ISNULL([value_total],0) * (1 + (ISNULL([vat], 19.0) * 0.01))) as numeric(12,2))
- , [vf] = MAX(1 + (ISNULL([vat], 19.0) * 0.01))
- , [invoice.Id] = inv.[id] --sreq.[invoice.Id]
- , [fds] = 1
- FROM [dbo].[fds__invoice_items] as itm
- --JOIN @sreq as sreq ON itm.[InvRqId] = SReq.[id]
- JOIN @inv as inv ON itm.[invid] = inv.[id] and [fds] = 1
- WHERE [fds] = 1
- GROUP BY inv.[id] --sreq.[invoice.Id]
- ),sc as(
- SELECT s.[invoice.Id], [fds], [#] = COUNT(s.[id]) FROM @SReq as s GROUP BY s.[invoice.Id], [fds]
- ), inv as(
- --select
- -- [Id] = CAST(iv.[Id] as varchar(20))
- -- ,[InvoiceId] = iv.[InvoiceId]
- -- ,[requestcount] = sc.[#]
- -- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = iv.id)
- -- ,[balance] = ABS([invoiceBalance])
- -- ,[EINZELPOS_brutto] = itm.bo_itemsum
- -- ,[EINZELPOS_netto] = itm.net_itemsum
- -- ,[vf]
- -- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- -- ,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
- -- ,[contra_account] = ca.[account]
- -- ,[Belegdatum] = iv.[DateOfCreation]
- -- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
- -- ,iv.[DateOfCreation]
- -- from [dbo].[mfr__reports] as iv
- -- LEFT JOIN itm on iv.Id = itm.[invoice.Id]
- -- LEFT JOIN [dbo].[fds__custom_vat] as vat ON iv.[Id] = vat.[EntityId] and vat.[EntityType] = 'report'
- -- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 0
- -- LEFT JOIN contra_accounts as ca ON ISNULL(vat.[vat], 19.0) = ca.[vat]
- -- where iv.Id in (SELECT [Id] FROM @inv Where fds = 0)
- --UNION
- select
- [Id] = CAST(iv.[Id] as varchar(20))
- ,[InvoiceId] = iv.[InvoiceId]
- ,[requestcount] = sc.[#]
- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = iv.id)
- ,[balance] = ABS([invoiceBalance])
- ,[EINZELPOS_brutto] = itm.bo_itemsum
- ,[EINZELPOS_netto] = itm.net_itemsum
- ,[vf]
- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- ,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
- ,[contra_account] = ca.[account]
- ,[Belegdatum] = iv.[DateOfCreation]
- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
- ,iv.[DateOfCreation]
- ,[file_guid]
- from [dbo].[mfr__invoices] as iv
- LEFT JOIN itm on iv.Id = itm.[invoice.Id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON iv.[Id] = vat.[EntityId] and vat.[EntityType] = 'report'
- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 0
- LEFT JOIN @contraaccounts as ca ON ISNULL(vat.[vat], ISNULL([dbo].[fds__fn_vatfrombalances]([invoiceBalance], [invoiceBalancenetto]),19.0)) = ca.[vat]
- where iv.Id in (SELECT [Id] FROM @inv Where fds = 0)
- UNION
- select
- iv.[Id]
- ,[InvoiceId] = iv.[InvoiceId]
- ,[requestcount] = sc.[#]
- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = iv.id)
- ,[balance] = ABS([invoiceBalance])
- ,[EINZELPOS_brutto] = itm.bo_itemsum
- ,[EINZELPOS_netto] = itm.net_itemsum
- ,[vf]
- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- ,[customer] = (SELECT TOP(1) [ExternalId] FROM [dbo].[mfr__companies] as c WHERE c.[Id] = iv.[CustomerId])
- ,[contra_account] = ca.[account]
- ,[Belegdatum] = iv.[DateCreated]
- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
- ,[DateOfCreation] = iv.[DateCreated]
- ,[file_guid]
- from [dbo].[fds__invoices] as iv
- LEFT JOIN itm on iv.Id = itm.[invoice.Id]
- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 1
- LEFT JOIN @contraaccounts as ca ON ISNULL(iv.[InvoiceVAT_1], 19.0) = ca.[vat]
- where iv.Id in (SELECT [Id] FROM @inv Where fds = 1)
- )
- select
- [Umsatz (ohne Soll/Haben-Kz)] = ABS([balance])--CAST(FORMAT(ABS([balance]), '0.00', 'de') as varchar(13))
- --,[EINZELPOS_brutto]
- --,[EINZELPOS_netto]
- --,vf
- ,[Soll/Haben-Kennzeichen] = [dbo].[ott_quote_255](UPPER([deb_cred]))
- ,[WKZ Umsatz] = [dbo].[ott_quote_255]('')
- ,[Kurs] = NULL
- ,[Basis-Umsatz] = NULL
- ,[WKZ Basis-Umsatz] = [dbo].[ott_quote_255]('')
- ,[Konto] = CAST(iv.[customer] as bigint) --CAST(iv.[customer] as varchar(9)) --(SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] ORDER BY SReq.DateOfCreation ASC)
- ,[Gegenkonto (ohne BU-Schlüssel)] = CAST([contra_account] as bigint )--CAST([contra_account] as varchar(9))]
- ,[BU-Schlüssel] = [dbo].[ott_quote_255]('')
- ,[Belegdatum] = FORMAT(iv.[Belegdatum], 'ddMM')
- ,[Belegfeld 1] = [dbo].[ott_quote_255](iv.[InvoiceId])
- ,[Belegfeld 2] = [dbo].[ott_quote_255]([dbo].[strings_removeLeading0_255](FORMAT(iv.[Belegdatum], 'ddMMyy')))
- ,[Skonto] = [dbo].[ott_quote_255]('')
- ,[Buchungstext] = [dbo].[ott_quote_255](CAST(ISNULL(LEFT( TRIM(CAST((SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id]) as varchar(255)) ), 60) ,'') as varchar(60)))
- ,[Postensperre] = NULL
- ,[Diverse Adressnummer] = [dbo].[ott_quote_255]('')
- ,[Geschäftspartnerbank] = null
- ,[Sachverhalt] = null
- ,[Zinssperre] = null
- ,[Beleglink] = [dbo].[ott_quote_255](CASE WHEN [file_guid] is null THEN NULL
- ELSE CAST( 'BEDI "' + LOWER(CAST([file_guid] as varchar(36))) + '"' as varchar(50))
- end)
- --,[order] = ROW_NUMBER() OVER (ORDER BY iv.[DateOfCreation] ASC)]
- ,[Beleginfo - Art 1] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Inhalt 1] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Art 2] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Inhalt 2] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Art 3] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Inhalt 3] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Art 4] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Inhalt 4] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Art 5] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Inhalt 5] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Art 6] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Inhalt 6] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Art 7] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Inhalt 7] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Art 8] = [dbo].[ott_quote_255]('')
- ,[Beleginfo - Inhalt 8] = [dbo].[ott_quote_255]('')
- ,[KOST1 - Kostenstelle] = [dbo].[ott_quote_255]('')
- ,[KOST2 - Kostenstelle] = [dbo].[ott_quote_255]('')
- ,[Kost-Menge] = null
- ,[EU-Land u. UStID (Bestimmung)] = [dbo].[ott_quote_255]('')
- ,[EU-Steuersatz (Bestimmung)] = null
- ,[Abw. Versteuerungsart] = [dbo].[ott_quote_255]('')
- ,[Sachverhalt L+L] = null
- ,[Funktionsergänzung L+L] = null
- ,[BU 49 Hauptfunktionstyp] = null
- ,[BU 49 Hauptfunktionsnummer] = null
- ,[BU 49 Funktionsergänzung] = null
- ,[Zusatzinformation - Art 1] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 1] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 2] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 2] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 3] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 3] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 4] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 4] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 5] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 5] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 6] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 6] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 7] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 7] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 8] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 8] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 9] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 9] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 10] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 10] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 11] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 11] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 12] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 12] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 13] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 13] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 14] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 14] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 15] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 15] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 16] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 16] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 17] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 17] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 18] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 18] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 19] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 19] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation - Art 20] = [dbo].[ott_quote_255]('')
- ,[Zusatzinformation- Inhalt 20] = [dbo].[ott_quote_255]('')
- ,[Stück] = null
- ,[Gewicht] = null
- ,[Zahlweise] = null
- ,[Forderungsart] = [dbo].[ott_quote_255]('')
- ,[Veranlagungsjahr] = null
- ,[Zugeordnete Fälligkeit] = null
- ,[Skontotyp] = null
- ,[Auftragsnummer] = [dbo].[ott_quote_255]('')
- ,[Buchungstyp] = [dbo].[ott_quote_255]('')
- ,[USt-Schlüssel (Anzahlungen)] = null
- ,[EU-Land (Anzahlungen)] = [dbo].[ott_quote_255]('')
- ,[Sachverhalt L+L (Anzahlungen)] = null
- ,[EU-Steuersatz (Anzahlungen)] = null
- ,[Erlöskonto (Anzahlungen)] = null
- ,[Herkunft-Kz] = [dbo].[ott_quote_255]('')
- ,[Buchungs GUID] = [dbo].[ott_quote_255]('')
- ,[KOST-Datum] = null
- ,[Mandatsreferenz] = [dbo].[ott_quote_255]('')
- ,[Skontosperre] = null
- ,[Gesellschaftername] = [dbo].[ott_quote_255]('')
- ,[Beteiligtennummer] = null
- ,[Identifikationsnummer] = [dbo].[ott_quote_255]('')
- ,[Zeichnernummer] = [dbo].[ott_quote_255]('')
- ,[Postensperre bis] = null
- ,[Bezeichnung SoBil-Sachverhalt] = [dbo].[ott_quote_255]('')
- ,[Kennzeichen SoBil-Buchung] = [dbo].[ott_quote_255]('')
- ,[Festschreibung] = 1
- ,[Leistungsdatum] = null
- ,[Datum Zuord. Steuerperiode] = null
- ,[Fälligkeit] = null
- ,[Generalumkehr (GU)] = 0
- ,[Steuersatz] = null
- ,[Land] = null
- --,[Abrechnungsreferenz]
- --,[BVV-Position]
- --,[EU-Land u. UStID (Ursprung)]
- --,[EU-Steuersatz (Ursprung)]
- from inv as iv
- order by TRY_CONVERT(integer, SUBSTRING(iv.[InvoiceId], 2,4)), TRY_CONVERT(integer, RIGHT(iv.[InvoiceId], 4)), iv.[DateOfCreation] ASC;
-
-
-
-
- WIth debs as (
- SELECT ROW_NUMBER() OVER (PARTITION BY [customer.Id] ORDER BY SReq.DateOfCreation ASC) as [#]
- , [customer.ExternalId]
- , [customer.Id]
- FROM @SReq as sreq
- ), dd as (
- SELECT distinct cy.* FROM [mfr__companies] as cy WHERE EXISTS ( SELECT * FROM debs WHERE debs.[customer.Id] = cy.[id] AND debs.[#] = 1)
- ), cc as (
- SELECT ROW_NUMBER() OVER (PARTITION BY dd.[id] ORDER BY CASE WHEN dd.[MainContactId] = c.[id] THEN 0 ELSE 1 END) as '#'
- , c.*
- , [company_id] = dd.[id]
- , [company_name] = dd.[Name]
- , [isCompany] = CAST (
- CASE WHEN ( not dd.[name] like '%c[/]o %'
- AND (
- dd.[Name] like '%mbH%'
- OR dd.[Name] like '%Ltd%'
- OR dd.[Name] like '% gbr%' OR dd.[Name] like 'gbr %'
- OR dd.[Name] like '% OHG%'
- OR (REPLACE(dd.[Name], '|' , ' ') + ' ') like '% AG %'
- OR (REPLACE(dd.[Name], '|' , ' ') + ' ') like '% KG %'
- OR (REPLACE(dd.[Name], '|' , ' ') + ' ') like '% SA %'
- OR (REPLACE(dd.[Name], '|' , ' ') + ' ') like '% UG %'
- OR dd.[Name] like '% eV%' or dd.[Name] like '%e[.]V[.]%'
- OR dd.[Name] like '%Gesellschaft%'
- OR dd.[Name] like '%Gemeinde%'
- OR dd.[Name] like '%Verwaltung%'
- OR dd.[Name] like '%Stadtwerke%'
- OR dd.[Name] like '%tagesstätte%'
- OR dd.[Name] like '%schützenverein%'
- OR dd.[Name] like '%akademie%'
- OR dd.[Name] like '%universität%'
- OR dd.[Name] like '%schule%'
- OR dd.[Name] like '%spedition%'
- OR dd.[Name] like '%immobilien%'
- OR dd.[Name] like '%krankenkasse%'
- OR dd.[Name] like '% holding %'
- OR dd.[Name] like '% Bautenschutz %'
- OR dd.[Name] like '%dienstleistung%'
- OR dd.[Name] like '%weinlokal%'
- OR dd.[Name] like '%restaurant%'
- OR dd.[Name] like '% hotel%'
- OR dd.[Name] like '%kanzlei%'
- OR dd.[Name] like '%praxis%'
- OR dd.[Name] like '%großhandel%'
- OR dd.[Name] like '%tischlerei%'
- OR dd.[Name] like '%haustechnik%'
- OR dd.[Name] like '%holztechnik%'
- OR dd.[Name] like '%heizungsbau%'
- OR dd.[Name] like '%bautenschutz%'
- OR dd.[Name] like '%tischlerei%'
- OR dd.[Name] like '%architekt%'
- OR dd.[Name] like '%sanitär%'
- OR dd.[Name] like '%pafümerie%'
- OR dd.[Name] like '%bauamt%'
- OR dd.[Name] like '%gebäudereinigung%'
- OR dd.[Name] like '%handwerksmeister%'
- OR dd.[Name] like '%fachbetrieb%'
- OR dd.[Name] like '%ausbau und montagen%'
- OR dd.[Name] like '%verband %'
- OR dd.[Name] like '%vermietung%'
- OR dd.[Name] like '%Bad [&] Heizung%'
- OR dd.[Name] like '%Bad[&]Wärme%'
- OR dd.[Name] like '% Düsseldorf%'
- OR dd.[Name] like '%niederlassung%'
- OR dd.[Name] like 'zentrum für %'
- OR dd.[Name] like '% Generalvertretung %'
- ))
-
- THEN 1 ELSE 0 END
- as bit)
- FROM [dbo].[mfr__contacts] as c JOIN dd on c.[CompanyId] = dd.[Id] OR dd.[MainContactId] = c.[id]
- )
- SELECT
- [Konto] = CAST(dd.[ExternalId] as bigint) --CAST(dd.[ExternalId] as varchar(9))
- ,[Name (Adressatentyp Unternehmen)] = [dbo].[ott_quote_255](CAST(LEFT(CAST(CASE WHEN cc.[isCompany] = 0 THEN '' ELSE REPLACE(REPLACE(REPLACE(ISNULL( cc.[company_name] ,''), CHAR(13), ' '), CHAR(10), ' '), ' ', ' ') END as varchar(255)), 50) as varchar(50)))
- ,[Unternehmensgegenstand] = [dbo].[ott_quote_255]('')
- ,[Name (Adressattyp natürl. Person)] = [dbo].[ott_quote_255](CAST(LEFT(CAST(CASE WHEN cc.[isCompany] = 1 THEN '' ELSE REPLACE(REPLACE(REPLACE(ISNULL( cc.[LastName] ,''), CHAR(13), ' '), CHAR(10), ' '), ' ', ' ') END as varchar(255)), 30) as varchar(30)))
- ,[Vorname (Adressattyp natürl. Person)] = [dbo].[ott_quote_255](CAST(LEFT(CAST(CASE WHEN cc.[isCompany] = 1 THEN '' ELSE REPLACE(REPLACE(REPLACE(ISNULL( cc.[FirstName] ,''), CHAR(13), ' '), CHAR(10), ' '), ' ', ' ') END as varchar(255)), 30) as varchar(30)))
- ,[Name (Adressattyp keine Angabe)] = [dbo].[ott_quote_255]('')
- ,[Adressattyp] = [dbo].[ott_quote_255](CAST(CASE WHEN cc.[isCompany] = 1 THEN 2 ELSE 1 END as varchar(1)))
- ,[Kurzbezeichnung] = [dbo].[ott_quote_255]('')
- ,[EU-Land] = [dbo].[ott_quote_255]('')
- ,[EU-UStID] = [dbo].[ott_quote_255]('')
- ,[Anrede] = [dbo].[ott_quote_255]('') --CASE WHEN LOWER(LEFT(cc.[Gender],1)) = 'm' THEN 'Herrn' WHEN LOWER(LEFT(cc.[Gender],1)) = 'w' THEN 'Frau' ELSE '' END
- ,[Titel/Akad. Grad] = [dbo].[ott_quote_255]('')
- ,[Adelstitel] = [dbo].[ott_quote_255]('')
- ,[Namensvorsatz] = [dbo].[ott_quote_255]('')
- ,[Adressart] = [dbo].[ott_quote_255](CAST( CASE WHEN ISNULL(l.[AddressString],'') like '%postfach%' THEN 'PF' ELSE 'STR' END as varchar(3)))
- ,[Straße] = [dbo].[ott_quote_255](CAST(LEFT(CAST(CASE WHEN ISNULL(l.[AddressString],'') like '%postfach%' THEN '' ELSE ISNULL(l.[AddressString],'') END as varchar(255)),36) as varchar(36)))
- ,[Postfach] = [dbo].[ott_quote_255](CAST(LEFT(CAST(CASE WHEN ISNULL(l.[AddressString],'') like '%postfach%' THEN TRIM(SUBSTRING(ISNULL(l.[AddressString],''), PATINDEX('%postfach%', ISNULL(l.[AddressString],'')) + 8 , 12)) ELSE '' END as varchar(255)),36) as varchar(36)))
- ,[Postleitzahl] = [dbo].[ott_quote_255](CAST(l.[Postal] as varchar(10)))
- ,[Ort] = [dbo].[ott_quote_255](CAST(l.City as varchar(30)))
- ,[Land] = [dbo].[ott_quote_255](CAST(REPLACE(UPPER(ISNULL(l.[Country], '')),'KE','') as varchar(2)))
- ,[Versandzusatz] = [dbo].[ott_quote_255]('')
- ,[Adresszusatz] = [dbo].[ott_quote_255]('')
- ,[Abweichende Anrede] = [dbo].[ott_quote_255]('')
- ,[Abw. Zustellbezeichnung 1] = [dbo].[ott_quote_255]('')
- ,[Abw. Zustellbezeichnung 2] = [dbo].[ott_quote_255]('')
- ,[Kennz. Korrespondenzadresse] = Cast(1 as int)
- ,[Adresse Gültig von] = [dbo].[ott_quote_255]('')
- ,[Adresse Gültig bis] = [dbo].[ott_quote_255]('')
- ,[Telefon] = [dbo].[ott_quote_255](CAST(ISNULL(cc.[Telephone], dd.[SupportTelephone]) as varchar(60)))
- ,[Bemerkung (Telefon)] = [dbo].[ott_quote_255]('')
- ,[Telefon GL] = [dbo].[ott_quote_255]('')
- ,[Bemerkung (Telefon GL)] = [dbo].[ott_quote_255]('')
- ,[E-Mail] = [dbo].[ott_quote_255](CAST( CASE WHEN ISNULL(cc.[Email], dd.[SupportMail]) like '%[@]%' THEN REPLACE(LOWER(ISNULL(cc.[Email], dd.[SupportMail])), ' ', '') ELSE NULL END as varchar(60)))
- ,[Bemerkung (E-Mail)] = [dbo].[ott_quote_255]('')
- ,[Internet] = [dbo].[ott_quote_255]('')
- ,[Bemerkung (Internet)] = [dbo].[ott_quote_255]('')
- ,[Fax] = [dbo].[ott_quote_255]('')
- ,[Bemerkung (Fax)] = [dbo].[ott_quote_255]('')
- ,[Sonstige] = [dbo].[ott_quote_255]('')
- ,[Bemerkung (Sonstige)] = [dbo].[ott_quote_255]('')
- ,[Bankleitzahl 1] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 1] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 1] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 1] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 1] = [dbo].[ott_quote_255]('')
- ,[IBAN1 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 1] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 1] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 1] = [dbo].[ott_quote_255]('')
- ,[Bankverb 1 Gültig von] = null
- ,[Bankverb 1 Gültig bis] = null
- ,[Bankleitzahl 2] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 2] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 2] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 2] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 2] = [dbo].[ott_quote_255]('')
- ,[IBAN2 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 2] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 2] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 2] = [dbo].[ott_quote_255]('')
- ,[Bankverb 2 Gültig von] = null
- ,[Bankverb 2 Gltig bis] = null
- ,[Bankleitzahl 3] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 3] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 3] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 3] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 3] = [dbo].[ott_quote_255]('')
- ,[IBAN3 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 3] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 3] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 3] = [dbo].[ott_quote_255]('')
- ,[Bankverb 3 Gültig von] = null
- ,[Bankverb 3 Gültig bis] = null
- ,[Bankleitzahl 4] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 4] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 4] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 4] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 4] = [dbo].[ott_quote_255]('')
- ,[IBAN4 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 4] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 4] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 4] = [dbo].[ott_quote_255]('')
- ,[Bankverb 4 Gültig von] = null
- ,[Bankverb 4 Gültig bis] = null
- ,[Bankleitzahl 5] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 5] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 5] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 5] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 5] = [dbo].[ott_quote_255]('')
- ,[IBAN5 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 5] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 5] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 5] = [dbo].[ott_quote_255]('')
- ,[Bankverb 5 Gültig von] = null
- ,[Bankverb 5 Gültig bis] = null
- ,[Leerfeld] = null
- ,[Briefanrede] = [dbo].[ott_quote_255]('')
- ,[Grußformel] = [dbo].[ott_quote_255]('')
- ,[Kundennummer] = [dbo].[ott_quote_255]('')
- ,[Steuernummer] = [dbo].[ott_quote_255]('')
- ,[Sprache] = null
- ,[Ansprechpartner] = [dbo].[ott_quote_255]('')
- ,[Vertreter] = [dbo].[ott_quote_255]('')
- ,[Sachbearbeiter] = [dbo].[ott_quote_255]('')
- ,[Diverse-Konto] = null
- ,[Ausgabeziel] = null
- ,[Währungssteuerung] = [dbo].[ott_quote_255]('')
- ,[Kreditlimit (Debitor)] = null
- ,[Zahlungsbedingung] = null
- ,[Fälligkeit in Tagen (Debitor)] = null
- ,[Skonto in Prozent (Debitor)] = null
- ,[Kreditoren-Ziel 1 Tg.] = null
- ,[Kreditoren-Skonto 1 %] = null
- ,[Kreditoren-Ziel 2 Tg.] = null
- ,[Kreditoren-Skonto 2 %] = null
- ,[Kreditoren-Ziel 3 Brutto Tg.] = null
- ,[Kreditoren-Ziel 4 Tg.] = null
- ,[Kreditoren-Skonto 4 %] = null
- ,[Kreditoren-Ziel 5 Tg.] = null
- ,[Kreditoren-Skonto 5 %] = null
- ,[Mahnung] = null
- ,[Kontoauszug] = null
- ,[Mahntext 1] = null
- ,[Mahntext 2] = null
- ,[Mahntext 3] = null
- ,[Kontoauszugstext] = null
- ,[Mahnlimit Betrag] = null
- ,[Mahnlimit %] = null
- ,[Zinsberechnung] = null
- ,[Mahnzinssatz 1] = null
- ,[Mahnzinssatz 2] = null
- ,[Mahnzinssatz 3] = null
- ,[Lastschrift] = [dbo].[ott_quote_255]('')
- ,[Verfahren] = [dbo].[ott_quote_255]('')
- ,[Mandantenbank] = null
- ,[Zahlungsträger] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 1] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 2] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 3] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 4] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 5] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 6] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 7] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 8] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 9] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 10] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 11] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 12] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 13] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 14] = [dbo].[ott_quote_255]('')
- ,[Indiv. Feld 15] = [dbo].[ott_quote_255]('')
- ,[Abweichende Anrede (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Adressart (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Straße (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Postfach (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Postleitzahl (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Ort (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Land (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Versandzusatz (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Adresszusatz (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Abw. Zustellbezeichnung 1 (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Abw. Zustellbezeichnung 2 (Rechnungsadresse)] = [dbo].[ott_quote_255]('')
- ,[Adresse Gültig von (Rechnungsadresse)] = null
- ,[Adresse Gültig bis (Rechnungsadresse)] = null
- ,[Bankleitzahl 6] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 6] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 6] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 6] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 6] = [dbo].[ott_quote_255]('')
- ,[IBAN6 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 6] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 6] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 6] = [dbo].[ott_quote_255]('')
- ,[Bankverb 6 Gültig von] = null
- ,[Bankverb 6 Gültig bis] = null
- ,[Bankleitzahl 7] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 7] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 7] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 7] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 7] = [dbo].[ott_quote_255]('')
- ,[IBAN7 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 7] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 7] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 7] = [dbo].[ott_quote_255]('')
- ,[Bankverb 7 Gültig von] = null
- ,[Bankverb 7 Gültig bis] = null
- ,[Bankleitzahl 8] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 8] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 8] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 8] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 8] = [dbo].[ott_quote_255]('')
- ,[IBAN8 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 8] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 8] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 8] = [dbo].[ott_quote_255]('')
- ,[Bankverb 8 Gültig von] = null
- ,[Bankverb 8 Gültig bis] = null
- ,[Bankleitzahl 9] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 9] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 9] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 9] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 9] = [dbo].[ott_quote_255]('')
- ,[IBAN9 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 9] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 9] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 9] = [dbo].[ott_quote_255]('')
- ,[Bankverb 9 Gültig von] = null
- ,[Bankverb 9 Gültig bis] = null
- ,[Bankleitzahl 10] = [dbo].[ott_quote_255]('')
- ,[Bankbezeichnung 10] = [dbo].[ott_quote_255]('')
- ,[Bank-Kontonummer 10] = [dbo].[ott_quote_255]('')
- ,[Länderkennzeichen 10] = [dbo].[ott_quote_255]('')
- ,[IBAN-Nr. 10] = [dbo].[ott_quote_255]('')
- ,[IBAN10 korrekt] = [dbo].[ott_quote_255]('')
- ,[SWIFT-Code 10] = [dbo].[ott_quote_255]('')
- ,[Abw. Kontoinhaber 10] = [dbo].[ott_quote_255]('')
- ,[Kennz. Hauptbankverb. 10] = [dbo].[ott_quote_255]('')
- ,[Bankverb 10 Gültig von] = null
- ,[Bankverb 10 Gültig bis] = null
- ,[Nummer Fremdsystem] = [dbo].[ott_quote_255]('')
- ,[Insolvent] = null
- ,[Mandatsreferenz 1] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 2] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 3] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 4] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 5] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 6] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 7] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 8] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 9] = [dbo].[ott_quote_255]('')
- ,[Mandatsreferenz 10] = [dbo].[ott_quote_255]('')
- ,[Verknüpftes OPOS-Konto] = null
- ,[Mahnsperre bis] = null
- ,[Lastschriftsperre bis] = null
- ,[Zahlungssperre bis] = null
- ,[gebührenberechnung] = null
- ,[Mahngebühr 1] = null
- ,[Mahngebühr 2] = null
- ,[Mahngebühr 3] = null
- ,[Pauschalenberechnung] = null
- ,[Verzugspauschale 1] = null
- ,[Verzugspauschale 2] = null
- ,[Verzugspauschale 3] = null
- ,[Alternativer Suchname] = null
- ,[Status] = null
- ,[Anschrift manuell geändert (Korrespondenzadresse)] = null
- ,[Anschrift individuell (Korrespondenzadresse)] = null
- ,[Anschrift manuell geändert (Rechnungsadresse)] = null
- ,[Anschrift individuell (Rechnungsadresse)] = null
- ,[Fristberechnung bei Debitor] = null
- ,[Mahnfrist 1] = null
- ,[Mahnfrist 2] = null
- ,[Mahnfrist 3] = null
- ,[Letzte Frist] = null
- FROM dd JOIN cc on cc.[#] = 1 AND cc.[company_id] = dd.[id]
- LEFT JOIN [dbo].[mfr__#locations] as l ON l.[EntityID] = dd.[id] and l.Property = 'Company:Location'
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvRequestItems.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvRequestItems.sql
deleted file mode 100644
index e5bd618..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvRequestItems.sql
+++ /dev/null
@@ -1,57 +0,0 @@
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getInvRequestItems]
- @invoiceid varchar(20)
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- DECLARE @idbigint bigint = TRY_CAST(@invoiceid as bigint);
-
-
- DECLARE @SReq TABLE ([id] bigint, [DateOfCreation] datetime, [name] nvarchar(255), [invoice.Id] varchar(20), [customer.ExternalId] bigint, [customer.Id] bigint, [mfr] bit);
-
- INSERT INTO @SReq
- SELECT s.[Id], s.[DateOfCreation], s.[name], [invoice.Id] = TRY_CAST(i.[Id] as varchar(20)), [customer.ExternalId] = cy.ExternalId , [customer.Id] = cy.[id], [mfr] = 1
- FROM [dbo].[mfr__servicerequests] as s JOIN [mfr__reports] as i on i.[id] = @idbigint and s.[InvoiceId] like ('%' + i.[InvoiceId] + '%') LEFT JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- where i.[id] = @idbigint
- UNION
- SELECT s.[Id], s.[DateOfCreation], s.[name], [invoice.Id] = i.[Id], [customer.ExternalId] = cy.ExternalId , [customer.Id] = cy.[id], [mfr] = 0
- FROM [dbo].[mfr__servicerequests] as s
- JOIN [dbo].[fds__invoice_servicerequests] as iq ON s.[id] = iq.[mfr__servicerequest]
- JOIN [dbo].[fds__invoices] as i on iq.[InvId] = i.[id] AND i.[id] = @invoiceid
- LEFT JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- where i.[id] = @invoiceid
- ;
-
- SELECT
- [id],[DateOfCreation],[name],[invoice.Id],[customer.ExternalId],[customer.Id], [mfr]
- ,[order] = ROW_NUMBER() OVER (ORDER BY [DateOfCreation])
- FROM @SReq;
-
-
- SELECT
- itm.[Id]
- , [net_pos] = CASE WHEN LOWER(itm.[type]) in ('Title','Text') THEN '' ELSE FORMAT( CAST( (ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0) as numeric(7,2)) , '#0.00 €','de') END
- , [bo_pos] = CASE WHEN LOWER(itm.[type]) in ('Title','Text') THEN '' ELSE FORMAT( CAST( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * (1 + (ISNULL(vat.[vat], 19.0) * 0.01)) as numeric(7,2)) , '#0.00 €','de') END
- , [vat] = CASE WHEN LOWER(itm.[type]) in ('Title','Text') THEN null ELSE FORMAT(ISNULL(vat.[vat], 19.0), '#0.0','de') + '%' END
- , itm.[ServiceRequestId]
- , itm.[SortOrder]
- , itm.[Type]
- , itm.[NameOrNumber]
- , sreq.[invoice.Id]
- , [order] = ROW_NUMBER() OVER (PARTITION BY itm.[ServiceRequestId] ORDER BY itm.[SortOrder])
- FROM [dbo].[mfr__items] as itm
- JOIN @sreq as sreq ON itm.[ServiceRequestId] = SReq.[id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item'
- ;
-
-
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoiceReminder.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoiceReminder.sql
deleted file mode 100644
index f5eaad5..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoiceReminder.sql
+++ /dev/null
@@ -1,43 +0,0 @@
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getInvoiceReminder]
- @InvId varchar(15)
- , @include_drafts bit = 0
- ,@authuser varchar(25)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- With inv as (
- SELECT TOP(1)
- [Id] = CAST([id] as varchar(15)), [InvoiceId], [DocumentName]
- FROM [dbo].[fds__invoices]
- WHERE [id] = @InvId
- ), inv2 as(
- SELECT * FROM inv
- UNION
- SELECT TOP(1)
- [Id] = CAST([id] as varchar(15)), [InvoiceId], [DocumentName]
- FROM [dbo].[mfr__invoices] as mi
- WHERE NOT EXISTS( SELECT 0 FROM inv )
- AND TRY_CAST(@InvId as bigint) is not null
- AND mi.[id] = TRY_CAST(@InvId as bigint)
- )
- SELECT rem.[Id]
- ,rem.[DateSent]
- ,[status] = CAST(CASE WHEN rem.[isSent] = 1 THEN 'versandt' WHEN rem.[isfinal] = 1 THEN 'fertig' WHEN rem.isfinal = 0 THEN 'Entwurf' ELSE '' END AS varchar(50))
- ,rem.[subject]
- ,rem.[DocumentName]
- ,rem.[amount_open]
- ,rem.[InvId]
- ,[InvoiceId] = inv2.[InvoiceId]
- --,[InvoiceDocumentName] = inv2.[DocumentName]
- ,[hasFile] = cast( IIF(rem.[file] is null, 0, 1) as bit)
- FROM [dbo].[fds__reminder] as rem
- LEFT JOIN inv2 on rem.[InvId] = inv2.[Id]
- WHERE [invId] = @InvId;
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoices_list2.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoices_list2.sql
deleted file mode 100644
index a601a60..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoices_list2.sql
+++ /dev/null
@@ -1,285 +0,0 @@
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getInvoices_list2]
- @tgtdate date
- ,@mode varchar(1) = 'm'
- , @include_drafts bit = 0
- , @search varchar(100)
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_inv', @authuser) < 1
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__getInvoices_list' ,@authuser , @search);
-
- DECLARE @startdate date, @enddate date, @today date = GETDATE();
- DECLARE @true bit = 1, @false bit = 0;
- DECLARE @searchmode as varchar(1) = CASE WHEN SUBSTRING(ISNULL(@search, '') + ' ', 2,1) <> ':' THEN '' ELSE LOWER(LEFT(@search,1 )) END;
-
-
- DECLARE @customerfilter TABLE ([CustomerID] bigint);
-
- IF @searchmode <> ''
- BEGIN
- SELECT @mode = 's', @search = SUBSTRING(@search,3, 1000);
-
- IF @searchmode = 'c' AND LEN(@search) > 3
- BeGIN
- INSERT INTO @customerfilter SELECT [id] FROM [dbo].[mfr__companies] WHERE [Name] like ('%' + @search + '%');
- END
- END
- ELSE
- SET @mode = LOWER(@mode);
- If @mode = 'm'
- BEGIN
- SELECT @startdate = [dbo].[date_monthfirst](@tgtdate)
- ,@enddate = [dbo].[date_monthend](@tgtdate);
- END
- ELSE If @mode = 'w'
- BEGIN
- SELECT @startdate = [dbo].[date_weekfirst](@tgtdate)
- ,@enddate = [dbo].[date_weekend](@tgtdate);
- END;
-
-
- --Reminder settings
- DECLARE @stage1 varchar(10), @stage2 varchar(10), @stage3 varchar(10);
- SELECT @stage1 = [stage1], @stage2 = [stage2], @stage3 = [stage3] FROM [dbo].[fds__admin_reminderSettings]();
-
-
-
- SELECT [startdate] = @startdate, [enddate] = @enddate, [mode] = @mode
- , [title] = 'Rechnungsübersicht für ' + CASE WHEN @mode = 'm' THEN 'MONAT ' + FORMAT(@startdate, 'MMM yyyy')
- WHEN @mode = 'w' THEN 'WOCHE ' + FORMAT(@startdate, 'dd.MM.yyyy') + ' - ' + FORMAT(@enddate, 'dd.MM.')
- WHEN @searchmode = 'i' THEN 'Suche nach Rechnungsnummer ''' + @search + ''''
- WHEN @searchmode = 'c' THEN 'Suche nach Kunde ''' + @search + ''''
- ELSE '' END
- ,[ust_options] = '19,0%;16,0%;0,0%';
-
-
- DECLARE @inv TABLE([Id] varchar(15), [InvoiceID] varchar(255), [URI] nvarchar(255), [DocumentName] nvarchar(255), [DateOfCreation] date, [fds] bit);
- --INSERT INTO @inv SELECT [Id],[invoiceid],[URI],[DocumentName],[DateOfCreation],[fds] = 0 FROM [dbo].[mfr__reports] where [IsInvoice] = 1 AND CAST([DateOfCreation] as date) between @startdate AND @enddate;
- INSERT INTO @inv SELECT [Id],[invoiceid],[URI],[DocumentName],[DateOfCreation],[fds] = 0 FROM [dbo].[mfr__invoices]
- where (CASE WHEN @searchmode = 'i' THEN
- (CASE WHEN [InvoiceID] = @search OR [InvoiceID] like ('R20[0-9][0-9][-]' + @search) THEN 1 ELSE 0 END)
- ELSE
- (CASE WHEN CAST([DateOfCreation] as date) between @startdate AND @enddate and (ISNULL(@include_drafts,0) = 1 OR [FileType] in( 'PdfInvoice','PdfCancelInvoice','PdfPartialInvoice') and ISNULL(InvoiceId,'') not in ('Preview','')) THEN 1 ELSE 0 END)
- END) = 1;
- INSERT INTO @inv SELECT [Id],[invoiceid],[URI] = null,[DocumentName],[DateOfCreation] = [DateCreated],[fds] = 1 FROM [dbo].[fds__invoices]
- where (CASE WHEN @searchmode = 'i' THEN
- (CASE WHEN [InvoiceID] = @search OR [InvoiceID] like ('R20[0-9][0-9][-]' + @search) THEN 1 ELSE 0 END)
- WHEN @searchmode = 'c' THEN
- (CASE WHEN [CustomerId] IN (SELECT [CustomerId] fROM @customerfilter) THEN 1 ELSE 0 END)
- ELSE
- (CASE WHEN CAST([DateCreated] as date) between @startdate AND @enddate and (ISNULL(@include_drafts,0) = 1 OR [isfinal] = 1) THEN 1 ELSE 0 END)
- END) = 1;
-
-
- DECLARE @SReq TABLE ([id] bigint, [DateOfCreation] datetime, [name] nvarchar(255), [invoice.Id] varchar(15), [customer.ExternalId] bigint, [customer.Id] bigint, [ExternalId] nvarchar(255), [fds] bit);
- INSERT INTO @SReq
- SELECT s.[Id], s.[DateOfCreation], s.[name], [invoice.Id] = i.[Id], [customer.ExternalId] = cy.ExternalId , [customer.Id] = cy.[id], s.[ExternalId], [fds]
- FROM [dbo].[mfr__servicerequests] as s
- JOIN dbo.[mfr__*PartnerSet] as p on p.[EntityId] = s.[Id] AND p.[Property] = 'ServiceRequest:Invoices'
- JOIN @inv as i on i.fds = 0 and p.[PartnerId] = i.[id] --s.[InvoiceId] like ('%' + i.[InvoiceId] + '%')
- LEFT JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- WHERE i.fds = 0;
- INSERT INTO @SReq
- SELECT s.[Id], s.[DateOfCreation], s.[name], [invoice.Id] = i.[Id], [customer.ExternalId] = cy.ExternalId , [customer.Id] = cy.[id], s.[ExternalId], [fds]
- FROM [dbo].[fds__invoice_servicerequests] as irq
- JOIN @inv as i on irq.[InvId] = i.[Id]
- LEFT JOIN [dbo].[mfr__servicerequests] as s ON irq.[mfr__servicerequest] = s.[id]
- LEFT JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- WHERE i.fds = 1;
-
- With itm as (
- SELECT
- [net_itemsum] = CAST( SUM((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) as numeric(12,2))
- , [bo_itemsum] = CAST( SUM( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * (1 + (ISNULL(vat.[vat], 19.0) * 0.01))) as numeric(12,2))
- , [vf] = MAX(1 + (ISNULL(vat.[vat], 19.0) * 0.01))
- , sreq.[invoice.Id]
- ,[fds] = 0
- FROM [dbo].[mfr__items] as itm
- JOIN @sreq as sreq ON itm.[ServiceRequestId] = SReq.[id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item'
- WHERE [fds] = 0
- GROUP BY sreq.[invoice.Id]
- UNION
- SELECT
- [net_itemsum] = CAST( SUM(ISNULL([value_total],0)) as numeric(12,2))
- , [bo_itemsum] = CAST( SUM(ISNULL([value_total],0) * (1 + (ISNULL([vat], 19.0) * 0.01))) as numeric(12,2))
- , [vf] = MAX(1 + (ISNULL([vat], 19.0) * 0.01))
- , [invoice.Id] = inv.[id] --sreq.[invoice.Id]
- , [fds] = 1
- FROM [dbo].[fds__invoice_items] as itm
- --JOIN @sreq as sreq ON itm.[InvRqId] = SReq.[id]
- JOIN @inv as inv ON itm.[invid] = inv.[id] and [fds] = 1
- WHERE [fds] = 1
- GROUP BY inv.[id] --sreq.[invoice.Id]
- ),sc as(
- SELECT s.[invoice.Id], [fds], [#] = COUNT(s.[id]) FROM @SReq as s GROUP BY s.[invoice.Id], [fds]
- ),contra_accounts as(
- SELECT [account] = [key], [vat] = TRY_PARSE([value2] as numeric(5,2) USING 'en-US') FROM [dbo].[fds__admin_settings] WHERE [type] = 'contra_account'
- ), inv as(
- --select
- -- [Id] = CAST(iv.[Id] as varchar(15))
- -- ,[InvoiceId] = iv.[InvoiceId]
- -- ,[InvoiceType] = CAST( CASE WHEN LEFT([documentname],5) = 'absch' THEN 'i'
- -- WHEN LEFT([documentname],5) = 'storn' THEN 'c'
- -- ELSE 'r'
- -- END
- -- as char(1))
- -- ,[DocumentName]
- -- ,[requestcount] = sc.[#]
- -- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = iv.id)
- -- ,[balance] = FORMAT(ABS([invoiceBalance]), '#0.00', 'de') + ' €'
- -- ,[EINZELPOS_brutto] = FORMAT(itm.bo_itemsum, '#0.00', 'de') + ' €'
- -- ,[EINZELPOS_netto] = FORMAT(itm.net_itemsum, '#0.00', 'de') + ' €'
- -- ,[vat] = FORMAT(ISNULL(vat.[vat], 19.0), '#0.0', 'de') + ' %'
- -- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- -- ,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
- -- ,[contra_account] = ca.[account]
- -- ,[Belegdatum] = FORMAT(iv.[DateOfCreation], 'dd.MM.yy')
- -- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
- -- ,iv.[DateOfCreation]
- -- ,iv.[DueDate]
- -- ,[PaymentTerm] = @stage1
- -- ,ivi.[PaymentStatus]
- -- ,[IsPayed] = CAST(CASE WHEN ISNULL(iv.[IsCanceled],0) = 1 THEN 1 ELSE ISNULL(ivi.[IsPayed],0) END as bit)
- -- ,[IsCanceled]
- -- ,[isSent] = @true
- -- ,[isFinal] = @true
- -- ,[hasFile] = CAST( CASE wHEN ISNULL([URI], '') <> '' THEN 1 ELSE 0 END as bit)
- -- ,[fds] = @false
- -- from [dbo].[mfr__reports] as iv
- -- LEFT JOIN [dbo].[fds__custom_invoiceinfo] as ivi on iv.[id] = ivi.[invid]
- -- LEFT JOIN itm on iv.Id = itm.[invoice.Id]
- -- LEFT JOIN [dbo].[fds__custom_vat] as vat ON iv.[Id] = vat.[EntityId] and vat.[EntityType] = 'report'
- -- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 0
- -- LEFT JOIN contra_accounts as ca ON ISNULL(vat.[vat], 19.0) = ca.[vat]
- -- where iv.Id in (SELECT [Id] FROM @inv Where fds = 0)
- --UNION
- select
- [Id] = CAST(iv.[Id] as varchar(15))
- ,[InvoiceId] = iv.[InvoiceId]
- ,[InvoiceType] = CAST( CASE WHEN LEFT([documentname],5) = 'absch' THEN 'i'
- WHEN LEFT([documentname],5) = 'storn' THEN 'c'
- ELSE 'r'
- END
- as char(1))
- ,[DocumentName]
- ,[requestcount] = sc.[#]
- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = TRY_CAST(iv.id as varchar(50)))
- ,[balance] = FORMAT([invoiceBalance], '#0.00', 'de') + ' €'
- ,[EINZELPOS_brutto] = NULL --FORMAT(itm.bo_itemsum, '#0.00', 'de') + ' €'
- ,[EINZELPOS_netto] = NULL --FORMAT(itm.net_itemsum, '#0.00', 'de') + ' €'
- ,[vat] = FORMAT(ISNULL(vat.[vat], ISNULL([dbo].[fds__fn_vatfrombalances]([invoiceBalance], [invoiceBalancenetto]) ,19.0)), '#0.0', 'de') + ' %'
- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- --,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE TRY_CAST(iv.id as varchar(50)) = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
- ,[contra_account] = ca.[account]
- ,[Belegdatum] = FORMAT(iv.[DateOfCreation], 'dd.MM.yy')
- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE TRY_CAST(iv.id as varchar(50)) = sreq.[invoice.Id])
- ,iv.[DateOfCreation]
- ,iv.[DueDate]
- ,[PaymentTerm] = @stage1
- ,ivi.[PaymentStatus]
- ,[IsPayed] = CAST(CASE WHEN ISNULL(ivi.isPayed,0) = 1 THEN 1 WHEN [InvoiceState] = 'eIsCancelled' THEN 1 WHEN [InvoiceState] = 'eIsPaid' THEN 1 ELSE 0 END as bit)
- ,[IsCanceled] = CAST(CASE WHEN [InvoiceState] = 'eIsCancelled' THEN 1 ELSE 0 END as bit)
- ,[isSent] = @true
- ,[isFinal] = @true
- ,[hasFile] = CAST( CASE wHEN ISNULL([URI], '') <> '' THEN 1 ELSE 0 END as bit)
- ,[fds] = @false
- ,[customer_id] = ps.[PartnerId]
- from [dbo].[mfr__invoices] as iv
- LEFT JOIN [dbo].[fds__custom_invoiceinfo] as ivi on iv.[id] = ivi.[invid]
- LEFT JOIN itm on TRY_CAST(iv.id as varchar(50)) = itm.[invoice.Id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON iv.[Id] = vat.[EntityId] and vat.[EntityType] = 'report'
- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 0
- LEFT JOIN contra_accounts as ca ON ISNULL(vat.[vat], 19.0) = ca.[vat]
- LEFT JOIN [dbo].[mfr__*PartnerSet] as ps ON iv.[Id] = ps.[EntityId] AND ps.[Property] = 'Invoice:Customer'
- where TRY_CAST(iv.id as varchar(50)) in (SELECT [Id] FROM @inv Where fds = 0)
- UNION
- select
- iv.[Id]
- ,[InvoiceId] = iv.[InvoiceId] + ISNULL((CASE WHEN iv.InvoiceType = 'c' THEN (SELECT TOP(1) ' >> ' + i2.[InvoiceId] FROM [dbo].[fds__invoices] as i2 JOIN [dbo].[fds__invoice_details] as id2 on i2.[Id] = id2.[StornoTo_InvId] where id2.[InvId] = iv.[id] and i2.[IsFinal] = 1) ELSE '' END), '')
- ,[InvoiceType]
- ,[DocumentName]
- ,[requestcount] = sc.[#]
- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = iv.id)
- ,[balance] = FORMAT([invoiceBalance], '#0.00', 'de') + ' €'
- ,[EINZELPOS_brutto] = NULL --FORMAT(itm.bo_itemsum, '#0.00', 'de') + ' €'
- ,[EINZELPOS_netto] = NULL --FORMAT(itm.net_itemsum, '#0.00', 'de') + ' €'
- ,[vat] = FORMAT(ISNULL(iv.[InvoiceVAT_1], 19.0), '#0.0', 'de') + ' %'
- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- --,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
- ,[contra_account] = ca.[account]
- ,[Belegdatum] = FORMAT(iv.[DateCreated], 'dd.MM.yy')
- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
- ,[DateOfCreation] = iv.[DateCreated]
- ,[DueDate]
- ,[PaymentTerm] = ISNULL([PaymentTerm], @stage1)
- ,[PaymentStatus]
- ,[IsPayed] = CAST(CASE WHEN ISNULL(iv.[IsCanceled],0) = 1 THEN 1 ELSE ISNULL([IsPayed],0) END as bit)
- ,[IsCanceled]
- ,[isSent]
- ,[isFinal]
- ,[hasFile] = CAST( CASE wHEN [file] is not null and [DocumentNAme] is not null THEN 1 ELSE 0 END as bit)
- ,[fds] = @true
- ,[customer_id] = iv.[CustomerId]
- from [dbo].[fds__invoices] as iv
- LEFT JOIN itm on iv.Id = itm.[invoice.Id]
- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 1
- LEFT JOIN contra_accounts as ca ON ISNULL(iv.[InvoiceVAT_1], 19.0) = ca.[vat]
- where iv.Id in (SELECT [Id] FROM @inv Where fds = 1)
- ), reminder as (
- SELECT [InvId], [lastReminder] = MAX([DateFinalized]), [#] = COUNT(*) FROM [dbo].[fds__reminder] WHERE [IsFinal] = 1 AND [invId] IN (SELECT [Id] FROM @inv) GROUP BY [InvId]
- )
- select
- inv.*
- ,[reminderstatus] = CASE WHEN [ispayed] = 1 THEN 0
- WHEN [dbo].[fds__fn_isInvoiceCancelled](inv.[Id]) = 1 THEN 0
- WHEN DueDate is null THEN 0
- WHEN [deb_cred] = 'H' THEN 0
- WHEN @stage3 <> '' AND rem.[#] = 2 AND @today > [dbo].[date_addcustom]([lastReminder], @stage3) THEN 3
- WHEN @stage2 <> '' AND rem.[#] = 1 AND @today > [dbo].[date_addcustom]([lastReminder], @stage2) THEN 2
- WHEN @stage1 <> '' AND ISNULL(rem.[#],0) = 0 AND @today > [dbo].[date_addcustom](ISNULL(DueDate, [DateOfCreation]), ISNULL([PaymentTerm],@stage1)) THEN 1
- ELSE 0 END
- ,[invstatus] = CASE WHEN [IsPayed] = 1 AND [isCanceled] = 0 THEN 'pyd'
- WHEN [isCanceled] = 1 OR [dbo].[fds__fn_isInvoiceCancelled](inv.[Id]) = 1 THEN 'cc'
- WHEN [isFinal] = 0 THEN 'dft'
- WHEN [isFinal] = 1 AND [isSent] = 0 THEN 'uns'
- WHEN [DueDate] is null THEN 'op'
- WHEN [deb_cred] = 'H' THEN ''
- WHEN @today >= [DueDate] THEN 'due'
- WHEN @stage1 <> '' AND ISNULL(rem.[#],0) = 0 AND @today > [dbo].[date_addcustom](ISNULL(DueDate, [DateOfCreation]), @stage1) THEN 'ovd'
- WHEN ISNULL(rem.[#],0) > 0 THEN 'rem'
- END
- ,[reminder] = rem.[#]
- ,[CustomerName] = c.[name]
- ,[order] = CASE WHEN @include_drafts = 1 THEN
- ROW_NUMBER() OVER (ORDER BY inv.[DateOfCreation] ASC)
- ELSE
- ROW_NUMBER() OVER (ORDER BY TRY_CAST(SUBSTRING([invoiceid], 2,4) AS int), TRY_CAST(SUBSTRING([invoiceid], 7,4) AS int), inv.[DateOfCreation] ASC)
- END
- ,[Payment] = CASE WHEN [paymentstatus] = 'a' THEN 'vollst.'
- WHEN [paymentstatus] = 'p' THEN FORMAT(ISNULL([dbo].[fds__fn_InvoicePaymentAmount](inv.[Id]),0.0), '0.00€', 'de')
- ELSE '' END
- FROM inv
- left JOIN reminder as rem ON inv.[Id] = rem.[InvId] --inv.[id] is already converted to varchar
- LEFT JOIN [dbo].[mfr__companies] as c ON inv.[customer_id] = c.[id]
- WHERE (CASE WHEN @searchmode = 'c' THEN
- (CASE WHEN inv.[customer_id] IN (SELECT [CustomerId] fROM @customerfilter) THEN 1 ELSE 0 END)
- ELSE 1 END) = 1
- order by inv.[DateOfCreation] ASC;
-
-
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoices_list_vario.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoices_list_vario.sql
deleted file mode 100644
index 00302ac..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getInvoices_list_vario.sql
+++ /dev/null
@@ -1,293 +0,0 @@
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getInvoices_list_vario]
- @tgtdate date
- ,@mode varchar(1) = 'm'
- , @includes varchar(50)
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- DECLARE @include_drafts bit = [dbo].[ott_csv_contains](@includes, 'd');
- DECLARE @only_drafts bit = 0, @only_unpayed bit = 0, @only_reminded bit = 0, @only_akonto bit = 0, @only_storno bit = 0, @only_remindedunpayed bit = 0;
- DECLARE @includetext varchar(50) = '';
-
- IF @includes = '#d'
- SELECT @includetext = ' (nur Entwürfe) ', @include_drafts = 1, @only_drafts = 1, @only_reminded = 0, @only_unpayed = 0, @only_akonto = 0, @only_storno = 0;
- ELSE IF @includes = 'all'
- SELECT @includetext = ' (alle) ', @include_drafts = 1, @only_drafts = 0, @only_reminded = 0, @only_unpayed = 0, @only_akonto = 0, @only_storno = 0;
- ELSE IF @includes = '#r'
- SELECT @includetext = ' (nur angemahnte) ', @include_drafts = 0, @only_drafts = 0, @only_reminded = 1, @only_unpayed = 0, @only_akonto = 0, @only_storno = 0;
- ELSE IF @includes = '#u'
- SELECT @includetext = ' (nur unbezahlte) ', @include_drafts = 0, @only_drafts = 0, @only_reminded = 0, @only_unpayed = 1, @only_akonto = 0, @only_storno = 0;
- ELSE IF @includes = '#a'
- SELECT @includetext = ' (nur Akonto) ', @include_drafts = 0, @only_drafts = 0, @only_reminded = 0, @only_unpayed = 0, @only_akonto = 1, @only_storno = 0;
- ELSE IF @includes = '#c'
- SELECT @includetext = ' (nur Storno) ', @include_drafts = 0, @only_drafts = 0, @only_reminded = 0, @only_unpayed = 0, @only_akonto = 0, @only_storno = 1;
- ELSE IF @includes = '#ru'
- SELECT @includetext = ' (nur gemahnt + unbez. + nicht storniert) ', @include_drafts = 0, @only_drafts = 0, @only_reminded = 0, @only_unpayed = 0, @only_akonto = 0, @only_storno = 0, @only_remindedunpayed = 1;
-
-
- IF [dbo].[fis_getModuleAuth]('fds_inv', @authuser) < 1
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__getInvoices_list' ,@authuser , '');
-
- DECLARE @startdate date, @enddate date, @today date = GETDATE();
- DECLARE @true bit = 1, @false bit = 0;
- SET @mode = LOWER(@mode);
- If @mode = 'm'
- BEGIN
- SELECT @startdate = [dbo].[date_monthfirst](@tgtdate)
- ,@enddate = [dbo].[date_monthend](@tgtdate);
- END
- ELSE If @mode = 'w'
- BEGIN
- SELECT @startdate = [dbo].[date_weekfirst](@tgtdate)
- ,@enddate = [dbo].[date_weekend](@tgtdate);
- END
- ELSE If @mode = 'a'
- BEGIN
- SELECT @startdate = [dbo].[date_weekfirst]('2000-01-01')
- ,@enddate = [dbo].[date_weekend](DATEADD(year, 1, @today));
- END
-
- --Reminder settings
- DECLARE @stage1 varchar(10), @stage2 varchar(10), @stage3 varchar(10);
- SELECT @stage1 = [stage1], @stage2 = [stage2], @stage3 = [stage3] FROM [dbo].[fds__admin_reminderSettings]();
-
-
-
- SELECT [startdate] = @startdate, [enddate] = @enddate, [mode] = @mode
- , [title] = 'Rechnungsübersicht ' + @includetext + ' für ' + CASE WHEN @mode = 'm' THEN 'MONAT ' + FORMAT(@startdate, 'MMM yyyy')
- WHEN @mode = 'w' THEN 'WOCHE ' + FORMAT(@startdate, 'dd.MM.yyyy') + ' - ' + FORMAT(@enddate, 'dd.MM.')
- WHEN @mode = 'a' THEN 'den gesamten Zeitraum'
- ELSE '' END
- ,[ust_options] = '19,0%;16,0%;0,0%';
-
-
- DECLARE @inv TABLE([Id] varchar(15), [InvoiceID] varchar(255), [URI] nvarchar(255), [DocumentName] nvarchar(255), [DateOfCreation] date, [fds] bit);
- --INSERT INTO @inv SELECT [Id],[invoiceid],[URI],[DocumentName],[DateOfCreation],[fds] = 0 FROM [dbo].[mfr__reports] where [IsInvoice] = 1 AND CAST([DateOfCreation] as date) between @startdate AND @enddate;
- INSERT INTO @inv SELECT [Id],[invoiceid],[URI],[DocumentName],[DateOfCreation],[fds] = 0 FROM [dbo].[mfr__invoices]
- where CAST([DateOfCreation] as date) between @startdate AND @enddate
- and (ISNULL(@include_drafts,0) = 1 OR [FileType] in( 'PdfInvoice','PdfCancelInvoice','PdfPartialInvoice') and ISNULL(InvoiceId,'') not in ('Preview',''))
- and (@only_drafts = 0 OR ISNULL(InvoiceId,'') in ('Preview',''))
- and (@only_akonto = 0 OR [FileType] = 'PdfPartialInvoice')
- and (@only_storno = 0 OR [FileType] = 'PdfCancelInvoice')
- and ((@only_unpayed = 0 AND @only_remindedunpayed = 0) OR [InvoiceState] not IN ('eIsCancelled', 'eIsPaid'));
- INSERT INTO @inv SELECT [Id],[invoiceid],[URI] = null,[DocumentName],[DateOfCreation] = [DateCreated],[fds] = 1 FROM [dbo].[fds__invoices]
- where CAST([DateCreated] as date) between @startdate AND @enddate
- and (ISNULL(@include_drafts,0) = 1 OR [isfinal] = 1)
- and (@only_drafts = 0 OR [isfinal] = 0)
- and (@only_akonto = 0 OR [InvoiceType] = 'i')
- and (@only_storno = 0 OR [InvoiceType] = 'c')
- and ((@only_unpayed = 0 AND @only_remindedunpayed = 0) OR (IsPayed = 0 AND IsCanceled = 0));
-
- DECLARE @SReq TABLE ([id] bigint, [DateOfCreation] datetime, [name] nvarchar(255), [invoice.Id] varchar(15), [customer.ExternalId] bigint, [customer.Id] bigint, [ExternalId] nvarchar(255), [fds] bit);
- INSERT INTO @SReq
- SELECT s.[Id], s.[DateOfCreation], s.[name], [invoice.Id] = i.[Id], [customer.ExternalId] = cy.ExternalId , [customer.Id] = cy.[id], s.[ExternalId], [fds]
- FROM [dbo].[mfr__servicerequests] as s
- JOIN dbo.[mfr__*PartnerSet] as p on p.[EntityId] = s.[Id] AND p.[Property] = 'ServiceRequest:Invoices'
- JOIN @inv as i on i.fds = 0 and p.[PartnerId] = i.[id] --s.[InvoiceId] like ('%' + i.[InvoiceId] + '%')
- LEFT JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- WHERE i.fds = 0;
- INSERT INTO @SReq
- SELECT s.[Id], s.[DateOfCreation], s.[name], [invoice.Id] = i.[Id], [customer.ExternalId] = cy.ExternalId , [customer.Id] = cy.[id], s.[ExternalId], [fds]
- FROM [dbo].[fds__invoice_servicerequests] as irq
- JOIN @inv as i on irq.[InvId] = i.[Id]
- LEFT JOIN [dbo].[mfr__servicerequests] as s ON irq.[mfr__servicerequest] = s.[id]
- LEFT JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- WHERE i.fds = 1;
-
- With itm as (
- SELECT
- [net_itemsum] = CAST( SUM((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) as numeric(12,2))
- , [bo_itemsum] = CAST( SUM( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * (1 + (ISNULL(vat.[vat], 19.0) * 0.01))) as numeric(12,2))
- , [vf] = MAX(1 + (ISNULL(vat.[vat], 19.0) * 0.01))
- , sreq.[invoice.Id]
- ,[fds] = 0
- FROM [dbo].[mfr__items] as itm
- JOIN @sreq as sreq ON itm.[ServiceRequestId] = SReq.[id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item'
- WHERE [fds] = 0
- GROUP BY sreq.[invoice.Id]
- UNION
- SELECT
- [net_itemsum] = CAST( SUM(ISNULL([value_total],0)) as numeric(12,2))
- , [bo_itemsum] = CAST( SUM(ISNULL([value_total],0) * (1 + (ISNULL([vat], 19.0) * 0.01))) as numeric(12,2))
- , [vf] = MAX(1 + (ISNULL([vat], 19.0) * 0.01))
- , [invoice.Id] = inv.[id] --sreq.[invoice.Id]
- , [fds] = 1
- FROM [dbo].[fds__invoice_items] as itm
- --JOIN @sreq as sreq ON itm.[InvRqId] = SReq.[id]
- JOIN @inv as inv ON itm.[invid] = inv.[id] and [fds] = 1
- WHERE [fds] = 1
- GROUP BY inv.[id] --sreq.[invoice.Id]
- ),sc as(
- SELECT s.[invoice.Id], [fds], [#] = COUNT(s.[id]) FROM @SReq as s GROUP BY s.[invoice.Id], [fds]
- ),contra_accounts as(
- SELECT [account] = [key], [vat] = TRY_PARSE([value2] as numeric(5,2) USING 'en-US') FROM [dbo].[fds__admin_settings] WHERE [type] = 'contra_account'
- ), inv as(
- --select
- -- [Id] = CAST(iv.[Id] as varchar(15))
- -- ,[InvoiceId] = iv.[InvoiceId]
- -- ,[InvoiceType] = CAST( CASE WHEN LEFT([documentname],5) = 'absch' THEN 'i'
- -- WHEN LEFT([documentname],5) = 'storn' THEN 'c'
- -- ELSE 'r'
- -- END
- -- as char(1))
- -- ,[DocumentName]
- -- ,[requestcount] = sc.[#]
- -- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = iv.id)
- -- ,[balance] = FORMAT(ABS([invoiceBalance]), '#0.00', 'de') + ' €'
- -- ,[EINZELPOS_brutto] = FORMAT(itm.bo_itemsum, '#0.00', 'de') + ' €'
- -- ,[EINZELPOS_netto] = FORMAT(itm.net_itemsum, '#0.00', 'de') + ' €'
- -- ,[vat] = FORMAT(ISNULL(vat.[vat], 19.0), '#0.0', 'de') + ' %'
- -- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- -- ,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
- -- ,[contra_account] = ca.[account]
- -- ,[Belegdatum] = FORMAT(iv.[DateOfCreation], 'dd.MM.yy')
- -- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
- -- ,iv.[DateOfCreation]
- -- ,iv.[DueDate]
- -- ,[PaymentTerm] = @stage1
- -- ,ivi.[PaymentStatus]
- -- ,[IsPayed] = CAST(CASE WHEN ISNULL(iv.[IsCanceled],0) = 1 THEN 1 ELSE ISNULL(ivi.[IsPayed],0) END as bit)
- -- ,[IsCanceled]
- -- ,[isSent] = @true
- -- ,[isFinal] = @true
- -- ,[hasFile] = CAST( CASE wHEN ISNULL([URI], '') <> '' THEN 1 ELSE 0 END as bit)
- -- ,[fds] = @false
- -- from [dbo].[mfr__reports] as iv
- -- LEFT JOIN [dbo].[fds__custom_invoiceinfo] as ivi on iv.[id] = ivi.[invid]
- -- LEFT JOIN itm on iv.Id = itm.[invoice.Id]
- -- LEFT JOIN [dbo].[fds__custom_vat] as vat ON iv.[Id] = vat.[EntityId] and vat.[EntityType] = 'report'
- -- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 0
- -- LEFT JOIN contra_accounts as ca ON ISNULL(vat.[vat], 19.0) = ca.[vat]
- -- where iv.Id in (SELECT [Id] FROM @inv Where fds = 0)
- --UNION
- select
- [Id] = CAST(iv.[Id] as varchar(15))
- ,[InvoiceId] = iv.[InvoiceId]
- ,[InvoiceType] = CAST( CASE WHEN LEFT([documentname],5) = 'absch' THEN 'i'
- WHEN LEFT([documentname],5) = 'storn' THEN 'c'
- ELSE 'r'
- END
- as char(1))
- ,[DocumentName]
- ,[requestcount] = sc.[#]
- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = TRY_CAST(iv.id as varchar(50)))
- ,[balance] = FORMAT([invoiceBalance], '#0.00', 'de') + ' €'
- ,[EINZELPOS_brutto] = NULL --FORMAT(itm.bo_itemsum, '#0.00', 'de') + ' €'
- ,[EINZELPOS_netto] = NULL --FORMAT(itm.net_itemsum, '#0.00', 'de') + ' €'
- ,[vat] = FORMAT(ISNULL(vat.[vat], ISNULL([dbo].[fds__fn_vatfrombalances]([invoiceBalance], [invoiceBalancenetto]) ,19.0)), '#0.0', 'de') + ' %'
- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- ,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE TRY_CAST(iv.id as varchar(50)) = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
- ,[contra_account] = ca.[account]
- ,[Belegdatum] = FORMAT(iv.[DateOfCreation], 'dd.MM.yy')
- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE TRY_CAST(iv.id as varchar(50)) = sreq.[invoice.Id])
- ,iv.[DateOfCreation]
- ,iv.[DueDate]
- ,[PaymentTerm] = @stage1
- ,ivi.[PaymentStatus]
- ,[IsPayed] = CAST(CASE WHEN ISNULL(ivi.isPayed,0) = 1 THEN 1 WHEN [InvoiceState] = 'eIsCancelled' THEN 1 WHEN [InvoiceState] = 'eIsPaid' THEN 1 ELSE 0 END as bit)
- ,[IsCanceled] = CAST(CASE WHEN [InvoiceState] = 'eIsCancelled' THEN 1 ELSE 0 END as bit)
- ,[isSent] = @true
- ,[isFinal] = @true
- ,[hasFile] = CAST( CASE wHEN ISNULL([URI], '') <> '' THEN 1 ELSE 0 END as bit)
- ,[fds] = @false
- ,[customer_id] = ps.[PartnerId]
- from [dbo].[mfr__invoices] as iv
- LEFT JOIN [dbo].[fds__custom_invoiceinfo] as ivi on iv.[id] = ivi.[invid]
- LEFT JOIN itm on TRY_CAST(iv.id as varchar(50)) = itm.[invoice.Id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON iv.[Id] = vat.[EntityId] and vat.[EntityType] = 'report'
- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 0
- LEFT JOIN contra_accounts as ca ON ISNULL(vat.[vat], 19.0) = ca.[vat]
- LEFT JOIN [dbo].[mfr__*PartnerSet] as ps ON iv.[Id] = ps.[EntityId] AND ps.[Property] = 'Invoice:Customer'
- where TRY_CAST(iv.id as varchar(50)) in (SELECT [Id] FROM @inv Where fds = 0)
- UNION
- select
- iv.[Id]
- ,[InvoiceId] = iv.[InvoiceId] + ISNULL((CASE WHEN iv.InvoiceType = 'c' THEN (SELECT TOP(1) ' >> ' + i2.[InvoiceId] FROM [dbo].[fds__invoices] as i2 JOIN [dbo].[fds__invoice_details] as id2 on i2.[Id] = id2.[StornoTo_InvId] where id2.[InvId] = iv.[id] and i2.[IsFinal] = 1) ELSE '' END), '')
- ,[InvoiceType]
- ,[DocumentName]
- ,[requestcount] = sc.[#]
- ,[request] = (SELECT TOP(1) s.[ExternalId] FROM @SReq as s WHERE s.[invoice.Id] = iv.id)
- ,[balance] = FORMAT([invoiceBalance], '#0.00', 'de') + ' €'
- ,[EINZELPOS_brutto] = NULL --FORMAT(itm.bo_itemsum, '#0.00', 'de') + ' €'
- ,[EINZELPOS_netto] = NULL --FORMAT(itm.net_itemsum, '#0.00', 'de') + ' €'
- ,[vat] = FORMAT(ISNULL(iv.[InvoiceVAT_1], 19.0), '#0.0', 'de') + ' %'
- ,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
- ,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
- ,[contra_account] = ca.[account]
- ,[Belegdatum] = FORMAT(iv.[DateCreated], 'dd.MM.yy')
- ,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
- ,[DateOfCreation] = iv.[DateCreated]
- ,[DueDate]
- ,[PaymentTerm] = ISNULL([PaymentTerm], @stage1)
- ,[PaymentStatus]
- ,[IsPayed] = CAST(CASE WHEN ISNULL(iv.[IsCanceled],0) = 1 THEN 1 ELSE ISNULL([IsPayed],0) END as bit)
- ,[IsCanceled] = CAST(IIF(ISNULL([IsCanceled],0) = 1 OR [dbo].[fds__fn_isInvoiceCancelled](iv.[Id]) = 1, 1,0) as bit)
- ,[isSent]
- ,[isFinal]
- ,[hasFile] = CAST( CASE wHEN [file] is not null and [DocumentNAme] is not null THEN 1 ELSE 0 END as bit)
- ,[fds] = @true
- ,[customer_id] = iv.[CustomerId]
- from [dbo].[fds__invoices] as iv
- LEFT JOIN itm on iv.Id = itm.[invoice.Id]
- LEFT JOIN sc on iv.[id] = sc.[invoice.Id] and sc.[fds] = 1
- LEFT JOIN contra_accounts as ca ON ISNULL(iv.[InvoiceVAT_1], 19.0) = ca.[vat]
- where iv.Id in (SELECT [Id] FROM @inv Where fds = 1)
- ), reminder as (
- SELECT [InvId], [lastReminder] = MAX([DateFinalized]), [#] = COUNT(*) FROM [dbo].[fds__reminder] WHERE [isFinal] = 1 AND [invId] IN (SELECT [Id] FROM @inv) GROUP BY [InvId]
- )
- select
- inv.*
- ,[reminderstatus] = CASE WHEN [ispayed] = 1 THEN 0
- WHEN [iscanceled] = 1 THEN 0
- WHEN DueDate is null THEN 0
- WHEN [deb_cred] = 'H' THEN 0
- WHEN @stage3 <> '' AND rem.[#] = 2 AND @today > [dbo].[date_addcustom]([lastReminder], @stage3) THEN 3
- WHEN @stage2 <> '' AND rem.[#] = 1 AND @today > [dbo].[date_addcustom]([lastReminder], @stage2) THEN 2
- WHEN @stage1 <> '' AND ISNULL(rem.[#],0) = 0 AND @today > [dbo].[date_addcustom](ISNULL(DueDate, [DateOfCreation]), ISNULL([PaymentTerm],@stage1)) THEN 1
- ELSE 0 END
- ,[invstatus] = CASE WHEN [IsPayed] = 1 AND [isCanceled] = 0 THEN 'pyd'
- WHEN [isCanceled] = 1 THEN 'cc'
- WHEN [isFinal] = 0 THEN 'dft'
- WHEN [isFinal] = 1 AND [isSent] = 0 THEN 'uns'
- WHEN [DueDate] is null THEN 'op'
- WHEN [deb_cred] = 'H' THEN ''
- WHEN @today >= [DueDate] THEN 'due'
- WHEN @stage1 <> '' AND ISNULL(rem.[#],0) = 0 AND @today > [dbo].[date_addcustom](ISNULL(DueDate, [DateOfCreation]), @stage1) THEN 'ovd'
- WHEN ISNULL(rem.[#],0) > 0 THEN 'rem'
- END
- ,[reminder] = rem.[#]
- ,[CustomerName] = c.[name]
- ,[order] = CASE WHEN @include_drafts = 1 THEN
- ROW_NUMBER() OVER (ORDER BY inv.[DateOfCreation] ASC)
- ELSE
- ROW_NUMBER() OVER (ORDER BY TRY_CAST(SUBSTRING([invoiceid], 2,4) AS int), TRY_CAST(SUBSTRING([invoiceid], 7,4) AS int), inv.[DateOfCreation] ASC)
- END
- ,[Payment] = IIF(py.[amount] is null,'',FORMAT(ISNULL(py.[amount],0.0), '0.00€', 'de') + IIF(py.[manu] = 1, ' man.',''))
- /*CASE WHEN [paymentstatus] = 'a' THEN 'vollst.'
- WHEN [paymentstatus] = 'p' THEN FORMAT(ISNULL([dbo].[fds__fn_InvoicePaymentAmount](inv.[Id]),0.0), '0.00€', 'de')
- ELSE '' END*/
- FROM inv
- left JOIN reminder as rem ON inv.[Id] = rem.[InvId] --inv.[id] is already converted to varchar
- LEFT JOIN [dbo].[mfr__companies] as c ON inv.[customer_id] = c.[id]
- LEFT JOIN [dbo].[fds__fn_bankingtransactions_perInvoice](@startdate, @enddate) as py ON py.[invid] = inv.[Id]
- WHERE ((@only_reminded = 0 AND @only_remindedunpayed = 0) OR ISNULL(rem.[#],0) > 0)
- AND (CASE WHEN @only_unpayed = 0 AND @only_remindedunpayed = 0 THEN 1 WHEN [IsCanceled] = 1 THEN 0 ELSE 1 END) = 1
- order by inv.[DateOfCreation] ASC;
-
-
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getReminder.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getReminder.sql
deleted file mode 100644
index dfaeac7..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getReminder.sql
+++ /dev/null
@@ -1,96 +0,0 @@
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getReminder]
- @Id varchar(8),
- @includefile bit,
- @authuser varchar(25)
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_reminder', @authuser) < 1
- THROW 60000, N'not authorized', 1;
-
-
- DECLARE @rem [dbo].[fds__tt__reminder_core];
-
-
- INSERT INTO @rem
- SELECT TOP(1) [Id]
- ,[Version]
- ,[DocumentName]
- ,[InvId]
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[type]
- ,[amount]
- ,[amount_payed]
- ,[amount_open]
- ,[subject]
- ,[text]
- ,[IsSent]
- ,[IsFinal]
- ,[CustomValues]
- ,[DateSent]
- ,[UserSent]
- ,[DateFinalized]
- ,[UserFinalized]
- ,[DateCreated]
- ,[UserCreated]
- ,[DateModified]
- ,[UserModified]
- ,[file] = CASE WHEN ISNULL(@includefile,0) = 1 THEN [file] else NULL END -- do not return file if not explicitly requested
- FROM [dbo].[fds__reminder]
- WHERE [Id] = @Id AND @Id is not null;
-
-
-
- DECLARE @InvId varchar(15) = (SELECT TOP(1) [InvId] fROM @rem);
-
- ---output
-
- --admin
- SELECT TOP(1)
- [today]
- , [sender] = N'Sebastian Fuchs GmbH & Co. KG ● Germaniastraße 15 ● 40223 Düsseldorf'
- , [CustomerId] = rem.[CustomerId]
- , [type] = rem.[type]
- FROM (VALUES(CAST(GETDATE() as date)))base ([today]) cross JOIN @rem as rem;
-
- --rem
- With inv1 as(
- select TOP(1) * FROM [dbo].[fds__invoices] WHERE [id] = @InvId
- ), inv as(
- SELECT [Id] = cast([id] as varchar(15))
- ,[Invoiceid]
- ,[DateFinalized]
- ,[InvoiceBalance]
- ,[DocumentName]
- ,[file]
- FROM inv1
- UNION
- SELECT [Id] = cast([id] as varchar(15))
- ,[Invoiceid]
- ,[DateFinalized] = [DateOfCreation]
- ,[InvoiceBalance]
- ,[DocumentName]
- ,[file] = NULL
- FROM [dbo].[mfr__invoices] as mfri
- WHERE [id] = TRY_CAST(@invId as bigint) AND NOT EXISTS( SELECT 0 FROM inv1 ) --will only be used, if id not present in fds__invoices
- )
- SELECT TOP(1) o.*
- ,inv.[InvoiceId]
- ,[InvoiceDate] = inv.[DateFinalized]
- ,[InvoiceFileName] = inv.[DocumentName]
- ,[InvoiceFile] = CASE WHEN ISNULL(@includefile,0) = 1 THEN inv.[file] else NULL END -- do not return file if not explicitly requested
- ,[hasFile] = CAST ( CASE WHEN o.[file] is null THEN 0 ELSE 1 END as bit)
- ,[UserNameFinalized] = [dbo].[fis_admin_getUserName_byID](o.[UserFinalized])
- ,[UserEmailFinalized] = [dbo].[fis_admin_getUserEmail_byID](o.[UserFinalized])
- from @rem as o
- join inv on o.[invid] = inv.[id];
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getReportDocument.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getReportDocument.sql
deleted file mode 100644
index 60d433e..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getReportDocument.sql
+++ /dev/null
@@ -1,26 +0,0 @@
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getReportDocument]
-
- @reportid varchar(20)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- DECLARE @idbigint bigint = TRY_CAST(@reportid as bigint);
-
- SELECT TOP(1)
- [Id] = CAST([Id] as varchar(20)),[InvoiceID],[URI],[DocumentName],[isInvoice] = 1,[DateOfCreation],[fds] = CAST( 0 as bit),[file] = CAST( null as varbinary(max))
- ,[order] = ROW_NUMBER() OVER (ORDER BY [DateOfCreation] ASC)
- FROM [dbo].[mfr__invoices] WHERE [id] = @idbigint and @idbigint is not null
- UNION
- SELECT TOP(1)
- [Id] = CAST([Id] as varchar(20)),[InvoiceID],[URI] = '',[DocumentName],[isInvoice] = 1,[DateOfCreation] = [DateCreated],[fds] = CAST( 1 as bit), [file]
- ,[order] = ROW_NUMBER() OVER (ORDER BY [DateCreated] ASC)
- FROM [dbo].[fds__invoices] WHERE [id] = @reportid AND [isFinal] = 1;
- ;
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequest_details.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequest_details.sql
deleted file mode 100644
index 4b97694..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequest_details.sql
+++ /dev/null
@@ -1,422 +0,0 @@
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getRequest_details]
- @servicerequestid bigint
- , @mode varchar(3)
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- IF [dbo].[fis_getModuleAuth]('fds_req', @authuser) < 1
- THROW 60000, N'not authorized', 1;
-
-
-
- DECLARE @today date = GETDATE();
- DECLARE @SReq TABLE (
- [Id] [bigint] NOT NULL,
- [Name] [nvarchar](255) NULL,
- [ExternalId] [nvarchar](255) NULL,
- [InvoiceId] [nvarchar](255) NULL,
- [ClosedAt] [datetime] NULL,
- [ReleasedAt] [datetime] NULL,
- [WorkDoneAt] [datetime] NULL,
- [TargetTimeInMinutes] [bigint] NOT NULL,
- [DateModified] [datetime] NULL,
- [DateOfCreation] [datetime] NULL,
- [DueDateRangeStart] [datetime] NULL,
- [DueDateRangeEnd] [datetime] NULL,
- [PortalLink] [nvarchar](255) NULL,
- [CostCenterId] [bigint] NULL,
- [Description] [nvarchar](max) NULL,
- [State] [nvarchar](255) NULL,
- [CustomValues] [nvarchar](max) NOT NULL,
- [CurrentOwnerId] [bigint] NULL,
- [CustomerId] [bigint] NULL,
- [ParentServiceRequestId] [bigint] NULL,
- [ParentExtenalId] [nvarchar](255) NULL,
- [ParentWorkDoneAt] [date] NULL,
- [ParentInvoiceId] [nvarchar](255) NULL,
- [Location#ID] [bigint] NULL,
- [Version] [int] NOT NULL,
- [IsTemplate] [bit] NOT NULL,
- [IsTemplateMobile] [bit] NOT NULL,
- [CreateFromServiceRequestTemplateId] [bigint] NOT NULL,
- [Type] [nvarchar](255) NULL,
- [Summary] nvarchar(255) NULL,
- [isChild] bit NULL,
- [baseorder] int,
- [provision] varchar(255) NULL,
- [open] bit NULL
- );
- insert into @SReq
- SELECT
- [Id]
- ,[Name]
- ,[ExternalId]
- ,[InvoiceId]
- ,[ClosedAt]
- ,[ReleasedAt]
- ,[WorkDoneAt]
- ,[TargetTimeInMinutes]
- ,[DateModified]
- ,[DateOfCreation]
- ,[DueDateRangeStart]
- ,[DueDateRangeEnd]
- ,[PortalLink]
- ,[CostCenterId]
- ,[Description]
- ,[State]
- ,[CustomValues]
- ,[CurrentOwnerId]
- ,[CustomerId]
- ,[ParentServiceRequestId] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then [id] ELSE [ParentServiceRequestId] END
- ,[ParentExtenalId] = cast(CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then null ELSE '?' END as nvarchar(255))
- ,[ParentWorkDoneAt] = cast(NULL as datetime)
- ,[ParentInvoiceId] = cast(NULL as nvarchar(255))
- ,[Location#ID]
- ,[Version]
- ,[IsTemplate]
- ,[IsTemplateMobile]
- ,[CreateFromServiceRequestTemplateId]
- ,[Type]
- ,[Summary] = NULL
- ,[isChild] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then 0 ELSE 1 END
- ,[baseorder] = 0
- ,[provision] = NULL
- ,[open] = 1
- FROM [dbo].[mfr__servicerequests] as s
- WHERE [id] = @servicerequestid;
-
- INSERT INTO @SReq
- SELECT s.[Id]
- ,s.[Name]
- ,s.[ExternalId]
- ,s.[InvoiceId]
- ,s.[ClosedAt]
- ,s.[ReleasedAt]
- ,s.[WorkDoneAt]
- ,s.[TargetTimeInMinutes]
- ,s.[DateModified]
- ,s.[DateOfCreation]
- ,s.[DueDateRangeStart]
- ,s.[DueDateRangeEnd]
- ,s.[PortalLink]
- ,s.[CostCenterId]
- ,s.[Description]
- ,s.[State]
- ,s.[CustomValues]
- ,s.[CurrentOwnerId]
- ,s.[CustomerId]
- ,s.[ParentServiceRequestId]
- ,[ParentExtenalId] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[ExternalId] ELSE NULL END
- ,[ParentWorkDoneAt] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[WorkDoneAt] ELSE NULL END
- ,[ParentInvoiceId] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[InvoiceId] ELSE NULL END
- ,s.[Location#ID]
- ,s.[Version]
- ,s.[IsTemplate]
- ,s.[IsTemplateMobile]
- ,s.[CreateFromServiceRequestTemplateId]
- ,s.[Type]
- ,[Summary] = NULL
- ,[isChild] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then 0 ELSE 1 END
- ,[baseorder] = 0
- , [provision] = null
- ,[open] = 1
- from [dbo].[mfr__servicerequests] as s JOIN @SReq as q ON (s.[ParentServiceRequestId] = q.[id] OR q.[ParentServiceRequestId] = s.[id]) --parents or childs
- WHERE NOT EXISTS (SELECT * FROM @SReq as s2 WHERE s2.[id] = s.[Id])
- ;
-
- -- need to use CTE, because row_number is not available with update statements
- WITH q as (
- SELECT [id], [baseorder] = (ROW_NUMBER() OVER (ORDER BY ISNULL([ParentWorkDoneAt], [WorkDoneAt]), ISNULL([ParentServiceRequestId],[id])) * 100)
- FROM @SReq as s
- WHERE [ischild] = 0
- )
- UPDATE s SET
- [baseorder] = q.baseorder
- FROM @SReq as s JOIN q ON s.[id] = q.[id];
-
-
- -- need to use CTE, because row_number is not available with update statements
- WITH q as (
- SELECT s.[id]
- , q.[ExternalId], q.[WorkDoneAt], q.[InvoiceId]
- , [baseorder] = q.[baseorder] + ROW_NUMBER() OVER (PARTITION BY q.[id] ORDER BY s.[dateofcreation])
- FROM @SReq as s JOIN @SReq as q ON s.[ParentServiceRequestId] = q.[id]
- WHERE s.[ischild] = 1
- )
- UPDATE s SET
- [ParentExtenalId] = q.[ExternalId]
- ,[ParentWorkDoneAt] = q.[WorkDoneAt]
- ,[ParentInvoiceId] = q.[InvoiceId]
- ,[baseorder] = q.[baseorder]
- FROM @SReq as s JOIN q ON s.[Id] = q.[id];
-
-
- DECLARE @inv TABLE ([Id] bigint, [Invoices] varchar(1000), [isOpen] bit);
- With fdsinv as(
- SELECT [Id] = fdsr.[mfr__servicerequest], fdsi.[InvoiceId], fdsi.[InvoiceType], [isCanceled] = ISNULL(fdsi.[isCanceled],0)
- FROM [dbo].[fds__invoice_servicerequests] as fdsr
- JOIN [dbo].[fds__invoices] as fdsi on fdsr.[invid] = fdsi.[id]
- JOIN @SReq as s ON fdsr.[mfr__servicerequest] = s.[id]
- WHERE [isFinal] = 1 AND fdsr.[mfr__servicerequest] is not null
-
- ), fi as(
- SELECT [Id], [isOpen] = MIN(CASE WHEN ISNULL([invoicetype],'r') = 'r' AND [isCanceled] = 0 THEN 0 ELSE 1 END) FROM fdsinv GROUP BY [Id]
- )
- INSERT INTO @inv
- SELECT [Id]
- , [invoices] = ISNULL(STUFF( (SELECT CHAR(10) + [InvoiceId] + ' (' + [InvoiceTYpe] + ')' FROM fdsinv as f2 WHERE f2.[id] = fi.[Id] FOR XML PATH, TYPE).value('.[1]','nvarchar(max)') ,1,1,'') , '')
- , [isOpen]
- FROM fi;
-
- UPDATE s
- SET s.[invoiceid] = [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid], inv.[Invoices])
- ,[open] = 1 --CASE WHEN s.[workdoneat] is not null AND [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid],'') = '' AND ISNULL(inv.[isOpen],1) = 1 THEN 1 ELSE 0 END
- FROM @SReq as s LEFT JOIN @inv as inv on s.[id] = inv.[id];
-
-
-
-
- DECLARE @step TABLE (
- [Id] [bigint] NOT NULL,
- [MobileId] [bigint] NULL,
- [Version] [int] NOT NULL,
- [Name] [nvarchar](255) NULL,
- [IsDone] [bit] NOT NULL,
- [HasError] [bit] NOT NULL,
- [TrackingId] [nvarchar](255) NULL,
- [Type] [nvarchar](255) NULL,
- [SortOrder] [int] NOT NULL,
- [Data] [nvarchar](max) NULL,
- [DateModifiedOffline] [datetime] NULL,
- [ServiceRequestId] [bigint] NULL,
- [Description] [nvarchar](max) NULL,
- [Comment] [nvarchar](max) NULL,
- [InternalComment] [nvarchar](max) NULL,
- [ServiceObjectId] [bigint] NULL,
- [StepListTemplateId] [bigint] NULL,
- [ParentId] [bigint] NULL,
- [order] int NOT NULL
- );
- DECLARE @company TABLE (
- [Id] [bigint] NOT NULL,
- [Location#ID] [bigint] NULL,
- [Version] [int] NOT NULL,
- [IsPhysicalPerson] [bit] NOT NULL,
- [IsOwner] [bit] NOT NULL,
- [IsEmailInvoicingActive] [bit] NOT NULL,
- [IsSupplier] [bit] NOT NULL,
- [MappingId] [nvarchar](255) NULL,
- [ExternalId] [nvarchar](255) NULL,
- [Name] [nvarchar](255) NULL,
- [Note] [nvarchar](255) NULL,
- [SupportTelephone] [nvarchar](255) NULL,
- [SupportFax] [nvarchar](255) NULL,
- [SupportMail] [nvarchar](255) NULL,
- [QuickSearch] [nvarchar](255) NULL,
- [DateModified] [datetime] NOT NULL,
- [CustomValues] [nvarchar](max) NOT NULL,
- [MainContactId] [bigint] NOT NULL,
- [address] nvarchar(1000) null
- );
- INSERT INTO @company SELECT DISTINCT cy.*, [address] = [dbo].[fds__getCompanyAddress](cy.[id]) FROM [mfr__companies] as cy JOIN @SReq as s on cy.id = s.[CustomerId];
- DECLARE @companyids [dbo].[fds__tt__idlist];
- INSERT INTO @companyids SELECT DISTINCT [id] FROM @company;
-
- /** OUTPUT + get other types **/
-
- IF @mode in ('r','ov', '','f', 'ful')
- BEGIN
-
- WITH app as(
- SELECT [start] = MIN(CAST(CASE WHEN a.[StartDateTime] is null THEN s.[workdoneat] WHEN CAST(a.[StartDateTime] as date) > s.[workdoneat] THEN CAST(a.[StartDateTime] as date) ELSE s.[workdoneat] END as date))
- , [end] = MAX(CAST(CASE WHEN a.[EndDateTime] is null THEN s.[workdoneat] WHEN CAST(a.[EndDateTime] as date) > s.[workdoneat] THEN CAST(a.[EndDateTime] as date) ELSE s.[workdoneat] END as date))
- , [CustomerId] = MAX (s.customerid)
- , [ParentServiceRequestId] = ISNULL(MIN(CASE WHEN [isChild] = 1 then null else s.[Id] END), MAX([ParentServiceRequestId])) --make sure only one returned
- FROM [dbo].[mfr__appointments] as a
- RIGHT JOIN @SReq as s on a.[ServiceRequestId] = s.[Id] AND a.[State] in ('IsWorkDone')
- )
- SELECT TOP(1)
- [today]
- , [provisionstart] = CASe WHEN [start] = [end] THEN NULL ELSE [start] END
- , [provisionend] = [end]
- , [sender] = N'Sebastian Fuchs GmbH & Co. KG ● Germaniastraße 15 ● 40223 Düsseldorf'
- , [paymentterms] = N'10wd'
- , [invoiceemail] = (SELECT TOP(1) [SupportMail] FROM @company where IsEmailInvoicingActive = 1)
- , [invoiceaddress] = (SELECT TOP(1) CONCAT([name], CHAR(10), [address]) FROM @company ORDER BY IsEmailInvoicingActive DESC)
- , [tax_servicerefund] = 0.2
- , [CustomerId] = [CustomerId]
- , [search] = @servicerequestid
- , [parent] = app.[ParentServiceRequestId]
- FROM (VALUES(CAST(GETDATE() as date)))base ([today]) CROSS JOIN app;
-
- SELECT
- *
- ,[order] = ROW_NUMBER() OVER (ORDER BY [baseorder])
- FROM @SReq;
- END
-
- IF @mode in ('i','ov')
- BEGIN
- SELECT
- itm.[Id]
- , [net_pos] = CASE WHEN LOWER(itm.[type]) in ('Title','Text') THEN '' ELSE FORMAT( CAST( (ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0) as numeric(7,2)) , '#0.00 €','de') END
- , [bo_pos] = CASE WHEN LOWER(itm.[type]) in ('Title','Text') THEN '' ELSE FORMAT( CAST( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * (1 + (ISNULL(vat.[vat], 19.0) * 0.01)) as numeric(7,2)) , '#0.00 €','de') END
- , [vat] = CASE WHEN LOWER(itm.[type]) in ('Title','Text') THEN null ELSE FORMAT(ISNULL(vat.[vat], 19.0), '#0.0','de') + '%' END
- , itm.[ServiceRequestId]
- , itm.[SortOrder]
- , itm.[Type]
- , itm.[NameOrNumber]
- , itm.[Note]
- , [order] = (s.[baseorder] * 100) + ROW_NUMBER() OVER (PARTITION BY itm.[ServiceRequestId] ORDER BY itm.[SortOrder])
- FROM [dbo].[mfr__items] as itm
- JOIN @SReq as s ON itm.ServiceRequestId = s.[Id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item'
- ;
- END
- ELSE IF @mode in ('f', 'ful')
- BEGIN
- SELECT
- itm.[Id]
- , [net] = ISNULL([Price],0)
- , [quantityhours] = ISNULL([quantityhours],1)
- , itm.[UnitString]
- , [net_val] = CAST( (ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0) as numeric(7,2))
- , [bo_val] = CAST( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * (1 + (ISNULL(vat.[vat], 19.0) * 0.01)) as numeric(7,2))
- , [vat] = CASE WHEN LOWER(itm.[type]) in ('Title','Text') THEN null ELSE FORMAT(ISNULL(vat.[vat], 19.0), '#0.0','de') + '%' END
- , [vat_val] = CAST( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * ((ISNULL(vat.[vat], 19.0) * 0.01)) as numeric(7,2))
- , itm.[ServiceRequestId]
- , itm.[SortOrder]
- , itm.[Type]
- , itm.[NameOrNumber]
- , itm.[Note]
- , [order] = (s.[baseorder] * 100) + ROW_NUMBER() OVER (PARTITION BY itm.[ServiceRequestId] ORDER BY itm.[SortOrder], itm.[Id])
- FROM [dbo].[mfr__items] as itm
- JOIN @SReq as s ON itm.ServiceRequestId = s.[Id]
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item'
- ;
- END
-
- IF @mode in ('f', 'ful')
- BEGIN
- INSERT INTO @step
- SELECT
- stp.*
- , [order] = (s.[baseorder] * 100) + ROW_NUMBER() OVER (PARTITION BY stp.[ServiceRequestId] ORDER BY stp.[SortOrder], stp.[Id])
- FROM [dbo].[mfr__steps] as stp JOIN @SReq as s ON stp.ServiceRequestId = s.[Id];
- SELECT * from @step;
-
-
-
- SELECT
- cc.[Id]
- , [CompanyName] = cc.[name]
- , ct.[Gender]
- , ct.[FirstName]
- , ct.[LastName]
- , ct.[Email]
- , cc.[address]
- FROM [dbo].[fds__getCompanysContacts](@companyids) as ct join @company as cc on cc.[Id] = ct.[CyId];
-
-
-
- SELECT DISTINCT
- [ref] = 'Einsatzort ' + so.[name]
- ,[address] = [dbo].[fds__fn_combineAddress] (so.[Name], loc.[AddressString], null
- ,loc.[Postal]
- ,loc.[City]
- ,loc.[State]
- ,loc.[Country])
- FROM @SReq as s
- LEFT JOIN [mfr__*PartnerSet] as p ON p.property = 'ServiceRequest:ServiceObjects' and p.[EntityId] = s.[id]
- LEFT JOIN [mfr__serviceobjects] as so ON so.id = p.[PartnerId]
- LEFT JOIN [mfr__*PartnerSet] as po ON p.property = 'ServiceObject:Location' and po.[EntityId] = so.[Id]
- LEFT join [dbo].[mfr__#locations] as loc ON (loc.[id] = so.[Location#ID] OR po.[PartnerId] = loc.[Id] OR (so.[Id] = loc.[EntityId] and loc.Property = 'ServiceObject:Location'))
- WHERE so.id is not null and loc.[id] is not null
- UNION
- SELECT DISTINCT
- [ref] = 'Auftragsort ' + [name]
- ,[address] = [dbo].[fds__fn_combineAddress] (loc.[AddressString], null, null
- ,loc.[Postal]
- ,loc.[City]
- ,loc.[State]
- ,loc.[Country])
- FROM @SReq as s
- LEFT JOIN [mfr__*PartnerSet] as p ON p.property = 'ServiceRequest:Location' and p.[EntityId] = s.[id]
- join [dbo].[mfr__#locations] as loc ON (s.[Location#ID] = loc.[id] OR p.[PartnerId] = loc.[Id] OR (s.[Id] = loc.[EntityId] and loc.Property = 'ServiceRequest:Location'))
- WHERE loc.[id] is not null
- UNION
- SELECT DISTINCT [ref] = 'Kunde'
- , [address]
- FROM @company;
-
-
-
- END
-
-
- --get invoices
-
- --Reminder settings
- DECLARE @stage1 varchar(10), @stage2 varchar(10), @stage3 varchar(10);
- SELECT @stage1 = [stage1], @stage2 = [stage2], @stage3 = [stage3] FROM [dbo].[fds__admin_reminderSettings]();
- With inv as(
- SELECT [id] = CAST(ir.invid as varchar(20)), [isChild] = CAST(MIN(CAST(s.[isChild] as tinyint)) as BIT), [baseorder] = MIN(s.[baseorder]), [sopen] = CAST( MIN( CAST(s.[open] as tinyint) ) as bit)
- FROM [dbo].[fds__invoice_servicerequests] as ir
- JOIN @sreq as s ON ir.[mfr__servicerequest] = s.[id]
- GROUP by ir.invid
- UNION
- SELECT [id] = CAST(i.[id] as varchar(20)), [isChild] = CAST(MIN(CAST(s.[isChild] as tinyint)) as BIT), [baseorder] = MIN(s.[baseorder]), [sopen] = CAST( MIN( CAST(s.[open] as tinyint) ) as bit)
- FROM [dbo].[mfr__servicerequests] as ms JOIN @sreq as s on ms.[id] = s.[id]
- JOIN [mfr__invoices] as i on ms.[InvoiceId] like ('%' + i.[InvoiceId] + '%')
- GROUP by i.[id]
- ),reminder as (
- SELECT [InvId], [lastReminder] = MAX([DateSent]), [#] = COUNT(*) FROM [dbo].[fds__reminder] WHERE [isSent] = 1 AND [invId] IN (SELECT [Id] FROM inv) GROUP BY [InvId]
- )
- SELECT [Id] = CAST(i.[Id] as varchar(20))
- ,i.[DateCreated]
- ,[isFinal]
- ,[isSent]
- ,i.[DocumentName]
- ,[invstatus] = CASE WHEN [IsPayed] = 1 AND [isCanceled] = 0 THEN 'pyd'
- WHEN [isCanceled] = 1 OR [dbo].[fds__fn_isInvoiceCancelled](inv.[Id]) = 1 THEN 'cc'
- WHEN [isFinal] = 0 THEN 'dft'
- WHEN [isFinal] = 1 AND [isSent] = 0 THEN 'uns'
- WHEN [DueDate] is null THEN 'op'
- WHEN [invoiceBalance] < 0 THEN ''
- WHEN @today >= [DueDate] THEN 'due'
- WHEN @stage1 <> '' AND ISNULL(rem.[#],0) = 0 AND @today > [dbo].[date_addcustom](ISNULL(DueDate, i.[DateCreated]), @stage1) THEN 'ovd'
- WHEN ISNULL(rem.[#],0) > 0 THEN 'rem'
- END
- ,[order] = ROW_NUMBER() OVER ( ORDER BY inv.[isChild], inv.[baseorder], i.[isFinal] DESC, i.[datecreated] ASC )
- FROM [dbo].[fds__invoices] as i
- JOIN inv on i.[Id] = inv.[Id]
- LEFT JOIN reminder as rem on inv.id = rem.[InvId]
- WHERE (inv.[sopen] = 1 OR i.[isfinal] = 1) --- don't show any draft invoices for final tasks;
- UNION
- SELECT [Id] = CAST(i.[Id] as varchar(20))
- ,[DateCreated] = i.[DateOfCreation]
- ,[isFinal] = 1
- ,[isSent] = 1
- ,i.[DocumentName]
- ,[invstatus] = CASE WHEN [invoicestate] in ('eIsPaid') THEN 'pyd'
- WHEN [invoicestate] in ('eIsCancelled') THEN 'cc'
- --WHEN [isFinal] = 0 THEN 'dft'
- --WHEN [isFinal] = 1 AND [isSent] = 0 THEN 'uns'
- WHEN [DueDate] is null THEN 'op'
- WHEN @today >= [DueDate] THEN 'due'
- WHEN ISNULL(rem.[#],0) > 0 THEN 'rem'
- WHEN @stage1 <> '' AND ISNULL(rem.[#],0) = 0 AND @today > [dbo].[date_addcustom](ISNULL(DueDate, i.[DateofCreation]), @stage1) THEN 'ovd'
- END
- ,[order] = ROW_NUMBER() OVER ( ORDER BY inv.[isChild], inv.baseorder, i.[dateofcreation] ASC)
- FROM [dbo].[mfr__invoices] as i
- JOIN inv on TRY_CAST(i.[Id] as varchar(20)) = inv.[Id]
- LEFT JOIN reminder as rem on inv.id = rem.[InvId];
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequests_list.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequests_list.sql
deleted file mode 100644
index 65d9b2c..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequests_list.sql
+++ /dev/null
@@ -1,278 +0,0 @@
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getRequests_list]
- @tgtdate date
- ,@mode varchar(1) = ''
- ,@completed bit = 1
- ,@authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_req', @authuser) < 1
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__getRequests_list' ,@authuser , '');
-
-
-
- DECLARE @startdate date, @enddate date, @today date = GETDATE();
- SET @mode = ISNULL(LOWER(@mode),'');
- If @mode in ('r') -- r = open recent
- BEGIN
- SET @tgtdate = @today;
- SELECT @startdate = DATEADD(week, -4, [dbo].[date_weekfirst](@tgtdate))
- ,@enddate = @today;
- END
- else If @mode in ('m') -- r = open recent
- BEGIN
- SELECT @startdate = [dbo].[date_monthfirst](@tgtdate)
- ,@enddate = [dbo].[date_monthend](@tgtdate);
- END
- ELSE If @mode = 'w'
- BEGIN
- SELECT @startdate = [dbo].[date_weekfirst](@tgtdate)
- ,@enddate = [dbo].[date_weekend](@tgtdate);
- END
-
- DECLARE @openmode as bit = CASE WHEN LOWER(LEFT(ISNULL(@mode, ''),1)) IN ('o', 'r') THEN 1 ELSE 0 END;
- SELECT [startdate] = @startdate, [enddate] = @enddate, [mode] = @mode
- , [title] = CASE WHEN @openmode = 1 AND @mode = 'r' THEN 'Übersicht der offenen Aufträge (letzte 4 Wochen seit ' + FORMAT(@startdate, 'dd.MM.yyyy') + ')'
- WHEN @openmode = 1 THEN 'Übersicht der offenen Aufträge'
- ELSE 'Auftragsübersicht für ' + CASE WHEN @mode = 'm' THEN 'MONAT ' + FORMAT(@startdate, 'MMM yyyy')
- WHEN @mode = 'w' THEN 'WOCHE ' + FORMAT(@startdate, 'dd.MM.yyyy') + ' - ' + FORMAT(@enddate, 'dd.MM.')
- ELSE '' END
- END
- , [note] = CASE WHEN @openmode = 1 and @mode = 'r' THEN 'Es werden alle Aufträge angezeigt, die selbst offen sind und seit ' + FORMAT(@startdate, 'dd.MM.yyyy') + ' erstellt wurden, oder deren Folgeauftrag offen ist und/oder seit ' + FORMAT(@startdate, 'dd.MM.yyyy') + ' erstellt wurden.'
- WHEN @openmode = 1 THEN 'Es werden alle Aufträge angezeigt, die selbst oder ein Folgeeauftrag offen ist.'
- ELSE '' END;
-
-
- DECLARE @SReq TABLE (
- [Id] [bigint] NOT NULL,
- [Name] [nvarchar](255) NULL,
- [ExternalId] [nvarchar](255) NULL,
- [InvoiceId] varchar(1000) NULL,
- [ClosedAt] [datetime] NULL,
- [ReleasedAt] [datetime] NULL,
- [WorkDoneAt] [datetime] NULL,
- [TargetTimeInMinutes] [bigint] NULL,
- [DateModified] [datetime] NULL,
- [DateOfCreation] [datetime] NULL,
- [DueDateRangeStart] [datetime] NULL,
- [DueDateRangeEnd] [datetime] NULL,
- [PortalLink] [nvarchar](255) NULL,
- [CostCenterId] [bigint] NULL,
- [Description] [nvarchar](max) NULL,
- [State] [nvarchar](255) NULL,
- [CustomValues] [nvarchar](max) NULL,
- [CurrentOwnerId] [bigint] NULL,
- [CustomerId] [bigint] NULL,
- [ParentServiceRequestId] [bigint] NULL,
- [ParentExtenalId] [nvarchar](255) NULL,
- [ParentWorkDoneAt] [date] NULL,
- [ParentInvoiceId] varchar(1000) NULL,
- [Location#ID] [bigint] NULL,
- [Version] [int] NULL,
- [IsTemplate] [bit] NULL,
- [IsTemplateMobile] [bit] NULL,
- [CreateFromServiceRequestTemplateId] [bigint] NULL,
- [Type] [nvarchar](255) NULL,
- [CustomerName] [nvarchar](255) NULL,
- [isChild] bit NULL,
- [open] bit,
- [baseorder] int
- );
- DECLARE @inv TABLE ([Id] bigint, [Invoices] varchar(1000), [isOpen] bit);
- With fdsinv as(
- SELECT [Id] = fdsr.[mfr__servicerequest], fdsi.[InvoiceId], fdsi.[InvoiceType], [isCanceled] = ISNULL(fdsi.[isCanceled],0) FROM [dbo].[fds__invoice_servicerequests] as fdsr
- JOIN [dbo].[fds__invoices] as fdsi on fdsr.[invid] = fdsi.[id]
- WHERE [isFinal] = 1 AND fdsr.[mfr__servicerequest] is not null
- ), fi as(
- SELECT [Id], [isOpen] = MIN(CASE WHEN ISNULL([invoicetype],'r') = 'r' AND [isCanceled] = 0 THEN 0 ELSE 1 END) FROM fdsinv GROUP BY [Id]
- )
- INSERT INTO @inv
- SELECT [Id]
- , [invoices] = ISNULL(STUFF( (SELECT CHAR(10) + [InvoiceId] + ' (' + [InvoiceTYpe] + ')' FROM fdsinv as f2 WHERE f2.[id] = fi.[Id] FOR XML PATH, TYPE).value('.[1]','nvarchar(max)') ,1,1,'') , '')
- , [isOpen]
- FROM fi;
-
-
- insert into @SReq
- SELECT
- s.[Id]
- ,[Name]
- ,[ExternalId]
- ,[InvoiceId] = [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid], inv.[Invoices])
- ,[ClosedAt]
- ,[ReleasedAt]
- ,[WorkDoneAt]
- ,[TargetTimeInMinutes]
- ,s.[DateModified]
- ,s.[DateOfCreation]
- ,[DueDateRangeStart]
- ,[DueDateRangeEnd]
- ,[PortalLink]
- ,[CostCenterId]
- ,[Description]
- ,[State]
- ,s.[CustomValues]
- ,[CurrentOwnerId]
- ,s.[CustomerId]
- ,[ParentServiceRequestId]
- ,[ParentExtenalId] = cast(CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then null ELSE '?' END as nvarchar(255))
- ,[ParentWorkDoneAt] = cast(NULL as datetime)
- ,[ParentInvoiceId] = cast(NULL as nvarchar(255))
- ,[Location#ID]
- ,s.[Version]
- ,[IsTemplate]
- ,[IsTemplateMobile]
- ,[CreateFromServiceRequestTemplateId]
- ,[Type]
- ,[CustomerName] = NULL
- ,[isChild] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then 0 ELSE 1 END
- ,[open] = CASE WHEN s.[workdoneat] is not null AND [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid],'') = '' AND ISNULL(inv.[isOpen],1) = 1 THEN 1 ELSE 0 END
- ,[baseorder] = 0
- FROM [dbo].[mfr__servicerequests] as s -- parent and childs;
- LEFT JOIN @inv as inv on inv.[Id] = s.[Id]
- WHERE
- ([type] in ('IsProject', 'IsMaintenance')
- AND
- (CASE WHEN @openmode = 1 AND @mode = 'r' THEN
- ( CASE WHEN
- [workdoneat] is not null
- --AND ISNULL(s.[invoiceid],'') = ''
- AND ISNULL([State], '') <> 'Closed'
- --AND ISNULL(inv.[isOpen],1) = 1
- AND NOT EXISTS (SELECT * FROM [dbo].[fds__custom_servicerequest] as sr where sr.[EntityID] = s.[id] and sr.[hidden] = 1)
- AND (CAST([DateOfCreation] as date) BETWEEN @startdate AND @today OR CAST([DateModified] as date) BETWEEN @startdate AND @today)
- AND EXISTS (SELECT 0 FROM [dbo].[mfr__*PartnerSet] as ps JOIN [dbo].[mfr__tags] as tg on ps.Property = 'ServiceRequest:Tags' and tg.Id = ps.[PartnerId] where EntityId = s.[id] and ps.partnerid = 16034758659 and [Type] = 'ServiceRequest')
- THEN 1 ELSE 0 END)
- WHEN @openmode = 1 AND @mode <> 'r' THEN
- ( CASE WHEN
- [workdoneat] is not null
- AND ISNULL(s.[invoiceid],'') = ''
- AND ISNULL([State], '') <> 'Closed'
- AND ISNULL(inv.[isOpen],1) = 1
- AND NOT EXISTS (SELECT * FROM [dbo].[fds__custom_servicerequest] as sr where sr.[EntityID] = s.[id] and sr.[hidden] = 1)
- THEN 1 ELSE 0 END)
- WHEN @openmode = 0 THEN
- ( CASE WHEN CAST([DateOfCreation] as date) BETWEEN @startdate AND @enddate THEN 1 ELSE 0 END)
- ELSE 0 END
- ) = 1);
-
- INSERT INTO @SReq
- SELECT DISTINCT
- ISNULL(s.[Id], CASE WHEN ISNULL(q.[ParentServiceRequestId],0) > 0 THEN q.[ParentServiceRequestId] ELSE NULL END)
- ,ISNULL(s.[Name], CASE WHEN ISNULL(q.[ParentServiceRequestId],0) > 0 THEN ' - - unbekannt - - ' ELSE NULL END)
- ,s.[ExternalId]
- ,[InvoiceId] = [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid], inv.[Invoices])
- ,s.[ClosedAt]
- ,s.[ReleasedAt]
- ,s.[WorkDoneAt]
- ,s.[TargetTimeInMinutes]
- ,s.[DateModified]
- ,s.[DateOfCreation]
- ,s.[DueDateRangeStart]
- ,s.[DueDateRangeEnd]
- ,s.[PortalLink]
- ,s.[CostCenterId]
- ,s.[Description]
- ,s.[State]
- ,s.[CustomValues]
- ,s.[CurrentOwnerId]
- ,s.[CustomerId]
- ,s.[ParentServiceRequestId]
- ,[ParentExtenalId] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[ExternalId] ELSE NULL END
- ,[ParentWorkDoneAt] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[WorkDoneAt] ELSE NULL END
- ,[ParentInvoiceId] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[InvoiceId] ELSE NULL END
- ,s.[Location#ID]
- ,s.[Version]
- ,s.[IsTemplate]
- ,s.[IsTemplateMobile]
- ,s.[CreateFromServiceRequestTemplateId]
- ,s.[Type]
- ,[CustomerName] = NULL
- ,[isChild] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then 0 ELSE 1 END
- ,[open] = CASE WHEN s.[workdoneat] is not null AND [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid],'') = '' AND ISNULL(inv.[isOpen],1) = 1 THEN 1 ELSE 0 END
- ,[baseorder] = 0
- from [dbo].[mfr__servicerequests] as s RIGHT JOIN @SReq as q ON (s.[ParentServiceRequestId] = q.[id] OR q.[ParentServiceRequestId] = s.[id]) --parents or childs
- LEFT JOIN @inv as inv on inv.[Id] = s.[Id]
- WHERE
- (s.[type] in ('IsProject', 'IsMaintenance')
- AND NOT EXISTS (SELECT * FROM @SReq as s2 WHERE s2.[id] = s.[Id])
- AND ISNULL(s.[Id], CASE WHEN ISNULL(q.[ParentServiceRequestId],0) > 0 THEN q.[ParentServiceRequestId] ELSE NULL END) is not null
- )
- ;
-
-
- WITH q as (
- SELECT [id], [baseorder] = (ROW_NUMBER() OVER (ORDER BY ISNULL([ParentWorkDoneAt], [WorkDoneAt]), CASE WHEN ISNULL([ParentServiceRequestId],0) = 0 THEN [id] ELSE [ParentServiceRequestId] END) * 100)
- FROM @SReq as s
- WHERE [ischild] = 0
- )
- UPDATE s SET
- [baseorder] = q.baseorder
- ,[ParentServiceRequestId] = CASE WHEN s.isChild = 0 THEN s.[Id] ELSE s.[ParentServiceRequestId] END
- FROM @SReq as s JOIN q ON s.[id] = q.[id];
-
-
- UPDATE s SET
- [CustomerName] = c.[name]
- FROM @SReq as s JOIN [mfr__companies] as c ON s.[CustomerId] = c.[id];
-
-
- WITH q as (
- SELECT s.[id]
- , q.[ExternalId], q.[WorkDoneAt], q.[InvoiceId]
- , [baseorder] = q.[baseorder] + ROW_NUMBER() OVER (PARTITION BY q.[id] ORDER BY s.[dateofcreation], s.[Id])
- FROM @SReq as s JOIN @SReq as q ON s.[ParentServiceRequestId] = q.[id]
- WHERE s.[ischild] = 1
- )
- UPDATE s SET
- [ParentExtenalId] = q.[ExternalId]
- ,[ParentWorkDoneAt] = q.[WorkDoneAt]
- ,[ParentInvoiceId] = q.[InvoiceId]
- ,[baseorder] = q.[baseorder]
- FROM @SReq as s JOIN q ON s.[Id] = q.[id];
-
-
-
- ---OUTPUT
-
- WITH tgs as(
- SELECT ps.[EntityId], tg.* FROM [dbo].[mfr__tags] as tg JOIN [dbo].[mfr__*PartnerSet] as ps ON ps.[Property] = 'ServiceRequest:Tags' and tg.[Id] = ps.[PartnerId] AND ISNULL(tg.[Name],'') <> '' and [Type] = 'ServiceRequest'
- WHERE tg.Id in (16288120843
- ,15842181123
- ,16034758659
- ,16050520064
- ,16783966210
- ,16802480128
- ,16830398466
- ,19650019330
- ,19670532096
- ,18925977600)
- AND EXISTS (SELECT 0 FROM @SReq as _s where _s.Id = ps.[EntityId])
- )
- SELECT
- s.*
- ,[tags] = STUFF( (SELECT ',' + TRIM([Name]) FROM tgs where tgs.[EntityId] = s.[Id] order by tgs.[name] FOR XML PATH, TYPE).value('.[1]','varchar(255)'), 1,1,'')
- FROM @SReq as s order by baseorder
-
-
-
- SELECT
- [requestID] = s.[Id]
- ,r.*
- ,[order] = ROW_NUMBER() OVER (PARTITION BY s.[Id] ORDER BY r.[dateofcreation] ASC, r.[Id])
- FROM [dbo].[mfr__invoices] as r
- JOIN [dbo].[mfr__*PartnerSet] as ps ON ps.[Property] like 'ServiceRequest:Invoices' and r.[id] = ps.PartnerId
- JOIN @SReq as s ON s.[Id] = ps.[EntityId]
- ORDER BY s.[Id], r.[dateofcreation] ASC;
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequests_list2.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequests_list2.sql
deleted file mode 100644
index d27a3fb..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__getRequests_list2.sql
+++ /dev/null
@@ -1,308 +0,0 @@
-
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__getRequests_list2]
- @tgtdate date
- ,@mode varchar(1) = ''
- ,@completed bit = 1
- , @search varchar(100)
- ,@authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_req', @authuser) < 1
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__getRequests_list' ,@authuser , @search);
-
-
-
- DECLARE @startdate date, @enddate date, @today date = GETDATE();
- DECLARE @searchmode as varchar(1) = CASE WHEN SUBSTRING(ISNULL(@search, '') + ' ', 2,1) <> ':' THEN '' ELSE LOWER(LEFT(@search,1 )) END;
-
- IF @searchmode <> ''
- BEGIN
- SELECT @mode = 's', @search = SUBSTRING(@search,3, 1000);
- END
- ELSE
- SET @mode = LOWER(@mode);
-
- If @mode in ('r') -- r = open recent
- BEGIN
- SET @tgtdate = @today;
- SELECT @startdate = DATEADD(week, -4, [dbo].[date_weekfirst](@tgtdate))
- ,@enddate = @today;
- END
- else If @mode in ('m') -- r = open recent
- BEGIN
- SELECT @startdate = [dbo].[date_monthfirst](@tgtdate)
- ,@enddate = [dbo].[date_monthend](@tgtdate);
- END
- ELSE If @mode = 'w'
- BEGIN
- SELECT @startdate = [dbo].[date_weekfirst](@tgtdate)
- ,@enddate = [dbo].[date_weekend](@tgtdate);
- END
-
- DECLARE @openmode as bit = CASE WHEN LOWER(LEFT(ISNULL(@mode, ''),1)) IN ('o', 'r') THEN 1 ELSE 0 END;
- SELECT [startdate] = @startdate, [enddate] = @enddate, [mode] = @mode
- , [title] = CASE WHEN @searchmode = 'n' THEN 'Übersicht der Aufträge mit der Auftragsnummer ' + @search
- WHEN @openmode = 1 AND @mode = 'r' THEN 'Übersicht der offenen Aufträge (letzte 4 Wochen seit ' + FORMAT(@startdate, 'dd.MM.yyyy') + ')'
- WHEN @openmode = 1 THEN 'Übersicht der offenen Aufträge'
- ELSE 'Auftragsübersicht für ' + CASE WHEN @mode = 'm' THEN 'MONAT ' + FORMAT(@startdate, 'MMM yyyy')
- WHEN @mode = 'w' THEN 'WOCHE ' + FORMAT(@startdate, 'dd.MM.yyyy') + ' - ' + FORMAT(@enddate, 'dd.MM.')
- ELSE '' END
- END
- , [note] = CASE WHEN @searchmode = 'n' THEN 'Es wird nur der Auftrag mit der Nummer ' + @search + ' angezeigt'
- WHEN @openmode = 1 and @mode = 'r' THEN 'Es werden alle Aufträge angezeigt, die selbst offen sind und seit ' + FORMAT(@startdate, 'dd.MM.yyyy') + ' erstellt wurden, oder deren Folgeauftrag offen ist und/oder seit ' + FORMAT(@startdate, 'dd.MM.yyyy') + ' erstellt wurden.'
- WHEN @openmode = 1 THEN 'Es werden alle Aufträge angezeigt, die selbst oder ein Folgeeauftrag offen ist.'
- ELSE '' END;
-
-
- DECLARE @SReq TABLE (
- [Id] [bigint] NOT NULL,
- [Name] [nvarchar](255) NULL,
- [ExternalId] [nvarchar](255) NULL,
- [InvoiceId] varchar(1000) NULL,
- [ClosedAt] [datetime] NULL,
- [ReleasedAt] [datetime] NULL,
- [WorkDoneAt] [datetime] NULL,
- [TargetTimeInMinutes] [bigint] NULL,
- [DateModified] [datetime] NULL,
- [DateOfCreation] [datetime] NULL,
- [DueDateRangeStart] [datetime] NULL,
- [DueDateRangeEnd] [datetime] NULL,
- [PortalLink] [nvarchar](255) NULL,
- [CostCenterId] [bigint] NULL,
- [Description] [nvarchar](max) NULL,
- [State] [nvarchar](255) NULL,
- [CustomValues] [nvarchar](max) NULL,
- [CurrentOwnerId] [bigint] NULL,
- [CustomerId] [bigint] NULL,
- [ParentServiceRequestId] [bigint] NULL,
- [ParentExtenalId] [nvarchar](255) NULL,
- [ParentWorkDoneAt] [date] NULL,
- [ParentInvoiceId] varchar(1000) NULL,
- [Location#ID] [bigint] NULL,
- [Version] [int] NULL,
- [IsTemplate] [bit] NULL,
- [IsTemplateMobile] [bit] NULL,
- [CreateFromServiceRequestTemplateId] [bigint] NULL,
- [Type] [nvarchar](255) NULL,
- [CustomerName] [nvarchar](255) NULL,
- [isChild] bit NULL,
- [open] bit,
- [baseorder] int
- );
- DECLARE @inv TABLE ([Id] bigint, [Invoices] varchar(1000), [isOpen] bit);
- With fdsinv as(
- SELECT [Id] = fdsr.[mfr__servicerequest], fdsi.[InvoiceId], fdsi.[InvoiceType], [isCanceled] = ISNULL(fdsi.[isCanceled],0) FROM [dbo].[fds__invoice_servicerequests] as fdsr
- JOIN [dbo].[fds__invoices] as fdsi on fdsr.[invid] = fdsi.[id]
- WHERE [isFinal] = 1 AND fdsr.[mfr__servicerequest] is not null
- ), fi as(
- SELECT [Id], [isOpen] = MIN(CASE WHEN ISNULL([invoicetype],'r') = 'r' AND [isCanceled] = 0 THEN 0 ELSE 1 END) FROM fdsinv GROUP BY [Id]
- )
- INSERT INTO @inv
- SELECT [Id]
- , [invoices] = ISNULL(STUFF( (SELECT CHAR(10) + [InvoiceId] + ' (' + [InvoiceTYpe] + ')' FROM fdsinv as f2 WHERE f2.[id] = fi.[Id] FOR XML PATH, TYPE).value('.[1]','nvarchar(max)') ,1,1,'') , '')
- , [isOpen]
- FROM fi;
-
- WITH s as (
- SELECT * FROM [dbo].[mfr__servicerequests] as _s
- WHERE (CASE
- WHEN @searchmode = 'n' THEN
- ( CASE WHEN [ExternalId] = @search OR [ExternalId] like ('_[-]' + @search) THEN 1 ELSE 0 END )
- WHEN @openmode = 1 AND @mode = 'r' THEN
- ( CASE WHEN
- [workdoneat] is not null
- --AND ISNULL(s.[invoiceid],'') = ''
- AND ISNULL([State], '') <> 'Closed'
- --AND ISNULL(inv.[isOpen],1) = 1
- AND NOT EXISTS (SELECT * FROM [dbo].[fds__custom_servicerequest] as sr where sr.[EntityID] = _s.[id] and sr.[hidden] = 1)
- AND (CAST([DateOfCreation] as date) BETWEEN @startdate AND @today OR CAST([DateModified] as date) BETWEEN @startdate AND @today)
- AND EXISTS (SELECT 0 FROM [dbo].[mfr__*PartnerSet] as ps JOIN [dbo].[mfr__tags] as tg on ps.Property = 'ServiceRequest:Tags' and tg.Id = ps.[PartnerId] where EntityId = _s.[id] and ps.partnerid = 16034758659 and [Type] = 'ServiceRequest')
- THEN 1 ELSE 0 END)
- WHEN @openmode = 1 AND @mode <> 'r' THEN -- will be covered later because invoice info is included
- 1
- --( CASE WHEN
- -- [workdoneat] is not null
- -- AND ISNULL(s.[invoiceid],'') = ''
- -- AND ISNULL([State], '') <> 'Closed'
- -- AND ISNULL(inv.[isOpen],1) = 1
- -- AND NOT EXISTS (SELECT * FROM [dbo].[fds__custom_servicerequest] as sr where sr.[EntityID] = s.[id] and sr.[hidden] = 1)
- -- THEN 1 ELSE 0 END)
- WHEN @openmode = 0 THEN
- ( CASE WHEN CAST([DateOfCreation] as date) BETWEEN @startdate AND @enddate THEN 1 ELSE 0 END)
- ELSE 0 END
- ) = 1
- )
- insert into @SReq
- SELECT
- s.[Id]
- ,[Name]
- ,[ExternalId]
- ,[InvoiceId] = [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid], inv.[Invoices])
- ,[ClosedAt]
- ,[ReleasedAt]
- ,[WorkDoneAt]
- ,[TargetTimeInMinutes]
- ,s.[DateModified]
- ,s.[DateOfCreation]
- ,[DueDateRangeStart]
- ,[DueDateRangeEnd]
- ,[PortalLink]
- ,[CostCenterId]
- ,[Description]
- ,[State]
- ,s.[CustomValues]
- ,[CurrentOwnerId]
- ,s.[CustomerId]
- ,[ParentServiceRequestId]
- ,[ParentExtenalId] = cast(CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then null ELSE '?' END as nvarchar(255))
- ,[ParentWorkDoneAt] = cast(NULL as datetime)
- ,[ParentInvoiceId] = cast(NULL as nvarchar(255))
- ,[Location#ID]
- ,s.[Version]
- ,[IsTemplate]
- ,[IsTemplateMobile]
- ,[CreateFromServiceRequestTemplateId]
- ,[Type]
- ,[CustomerName] = NULL
- ,[isChild] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then 0 ELSE 1 END
- ,[open] = CASE WHEN s.[workdoneat] is not null AND [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid],'') = '' AND ISNULL(inv.[isOpen],1) = 1 THEN 1 ELSE 0 END
- ,[baseorder] = 0
- FROM s -- parent and childs;
- LEFT JOIN @inv as inv on inv.[Id] = s.[Id]
- WHERE
- ([type] in ('IsProject', 'IsMaintenance')
- AND
- (CASE
- WHEN @openmode = 1 AND @mode <> 'r' THEN
- ( CASE WHEN
- [workdoneat] is not null
- AND ISNULL(s.[invoiceid],'') = ''
- AND ISNULL([State], '') <> 'Closed'
- AND ISNULL(inv.[isOpen],1) = 1
- AND NOT EXISTS (SELECT * FROM [dbo].[fds__custom_servicerequest] as sr where sr.[EntityID] = s.[id] and sr.[hidden] = 1)
- THEN 1 ELSE 0 END)
- ELSE 1 END -- heres the difference, because main filter is applied in CTE
- ) = 1);
-
-
- INSERT INTO @SReq
- SELECT DISTINCT
- ISNULL(s.[Id], CASE WHEN ISNULL(q.[ParentServiceRequestId],0) > 0 THEN q.[ParentServiceRequestId] ELSE NULL END)
- ,ISNULL(s.[Name], CASE WHEN ISNULL(q.[ParentServiceRequestId],0) > 0 THEN ' - - unbekannt - - ' ELSE NULL END)
- ,s.[ExternalId]
- ,[InvoiceId] = [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid], inv.[Invoices])
- ,s.[ClosedAt]
- ,s.[ReleasedAt]
- ,s.[WorkDoneAt]
- ,s.[TargetTimeInMinutes]
- ,s.[DateModified]
- ,s.[DateOfCreation]
- ,s.[DueDateRangeStart]
- ,s.[DueDateRangeEnd]
- ,s.[PortalLink]
- ,s.[CostCenterId]
- ,s.[Description]
- ,s.[State]
- ,s.[CustomValues]
- ,s.[CurrentOwnerId]
- ,s.[CustomerId]
- ,s.[ParentServiceRequestId]
- ,[ParentExtenalId] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[ExternalId] ELSE NULL END
- ,[ParentWorkDoneAt] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[WorkDoneAt] ELSE NULL END
- ,[ParentInvoiceId] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[InvoiceId] ELSE NULL END
- ,s.[Location#ID]
- ,s.[Version]
- ,s.[IsTemplate]
- ,s.[IsTemplateMobile]
- ,s.[CreateFromServiceRequestTemplateId]
- ,s.[Type]
- ,[CustomerName] = NULL
- ,[isChild] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then 0 ELSE 1 END
- ,[open] = CASE WHEN s.[workdoneat] is not null AND [dbo].[fds__fn_InvoiceIDs_mfr](s.[invoiceid],'') = '' AND ISNULL(inv.[isOpen],1) = 1 THEN 1 ELSE 0 END
- ,[baseorder] = 0
- from [dbo].[mfr__servicerequests] as s RIGHT JOIN @SReq as q ON (s.[ParentServiceRequestId] = q.[id] OR q.[ParentServiceRequestId] = s.[id]) --parents or childs
- LEFT JOIN @inv as inv on inv.[Id] = s.[Id]
- WHERE
- (s.[type] in ('IsProject', 'IsMaintenance')
- AND NOT EXISTS (SELECT * FROM @SReq as s2 WHERE s2.[id] = s.[Id])
- AND ISNULL(s.[Id], CASE WHEN ISNULL(q.[ParentServiceRequestId],0) > 0 THEN q.[ParentServiceRequestId] ELSE NULL END) is not null
- )
- ;
-
-
- WITH q as (
- SELECT [id], [baseorder] = (ROW_NUMBER() OVER (ORDER BY ISNULL([ParentWorkDoneAt], [WorkDoneAt]), CASE WHEN ISNULL([ParentServiceRequestId],0) = 0 THEN [id] ELSE [ParentServiceRequestId] END) * 100)
- FROM @SReq as s
- WHERE [ischild] = 0
- )
- UPDATE s SET
- [baseorder] = q.baseorder
- ,[ParentServiceRequestId] = CASE WHEN s.isChild = 0 THEN s.[Id] ELSE s.[ParentServiceRequestId] END
- FROM @SReq as s JOIN q ON s.[id] = q.[id];
-
-
- UPDATE s SET
- [CustomerName] = c.[name]
- FROM @SReq as s JOIN [mfr__companies] as c ON s.[CustomerId] = c.[id];
-
-
- WITH q as (
- SELECT s.[id]
- , q.[ExternalId], q.[WorkDoneAt], q.[InvoiceId]
- , [baseorder] = q.[baseorder] + ROW_NUMBER() OVER (PARTITION BY q.[id] ORDER BY s.[dateofcreation], s.[Id])
- FROM @SReq as s JOIN @SReq as q ON s.[ParentServiceRequestId] = q.[id]
- WHERE s.[ischild] = 1
- )
- UPDATE s SET
- [ParentExtenalId] = q.[ExternalId]
- ,[ParentWorkDoneAt] = q.[WorkDoneAt]
- ,[ParentInvoiceId] = q.[InvoiceId]
- ,[baseorder] = q.[baseorder]
- FROM @SReq as s JOIN q ON s.[Id] = q.[id];
-
-
-
- ---OUTPUT
-
- WITH tgs as(
- SELECT ps.[EntityId], tg.* FROM [dbo].[mfr__tags] as tg JOIN [dbo].[mfr__*PartnerSet] as ps ON ps.[Property] = 'ServiceRequest:Tags' and tg.[Id] = ps.[PartnerId] AND ISNULL(tg.[Name],'') <> '' and [Type] = 'ServiceRequest'
- WHERE tg.Id in (16288120843
- ,15842181123
- ,16034758659
- ,16050520064
- ,16783966210
- ,16802480128
- ,16830398466
- ,19650019330
- ,19670532096
- ,18925977600)
- AND EXISTS (SELECT 0 FROM @SReq as _s where _s.Id = ps.[EntityId])
- )
- SELECT
- s.*
- ,[tags] = STUFF( (SELECT ',' + TRIM([Name]) FROM tgs where tgs.[EntityId] = s.[Id] order by tgs.[name] FOR XML PATH, TYPE).value('.[1]','varchar(255)'), 1,1,'')
- FROM @SReq as s order by baseorder
-
-
-
- SELECT
- [requestID] = s.[Id]
- ,r.*
- ,[order] = ROW_NUMBER() OVER (PARTITION BY s.[Id] ORDER BY r.[dateofcreation] ASC, r.[Id])
- FROM [dbo].[mfr__invoices] as r
- JOIN [dbo].[mfr__*PartnerSet] as ps ON ps.[Property] like 'ServiceRequest:Invoices' and r.[id] = ps.PartnerId
- JOIN @SReq as s ON s.[Id] = ps.[EntityId]
- ORDER BY s.[Id], r.[dateofcreation] ASC;
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__lookupReminders.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__lookupReminders.sql
deleted file mode 100644
index 1230c57..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__lookupReminders.sql
+++ /dev/null
@@ -1,113 +0,0 @@
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__lookupReminders]
- @InvId varchar(15)
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_reminder', @authuser) < 2
- THROW 60000, N'not authorized', 1;
- ELSE IF NOT EXISTS (select 0 FROM [dbo].[fds__invoices] WHERE [id] = @InvId) AND NOT EXISTS (select 0 FROM [dbo].[mfr__invoices] WHERE [id] = TRY_CAST(@InvId as bigint))
- THROW 60000, N'invoice not found', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__lookupReminders' ,@authuser , (SELECT * FROM (VALUES(@InvId, @authuser)) as z ([InvId],[authuser]) FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER));
-
- DECLARE @REM TABLE (
- [Id] [varchar](10) NOT NULL,
- [Version] [int] NOT NULL,
- [DocumentName] [varchar](100) NULL,
- [InvId] [varchar](15) NOT NULL,
- [CustomerId] [bigint] NULL,
- [SendToAddress] [nvarchar](1000) NULL,
- [SendToEmail] [nvarchar](255) NULL,
- [type] [varchar](3) NOT NULL,
- [amount] [numeric](10, 3) NULL,
- [amount_payed] [numeric](10, 3) NULL,
- [amount_open] [numeric](10, 3) NULL,
- [subject] [nvarchar](255) NULL,
- [text] [nvarchar](2000) NULL,
- [IsSent] [bit] NOT NULL,
- [IsFinal] [bit] NULL,
- [CustomValues] [nvarchar](max) NULL,
- [DateSent] [datetime] NULL,
- [UserSent] [varchar](25) NULL,
- [DateFinalized] [datetime] NULL,
- [UserFinalized] [varchar](25) NULL,
- [DateCreated] [datetime] NOT NULL,
- [UserCreated] [varchar](25) NOT NULL,
- [DateModified] [datetime] NOT NULL,
- [UserModified] [varchar](25) NOT NULL,
- [order] int
- );
-
- INSERT INTO @REM
- ([Id]
- ,[Version]
- ,[DocumentName]
- ,[InvId]
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[type]
- ,[amount]
- ,[amount_payed]
- ,[subject]
- ,[text]
- ,[IsSent]
- ,[IsFinal]
- ,[CustomValues]
- ,[DateSent]
- ,[UserSent]
- ,[DateFinalized]
- ,[UserFinalized]
- ,[DateCreated]
- ,[UserCreated]
- ,[DateModified]
- ,[UserModified]
- ,[order])
- SELECT [Id]
- ,[Version]
- ,[DocumentName]
- ,[InvId]
- ,[CustomerId]
- ,[SendToAddress]
- ,[SendToEmail]
- ,[type]
- ,[amount]
- ,[amount_payed]
- ,[subject]
- ,[text]
- ,[IsSent]
- ,[IsFinal]
- ,[CustomValues]
- ,[DateSent]
- ,[UserSent]
- ,[DateFinalized]
- ,[UserFinalized]
- ,[DateCreated]
- ,[UserCreated]
- ,[DateModified]
- ,[UserModified]
- , [order] = ROW_NUMBER() OVER (ORDER BY DateFinalized ASC)
- FROM [dbo].[fds__reminder] WHERE [invid] = @InvId AND [IsFinal] = 1;
-
- DECLARE @last varchar(1) = ISNULL(( SELECT TOP(1) [type] FROM @rem ORDER BY [DateFinalized] DESC), '');
- DECLARE @newnum int = CASE WHEN @last IN('l','f') THEN (SELECT COUNT(*) FROM @REM) + 1
- WHEN @last = 'm' THEN ISNULL( (SELECT TOP(1) TRY_CAST(LEFT([type],1) as int) FROM @rem ORDER BY [DateFinalized] DESC) , (SELECT COUNT(*) FROM @REM) + 1)
- ELSE 1
- END;
-
- ---output
-
- SELECT
- [type] = CAST( CASE WHEN @last = 'f' THEN 'm' WHEN @last = 'm' THEN 'l' ELSE 'f' END as varchar(1))
- ,[level] = @newnum;
-
- SELECT [subject], [amount], [amount_payed], [DateFinalized] FROM @REM;
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__prepReminder.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__prepReminder.sql
deleted file mode 100644
index 4d02e9a..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__prepReminder.sql
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__prepReminder]
- @InvId varchar(15)
- , @authuser varchar(100)
- , @type varchar(1)
- , @level int
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_reminder', @authuser) < 2
- THROW 60000, N'not authorized', 1;
- ELSE IF ISNULL(@type,'') NOT IN ('f','m','l') OR ISNULL(@level, 0) < 1
- THROW 60000, N'inputs not valid', 1;
- ELSE IF NOT EXISTS (select 0 FROM [dbo].[fds__invoices] WHERE [id] = @InvId) AND NOT EXISTS (select 0 FROM [dbo].[mfr__invoices] WHERE [id] = TRY_CAST(@InvId as bigint))
- THROW 60000, N'invoice not found', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__prepReminder' ,@authuser , (SELECT * FROM (VALUES(@InvId, @authuser, @type, @level)) as z ([InvId],[authuser],[type],[level]) FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER));
-
-
- DECLARE @now datetime = GETDATE();
- DECLARE @today date = CAST(@now as date);
-
-
- --output
-
- With inv1 as(
- select TOP(1) * FROM [dbo].[fds__invoices] WHERE [id] = @InvId
- ), inv as(
- SELECT [Id] = cast([id] as varchar(15))
- ,[PaymentTerm]
- ,[SendToemail]
- ,[SendToAddress]
- ,[CustomerId]
- ,[Invoiceid]
- ,[DateFinalized]
- ,[InvoiceBalance]
- FROM inv1
- UNION
- SELECT [Id] = cast([id] as varchar(15))
- ,[PaymentTerm] = '10wd'
- ,[SendToEmail] = sy.[SupportMail]
- ,[SendToAddress] = (select TOP(1) sy.[name] + CHAR(10) + l.[addressString] + CHAR(10) + l.[postal] + ' ' + l.[city] + CHAR(10) + l.[country] from [dbo].[mfr__#locations] as l where l.[EntityId] = sy.[CustomerId])
- ,[CustomerId]
- ,[Invoiceid]
- ,[DateFinalized] = [DateOfCreation]
- ,[InvoiceBalance]
- FROM [dbo].[mfr__invoices] as mfri
- LEFT JOIN (SELECT TOP(1) [invid] = p.[PartnerId], s.[CustomerId], cy.[supportmail], cy.[Name]
- FROM dbo.[mfr__*PartnerSet] as p
- JOIN [dbo].[mfr__servicerequests] as s on p.[EntityId] = s.[Id] AND p.[Property] = 'ServiceRequest:Invoices'
- JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
- WHERE p.PartnerId = TRY_CAST(@invId as bigint)) as sy on mfri.Id = sy.[invid]
- WHERE [id] = TRY_CAST(@invId as bigint) AND NOT EXISTS( SELECT 0 FROM inv1 ) --will only be used, if id not present in fds__invoices
- AND [Filetype] not in ('PdfCancelInvoice')
- AND [invoiceState] not in ('eIsCancelled','eIsPaid')
- )
- SELECT TOP(1)
- [today] = @today
- , [invid] = inv.[id]
- , [sender] = N'Sebastian Fuchs GmbH & Co. KG ● Germaniastraße 15 ● 40223 Düsseldorf'
- , [paymentterms] = [PaymentTerm]
- , [invoiceemail] = [SendToemail]
- , [invoiceaddress] = [SendToAddress]
- , [CustomerId] = [CustomerId]
- , [subject] = CASE WHEN @type = 'f' THEN N'Zahlungserinnerung'
- WHEN @type = 'm' THEN FORMAT(@level,'0','de-de') + N'. Mahnung'
- WHEN @type = 'l' THEN N'Letzte außergerichtliche Mahnung'
- ELSE N'Zahlungserinnerung'
- END
- , [type] = @type
- , [invoiceid] = inv.[Invoiceid]
- , [invoicedate] = inv.[DateFinalized]
- , [amount] = inv.[InvoiceBalance]
- , [amount_payed] = CAST( ISNULL([dbo].[fds__fn_InvoicePaymentAmount](inv.[Id]),0.0) as numeric(10,2))
- FROM inv;
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__prepStorno_recreate.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__prepStorno_recreate.sql
deleted file mode 100644
index f0c473a..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__prepStorno_recreate.sql
+++ /dev/null
@@ -1,459 +0,0 @@
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__prepStorno_recreate]
- @InvId varchar(20)
- , @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
- IF [dbo].[fis_getModuleAuth]('fds_inv', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__prepStorno_recreate' ,@authuser , '');
-
-
-
- DECLARE @today date = GETDATE();
- DECLARE @type char(1) = 'r';
-
- DECLARE @selReq as TABLE ([id] bigint);
- IF EXISTS (SELECT 0 FROM [dbo].[fds__invoices] WHERE [id] = @InvId AND ISNULL([isfinal],0) = 1)
- BEGIN
- INSERT INTO @selReq SELECT DISTINCT irq.[mfr__servicerequest] from [dbo].[fds__invoice_servicerequests] as irq where InvId = @InvId;
- END
- ELSE IF EXISTS (SELECT 0 FROM [dbo].[mfr__invoices] as _i where TRY_CAST(_i.[Id] as varchar(20)) = @InvId AND [FileType] in ('PdfInvoice','PdfPartialInvoice'))
- BEGIN
- INSERT INTO @selReq SELECT DISTINCT ps.[PartnerId] from [dbo].[mfr__invoices] as _i JOIN [mfr__*PartnerSet] as ps ON _i.[Id] = ps.[EntityId] and ps.[Property] = 'Invoice:SourceServiceRequest' where TRY_CAST(_i.Id as varchar(20)) = @InvId and EXISTS ( SELECT 0 FROM [dbo].[mfr__servicerequests] as _s WHERE _s.[Id] = ps.[PartnerId]);
- END
-
- DECLARE @SReq TABLE (
- [Id] [bigint] NULL,
- [Name] [nvarchar](255) NULL,
- [ExternalId] [nvarchar](255) NULL,
- [InvoiceId] [nvarchar](255) NULL,
- [ClosedAt] [datetime] NULL,
- [ReleasedAt] [datetime] NULL,
- [WorkDoneAt] [datetime] NULL,
- [TargetTimeInMinutes] [bigint] NULL,
- [DateModified] [datetime] NULL,
- [DateOfCreation] [datetime] NULL,
- [DueDateRangeStart] [datetime] NULL,
- [DueDateRangeEnd] [datetime] NULL,
- [PortalLink] [nvarchar](255) NULL,
- [CostCenterId] [bigint] NULL,
- [Description] [nvarchar](max) NULL,
- [State] [nvarchar](255) NULL,
- [CustomValues] [nvarchar](max) NULL,
- [CurrentOwnerId] [bigint] NULL,
- [CustomerId] [bigint] NULL,
- [ParentServiceRequestId] [bigint] NULL,
- [ParentExtenalId] [nvarchar](255) NULL,
- [ParentWorkDoneAt] [date] NULL,
- [ParentInvoiceId] [nvarchar](255) NULL,
- [Location#ID] [bigint] NULL,
- [Version] [int] NULL,
- [IsTemplate] [bit] NULL,
- [IsTemplateMobile] [bit] NULL,
- [CreateFromServiceRequestTemplateId] [bigint] NULL,
- [Type] [nvarchar](255) NULL,
- [Summary] nvarchar(255) NULL,
- [isChild] bit NULL,
- [baseorder] int,
- [provision] varchar(255) NULL
- );
-
- insert into @SReq
- SELECT
- [Id]
- ,[Name]
- ,[ExternalId]
- ,[InvoiceId]
- ,[ClosedAt]
- ,[ReleasedAt]
- ,[WorkDoneAt]
- ,[TargetTimeInMinutes]
- ,[DateModified]
- ,[DateOfCreation]
- ,[DueDateRangeStart]
- ,[DueDateRangeEnd]
- ,[PortalLink]
- ,[CostCenterId]
- ,[Description]
- ,[State]
- ,[CustomValues]
- ,[CurrentOwnerId]
- ,[CustomerId]
- ,[ParentServiceRequestId] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then [id] ELSE s.[ParentServiceRequestId] END
- ,[ParentExtenalId] = cast(CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then null ELSE '?' END as nvarchar(255))
- ,[ParentWorkDoneAt] = cast(NULL as datetime)
- ,[ParentInvoiceId] = cast(NULL as nvarchar(255))
- ,[Location#ID]
- ,[Version]
- ,[IsTemplate]
- ,[IsTemplateMobile]
- ,[CreateFromServiceRequestTemplateId]
- ,[Type]
- ,[Summary] = NULL
- ,[isChild] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then 0 ELSE 1 END
- ,[baseorder] = 0
- ,[provision] = NULL
- FROM [dbo].[mfr__servicerequests] as s
- WHERE [id] IN (SELECT [Id] from @selReq);
-
- IF @type <> 'i' -- for interim invoices, only one selected servicerequest is allowed -> childs and parents are ignored
- BEGIN
- INSERT INTO @SReq
- SELECT s.[Id]
- ,s.[Name]
- ,s.[ExternalId]
- ,s.[InvoiceId]
- ,s.[ClosedAt]
- ,s.[ReleasedAt]
- ,s.[WorkDoneAt]
- ,s.[TargetTimeInMinutes]
- ,s.[DateModified]
- ,s.[DateOfCreation]
- ,s.[DueDateRangeStart]
- ,s.[DueDateRangeEnd]
- ,s.[PortalLink]
- ,s.[CostCenterId]
- ,s.[Description]
- ,s.[State]
- ,s.[CustomValues]
- ,s.[CurrentOwnerId]
- ,s.[CustomerId]
- ,s.[ParentServiceRequestId]
- ,[ParentExtenalId] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[ExternalId] ELSE NULL END
- ,[ParentWorkDoneAt] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[WorkDoneAt] ELSE NULL END
- ,[ParentInvoiceId] = CASE WHEN s.[ParentServiceRequestId] = q.[id] THEN q.[InvoiceId] ELSE NULL END
- ,s.[Location#ID]
- ,s.[Version]
- ,s.[IsTemplate]
- ,s.[IsTemplateMobile]
- ,s.[CreateFromServiceRequestTemplateId]
- ,s.[Type]
- ,[Summary] = NULL
- ,[isChild] = CASE WHEN ISNULL(s.[ParentServiceRequestId],0) = 0 then 0 ELSE 1 END
- ,[baseorder] = 0
- , [provision_start] = null
- from [dbo].[mfr__servicerequests] as s JOIN @SReq as q ON (s.[ParentServiceRequestId] = q.[id] OR q.[ParentServiceRequestId] = s.[id]) --parents or childs
- WHERE NOT EXISTS (SELECT * FROM @SReq as s2 WHERE s2.[id] = s.[Id])
- END;
-
-
-
- WITH q as (
- SELECT [id], [baseorder] = (ROW_NUMBER() OVER (ORDER BY ISNULL([ParentWorkDoneAt], [WorkDoneAt]), ISNULL([ParentServiceRequestId],[id])) * 100)
- FROM @SReq as s
- WHERE [ischild] = 0
- )
- UPDATE s SET
- [baseorder] = q.baseorder
- FROM @SReq as s JOIN q ON s.[id] = q.[id];
-
-
- WITH q as (
- SELECT s.[id]
- , q.[ExternalId], q.[WorkDoneAt], q.[InvoiceId]
- , [baseorder] = q.[baseorder] + ROW_NUMBER() OVER (PARTITION BY q.[id] ORDER BY s.[dateofcreation])
- FROM @SReq as s JOIN @SReq as q ON s.[ParentServiceRequestId] = q.[id]
- WHERE s.[ischild] = 1
- )
- UPDATE s SET
- [ParentExtenalId] = q.[ExternalId]
- ,[ParentWorkDoneAt] = q.[WorkDoneAt]
- ,[ParentInvoiceId] = q.[InvoiceId]
- ,[baseorder] = q.[baseorder]
- FROM @SReq as s JOIN q ON s.[Id] = q.[id];
-
- IF @type <> 'i'
- BEGIN
- DELETE s FROM @SReq as s WHERE NOT EXISTS(SELECT * FROM @selReq as sel where sel.[id] = s.[Id])
- END
-
-
-
- DECLARE @step [dbo].[fds__tt__mfr_steps];
- DECLARE @itm [dbo].[fds__tt__mfr_items];
- DECLARE @company TABLE (
- [Id] [bigint] NOT NULL,
- [Location#ID] [bigint] NULL,
- [Version] [int] NOT NULL,
- [IsPhysicalPerson] [bit] NOT NULL,
- [IsOwner] [bit] NOT NULL,
- [IsEmailInvoicingActive] [bit] NOT NULL,
- [IsSupplier] [bit] NOT NULL,
- [MappingId] [nvarchar](255) NULL,
- [ExternalId] [nvarchar](255) NULL,
- [Name] [nvarchar](255) NULL,
- [Note] [nvarchar](255) NULL,
- [SupportTelephone] [nvarchar](255) NULL,
- [SupportFax] [nvarchar](255) NULL,
- [SupportMail] [nvarchar](255) NULL,
- [QuickSearch] [nvarchar](255) NULL,
- [DateModified] [datetime] NOT NULL,
- [CustomValues] [nvarchar](max) NOT NULL,
- [MainContactId] [bigint] NOT NULL,
- [address] nvarchar(1000) null
- );
- INSERT INTO @company SELECT DISTINCT cy.*, [address] = [dbo].[fds__getCompanyAddress](cy.[id]) FROM [mfr__companies] as cy JOIN @SReq as s on cy.id = s.[CustomerId];
- DECLARE @companyids [dbo].[fds__tt__idlist];
- INSERT INTO @companyids SELECT DISTINCT [id] FROM @company;
-
-
- INSERT INTO @itm
- SELECT itm.*, [baseorder] = s.[baseorder], [order] = ROW_NUMBER() OVER (PARTITION BY [ServiceRequestId] ORDER BY [SortOrder], itm.[Id])
- from [dbo].[mfr__items] as itm JOIN @SReq as s ON itm.ServiceRequestId = s.[Id];
-
- DECLARE @NUM_of_int_Invoices int = 0;
-
-
-
- -- Add virtual items for intermediate invoices
- INSERT INTO @itm
- SELECT
- [Id] = -2
- ,[Version] = 0
- ,[QuantityHours] = 1
- ,[PlannedQuantityHours] = 1
- ,[ItemTypeId] = NULL
- ,[ItemNumber] = NULL
- ,[TrackingId] = NULL
- ,[Manufacture] = NULL
- ,[Price] = inv.InvoiceBalance_net * -1.0 --without VAT
- ,[Costs] = inv.InvoiceBalance_net * -1.0 --without VAT
- ,[NameOrNumber] = REPLACE(inv.DocumentName, '.pdf','')
- ,[CustomValues] = NULL
- ,[Note] = '' + 'Anrechnung der ' + REPLACE(inv.DocumentName, '.pdf','') + ' vom ' + FORMAT(inv.[dateFinalized], 'dd.MM.yyyy', 'de-de') + '
'
- ,[ExternalId] = NULL
- ,[Discount] = NULL
- ,[VAT] = inv.InvoiceVAT_1
- ,[IsManual] = 1
- ,[SortOrder] = ROW_NUMBER() OVER (PARTITION BY srq.[mfr__servicerequest] ORDER BY inv.[dateFinalized], inv.DateCreated)
- ,[Type] = 'PartialInvoice'
- ,[ServiceRequestId] = -2 --s.[id]
- ,[ServiceObjectId] = Null
- ,[CreatorId] = NULL
- ,[UnitId] = 15825600513
- ,[UnitString] = 'Pauschal'
- ,[baseorder] = s.[baseorder], [order] = 10000 + ROW_NUMBER() OVER (PARTITION BY srq.[mfr__servicerequest] ORDER BY inv.[dateFinalized], inv.DateCreated)
- from [dbo].[fds__invoices] as inv
- JOIN [dbo].[fds__invoice_servicerequests] as srq ON inv.[Id] = srq.[InvId] AND inv.[InvoiceType] = 'i' --important
- JOIN @SReq as s ON srq.[mfr__servicerequest] = s.[Id]
- WHERE inv.[InvoiceType] = 'i' --important;
- AND ISNULL(inv.[isFinal],0) = 1 AND ISNULL(inv.[IsCanceled],0) = 0
- AND [dbo].[fds__fn_IntermediateIsAllocatedToOther](inv.[id],@InvId) = 0; --inonly those intermediates that are not already allocated to any other (than the to be replaced Inv);
-
- IF EXISTS (SELECT * FROM @itm WHERE [ServiceRequestId] = -2)
- BEGIN
- -- Add virtual request
- INSERT INTO @SReq ([Id]
- ,[Name]
- ,[Type]
- ,[isChild]
- ,[baseorder])
- VALUES(-2
- ,'Abschlagszahlungen'
- ,'vrii'
- ,0
- ,999);
-
- SET @type = 'f';
-
- END;
-
-
- -- Add virtual item (to front) for (to-be) replaced invoice
- INSERT INTO @itm
- SELECT TOP(1) --can only be one
- [Id] = -2
- ,[Version] = 0
- ,[QuantityHours] = 1
- ,[PlannedQuantityHours] = 1
- ,[ItemTypeId] = NULL
- ,[ItemNumber] = NULL
- ,[TrackingId] = NULL
- ,[Manufacture] = NULL
- ,[Price] = inv.InvoiceBalance_net * -1.0 --without VAT
- ,[Costs] = inv.InvoiceBalance_net * -1.0 --without VAT
- ,[NameOrNumber] = REPLACE(inv.DocumentName, '.pdf','')
- ,[CustomValues] = NULL
- ,[Note] = '' + 'Storno der ' + REPLACE(inv.DocumentName, '.pdf','') + ' vom ' + FORMAT(inv.[dateFinalized], 'dd.MM.yyyy', 'de-de') + '
'
- ,[ExternalId] = NULL
- ,[Discount] = NULL
- ,[VAT] = inv.InvoiceVAT_1
- ,[IsManual] = 1
- ,[SortOrder] = 1
- ,[Type] = 'CanceledInvoice'
- ,[ServiceRequestId] = -3 --s.[id]
- ,[ServiceObjectId] = Null
- ,[CreatorId] = NULL
- ,[UnitId] = 15825600513
- ,[UnitString] = 'Pauschal'
- ,[baseorder] = 0, [order] = 1
- from [dbo].[fds__invoices] as inv
- WHERE ISNULL(inv.[isFinal],0) = 1 AND ISNULL(inv.[IsCanceled],0) = 0
- AND inv.[Id] = @InvId;
-
- IF EXISTS (SELECT * FROM @itm WHERE [ServiceRequestId] = -3)
- BEGIN
- -- Add virtual request
- INSERT INTO @SReq ([Id]
- ,[Name]
- ,[Type]
- ,[isChild]
- ,[baseorder])
- VALUES(-3
- ,'Storno'
- ,'vrci'
- ,0
- ,-999);
-
- END;
-
-
-
-
- /** OUTPUT + get other types **/
-
-
- WITH app as(
- SELECT [start] = MIN(CAST(CASE WHEN a.[StartDateTime] is null THEN s.[workdoneat] WHEN CAST(a.[StartDateTime] as date) > s.[workdoneat] THEN CAST(a.[StartDateTime] as date) ELSE s.[workdoneat] END as date))
- , [end] = MAX(CAST(CASE WHEN a.[EndDateTime] is null THEN s.[workdoneat] WHEN CAST(a.[EndDateTime] as date) > s.[workdoneat] THEN CAST(a.[EndDateTime] as date) ELSE s.[workdoneat] END as date))
- , [CustomerId] = MIN (s.customerid)
- FROM [dbo].[mfr__appointments] as a
- RIGHT JOIN @SReq as s on a.[ServiceRequestId] = s.[Id] AND a.[State] in ('IsWorkDone')
- )
- SELECT TOP(1)
- [today]
- , [provisionstart] = CASe WHEN @type = 'i' THEN NULL WHEN [start] = [end] THEN NULL ELSE [start] END
- , [provisionend] = CASe WHEN @type = 'i' THEN @today ELSE [end] END -- Abschlagsrechnungen immer mit Tagesdatum
- , [provisionlocation] = ISNULL((SELECT TOP(1) [provisionlocation] FROM [dbo].[fds__invoices] where [Id] = @InvId and ISNULL([provisionlocation],'') <>''),N'')
- , [sender] = N'Sebastian Fuchs GmbH & Co. KG ● Germaniastraße 15 ● 40223 Düsseldorf'
- , [paymentterms] = ISNULL((SELECT TOP(1) [PaymentTerm] FROM [dbo].[fds__invoices] where [Id] = @InvId and ISNULL([PaymentTerm],'') <>''),N'10wd')
- , [invoiceemail] = ISNULL((SELECT TOP(1) [SendToemail] FROM [dbo].[fds__invoices] where [Id] = @InvId and ISNULL([sendToEmail],'') <>''),(SELECT TOP(1) [SupportMail] FROM @company where IsEmailInvoicingActive = 1))
- , [invoiceaddress] = ISNULL((SELECT TOP(1) [SendToAddress] FROM [dbo].[fds__invoices] where [Id] = @InvId and ISNULL([SendToAddress],'') <>''),(SELECT TOP(1) CONCAT([name], CHAR(10), [address]) FROM @company ORDER BY IsEmailInvoicingActive DESC))
- , [tax_servicerefund] = 0.2
- , [CustomerId] = [CustomerId]
- , [invoicetitle] = CASE WHEN @type = 'i' THEN (CASE WHEN @NUM_of_int_Invoices > 0 THEN CAST((@NUM_of_int_Invoices + 1) as varchar(3)) + '. ' ELSE '' END) + 'Abschlagsrechnung'
- WHEN @type = 'f' THEN 'Schlussrechnung' WHEN @type = 'c' THEN 'Stornorechnung' ELSE 'Rechnung' END
- , [type] = @type
- FROM (VALUES(CAST(GETDATE() as date)))base ([today]) CROSS JOIN app;
-
- SELECT
- *
- ,[order] = ROW_NUMBER() OVER (ORDER BY [baseorder])
- FROM @SReq;
-
-
-
- IF @type <> 'i'
- BEGIN
- SELECT
- itm.[Id]
- , [net] = ISNULL([Price],0)
- , [quantityhours] = ISNULL([quantityhours],1)
- , itm.[UnitString]
- , [net_val] = CAST( (ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0) as numeric(7,2))
- , [bo_val] = CAST( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * (1 + (ISNULL(vat.[vat], 19.0) * 0.01)) as numeric(7,2))
- , [vat] = CASE WHEN LOWER(itm.[type]) in ('Title','Text') THEN null ELSE FORMAT(ISNULL(vat.[vat], 19.0), '#0.0','de') + '%' END
- , [vat_val] = CAST( ((ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0)) * ((ISNULL(vat.[vat], 19.0) * 0.01)) as numeric(7,2))
- , itm.[ServiceRequestId]
- , itm.[SortOrder]
- , itm.[Type]
- , itm.[NameOrNumber]
- , itm.[Note]
- , [order] = (itm.[baseorder] * 100) + itm.[order]
- FROM @itm as itm
- LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item';
- END
- ELSE
- BEGIN
- WITH citm as (
- SELECT itm.[ServiceRequestId], [net_val] = CAST( SUM( (ISNULL([Price],0) * ISNULL([quantityhours],1)) - ISNULL([discount],0) ) as numeric(7,2))
- FROM @itm as itm
- WHERE itm.[Type] = 'Material'
- GROUP BY itm.[ServiceRequestId]
- )
- SELECT
- [Id] = -1
- , [net] = 1000.0
- , [quantityhours] = 1
- , [UnitString] = 'Pauschal'
- , [net_val] = CAST( 1000.0 as numeric(7,2))
- , [bo_val] = CAST( 1000.0 * 1.19 as numeric(7,2))
- , [vat] = FORMAT( 19.0, '#0.0','de') + '%'
- , [vat_val] = CAST( 1000.0 * 0.19 as numeric(7,2))
- , [ServiceRequestId] = s.[id]
- , [SortOrder] = 0
- , [Type] = 'PartialInvoice'
- , [NameOrNumber] = 'Abschlagsbetrag für bereits erbrachte Arbeiten, Dienstleistungen, Materiallieferungen und getätigte Bestellvorgänge zum oben genannten Bauvorhaben'
- , [Note] = ''
- , [order] = 1
- FROM @SReq as s;
-
- END
-
-
-
- INSERT INTO @step
- SELECT
- stp.*
- , s.[baseorder]
- , [order] = (s.[baseorder] * 100) + ROW_NUMBER() OVER (PARTITION BY stp.[ServiceRequestId] ORDER BY stp.[SortOrder], stp.[Id])
- FROM [dbo].[mfr__steps] as stp JOIN @SReq as s ON stp.ServiceRequestId = s.[Id];
- SELECT * from @step;
-
-
-
- SELECT
- cc.[Id]
- , [CompanyName] = cc.[name]
- , ct.[Gender]
- , ct.[FirstName]
- , ct.[LastName]
- , ct.[Email]
- , cc.[address]
- FROM [dbo].[fds__getCompanysContacts](@companyids) as ct join @company as cc on cc.[Id] = ct.[CyId];
-
-
-
- SELECT DISTINCT
- [ref] = 'Einsatzort ' + so.[name]
- ,[address] = [dbo].[fds__fn_combineAddress] (so.[Name], loc.[AddressString], null
- ,loc.[Postal]
- ,loc.[City]
- ,loc.[State]
- ,loc.[Country])
- FROM @SReq as s
- LEFT JOIN [mfr__*PartnerSet] as p ON p.property = 'ServiceRequest:ServiceObjects' and p.[EntityId] = s.[id]
- LEFT JOIN [mfr__serviceobjects] as so ON so.id = p.[PartnerId]
- LEFT JOIN [mfr__*PartnerSet] as po ON p.property = 'ServiceObject:Location' and po.[EntityId] = so.[Id]
- LEFT join [dbo].[mfr__#locations] as loc ON (loc.[id] = so.[Location#ID] OR po.[PartnerId] = loc.[Id] OR (so.[Id] = loc.[EntityId] and loc.Property = 'ServiceObject:Location'))
- WHERE so.id is not null and loc.[id] is not null
- UNION
- SELECT DISTINCT
- [ref] = 'Auftragsort ' + [name]
- ,[address] = [dbo].[fds__fn_combineAddress] (loc.[AddressString], null, null
- ,loc.[Postal]
- ,loc.[City]
- ,loc.[State]
- ,loc.[Country])
- FROM @SReq as s
- LEFT JOIN [mfr__*PartnerSet] as p ON p.property = 'ServiceRequest:Location' and p.[EntityId] = s.[id]
- join [dbo].[mfr__#locations] as loc ON (s.[Location#ID] = loc.[id] OR p.[PartnerId] = loc.[Id] OR (s.[Id] = loc.[EntityId] and loc.Property = 'ServiceRequest:Location'))
- WHERE loc.[id] is not null
- UNION
- SELECT DISTINCT [ref] = 'Kunde'
- , [address]
- FROM @company;
-
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByMonth.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByMonth.sql
deleted file mode 100644
index b6d92b0..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByMonth.sql
+++ /dev/null
@@ -1,61 +0,0 @@
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__r_getBalanceByMonth]
- @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- DECLARE @today date = GETDATE()
- DECLARE @tomorrow date = DATEADD(DAY,1,@today);
-
- IF [dbo].[fis_getModuleAuth]('fds_reports', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
-
- DECLARE @Admin [dbo].[fds__tt__admin_ReportAdminTable];
-
- --Admin Table
- INSERT INTO @Admin
- VALUES (
- 'bbm'
- ,'Umsatz nach Monaten'
- ,'Umsatz nach Monaten'
- ,'' + FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm')
- ,''
- ,'table' --typ
- , '' --settings
- , ''
- , 0)
-
- SELECT * FROM @Admin;
-
- WITH inv as (
- SELECT
- i.[Dateofcreation]
- ,i.[InvoiceBalance]
- ,i.[InvoiceBalanceNetto]
- FROM [dbo].[mfr__invoices] as i
- where --i.[invoicestate] in('eIsSent','eIsPaid','eIsOpen') and
- i.[FileType] in( 'PdfInvoice','PdfCancelInvoice','PdfPartialInvoice') and ISNULL(InvoiceId,'') not in ('Preview','')
- UNION
- SELECT
- [Dateofcreation] = i.[DateCreatEd]
- ,i.[InvoiceBalance]
- ,[InvoiceBalanceNetto] = i.[InvoiceBalance_net]
- FROM [dbo].[fds__invoices] as i
- WHERE i.[isFinal] = 1
- )
- SELECT
- [Monat] = FORMAT( inv.[Dateofcreation], 'yyyy - MM', 'de')
- , [∑ Umsätze] = FORMAT( SUM( ISNULL(inv.[InvoiceBalance],0) ), '#,0.00 €', 'de')
- , [style:∑ Umsätze] = 'text-align: right'
- , [∑ Umsätze_netto] = FORMAT( SUM( ISNULL(inv.[InvoiceBalanceNetto],0) ), '#,0.00 €', 'de')
- , [style:∑ Umsätze_netto] = 'text-align: right'
- FROM inv
- GROUP BY FORMAT( inv.[Dateofcreation], 'yyyy - MM', 'de');
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByYearTopCustomer.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByYearTopCustomer.sql
deleted file mode 100644
index bf16db0..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByYearTopCustomer.sql
+++ /dev/null
@@ -1,91 +0,0 @@
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__r_getBalanceByYearTopCustomer]
- @year int,
-
- @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- DECLARE @today date = GETDATE()
- DECLARE @tomorrow date = DATEADD(DAY,1,@today);
-
- IF [dbo].[fis_getModuleAuth]('fds_reports', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- DECLARE @Admin [dbo].[fds__tt__admin_ReportAdminTable];
-
- --Admin Table
- INSERT INTO @Admin
- VALUES (
- 'bbm'
- ,'Umsatz der Top 10 Kunden für Jahr ' + CAST( @year as varchar(10))
- ,'Umsatz der Top 10 Kunden pro Jahr ' + CAST( @year as varchar(10))
- ,'' + FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm')
- ,''
- ,'table' --typ
- , '' --settings
- , ''
- , 0);
-
- SELECT * FROM @Admin;
-
-
- WITH inv as(
- select
- [InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
- ,[Dateofcreation] = CAST(_i.[Dateofcreation] as date)
- ,srq.CustomerId
- ,[customerName] = cy.Name
- ,[seq] = ROW_NUMBER() OVER (ORDER BY CAST(_i.[Dateofcreation] as date))
- FROM [dbo].[mfr__invoices] as _i
- JOIN [dbo].[mfr__servicerequests] as srq on srq.InvoiceId like ('%' + _i.[InvoiceId] + '%')
- JOIN [dbo].[mfr__companies] as cy on srq.CustomerId = cy.id
- where _i.[invoicestate] in('eIsSent','eIsPaid','eIsOpen') and YEAR(_i.[Dateofcreation]) = @year
- GROUP BY CAST(_i.[Dateofcreation] as date), CustomerId, cy.name
- UNION
- select
- [InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
- ,[Dateofcreation] = CAST(_i.[DateCreated] as date)
- ,_i.CustomerId
- ,[customerName] = cy.Name
- ,[seq] = ROW_NUMBER() OVER (ORDER BY CAST(_i.[DateCreated] as date))
- FROM [dbo].[fds__invoices] as _i
- JOIN [dbo].[mfr__companies] as cy on _i.CustomerId = cy.id
- where YEAR(_i.[DateCreated]) = @year and _i.[isfinal] = 1
- GROUP BY CAST(_i.[DateCreated] as date), CustomerId, cy.name
- ), yr1 as (
- SELECT
- [year] = YEAR( inv.[Dateofcreation] )
- , [total] = SUM( ISNULL(inv.[InvoiceBalance],0) )
- FROM [dbo].[mfr__invoices] as inv
- where inv.[invoicestate] in('eIsSent','eIsPaid','eIsOpen')
- GROUP BY YEAR( inv.[Dateofcreation])
- UNION
- SELECT
- [year] = YEAR( _i.[DateCreated] )
- , [total] = SUM( ISNULL(_i.[InvoiceBalance],0) )
- FROM [dbo].[fds__invoices] as _i
- WHERE _i.[isfinal] = 1
- GROUP BY YEAR( _i.[DateCreated])
- ), yr as (
- SELECT [year], [total] = SUM([total])
- from yr1 GROUP BY [year]
- )
- SELECT TOP(10)
- [Jahr] = CAST( YEAR( inv.[Dateofcreation] ) as varchar(4))
- , [Name d. Kunden] = [customerName]
- , [∑ Umsätze] = FORMAT( SUM( ISNULL(inv.[InvoiceBalance],0) ), '#,0.00 €', 'de')
- , [style:∑ Umsätze] = 'text-align: right'
- , [% Anteil] = CASE WHEN yr.[total] > 0 THEN FORMAT( SUM( ISNULL(inv.[InvoiceBalance],0) ) / [total], '0 %', 'de') ELSE NULL END
- , [style:% Anteil] = 'text-align: right'
- , [order] = ROW_NUMBER() OVER ( ORDER By SUM( ISNULL(inv.[InvoiceBalance],0) ) DESC)
- FROM inv LEFT JOIN yr on YEAR( inv.[Dateofcreation] ) = yr.[year]
- GROUP BY YEAR( inv.[Dateofcreation] ), yr.[total], [customerName];
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByYearTopMaterial.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByYearTopMaterial.sql
deleted file mode 100644
index 513a7dc..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceByYearTopMaterial.sql
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__r_getBalanceByYearTopMaterial]
- @year int,
-
- @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
- DECLARE @today date = GETDATE()
- DECLARE @tomorrow date = DATEADD(DAY,1,@today);
-
- IF [dbo].[fis_getModuleAuth]('fds_reports', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- DECLARE @Admin [dbo].[fds__tt__admin_ReportAdminTable];
-
- --Admin Table
- INSERT INTO @Admin
- VALUES (
- 'bbm'
- ,'Umsatz der Top 10 Materialien für Jahr ' + CAST( @year as varchar(10))
- ,'Umsatz der Top 10 Materialien für Jahr ' + CAST( @year as varchar(10))
- ,'' + FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm')
- ,''
- ,'table' --typ
- , '' --settings
- , ''
- , 0);
-
- SELECT * FROM @Admin;
-
-
- WITH inv as(
- select
- [itmPrice] = SUM( (ISNULL(itm.[price],0) * ISNULL(itm.[QuantityHours],0) ) -ISNULL(itm.[discount],0) )
- ,[Dateofcreation] = CAST(_i.[Dateofcreation] as date)
- ,[material] = itm.NameOrNumber
- ,[seq] = ROW_NUMBER() OVER (ORDER BY CAST(_i.[Dateofcreation] as date))
- FROM [dbo].[mfr__invoices] as _i
- JOIN [dbo].[mfr__servicerequests] as srq on srq.InvoiceId like ('%' + _i.[InvoiceId] + '%')
- JOIN [dbo].[mfr__items] as itm on srq.Id = itm.[ServiceRequestId] and itm.[Type] like 'Material'
- where _i.[invoicestate] in('eIsSent','eIsPaid','eIsOpen') and YEAR(_i.[Dateofcreation]) = @year
- GROUP BY CAST(_i.[Dateofcreation] as date), itm.NameOrNumber
- UNION
- SELECT
- [itmPrice] = SUM( ISNULL(itm.[value_total],0) )
- ,[Dateofcreation] = CAST(_i.[DateCreated] as date)
- ,[material] = itm.[text]
- ,[seq] = ROW_NUMBER() OVER (ORDER BY CAST(_i.[DateCreated] as date))
- FROM [dbo].[fds__invoices] as _i
- JOIN [fds__invoice_items] as itm on itm.[invid] = _i.[id] AND itm.[Type] like 'Material'
- where YEAR(_i.[DateCreated]) = @year and _i.[isfinal] = 1
- GROUP BY CAST(_i.[DateCreated] as date), itm.[text]
- ), yr1 as (
- SELECT
- [year] = YEAR( inv.[Dateofcreation] )
- , [total] = SUM( ISNULL(inv.[InvoiceBalance],0) )
- FROM [dbo].[mfr__invoices] as inv
- where inv.[invoicestate] in('eIsSent','eIsPaid','eIsOpen')
- GROUP BY YEAR( inv.[Dateofcreation])
- UNION
- SELECT
- [year] = YEAR( _i.[DateCreated] )
- , [total] = SUM( ISNULL(_i.[InvoiceBalance],0) )
- FROM [dbo].[fds__invoices] as _i
- WHERE _i.[isfinal] = 1
- GROUP BY YEAR( _i.[DateCreated])
- ), yr as (
- SELECT [year], [total] = SUM([total])
- from yr1 GROUP BY [year]
- )
- SELECT TOP(10)
- [Jahr] = CAST( YEAR( inv.[Dateofcreation] ) as varchar(4))
- , [Material] = [material]
- , [∑ Umsätze] = FORMAT( SUM( ISNULL(inv.[itmPrice],0) ), '#,0.00 €', 'de')
- , [style:∑ Umsätze] = 'text-align: right'
- , [% Anteil] = CASE WHEN yr.[total] > 0 THEN FORMAT( SUM( ISNULL(inv.[itmPrice],0) ) / [total], '0 %', 'de') ELSE NULL END
- , [style:% Anteil] = 'text-align: right'
- , [order] = ROW_NUMBER() OVER ( ORDER By SUM( ISNULL(inv.[itmPrice],0) ) DESC)
- FROM inv LEFT JOIN yr on YEAR( inv.[Dateofcreation] ) = yr.[year]
- GROUP BY YEAR( inv.[Dateofcreation] ), yr.[total], [material];
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceTrendByMonth.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceTrendByMonth.sql
deleted file mode 100644
index f94b85a..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceTrendByMonth.sql
+++ /dev/null
@@ -1,72 +0,0 @@
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__r_getBalanceTrendByMonth]
- @year int
- ,@month int,
-
- @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
-
-
- DECLARE @today date = GETDATE()
- DECLARE @tomorrow date = DATEADD(DAY,1,@today);
-
- IF [dbo].[fis_getModuleAuth]('fds_reports', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- set @month = ISNULL(@month, Month(@today));
- set @year= ISNULL(@year, Year(@year));
-
-
- DECLARE @Admin [dbo].[fds__tt__admin_ReportAdminTable];
-
- --Admin Table
- INSERT INTO @Admin
- VALUES (
- 'bbm'
- ,'UmsatzTrend für Monat ' + FORMAT(@Month, '00') + ' / ' + FORMAT(@year, '0000')
- ,'UmsatzTrend für Monat ' + FORMAT(@Month, '00') + ' / ' + FORMAT(@year, '0000')
- ,'' + FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm')
- ,''
- ,'chart' --typ
- , '{ "charttype": "line", "x1_label_angle": -90, "color": "e0301e", "linewidth": 2, "valuelabels": false, "marker": "none", "colorpalette": "00B050;00B050;00B050", "x1_column": "date", "y1_column": "Value", "y1_title": "Actuals", "x1_title": "", "series_column": "series", "legend_position": "bottom", "show_datalabel": true, "datalabelfontsizescale": 0.6, "height": 600, "width": 1200, "x1_labelformat": "ddd, dd/MM"}' --settings
- , ''
- , 0)
-
- SELECT * FROM @Admin;
-
-
-
-
- with inv as(
- select
- [InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
- ,[Dateofcreation] = CAST([Dateofcreation] as date)
- ,[seq] = ROW_NUMBER() OVER (ORDER BY CAST([Dateofcreation] as date))
- FROM [dbo].[mfr__invoices] as _i
- where _i.[invoicestate] in('eIsSent','eIsPaid','eIsOpen') and month([Dateofcreation]) = @Month and YEAR([Dateofcreation]) = @year
- GROUP BY CAST([Dateofcreation] as date)
- UNION
- select
- [InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
- ,[Dateofcreation] = CAST([Datecreated] as date)
- ,[seq] = ROW_NUMBER() OVER (ORDER BY CAST([Datecreated] as date))
- FROM [dbo].[fds__invoices] as _i where _i.IsFinal = 1 and month([Datecreated]) = @Month and YEAR([Datecreated]) = @year
- GROUP BY CAST([Datecreated] as date)
- )
- SELECT
- --[Monat] = FORMAT( inv.[Dateofcreation], 'yyyy - MM', 'de')
- --,[Umsatz] = FORMAT( ISNULL(inv.[InvoiceBalance],0) , '#0.00', 'de')
- [series] = 'Umsatz'
- ,[date] = CAST(inv.[Dateofcreation] as date)
- ,[value] = CAST( SUM( ISNULL(inv.[InvoiceBalance],0) ) OVER (ORDER BY [seq]) as numeric(9,2))
- FROM inv
- ORDER BY [seq]
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceTrendByYear.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceTrendByYear.sql
deleted file mode 100644
index 744caf0..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__r_getBalanceTrendByYear.sql
+++ /dev/null
@@ -1,71 +0,0 @@
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__r_getBalanceTrendByYear]
- @year int,
-
- @authuser varchar(100)
-AS
-BEGIN
- SET NOCOUNT ON;
-
-
-
- DECLARE @today date = GETDATE()
- DECLARE @tomorrow date = DATEADD(DAY,1,@today);
-
- IF [dbo].[fis_getModuleAuth]('fds_reports', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- set @year= ISNULL(@year, Year(@year));
-
-
- DECLARE @Admin [dbo].[fds__tt__admin_ReportAdminTable];
-
- --Admin Table
- INSERT INTO @Admin
- VALUES (
- 'bbm'
- ,'UmsatzTrend für Jahr ' + FORMAT(@year, '0000')
- ,'UmsatzTrend für Jahr ' + FORMAT(@year, '0000')
- ,'' + FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm')
- ,''
- ,'chart' --typ
- , '{ "charttype": "line", "x1_label_angle": -90, "color": "e0301e", "linewidth": 2, "valuelabels": false, "marker": "none", "colorpalette": "00B050;00B050;00B050", "x1_column": "date", "y1_column": "Value", "y1_title": "Actuals", "x1_title": "", "series_column": "series", "legend_position": "bottom", "show_datalabel": true, "datalabelfontsizescale": 0.6, "height": 600, "width": 1200, "x1_labelformat": "ddd, dd/MM"}' --settings
- , ''
- , 0)
-
- SELECT * FROM @Admin;
-
-
-
-
- with inv as(
- select
- [InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
- ,[Dateofcreation] = CAST([Dateofcreation] as date)
- ,[seq] = ROW_NUMBER() OVER (ORDER BY CAST([Dateofcreation] as date))
- FROM [dbo].[mfr__invoices] as _i
- where _i.[invoicestate] in('eIsSent','eIsPaid','eIsOpen') and YEAR([Dateofcreation]) = @year
- GROUP BY CAST([Dateofcreation] as date)
- UNION
- select
- [InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
- ,[Dateofcreation] = CAST([Datecreated] as date)
- ,[seq] = ROW_NUMBER() OVER (ORDER BY CAST([Datecreated] as date))
- FROM [dbo].[fds__invoices] as _i where _i.IsFinal = 1 and YEAR([Datecreated]) = @year
- GROUP BY CAST([Datecreated] as date)
- )
- SELECT
- --[Monat] = FORMAT( inv.[Dateofcreation], 'yyyy - MM', 'de')
- --,[Umsatz] = FORMAT( ISNULL(inv.[InvoiceBalance],0) , '#0.00', 'de')
- [series] = 'Umsatz'
- ,[date] = CAST(inv.[Dateofcreation] as date)
- ,[value] = CAST( SUM( ISNULL(inv.[InvoiceBalance],0) ) OVER (ORDER BY [seq]) as numeric(9,2))
- FROM inv
- ORDER BY [seq]
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__setBankingtransaction_autoAssigns.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__setBankingtransaction_autoAssigns.sql
deleted file mode 100644
index 65a504f..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__setBankingtransaction_autoAssigns.sql
+++ /dev/null
@@ -1,70 +0,0 @@
-
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__setBankingtransaction_autoAssigns]
-AS
-BEGIN
- SET NOCOUNT ON;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__setBankingtransaction_autoAssigns' ,'', '');
-
- with
- icr as (
- SELECT * FROM [dbo].[fds__getInvoiceCredits] (null, null)
- ), ic as (
- SELECT
- icr.[uid]
- , icr.[InvoiceId]
- , [InvID] = CAST(i.[Id] as varchar(15))
- , icr.amount
- , [auto] = CAST(1 as bit)
- FROM icr
- JOIN [dbo].[fds__invoices] as i on icr.[InvoiceId] = i.[InvoiceId] and i.[InvoiceId] is not null and i.[IsFinal] = 1
- UNION
- SELECT
- icr.[uid]
- , icr.[InvoiceId]
- , [InvID] = CAST(i.[Id] as varchar(15))
- , icr.amount
- , [auto] = CAST(1 as bit)
- FROM icr
- JOIN [dbo].[mfr__invoices] as i on icr.[InvoiceId] = i.[InvoiceId] and i.[InvoiceId] is not null
- --UNION
- --SELECT
- -- bt.[uid]
- -- , i.[InvoiceId]
- -- , [InvID] = i.[Id]
- -- , bt.[amount]
- -- , [auto] = CAST(0 as bit)
- --FROM [dbo].[fds__bankingtransactions] as bt JOIN [dbo].[fds__bankingtransactions_settings] as bs ON bt.uid = bs.[banking_uid] AND ISNULL(bs.[assigned_invoice_id], '') <> ''
- -- JOIN [dbo].[fds__invoices] as i on bs.[assigned_invoice_id] = i.[Id] and i.[IsFinal] = 1
-
- ), ic2 as (
- SELECT [banking_uid] = ic.[uid]
- , [amount] = SUM(ISNULL(ic.[amount], 0.0))
- , [InvID_csv] = STRING_AGG(ic.[InvID], ',')
- from ic
- WHERE ic.[InvID] is not null
- GROUP BY ic.[uid]
- )
- --select * from ic2
- MERGE [dbo].[fds__bankingtransactions_settings] as TARGET
- USING ic2 as SOURCE ON TARGET.[banking_uid] = SOURCE.[banking_uid]
- WHEN NOT MATCHED BY TARGET THEN
- INSERT
- ([banking_uid]
- ,[auto_invoice_id])
- VALUES
- (SOURCE.[banking_uid]
- ,SOURCE.[InvID_csv])
- WHEN MATCHED THEN
- UPDATE SET [auto_invoice_id] = [dbo].[ott_merge_csv](TARGET.[auto_invoice_id],SOURCE.[InvID_csv]);
-
-
-
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/backup__fds__setInvoicePayed.sql b/Fuchs_Database/dbo/Stored Procedures/backup__fds__setInvoicePayed.sql
deleted file mode 100644
index ad0d013..0000000
--- a/Fuchs_Database/dbo/Stored Procedures/backup__fds__setInvoicePayed.sql
+++ /dev/null
@@ -1,46 +0,0 @@
--- =============================================
--- Author:
--- Create date:
--- Description:
--- =============================================
-CREATE PROCEDURE [dbo].[backup__fds__setInvoicePayed]
- @Id varchar(15),
- @authuser varchar(25)
-AS
-BEGIN
- SET NOCOUNT ON;
- DECLARE @now datetime = GETUTCDATE();
-
- IF [dbo].[fis_getModuleAuth]('fds_inv', @authuser) < 2
- THROW 60000, N'not authorized', 1;
-
- INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
- VALUES ('fds__setInvoicePayed' ,@authuser , (SELECT * FROM (VALUES(@Id, @authuser)) as z ([id],[authuser]) FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER));
-
- UPDATE [dbo].[fds__invoices] SET [IsPayed] = 1, [paymentstatus] = 'm', [DateModified] = @now, [UserModified] = @authuser, [version] = (ISNULL([version],0) + 1)
- OUTPUT inserted.*
- WHERE [Id] = @Id AND @Id is not null and [IsPayed] = 0;
-
- IF TRY_CAST(@id as bigint) is not null and EXISTS(SELECT 0 FROM [dbo].[mfr__invoices] as i where i.[id] = TRY_CAST(@id as bigint))
- BEGIN
- MERGE [dbo].[fds__custom_invoiceinfo] as TARGET
- USING (VALUES
- (TRY_CAST(@id as bigint)
- ,CAST('m' as char(1))
- ,CAST(1 as bit))) as SOURCE([InvId],[PaymentStatus],[isPayed])
- ON TARGET.[InvID] = SOURCE.[InvID]
- WHEN MATCHED THEN
- UPDATE SET TARGET.[PaymentStatus] = SOURCE.[PaymentStatus]
- ,TARGET.[isPayed] = SOURCE.[isPayed]
- WHEN NOT MATCHED THEN
- INSERT ([InvId],[PaymentStatus],[isPayed],[file])
- VALUES(
- SOURCE.[InvId]
- ,SOURCE.[PaymentStatus]
- ,SOURCE.[isPayed]
- ,NULL
- );
-
- END
-
-END
\ No newline at end of file
diff --git a/Fuchs_Database/dbo/Stored Procedures/fds__prepInvoice.sql b/Fuchs_Database/dbo/Stored Procedures/fds__prepInvoice.sql
index f53f3a5..7ce1154 100644
--- a/Fuchs_Database/dbo/Stored Procedures/fds__prepInvoice.sql
+++ b/Fuchs_Database/dbo/Stored Procedures/fds__prepInvoice.sql
@@ -209,14 +209,12 @@ BEGIN
itm.*
, [baseorder] = s.[baseorder]
, [order] = ROW_NUMBER() OVER (PARTITION BY itm.[ServiceRequestId] ORDER BY itm.[SortOrder], itm.[Id])
- , [SetItmID] = CASE WHEN itm.[Type] = 'Set' AND ISNULL(itm.[Price], 0) > 0 THEN NULL
- ELSE MAX(CASE WHEN itm.[Type] = 'Set' AND ISNULL(itm.[Price], 0) > 0 THEN itm.[Id] ELSE NULL END)
+ , [SetItmID] = MAX(CASE WHEN itm.[Type] = 'Set' AND ISNULL(itm.[Price], 0) = 0 THEN itm.[Id] ELSE NULL END)
OVER (
PARTITION BY itm.[ServiceRequestId]
ORDER BY itm.[SortOrder], itm.[Id]
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)
- END
FROM [dbo].[mfr__items] as itm
JOIN @SReq as s ON itm.ServiceRequestId = s.[Id]
WHERE itm.[Type] <> 'PartialInvoice';
diff --git a/Fuchs_Database/dbo/Stored Procedures/fds__prepStorno_recreate.sql b/Fuchs_Database/dbo/Stored Procedures/fds__prepStorno_recreate.sql
index 96b8b76..c1a427d 100644
--- a/Fuchs_Database/dbo/Stored Procedures/fds__prepStorno_recreate.sql
+++ b/Fuchs_Database/dbo/Stored Procedures/fds__prepStorno_recreate.sql
@@ -207,14 +207,12 @@ BEGIN
SELECT itm.*
, [baseorder] = s.[baseorder]
, [order] = ROW_NUMBER() OVER (PARTITION BY itm.[ServiceRequestId] ORDER BY itm.[SortOrder], itm.[Id])
- , [SetItmID] = CASE WHEN itm.[Type] = 'Set' AND ISNULL(itm.[Price], 0) > 0 THEN NULL
- ELSE MAX(CASE WHEN itm.[Type] = 'Set' AND ISNULL(itm.[Price], 0) > 0 THEN itm.[Id] ELSE NULL END)
+ , [SetItmID] = MAX(CASE WHEN itm.[Type] = 'Set' AND ISNULL(itm.[Price], 0) = 0 THEN itm.[Id] ELSE NULL END)
OVER (
PARTITION BY itm.[ServiceRequestId]
ORDER BY itm.[SortOrder], itm.[Id]
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)
- END
FROM [dbo].[mfr__items] as itm
JOIN @SReq as s ON itm.ServiceRequestId = s.[Id];
diff --git a/MFR_RESTClient/MFR_RESTClient.csproj b/MFR_RESTClient/MFR_RESTClient.csproj
index a8258f9..797d81c 100644
--- a/MFR_RESTClient/MFR_RESTClient.csproj
+++ b/MFR_RESTClient/MFR_RESTClient.csproj
@@ -26,21 +26,21 @@
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
-
+
+