Include (KZLibrary, KZISSetup) ///

Projekt: KZIS ///

Author : M. Brousek ///

Created: 22.7.2010 ///

Description: Třída BO pro import dokladů ze systému Apothéké prostřednictvím csv souborů. Class KZIS.BO.Apo.ImportVoucherFiles Extends Ens.BusinessOperation [ ProcedureBlock ] { Parameter ADAPTER = "EnsLib.File.OutboundAdapter"; Parameter INVOCATION = "Queue"; /// Oddělovač položek v exportovaných souborech Parameter CSVSeparator = "|"; /// Kótovací znak ohraničující hodnoty položek Parameter CSVQuoteChar; /// Počet položek importovaného záznamu hlavičky dokladu. ///

Používá se pro kontrolu správnosti přenášených dat a pro případ, /// kdy by hodnoty obsahovaly znak separátoru, což by vedlo k chybné interpretaci jednotlivých položek. Parameter VoucherHeaderFieldsCount = 15; /// Počet položek importovaného záznamu položky dokladu. ///

Používá se pro kontrolu správnosti přenášených dat a pro případ, /// kdy by hodnoty obsahovaly znak separátoru, což by vedlo k chybné interpretaci jednotlivých položek. Parameter VoucherItemFieldsCount = 18; /// Transakce, v rámci které byla instance třídy této BO vytvořena Property Transaction As KZIS.Data.TS.MWTransaction; /// Jméno aktuálně zpracovávaného souboru Property CurrentFileName As %String; /// Aktuální počet nastalých chyb Property ErrorCount As %Integer; /// Instace souboru pro logování chybných záznamů Property LogFile As KZIS.MW.LogFile; /// Inicializace importu dokladů Method InitImport() { set ..ErrorCount = 0 set ..LogFile = ##class(KZIS.MW.LogFile).%New() set ..LogFile.Directory = ##class(KZIS.MW.Archiv).GetFullPath($$$ApoArchivDir, ..Transaction.TransactionID) set ..Adapter.FilePath = $$$KZISDataFullPath_$$$ApoIncomingDir } /// Dokončení importu dokladů ///

Provede přesun zpracovaného souboru do archivu. V případě nastalé chyby /// uzavře logovací soubor a vyvolá výjimku, která ukončí příslušný proces. Method DoneImport() { do ..MoveVoucherFilesToArchiv() if (..ErrorCount '= 0) { do ..LogFile.Close() set ..LogFile = "" throw $$$KZISError("Error importing file: "_..CurrentFileName, "Error count: "_..ErrorCount) } } /// Zaznamená nastalou chybu a její popis Method LogDataError(pMessage As %String) { set ..ErrorCount = ..ErrorCount + 1 $$$LOGERROR(pMessage) } /// Přesune aktuálně zpracovávané soubory dokladů do archivu Method MoveVoucherFilesToArchiv() { //Headers set tSourceFileName = ..Adapter.fixPath(..Adapter.FilePath)_$$$ApoVoucherHeadersFileName set tArchivFileName = $$$ArchivFullPath($$$ApoArchivDir, ..Transaction.TransactionID)_$$$ApoVoucherHeadersFileName if ##class(%File).Exists(tArchivFileName) do ##class(%File).Delete(tArchivFileName) set tSC = ##class(%File).Rename(tSourceFileName, tArchivFileName) if 'tSC $$$LOGERROR("Could not move '"_tSourceFileName_"' to KZIS archiv directory") //Items set tSourceFileName = ..Adapter.fixPath(..Adapter.FilePath)_$$$ApoVoucherItemsFileName set tArchivFileName = $$$ArchivFullPath($$$ApoArchivDir, ..Transaction.TransactionID)_$$$ApoVoucherItemsFileName if ##class(%File).Exists(tArchivFileName) do ##class(%File).Delete(tArchivFileName) set tSC = ##class(%File).Rename(tSourceFileName, tArchivFileName) if 'tSC $$$LOGERROR("Could not move '"_tSourceFileName_"' to KZIS archiv directory") } /// Převede řádku souboru hlaviček dokladů do atributů instance odpovídající třídy Method AddVoucherHeaderRec(pLine As %String, ByRef pRec As KZIS.Data.Apo.VoucherHeader) { set Values = $LISTFROMSTRING(pLine, ..#CSVSeparator) //Kontrola na správný počet položek záznamu. //Nalezne také případnou chybu způsobenou tím, že některá hodnota obsahovala znak separátoru if $LISTLENGTH(Values) '= ..#VoucherHeaderFieldsCount { do ..LogDataError("List length: "_$LISTLENGTH(Values)_"; expected length: "_..#VoucherHeaderFieldsCount) do ..LogFile.Update(pLine) q } //Jednotlivé položky seznamu mají dané pořadí¨ set pRec.VoucherNo = $LIST(Values, 1) set pRec.VoucherDate = ##class(%Date).OdbcToLogical($LIST(Values, 2)) set pRec.VoucherKind = $LIST(Values, 3) set pRec.CustomerNo = $LIST(Values, 4) set pRec.PaymentDate = ##class(%Date).OdbcToLogical($LIST(Values, 5)) set pRec.InsurerCode = $LIST(Values, 6) set pRec.CostCenter = $LIST(Values, 7) set pRec.ApoKind = $LIST(Values, 8) set pRec.StockFrom = $LIST(Values, 9) set pRec.StockTo = $LIST(Values, 10) set pRec.FarmisOpKind = $LIST(Values, 11) set pRec.BookingOrder = $LIST(Values, 12) set pRec.Branch = $LIST(Values, 13) set pRec.InvoiceNo = $LIST(Values, 14) set pRec.DeliveryNo = $LIST(Values, 15) } /// Převede řádku souboru položek dokladů do atributů instance odpovídající třídy Method AddVoucherItemRec(pLine As %String) { set Values = $LISTFROMSTRING(pLine, ..#CSVSeparator) //Kontrola na správný počet položek záznamu. //Nalezne také případnou chybu způsobenou tím, že některá hodnota obsahovala znak separátoru if $LISTLENGTH(Values) '= ..#VoucherItemFieldsCount { do ..LogDataError("List length: "_$LISTLENGTH(Values)_"; expected length: "_..#VoucherItemFieldsCount) do ..LogFile.Update(pLine) q } //Jednotlivé položky seznamu mají dané pořadí¨ set tNewRec = ##class(KZIS.Data.Apo.VoucherItem).%New() set tNewRec.ItemID = $LIST(Values, 1) set tNewRec.ItemCode = $LIST(Values, 3) set tNewRec.Amount = $$$NormalizeDS($LIST(Values, 4)) set tNewRec.AmountWithVAT = $$$NormalizeDS($LIST(Values, 5)) set tNewRec.SAmout = $$$NormalizeDS($LIST(Values, 6)) set tNewRec.SAmoutWithVAT = $$$NormalizeDS($LIST(Values, 7)) set tNewRec.VAT = $LIST(Values, 8) set tNewRec.Qtty = $$$NormalizeDS($LIST(Values, 9)) set tNewRec.ItemDescription = $LIST(Values, 10) set tNewRec.Charge = $LIST(Values, 11) set tNewRec.StockCardID = $LIST(Values, 12) set tNewRec.ExpDate = ##class(%Date).OdbcToLogical($LIST(Values, 13)) set tNewRec.ProdDate = ##class(%Date).OdbcToLogical($LIST(Values, 14)) set tNewRec.VZPCode = $LIST(Values, 15) set tNewRec.BookingClass = $LIST(Values, 16) set tNewRec.ItemKind = $LIST(Values, 17) set tNewRec.PackageDsc = $LIST(Values, 18) set tHeader = ##class(KZIS.Data.Apo.VoucherHeader).OpenByNumber($LIST(Values, 2), ..Transaction.%Id()) if tHeader '= "" { set tNewRec.Header = tHeader do tHeader.%Save() } else { do tNewRec.%Save() } } /// Importuje soubor hlaviček dokladů do interní DB Method VoucherHeadersIN() { set ..CurrentFileName = $$$ApoVoucherHeadersFileName set ..LogFile.FileName = ..CurrentFileName $$$LOGINFO("Apo Importing file: "_..Adapter.fixPath(..Adapter.FilePath)_..CurrentFileName) set tSC = ..Adapter.GetStream(..CurrentFileName, .tStream) if $$$ISERR(tSC) { throw $$$KZISError("BO Apo.ImportVoucherFiles VoucherHeadersIN:", "Error reading source file") } while 'tStream.AtEnd { set tLine = tStream.ReadLine() //Create new record instance set tNewRec = ##class(KZIS.Data.Apo.VoucherHeader).%New() set tNewRec.Transaction = ..Transaction try { do ..AddVoucherHeaderRec(tLine, .tNewRec) if (tNewRec.VoucherNo '= "") { set tSC = tNewRec.%Save() if $$$ISERR(tSC) { throw $$$KZISError("BO Apo.ImportVoucherFiles AddVoucherHeaderRec error:", "Error saving new rec: "_##class(%SYSTEM.Status).GetErrorText(tSC)) } } } catch E { do ..LogDataError("BO Apo.ImportVoucherFiles VoucherHeadersIN exception: "_E.Location_"; "_E.Name_" - "_E.Data) do ..LogFile.Update(tLine) } } } /// Importuje soubor položek dokladů do interní DB Method VoucherItemsIN() { set ..CurrentFileName = $$$ApoVoucherItemsFileName set ..LogFile.FileName = ..CurrentFileName $$$LOGINFO("Apo Importing file: "_..Adapter.fixPath(..Adapter.FilePath)_..CurrentFileName) set tSC = ..Adapter.GetStream(..CurrentFileName, .tStream) if $$$ISERR(tSC) { throw $$$KZISError("BO Apo.ImportVoucherFiles VoucherItemsIN:", "Error reading source file") } while 'tStream.AtEnd { set tLine = tStream.ReadLine() try { do ..AddVoucherItemRec(tLine) } catch E { do ..LogDataError("BO Apo.ImportVoucherFiles VoucherItemsIN exception: "_E.Location_"; "_E.Name_" - "_E.Data) do ..LogFile.Update(tLine) } } } /// Výkonná metoda pro import dokladů do interní DB. Method VouchersIN() { do ..VoucherHeadersIN() do ..VoucherItemsIN() } /// Metoda, zpracovávající došlý požadavek. ///

Provádí spuštění příslušné výkonné metody podle kódu druhu transakce. /// V případě, že požadavek obsahuje kód transakce, který neodpovídá transakci importu dokladů Apothékém /// vyvolá metoda výjimku, která ukončí daný proces. /// Viz též třída požadavku KZIS.Msg.MW.BODataRequest. Method ImportCSVFile(pRequest As KZIS.Msg.MW.BODataRequest, Output pResponse As KZIS.Msg.MW.CommonDataResponse) As %Status { $$$LOGINFO("Apo.ImportVoucherFiles: 'Starting operation'") Quit:'$ISOBJECT(pRequest) $$$ERROR($$$GeneralError,"Apo.ImportVoucherFiles: 'Request missing'") Quit:'$ISOBJECT(pRequest.Transaction) $$$ERROR($$$GeneralError,"Apo.ImportVoucherFiles: 'Transaction missing'") TRY { set ..Transaction = pRequest.Transaction do ..InitImport() set pResponse = ##class(KZIS.Msg.MW.CommonDataResponse).%New() set pResponse.Transaction = pRequest.Transaction if pRequest.KindCode = $$$tkcApoSyncVouchers { do ..VouchersIN() } else { throw $$$KZISError("BO Apo.ImportVoucherFiles error:", "Invalid transaction kind code") } do ..DoneImport() $$$LOGINFO("Apo.ImportVoucherFiles '"_pRequest.Transaction.Kind.Description_"' finished") set tSC = $$$OK } CATCH E { $$$LOGERROR("Operation 'Apo.ImportVoucherFiles' error: Exception("_E.Location_": "_E.Name_" - "_E.Data_")") set tSC = $$$ERROR($$$GeneralError) } Quit tSC } /// Metoda pro testování této třídy v testovacím prostředí portálu. Method TestExport(pRequest As Ens.Request, Output pResponse As KZIS.Msg.MW.CommonDataResponse) As %Status { set ..Transaction = pRequest.Transaction set pResponse = ##class(KZIS.Msg.MW.CommonDataResponse).%New() do ..VouchersIN() Quit $$$OK } XData MessageMap { ImportCSVFile TestExport } }