#include "Gra.ch"
#include "Xbp.ch"
#include "Appevent.ch"
#include "Appedit.ch"
#include "Appbrow.ch"
#include "Font.ch"
#include "fileio.ch"
PROCEDURE Rechdruni( cAuf, edrucker, zdate, textjn, anz, lAbr, oDlg1 )
// universelles Rechnungsdruckprogramm fr KSO
LOCAL nOldArea := Select(), nRec := RecNo() //+11.10.2018 14:24
LOCAL aLeist1 := {}, aLeist2 := {}, aLeist3 := {}, aLeistA := {} //01.05.2008 16:02 aLeistA
LOCAL nL1Sum := 0, nL2Sum := 0, nL3Sum := 0, nLASum := 0
LOCAL n4 := 4 , n5 := 5, nL12 := 0
LOCAL sbetr, grsu, smwsta, smwstb, zae
PRIVATE aBlatt := {}, aBlattZ := {}, cAnz, cdate, ctextjn
PRIVATE cSeite, cNa, cPrompt, cText, nTFont, cBereich, cFeld, nFFont, nZei, nSpa
PRIVATE aSeite := {}, aNa := {}, aPrompt := {}, aText := {}, aTFont := {}
PRIVATE aBereich := {}, aFeld := {}, aFFont := {}, aZei := {}, aSpa := {}
CRLF := Chr(13)+Chr(10) //09.12.2025 17:54
/*21.05.2008 18:25 */
IF xdmeu="D" /* DM darf nicht mehr gebraucht werden fr neue F„lle!! */
RETURN
ENDIF
/**/
RechnungZeilenKorrektur(cAuf) //+21.10.2018 19:21 (falls auftrnr oder Zeilennr darin fehlt
//================================================================================================
//04.01.2026 19:10 die Dateien der Rechnung (.html + .odt + .pdf + .zug.xml + zug.pdf) ...
// ... werden in diesem Verzeichnis archiviert:
PRIVATE cRechDir := cDatver + "Scans\Dokumente\" + StrZero(1->auftrnr,6,0) + "\_Rechnung\"
IF FExists(cRechDir+"R"+StrZero(1->auftrnr,6,0)+".xml") .OR. ;
FExists(cRechDir+"R"+StrZero(1->auftrnr,6,0)+"_zug.xml")
msgbox("Es ist bereits eine Rechnung fr diesen Fall"+CR+LF+StrZero(1->auftrnr,6,0)+" gedruckt worden!")
IF !AppKeyState(65553)==1 // wenn nicht die Strg-Taste gedrckt
RETURN
ENDIF
ENDIF
// Verzeichnis erzeugen (wenn noch nicht geschehen):
IF !FExists( Left(cRechDir,Len(cRechDir)-1),"D" )
RunShell( "/C MD "+cRechDir,, .T. )
sleep(200)
ELSEIF FExists(cRechDir+"R"+StrZero(1->auftrnr,6,0)+".odt")
nHandle := FOpen( cRechDir+"R"+StrZero(1->auftrnr,6,0)+".odt", FO_EXCLUSIVE )
IF nHandle = -1
//+ Die Datei ist bereits auf diesem PC ge”ffnet
FClose(nHandle)
msgbox("Es ist bereits eine Datei R"+StrZero(1->auftrnr,6,0)+".odt offen!"+CRLF+;
"Bitte im OfficeWriter schlieáen, dann nochmal versuchen!")
RETURN
ELSE
FClose(nHandle)
ENDIF
ELSEIF FExists(cRechDir+"R"+StrZero(1->auftrnr,6,0)+".html")
nHandle := FOpen( cRechDir+"R"+StrZero(1->auftrnr,6,0)+".html", FO_EXCLUSIVE )
IF nHandle = -1
//+ Die Datei ist bereits auf diesem PC ge”ffnet
FClose(nHandle)
msgbox("Es ist bereits eine Datei R"+StrZero(1->auftrnr,6,0)+".html offen!"+CRLF+;
"Bitte im OfficeWriter schlieáen, dann nochmal versuchen!")
RETURN
ELSE
FClose(nHandle)
ENDIF
ENDIF
//================================================================================================
// fr alle F„lle:
ASize( aLeist1, 0 ); ASize( aLeist2, 0 ); ASize( aLeist3, 0 ); ASize( aLeistA, 0 )
nAnz := IIf(ValType(anz)=="C",Val(anz),anz) //+22.10.2018 12:26
nArea := 13 // weil oDlg1 fr den Ausdruck ohnehin von Typ 'L' ist, damit es in 'auf3AUFTRNR.dbf' sucht
SELECT &nArea
GO TOP
DbSuspendNotifications() //05.03.2008 13:06
IF Upper(anz)$"ZCXU"
// Variablen mit Daten dieses Auftrags fllen:
IF Upper(anz) $ "ZC" // CII
cDash := ""
ELSEIF Upper(anz) $ "XU" // UBL
cDash := "-"
ENDIF
zdate := DtoC(DATE()) // muss ggf noch geREMt werden !?!
// ab hier werden das lauter neue PRIVATE-Variablen:
cRechnr := "R"+StrZero(1->auftrnr,6,0) // provisorisch erstmal fr "WP"
cJJJJMMTT := SubStr(zdate,7,4)+cDash+SubStr(zdate,4,2)+cDash+SubStr(zdate,1,2)
cJJJJMMTT_Lief := SubStr(zdate,7,4)+cDash+SubStr(zdate,4,2)+cDash+SubStr(zdate,1,2)
ydate := DtoC(CtoD(zdate)+10)
cJJJJMMTT_Zahl := SubStr(ydate,7,4)+cDash+SubStr(ydate,4,2)+cDash+SubStr(ydate,1,2)
cRevCharge := Wandeln_in_UTF8("RC-Text")
cVatProz := "19.00"
nTotalNetto4 := 0.0000
cSumMwSt := 0.0000
nSumNettoV4 := 0.00
nSumNettoH4 := 0.00
nTotalNetto4 := 0.00
nSumMwStV4 := 0.00
nSumMwStH4 := 0.00
nTotalMwSt4 := 0.00
nTotalBrutto4 := 0.00
cVATvoll := "19.00"
cVAThalb := "7.00"
cSumNettoV := ""
cSumNettoH := ""
cTotalNetto := ""
cSumMwStV := ""
cSumMwStH := ""
cTotalMwSt := ""
cTotalBrutto := ""
cAuftrag := StrZero(1->auftrnr,6,0)
cKdnr := "A" + cAuftrag
cLief := "Schumacher"
cLieferant := "Beerdigungsinstitut Karl Schumacher e.K."
cHRBnr := "HRA 8177" // "hrb"
cMA_Lief := 1->berater
cTel_Lief := "0208 69 04 80"
cMail_Lief := "zentrale@karl-schumacher.de"
cPLZ_Lief := "46117"
cStr_Lief := Wandeln_in_UTF8("Vestische Straáe 146")
cOrt_Lief := Wandeln_in_UTF8("Oberhausen")
cLand_Lief := "DE"
cVAT_Lief := "DE120633201"
cKunde := Wandeln_in_UTF8(Trim(1->ansp_name))
cMA_Kunde := cKunde // vorl„ufig
cMail_Kunde := IIf("@"$1->ansp_ktoi,Trim(1->ansp_ktoi),"eine.leere@mail.ee")
cMail_MA_Kunde := Wandeln_in_UTF8(cMail_Kunde) // vorl„ufig
cPLZ_Kunde := SubStr (1->ansp_ort,1,5)
cStr_Kunde := Wandeln_in_UTF8(Trim(1->ansp_str))
cOrt_Kunde := Wandeln_in_UTF8(ORTohnePLZ(1->ansp_ort))
cLand_Kunde := "DE" // vorl„ufig
cVAT_Kunde := "DE123456789" // vorl„ufig
cKontoNameLief := "Beerdigungsinstitut Karl Schumacher e.K."
cIBAN_Lief := "DE43350603864400670204"
cBIC_Lief := "GENODED1VRR"
cZahlungsbedingungen := "zahlbar innerhalb 8 Tagen"
// schon mal fr die Rechnungszeilen:
cMenge := "1.0000"
cXml3 := ''
ENDIF
//07.12.2025 10:21 XML-Erzeugung: KOPF vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
IF Upper(anz) $ "ZC" // = CII fr ZUGFeRD
cXML1 := '' + CRLF + ;
'
'+CRLF+;
'', ;
''+CRLF+;
'' )
nRTxtLen = Len(MemoRead(cRechDir + "R"+StrZero(1->auftrnr,6,0)+".rdr")) //geht das anders? nur die Filel„nge?
nHandle := FOpen( cRechDir + "R"+StrZero(1->auftrnr,6,0)+".rdr", FO_READ )
cBuffer := Space(nRTxtLen)
nBytes := FRead( nHandle, @cBuffer, nRTxtLen ) // liest die .rdr in die Variable cBuffer
cHtmlRech += AllTrim(cBuffer) // schiebt die .rdr aus cBuffer in die .html
FClose( nHandle ) // schlieát die .rdr (wird unten nochmal beschrieben)
cHtmlRech += CRLF + '
'
cFilehtml := cRechDir + "R"+StrZero(1->auftrnr,6,0)+".html"
nHandle := FCreate(cFilehtml)
// FWrite(nHandle,Wandeln_in_UTF8(cHtmlRech)) // schreibt die .html
FWrite(nHandle,cHtmlRech) // .rdr ist schon UTF8 ! // schreibt die .html
FClose(nHandle)
//11.03.2026 19:03:
cFileodt := cRechDir + "R"+StrZero(1->auftrnr,6,0)+".odt"
COPY FILE (cDatver+"F\ODT\KSOXbb.odt") TO (cFileodt) // leere Rechnungsdatei mit Briefkopf
sleep(200)
cCommand := ' &cFileodt macro:///Standard.Module1.xRechodtPDF '
RunShell (' &cFileodt macro:///Standard.Module1.xRechodtPDF ', 'C:\Program Files\LibreOffice\program\swriter.exe') //,.T.) .T.=async !!
// ohne .T. wird KSOX.exe hier so lange angehalten bis RunShell() komplett fertig ist. (sollte jedenfalls...)
// w„hrend RunShell(MAKRO) wird .odt angezeigt und zu .pdf verwandelt (ggf. zu ZUGFeRD-PDF)
// die mit obigem RunShell() erzeugten .pdf werden hier mit AdobeReader angezeigt:
IF Upper(anz)$"ZX" //10.03.2026 20:57
IF Upper(anz)$"Z"
cFilepdf := Stuff(cFilehtml,At(".HTML",Upper(cFilehtml)),5,"_zug.pdf")
ELSE
cFilepdf := Stuff(cFilehtml,At(".HTML",Upper(cFilehtml)),5,".pdf")
ENDIF
IF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe') //64bit Reader
RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.)
ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe') //32bit Reader
RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.)
ENDIF
ELSEIF Upper(anz)$"CU"
IF Upper(anz)$"C"
cFilexml := Stuff(cFilehtml,At(".HTML",Upper(cFilehtml)),5,"_zug.xml")
ELSE
cFilexml := Stuff(cFilehtml,At(".HTML",Upper(cFilehtml)),5,".xml")
ENDIF
IF FExists("C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe")
RunShell("&cFilexml","C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe",.T.)
ENDIF
ENDIF
RunShell ("&cRechDir","explorer.exe",.T.) // ”ffnet das Archiv-Verzeichnis dieses Falles
ELSEIF Upper(anz)$"WP" // auf Writer ohne ("W") und mit ("P") Briefkopf
//24.12.2025 15:47 Die Rechnung als HTML-Datei abspeichern: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// und dann erst als ODT ausdrucken
cRechKopf := cDatver + "KSOX_BB.png"
cHtmlRech := '' + CRLF + ;
'' + CRLF + ;
'' + CRLF + ;
' ' + CRLF + ;
' '+CRLF+;
'', ;
''+CRLF+;
'' )
// '' + CRLF + ;
// ''
nRTxtLen = Len(MemoRead(cRechDir + "R"+StrZero(1->auftrnr,6,0)+".rdr")) //geht das anders? nur die Filel„nge?
nHandle := FOpen( cRechDir + "R"+StrZero(1->auftrnr,6,0)+".rdr", FO_READ )
cBuffer := Space(nRTxtLen)
nBytes := FRead( nHandle, @cBuffer, nRTxtLen )
cHtmlRech += AllTrim(cBuffer)
FClose( nHandle )
cHtmlRech += CRLF + '
'
cFilehtml := cRechDir + "R"+StrZero(1->auftrnr,6,0)+".html"
nHandle := FCreate(cFilehtml)
FWrite(nHandle,Wandeln_in_UTF8(cHtmlRech))
FClose(nHandle)
// cAuftrag := StrZero(1->auftrnr,6,0)
cFileodt := cRechDir + "R"+StrZero(1->auftrnr,6,0)+".odt"
IF Upper(anz)$"W" // Druck ohne Briefkopf
COPY FILE (cDatver+"F\ODT\KSOXleer.odt") TO (cFileodt) // leere Rechnungsdatei ohne Briefkopf 08.08.2026 12:50 cDatver
ELSEIF Upper(anz)$"P" // Druck mit Briefkopf
COPY FILE (cDatver+"F\ODT\KSOXbb.odt") TO (cFileodt) // leere Rechnungsdatei mit Briefkopf 08.08.2026 12:50 cDatver
ENDIF
cCommand := ' &cFileodt macro:///Standard.Module1.xRechODT '
RunShell (' &cFileodt macro:///Standard.Module1.xRechODT ', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
ENDIF
select 1
IF &r_b_1 <> aLeist1[nL1+1] .AND. nAnzahl > 0
satzsperren()
// damit die erg„nzten BestFallDaten auch bertragen werden k”nnen
aData1 := SatzGet( Select(), RecNo() )
//
IF xdmeu="D" /* DM darf nicht mehr gebraucht werden fr neue F„lle!! */
ELSE
repl &r_b_1 with aLeist1[nL1+1]
ENDIF
// damit die erg„nzten BestFallDaten auch bertragen werden
trckng( Select(), RecNo(), aData1 )
//
satzentsperren()
ENDIF
IF &r_b_2 <> aLeist2[nL2+1] .AND. nAnzahl > 0
satzsperren()
// damit die erg„nzten BestFallDaten auch bertragen werden k”nnen
aData1 := SatzGet( Select(), RecNo() )
//
IF xdmeu="D" /* DM darf nicht mehr gebraucht werden fr neue F„lle!! */
ELSE
repl &r_b_2 with aLeist2[nL2+1]
ENDIF
// damit die erg„nzten BestFallDaten auch bertragen werden
trckng( Select(), RecNo(), aData1 )
//
satzentsperren()
ENDIF
/*04.05.2008 22:11 wird (noch) nicht in best.dbf abgespeichert */
/*21.05.2008 18:17 ab jetzt werden die Hintergrundw„hrungsfelder fr Leistung III und Fremdleistung verwendet */
IF nAnzahl > 0
satzsperren()
// damit die erg„nzten BestFallDaten auch bertragen werden k”nnen
aData1 := SatzGet( Select(), RecNo() )
//
IF xdmeu="D" /* DM darf nicht mehr gebraucht werden fr neue F„lle!! */
ELSE
//06.03.2026 16:50 aLeistA ist obsolet! repl &r_b_1h with aLeistA[nLA+1]
repl rech_dat WITH CtoD(zdate) //+16.07.2008 21:08 zdate ist "C"
ENDIF
// damit die erg„nzten BestFallDaten auch bertragen werden
trckng( Select(), RecNo(), aData1 )
//
satzentsperren()
ENDIF
/**/
IF nArea == 13 //+30.10.2018 12:53 nur wenn normaler Rechnungsdruck mit BregieR3L
// Anfang Schreiben der Auftrag-Backup-Datei
SELECT 9
USE AUFTR_B
SELECT &nArea
DbGotop() //05.03.2008 13:09
DbSuspendNotifications()
INDEX ON Str(auftrnr,6,0)+rn+kennz+zeile TO C:\HDBE\xtemp
nZeile := 0
FOR nt := 0 TO 2 STEP 2
SELECT &nArea
IF .NOT. Bof()
GO TOP
ENDIF
DO WHILE .NOT. Eof()
IF Val( (nArea)->rn ) <> nt .OR. (nArea)->auftrnr != 1->auftrnr
SKIP
LOOP
ENDIF
++nZeile
FOR n := 1 to FCount()
aData2[n] := FieldGet( n )
NEXT
SELECT 9
APPEND BLANK
FOR n := 1 to FCount()
FieldPut( n, aData2[n] )
NEXT
REPLACE 9->zeile WITH Str( nZeile,2,0 )
DbRUnlock( Recno() )
SELECT &nArea
SKIP
ENDDO
NEXT
/*01.05.2008 16:19 fr LeistungIII */
GO TOP
DO WHILE .NOT. Eof()
IF (nArea)->rn != "A" .OR. (nArea)->auftrnr != 1->auftrnr
SKIP
LOOP
ENDIF
++nZeile
For n := 1 to FCount()
aData2[n] := FieldGet( n )
NEXT
SELECT 9
APPEND BLANK
For n := 1 to FCount()
FieldPut( n, aData2[n] )
NEXT
REPLACE 9->zeile WITH Str( nZeile,2,0 )
DbRUnlock( Recno() )
SELECT &nArea
SKIP
ENDDO
SELECT 9
USE
SELECT &nArea
SET INDEX TO
DbGotop() //05.03.2008 13:10
DbResumeNotifications()
// Ende Schreiben der Auftrag-Backup-Datei
ENDIF
SELECT &nOldArea
DbGoto(nRec) //+11.10.2018 14:25
RETURN
FUNCTION Leistdruck( aLeist, n, zae, nS, cRArt ) //04.01.2026 14:57 nS + 26.02.2026 15:14 cRArt
LOCAL mproz := zschl_voll //26.02.2026 15:14
IF zae > 0 //04.05.2008 17:11 s.u.
IF n == 4
// FOR i := 5 to ( nLL + 1 ) STEP 5 // die zweite Zeile der Bezeichnung
FOR i := n to ( nLL + 1 ) STEP n
// @ ++zae,10 say aLeist[i-4]
// IF Len(Trim(aLeist[i-3])) > 0
@ ++zae,10-nS say aLeist[i-3]
// ENDIF
@ zae,57-nS say w_g
IF cRArt$"ZCXU" //26.02.2026 15:48 CII und UBL sind immer mit Nettobetr„gen in den Zeilen
IF aLeist[i-1] == "2"
@ zae,60-nS say str( aLeist[i-2]/(100+zschl_halb)*100,8,2 ) + " *"
aLeist[nLL+2]=aLeist[nLL+2] + aLeist[i-2]/(100+zschl_halb)*100
ELSE // == "3" alle anderen sind per Definition "3"
@ zae,60-nS say str( aLeist[i-2]/(100+zschl_voll)*100,8,2 )
aLeist[nLL+1]=aLeist[nLL+1] + aLeist[i-2]/(100+zschl_voll)*100
ENDIF
ELSE
@ zae,60-nS say str( aLeist[i-2],8,2 )
aLeist[nLL+1]=aLeist[nLL+1] + aLeist[i-2]
aLeist[nLL+2]=aLeist[nLL+2] + aLeist[i-2]
ENDIF
IF aLeist[i-1]="2"
aLeist[nLL+4]=aLeist[nLL+4] + (aLeist[i-2] / (100+zschl_halb) * zschl_halb)
// endif
// if aLeist[i-1]="3"
ELSE
aLeist[nLL+3]=aLeist[nLL+3] + (aLeist[i-2] / (100+zschl_voll) * zschl_voll)
ENDIF
NEXT
ELSE
AAdd( aLeist, 0, nLL+5 )
FOR i := n to ( nLL + 1 ) STEP n
@ ++zae,5 say "Rechnung-"+Substr(aLeist[i-4],1,34)+"-"+aLeist[i-3]
@ zae,64 say w_g
@ zae,67 say str( aLeist[i-2],8,2 )
aLeist[nLL+1]=aLeist[nLL+1] + aLeist[i-2]
aLeist[nLL+2]=aLeist[nLL+2] + aLeist[i-2]
if aLeist[i-1]="3"
aLeist[nLL+3]=aLeist[nLL+3] + (aLeist[i-2] / (100+zschl_voll) * zschl_voll)
endif
if aLeist[i-1]="2"
aLeist[nLL+4]=aLeist[nLL+4] + (aLeist[i-2] / (100+zschl_halb) * zschl_halb)
endif
NEXT
ENDIF
ELSEIF zae == 0 //04.05.2008 17:10 rechnet in Aufstellung die Vorfinanzierungskosten aus:
FOR i := n to ( nLL + 1 ) STEP n
aLeist[nLL+1]=aLeist[nLL+1] + aLeist[i-2]
aLeist[nLL+2]=aLeist[nLL+2] + aLeist[i-2]
NEXT
ENDIF
RETURN aLeist
FUNCTION Leistdruck_ZCWXUP( aLeist, n, zae, nS, cRArt, cTextRef ) //04.01.2026 14:57 nS + 26.02.2026 15:14 cRArt
LOCAL mproz := zschl_voll //26.02.2026 15:14
FOR i := n to ( nLL + 1 ) STEP n
cTextRef += CRLF + Space(10-nS) + aLeist[i-3]
nLang := Len(Space(10-nS) + aLeist[i-3])
cTextRef += Space(57-nS-nLang) + w_g
IF cRArt$"ZCXU" //26.02.2026 15:48 CII und UBL sind immer mit Nettobetr„gen in den Zeilen
IF aLeist[i-1] == "2"
cTextRef += Space(0) + Str( aLeist[i-2]/(100+zschl_halb)*100,8,2 ) + " *"
aLeist[nLL+2]=aLeist[nLL+2] + aLeist[i-2]/(100+zschl_halb)*100
ELSE // == "3" alle anderen sind per Definition "3"
cTextRef += Space(0) + Str( aLeist[i-2]/(100+zschl_voll)*100,8,2 )
aLeist[nLL+1]=aLeist[nLL+1] + aLeist[i-2]/(100+zschl_voll)*100
ENDIF
ELSE
cTextRef += Space(0) + Str( aLeist[i-2],8,2 )
aLeist[nLL+1]=aLeist[nLL+1] + aLeist[i-2]
aLeist[nLL+2]=aLeist[nLL+2] + aLeist[i-2]
ENDIF
IF aLeist[i-1]="2"
aLeist[nLL+4]=aLeist[nLL+4] + (aLeist[i-2] / (100+zschl_halb) * zschl_halb)
ELSE
aLeist[nLL+3]=aLeist[nLL+3] + (aLeist[i-2] / (100+zschl_voll) * zschl_voll)
ENDIF
NEXT
RETURN aLeist
FUNCTION BSEingabe( aBlatt, oDlg1 )
LOCAL oDlg, nEvent, mp1, mp2
LOCAL aSizeDesktop := AppDesktop():currentSize()
LOCAL nBSb := aSizeDesktop[1]
LOCAL nBSh := aSizeDesktop[2]
// folgende Zahlen-Werte basieren auf 800x600:
LOCAL nV := nBSb/800 // Korrekturfaktor fr tats„chliche Aufl”sung
LOCAL nOldArea := Select()
LOCAL aEditcontrols := {}
// LOCAL oFocus := SetAppFocus()
LOCAL aSeite := {}, aNa := {}, aPrompt := {}, aText := {}, aTFont := {}
LOCAL aBereich := {}, aFeld := {}, aFFont := {}, aZei := {}, aSpa := {}
PRIVATE oWin := oDlg1
cFont := IIf( nBSb < 700, "7.Arial", "8.Arial" )
oDlg := XbpDialog():new( AppDeskTop(), oDlg1 )
oDlg:tasklist := .T.
oDlg:title := "Felder korrigieren/eingeben"
oDlg:maxButton := .F.
oDlg:clipSiblings := .T.
oDlg:border := XBPDLG_RAISEDBORDERTHIN_FIXED
oDlg:create(,, {10,10}, {int(740*nV),int(460*nV)} )
oDlg:drawingArea:setFontCompoundName( "8.Arial" )
oDlg:drawingArea:setColorBG( GRA_CLR_DARKGREEN )
oCB := oDlg:drawingArea
oCB:clipSiblings := .T.
nBo := int(430*nV)
nBr := 0
j := 0
FOR i := 1 to Len( aBlatt )
aBlattZ := aBlatt[i]
AAdd( aSeite, aBlattZ[1] )
AAdd( aNa, aBlattZ[2] )
AAdd( aPrompt, aBlattZ[3] )
AAdd( aText, aBlattZ[4] )
AAdd( aTFont, aBlattZ[5] )
AAdd( aBereich, aBlattZ[6] )
AAdd( aFeld, aBlattZ[7] ) // Feldbezeichnung
AAdd( aFFont, aBlattZ[8] )
AAdd( aZei, aBlattZ[9] )
AAdd( aSpa, aBlattZ[10] )
// fr die Positionierung im Editierfenster:
nBr := IIf( i<>1 .AND. (aSeite[i]="n" .OR. nBo-Int(j*25*nV) < Int(30*nV)), ;
(nBr+Int(370*nV)), nBr )
j := IIf( nBo-Int(j*25*nV) < Int(30*nV) .OR. aSeite[i]="n", 0, j )
IF Upper( aSeite[i] ) = "R" .OR. Upper( aSeite[i] ) = "V"
// keine Žnderungen, wenn es sich um "Rechnungszeilen" handelt
AAdd( aEditcontrols, aFeld[i] )
ELSE
IF aNa[i] = "t" // Text ist zu ver„ndern
// aText[i] := aText[i]+Space(70-len(aText[i]))
oXbp := XbpStatic():new( oDlg:drawingArea, , {nBr+int(30*nV),nBo-int(++j*25*nV)}, {int(100*nV),int(25*nV)})
oXbp:caption := aPrompt[i]
oXbp:clipSiblings := .T.
oXbp:options := XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT
oXbp:create()
oSle := XbpSLE():new( oDlg:drawingArea, , {nBr+int(140*nV),nBo-int(j*25*nV)}, {int(200*nV),int(25*nV)}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
oSle:bufferLength := 70
oSle:setInputFocus := {|mp1,mp2,obj| HiliteSle( obj ) }
oSle:killInputFocus := {|mp1,mp2,obj| DeHiliteSle( obj ) }
oSle:group := XBP_WITHIN_GROUP
oSle:dataLink := {|x| IIf( PCOUNT()==0, Trim( aText[i] ), aText[i] := x ) }
oSle:create():setData()
AAdd( aEditcontrols, oSle )
// IF ASC( aFeld[i] ) > 32
cB := aBereich[i] ; cF := aFeld[i]
IF !Empty( cF ) .AND. Val( cB ) > 0
aFeld[i] := ((&cB)->(&cF)) //Feldinhalt
ENDIF
ELSEIF aNa[i] = "f" // Feldinhalt soll editiert werden
cB := aBereich[i] ; cF := aFeld[i]
xF := ( (&cB)->(&cF) ) //Feldinhalt
DO CASE
CASE Valtype( xF ) == "C"
aFeld[i] := xF
CASE ValType( xF ) == "N"
aFeld[i] := Str( xF )
CASE ValType( xF ) == "D"
aFeld[i] := DtoC( xF )
ENDCASE
oXbp := XbpStatic():new( oDlg:drawingArea, , {nBr+int(30*nV),nBo-int(++j*25*nV)}, {int(100*nV),int(25*nV)})
oXbp:caption := aPrompt[i]
oXbp:clipSiblings := .T.
oXbp:options := XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT
oXbp:create()
oSle := XbpSLE():new( oDlg:drawingArea, , {nBr+int(140*nV),nBo-int(j*25*nV)}, {int(200*nV),int(25*nV)}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
oSle:bufferLength := 50
oSle:setInputFocus := {|mp1,mp2,obj| HiliteSle( obj ) }
oSle:killInputFocus := {|mp1,mp2,obj| DeHiliteSle( obj ) }
oSle:group := XBP_WITHIN_GROUP
oSle:dataLink := {|x| IIf( PCOUNT()==0, Trim( aFeld[i] ), aFeld[i] := x ) }
oSle:create():setData()
AAdd( aEditcontrols, oSle )
aText[i] := ""
ELSEIF aNa[i] = "v" .AND. aBereich[i] = "v" // Variable soll editiert werden
cF := aFeld[i]
xF := &(cF) //Variableninhalt
DO CASE
CASE Valtype( xF ) == "C"
aFeld[i] := xF
CASE ValType( xF ) == "N"
aFeld[i] := Str( xF )
CASE ValType( xF ) == "D"
aFeld[i] := DtoC( xF )
ENDCASE
oXbp := XbpStatic():new( oDlg:drawingArea, , {nBr+int(30*nV),nBo-int(++j*25*nV)}, {int(100*nV),int(25*nV)})
oXbp:caption := aPrompt[i]
oXbp:clipSiblings := .T.
oXbp:options := XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT
oXbp:create()
oSle := XbpSLE():new( oDlg:drawingArea, , {nBr+int(140*nV),nBo-int(j*25*nV)}, {int(200*nV),int(25*nV)}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
oSle:bufferLength := 50
oSle:setInputFocus := {|mp1,mp2,obj| HiliteSle( obj ) }
oSle:killInputFocus := {|mp1,mp2,obj| DeHiliteSle( obj ) }
oSle:group := XBP_WITHIN_GROUP
oSle:dataLink := {|x| IIf( PCOUNT()==0, Trim( aFeld[i] ), aFeld[i] := x ) }
oSle:create():setData()
AAdd( aEditcontrols, oSle )
ELSEIF aNa[i] <> "v" .AND. aBereich[i] = "v" // im aFeld steht Mem-Variable
cF := aFeld[i]
aFeld[i] := "&(" + cF + ")"
AAdd( aEditcontrols, aFeld[i] )
ELSE
IF ASC( aFeld[i] ) > 32
cB := aBereich[i] ; cF := aFeld[i]
aFeld[i] := ((&cB)->(&cF)) //Feldinhalt
ENDIF
AAdd( aEditcontrols, aFeld[i] )
ENDIF
IF ValType(cF)="C"
IF Upper(cF) = "FAM" .OR. Upper(cF) = "KONF"
aFeld[i] := Kurzlang( aFeld[i] )
ENDIF
ENDIF
ENDIF
NEXT
i=1
oDlg:setModalState( XBP_DISP_APPMODAL )
oDlg:show()
IF Len( aEditcontrols ) > 0 .AND. ValType( aEditControls[1] ) = "O"
oFocus := SetAppFocus( aEditcontrols[1] )
ELSE
oFocus := SetAppFocus( oDlg )
ENDIF
DO WHILE nEvent <> xbeP_Close
nEvent := AppEvent( @mp1, @mp2, @oXbp )
IF nEvent == xbeM_LbDblClick
PostAppEvent( xbeP_Close)
ENDIF
IF nEvent == xbeP_Keyboard
DO CASE
CASE mp1 == xbeK_ESC
lFluchtB := .T. //+21.10.2018 18:41 ESC bricht jetzt das Drucken ab
PostAppEvent( xbeP_Close)
CASE mp1 == xbeK_F10
PostAppEvent( xbeP_Close)
ENDCASE
ENDIF
oXbp:handleEvent( nEvent, mp1, mp2 )
ENDDO
IF lFluchtB == .F. //+21.10.2018 18:42 zum Abbrechen des Drucks
// wie Gather( aEditcontrols ) :
FOR i := 1 TO len( aEditcontrols )
IF ValType( aEditcontrols[i] ) == "O"
IF aNa[i] == "t"
aText[i] := aEditcontrols[i]:getdata()
ELSE
aFeld[i] := aEditcontrols[i]:getdata()
ENDIF
ENDIF
NEXT
FOR i=1 to len(aBlatt)
aBlattZ := { aSeite[i], aNa[i], aPrompt[i], Trim(aText[i]), aTFont[i], aBereich[i], ;
IIf( ValType(aFeld[i])="C", Trim(aFeld[i]), aFeld[i]), ;
aFFont[i], aZei[i], aSpa[i] }
aBlatt[i] := aBlattZ
NEXT
ELSE
aBlatt := .F.
ENDIF
oDlg:setModalState( XBP_DISP_MODELESS )
oDlg:destroy()
SetAppFocus( oFocus )
SELECT &nOldArea
RETURN aBlatt
FUNCTION Z1214(a)
DO CASE
CASE cLPT = "LPTA" .and. a = chr(27)+z12p
aFonts := {"12.COURIER NEW Fett"}
a := ""
CASE cLPT = "LPTA" .and. a = chr(27)+z14p
aFonts := {"14.COURIER NEW Fett"}
a := ""
CASE cLPT = "LPTA" .and. a = chr(27)+znorm
aFonts := {"12.COURIER NEW"}
a := ""
CASE cLPT != "LPTA"
aFonts := {}
ENDCASE
//+25.06.2018 19:21 bei HTML-Druck auf Fettdruck schalten: vvvvvvvvvvvvvvv
IF isMemVar("cDruckabr") .AND. "HTML"$cDruckabr
IF "Fett"$aFonts[1]
a := ""
ELSEIF Len(aFonts) = 1
a := ""
ENDIF
ENDIF
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RETURN a
//+21.10.2018 19:22 macht das vor dem Drucken, was sonst erst vor dem Speichern in auftr.dbf gemacht wird:
FUNCTION RechnungZeilenKorrektur(cAuf)
LOCAL nOldArea := SELECT()
LOCAL nZeile := 0, nRec := RecNo()
DbSuspendNotifications()
IF ConfirmBox( oCB, "Soll die Rechnung geprft und korrigiert werden?" + CRLF +;
"(Zeilen ohne Artikelnr oder Artikelbezeichnung l”schen.)", ;
"Abrechnungs-Zeilen Checken", ;
XBPMB_YESNO, ;
XBPMB_QUESTION ) == XBPMB_RET_NO
DbResumeNotifications()
RETURN .F.
ENDIF
SELECT 13
// DELETE ALL FOR 13->auftrnr <> Val( cAuf ) .OR. ( Empty(13->zugr_z_st) .AND. Empty(13->bezeichf1))
//+14.10.2018 13:43 statt der Vorzeile folgende Schleife:
// hier wird die Temp-Datei von leeren und falschen Zeilen befreit (siehe auch BregieR5L.prg) ***
DbGotop()
DO WHILE !Eof()
IF 13->auftrnr <> Val( cAuf ) .AND. ( !Empty(13->zugr_z_st) .AND. !Empty(13->bezeich))
IF ConfirmBox( oCB, "Zeile erg„nzen+behalten=ja - Zeile l”schen=nein", ;
"Zeile "+13->zeile+" hat noch keine Auftragsnummer!", ;
XBPMB_YESNO, ;
XBPMB_QUESTION ) == XBPMB_RET_YES
13->auftrnr := Val(cAuf)
ELSE
DbDelete()
ENDIF
ELSEIF 13->auftrnr == Val( cAuf ) .AND. (Empty(13->zugr_z_st) .OR. Empty(13->bezeich))
IF ConfirmBox( oCB, "Zeile behalten=ja - Zeile l”schen=nein", ;
"Zeile "+13->zeile+": Artikelnr oder -bezeichnung ist leer!", ;
XBPMB_YESNO, ;
XBPMB_QUESTION ) == XBPMB_RET_YES
13->auftrnr := Val(cAuf) // vorsichtshalber ...
ELSE
DbDelete()
ENDIF
ELSEIF 13->auftrnr <> Val( cAuf )
DbDelete() // der Rest: keine/falsche Auftragsnummer und leere Zeilen
ENDIF
DbSkip()
ENDDO
// bis hier geht die neue DELETE-Routine vom 14.10.2018
PACK
IF .NOT. Bof()
GO TOP
ENDIF
DO WHILE .NOT. Eof()
++nZeile
REPLACE 13->zeile WITH Str( nZeile,2,0 )
DbSkip()
ENDDO
DO WHILE Recno() < 20
APPEND BLANK
ENDDO
SELECT &nOldArea
DbCommit()
DbResumeNotifications()
DbGotop()
DbGoto(nRec)
RETURN .T.
FUNCTION Wandeln_in_UTF8(cString)
LOCAL aUml := {"„","”","","á","Ž","™","š"}
LOCAL aUTF8 := {Chr(0xC3)+Chr(0xA4),Chr(0xC3)+Chr(0xB6),Chr(0xC3)+Chr(0xBC),Chr(0xC3)+Chr(0x9F),Chr(0xC3)+Chr(0x84),Chr(0xC3)+Chr(0x96),Chr(0xC3)+Chr(0x9C)}
FOR i:=1 TO Len(cString)
IF (n := AScan(aUml, cString[i])) > 0
cString := Stuff( cString, i, 1, aUTF8[n])
++i
ENDIF
NEXT
RETURN cString
/* >>>>>>>>>>>>>>> Aus dem Makro ExportPDF der LibreOffice ZUGFeRD-L”sung: <<<<<<<<<<<<<<<<<<<<<<<<<<
REM +++ Erstellung des Pfades zum Archivieren der Dateien. Achiv Jahr Monat Dateiname
REM +++ Abspeichern der *.odt-Datei und Erstellen einer *.pdf-Datei, die mit dem entsprechenden Namen versehen ebenfalls abgespeichert wird.
REM +++ Wird aus FillTableCarryOver aufgerufen
//SUB ExportPDF(oNewDoc AS OBJECT, stPrintDir AS STRING, oForm AS OBJECT, stTarget AS STRING, arSources(), boOhnePreis AS BOOLEAN)
// DIM oFrames AS OBJECT, oFrame AS OBJECT, oOldDoc AS OBJECT
// DIM stFile AS STRING, stDate AS STRING, stFilename AS STRING, stYear AS STRING, stMonth AS STRING
// DIM stWriterFile AS STRING, stXRechnungFile AS STRING, stZUGFeRDFile AS STRING, stZUGFeRDPrintDir AS STRING, stPDFSource AS STRING
// DIM stWinEnd AS STRING, stXMLSource AS STRING, stPDFTarget AS STRING, stProgUrl AS STRING
// DIM inMonth as INTEGER, inOpen AS INTEGER, i AS INTEGER
// DIM arg1(), arMonth(), ar()
FUNCTION ExportPDF(oNewDoc AS OBJECT, stPrintDir AS STRING, oForm AS OBJECT, stTarget AS STRING, arSources(), boOhnePreis AS BOOLEAN)
LOCAL oFrames AS OBJECT, oFrame AS OBJECT, oOldDoc AS OBJECT
LOCAL stFile AS STRING, stDate AS STRING, stFilename AS STRING, stYear AS STRING, stMonth AS STRING
LOCAL stWriterFile AS STRING, stXRechnungFile AS STRING, stZUGFeRDFile AS STRING, stZUGFeRDPrintDir AS STRING, stPDFSource AS STRING
LOCAL stWinEnd AS STRING, stXMLSource AS STRING, stPDFTarget AS STRING, stProgUrl AS STRING
LOCAL inMonth as INTEGER, inOpen AS INTEGER, i AS INTEGER
LOCAL arg1(), arMonth(), ar()
stFile = oForm.getString(oForm.findColumn("RechnungsnummerMitZusatz"))
stFile = Join(Split(stFile, "/"),"_")
stDate = oForm.getString(oForm.findColumn("Rechnungsdatum"))
stKunde = Trim(oForm.getString(oForm.findColumn("KuerzelDatei")))
stRechnungsname = Trim(oForm.getString(oForm.findColumn("Rechnungsname")))
stDateiname = Trim(oForm.getString(oForm.findColumn("Dateiname")))
IF stKunde <> "" THEN stKunde = stKunde & "_"
IF stDateiname <> "" THEN
stFilename = Join(Split(stDateiname, "/"),"_")
ELSEIF stRechnungsname <> "" THEN
stFilename = stFile
ELSE
stFilename = stKunde & stFile & "_" & stDate
END IF
REM Bei eingegangenen Rechungen, die weitergeleitet werden, erscheint [WL-]
IF arSources(0) = "viw_Lieferung_Spalten_Aenderung" THEN stFilename = "WL-" & stFilename
IF arSources(0) = "-M" THEN stFilename = stFilename & arSources(1)
stPfad = ArchivPfad(stDate,"",True)
stFile = stPfad & stFilename
stZUGFeRDDefault = ConvertFromUrl(stPfad & "xrechnung.xml")
stWriterFile = stFile & ".odt"
oNewDoc.DocumentProperties.Title = stFilename
stXRechnungFile = stFile & ".xml"
stZUGFeRDFile = stFile & "_zug" & ".xml"
stPrintDir = stFile & ".pdf"
stZUGFeRDPrintDir = stFile & "_zug" & ".pdf"
stPDFSource = ConvertFromUrl(stPrintDir)
stXMLSource = ConvertFromUrl(stZUGFeRDFile)
stPDFTarget = ConvertFromUrl(stZUGFeRDPrintDir)
DIM filterArgs(1) as New com.sun.star.beans.PropertyValue
filterArgs(1).Name = "SelectPdfVersion"
filterArgs(1).Value = 3
DIM arg(1) AS NEW com.sun.star.beans.PropertyValue
arg(0).name = "FilterName"
arg(0).value = "writer_pdf_Export"
arg(1).Name = "FilterData"
arg(1).Value = filterArgs
oNewDoc.storeToURL(stPrintDir, arg())
REM Writer-Datei bleibt offen - erst kontrollieren, ob eine entsprechende Datei bereits offen ist
oFrames = StarDesktop.getFrames()
FOR i = 1 TO oFrames.getCount()
oFrame = oFrames.getByIndex(i-1)
IF InStr(oFrame.Title, stFilename & ".odt") > 0 THEN
inOpen = 1
oOldDoc = oFrame.Controller.Model
END IF
NEXT
IF inOpen = 1 THEN
oOldDoc.close(True)
END IF
oNewDoc.storeAsURL(stWriterFile, arg1())
REM Nur als XRechnung erstellen und per Mail weiterleiten, wenn das Dokument Preise enth„lt.
REM Ansonsten wird das Dokument nur gespeichert.
IF boOhnePreis = False AND boXRErstellen = True THEN
oDatasource = thisDatabaseDocument.CurrentController
oConnection = oDatasource.ActiveConnection()
oSQL_Statement = oConnection.createStatement()
stSql = "SELECT ""Java_Pfad"" FROM ""tbl_Firma"""
oResult = oSQL_Statement.executeQuery(stSql)
WHILE oResult.Next
stProgUrl = oResult.getString(1)
WEND
IF stProgUrl = "" THEN
stProgUrl = "java"
IF GetGuiType = 1 THEN stProgUrl = stProgUrl & ".exe"' Windows
END IF
stApp = ConvertFromUrl(StartPfad & "MustangZug.jar") 'Datei Mustang-CLI-2.20.0.jar einfach umbenannt, damit bei einem Tausch der Code nicht ge„ndert werden muss. Geht auch mit Link.
IF stTarget = "ZUGFeRD" THEN
SaveZUGFeRD(oForm,stZUGFeRDFile,arSources())
IF FileExists(stPDFTarget) THEN kill(stPDFTarget) 'šberschreiben geht sonst nicht mit Mustang
stCommand = stProgUrl & " -jar """ & stApp & """ --action combine --source """ & stPDFSource & """ --source-xml """ & stXMLSource &_
""" --format zf --version 2 --profile X --out """ & stPDFTarget & """ --no-additional-attachments"
Shell( stCommand, 1, "", true )
ELSE
SaveXRechnung(oForm,stXRechnungFile,arSources())
END IF
IF FileExists(StartPfad & "MustangZug.jar") THEN
stMsg = "?? Soll die angezeigte Rechnung zus„tzlich validiert werden? ??" & CHR(13) & "Die Validierung kann ca. eine Minute in Anspruch nehmen."
inMsg = MsgBox (stMsg, 292, "Validieren") '"Nein" (2. Button) ist der Defaulteintrag
IF inMsg = 6 THEN
IF stTarget = "ZUGFeRD" THEN
stValTest = stPDFTarget
REM Im Pfad der Datenbankdatei befindet sich ein Link zu dem Verzeichnis, in dem die Ergebnisdatei gesucht wird. Der Link ist mit "Validation" gekennzeichnet.
stValidate = StartPfad & "Validation/" & stFilename & "_zug_result.pdf"
ELSE
stValTest = ConvertFromUrl(stXRechnungFile)
REM Im Pfad der Datenbankdatei befindet sich ein Link zu dem Verzeichnis, in dem die Ergebnisdatei gesucht wird. Der Link ist mit "Validation" gekennzeichnet.
stValidate = StartPfad & "Validation/" & stFilename & "_result.pdf"
END IF
REM Validierung der erzeugten Datei - bisher nur ber Umwege lauff„hig, da die erzeugte PDF-Datei an der Stelle abgeladen wird, von der aus die Base-Datei ge”ffnet wird.
REM Wird die Base-Datei durch einen direkten Klick auf die Datei selbst ge”ffnet, so erscheint die Validierungsdatei an diesem Ort.
REM Nur in diesem Fall sollte aus Link fr stValidate ® "Validation/" & ¯ entfernt werden.
REM Wird die Base-Datei durch einen Link vom Desktop aus ge”ffnet, so erscheint die Validierungsdatei auf dem Desktop.
REM Wird die Base-Datei ber das Start-Men des Betriebssystems ge”ffnet, so erscheint die Validierungsdatei direkt im eigenen Home-Verzeichnis.
stCommand = stProgUrl & " -jar """ & stApp & """ --action validate --no-notices --source """ & stValTest & """ --log-as-pdf"
Shell( stCommand, 1, "", true )
IF FileExists(stValidate) THEN
REM Nur wenn die Datei existiert soll der Aufruf versucht werden. Ansonsten soll der (falsche) Pfad in einer Fehlermeldung ausgegeben werden.
oShell = createUnoService("com.sun.star.system.SystemShellExecute")
oShell.execute(stValidate,"",0)
ELSE
stValidate = ConvertFromUrl(stValidate)
msgbox "Die PDF-Datei mit dem Ergebnis der Validierung konnte nicht gefunden werden." & CHR(13) & "Der angebliche Pfad sollte sein:" & CHR(13) & stValidate
END IF
END IF
END IF
stMsg = "?? Soll die Rechnung an das Mailprogamm weitergeleitet werden? ??" & CHR(13) & "Die Rechnung wird bei der ersten Weiterleitung" & CHR(13) & "mit einem entsprechenden Versanddatum gekennzeichnet."
inMsg = MsgBox (stMsg, 36, "Mail erstellen")
IF inMsg = 6 THEN
StartMail(oForm,stFile,stTarget)
END IF
END IF
END SUB
*/
//ENDE