/// <summary> /// run the report /// </summary> private void Run(string ASessionID) { // need to initialize the database session TSession.InitThread(ASessionID); IsolationLevel Level; if (FParameterList.Get("IsolationLevel").ToString().ToLower() == "readuncommitted") { // for long reports, that should not take out locks; // the data does not need to be consistent or will most likely not be changed during the generation of the report Level = IsolationLevel.ReadUncommitted; } else if (FParameterList.Get("IsolationLevel").ToString().ToLower() == "repeatableread") { // for financial reports: it is important to have consistent data; e.g. for totals Level = IsolationLevel.RepeatableRead; } else if (FParameterList.Get("IsolationLevel").ToString().ToLower() == "serializable") { // for creating extracts: we need to write to the database Level = IsolationLevel.Serializable; } else { // default behaviour for normal reports Level = IsolationLevel.ReadCommitted; } FSuccess = false; TDBTransaction Transaction = null; bool SubmissionOK = false; try { DBAccess.GDBAccessObj.BeginAutoTransaction(Level, ref Transaction, ref SubmissionOK, delegate { if (FDatacalculator.GenerateResult(ref FParameterList, ref FResultList, ref FErrorMessage, ref FException)) { FSuccess = true; SubmissionOK = true; } else { TLogging.Log(FErrorMessage); } }); } catch (Exception Exc) { TLogging.Log("Problem calculating report: " + Exc.ToString()); TLogging.Log(Exc.StackTrace, TLoggingType.ToLogfile); FSuccess = false; FErrorMessage = Exc.Message; FException = Exc; } if (TDBExceptionHelper.IsTransactionSerialisationException(FException)) { // do nothing - we want this exception to bubble up } else if (FException is Exception && FException.InnerException is EOPDBException) { EOPDBException DbExc = (EOPDBException)FException.InnerException; if (DbExc.InnerException is Exception) { if (DbExc.InnerException is PostgresException) { PostgresException PgExc = (PostgresException)DbExc.InnerException; if (PgExc.SqlState == "57014") // SQL statement timeout problem { FErrorMessage = Catalog.GetString( "Error - Database took too long to respond. Try different parameters to return fewer results."); } } else { FErrorMessage = DbExc.InnerException.Message; } FException = null; } } TProgressTracker.FinishJob(FProgressID); }
/// <summary> /// todoComment /// </summary> /// <param name="ASender"></param> /// <param name="AEventArgs"></param> public void OnThreadException(object ASender, ThreadExceptionEventArgs AEventArgs) { TUnhandledExceptionForm UEDialogue; string FunctionalityNotImplementedMsg = AppCoreResourcestrings.StrFunctionalityNotAvailableYet; string Reason = String.Empty; Exception TheException = ((Exception)AEventArgs.Exception); // 'Unwrap' the Exception if it is contained inside a TargetInvocationException if ((TheException is TargetInvocationException) && (TheException.InnerException != null)) { TheException = TheException.InnerException; } if (TExceptionHelper.IsExceptionCausedByUnavailableDBConnectionClientSide(TheException)) { TExceptionHelper.ShowExceptionCausedByUnavailableDBConnectionMessage(false); return; } if (TheException is NotImplementedException) { if (TheException.Message != String.Empty) { FunctionalityNotImplementedMsg = TheException.Message; } TLogging.Log(FunctionalityNotImplementedMsg); TLogging.Log(TheException.StackTrace); MessageBox.Show(FunctionalityNotImplementedMsg, AppCoreResourcestrings.StrFunctionalityNotAvailableYetTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (TDBExceptionHelper.IsTransactionSerialisationException(TheException)) { TConcurrentServerTransactions.ShowTransactionSerializationExceptionDialog(); } else if ((TheException is EOPDBException) && ((TheException.InnerException != null) && (TheException.InnerException is EDBAccessLackingCoordinationException))) { TExceptionHandlingCommon.ProcessEDBAccessLackingCoordinationExc((EDBAccessLackingCoordinationException)TheException.InnerException); } else if (TheException is EDBAccessLackingCoordinationException) { TExceptionHandlingCommon.ProcessEDBAccessLackingCoordinationExc((EDBAccessLackingCoordinationException)TheException); } else if (TheException is ECachedDataTableLoadingRetryGotCancelledException) { if (TLogging.DebugLevel >= TLogging.DEBUGLEVEL_COORDINATED_DB_ACCESS) { TLogging.Log(Catalog.GetString( TLogging.LOG_PREFIX_INFO + "The OpenPetra Server was too busy to retrieve the data for a Cacheable DataTable and the user cancelled the loading after the retry attempts were exhausted.")); TLogging.Log(TheException.StackTrace); } TServerBusyHelperGui.ShowLoadingOfDataGotCancelledDialog(); } else if (TheException is ESecurityAccessDeniedException) { if (ProcessSecurityAccessDeniedException != null) { ProcessSecurityAccessDeniedException((ESecurityAccessDeniedException)TheException, ASender.GetType()); } else { MessageBox.Show( "Unhandled Thread Exception Handler: encountered ESecurityAccessDeniedException, but Delegate " + "'ProcessSecurityAccessDeniedException' isn't set up - which is a mistake that needs to be corrected." + Environment.NewLine + "Message of the ProcessSecurityAccessDeniedException instance:" + Environment.NewLine + ProcessSecurityAccessDeniedException.ToString()); } } else if (TheException is System.OutOfMemoryException) { TExceptionHelper.ShowExceptionCausedByOutOfMemoryMessage(false); TLogging.Log(TheException.ToString()); } else if ((TheException is InvalidOperationException) && (Application.OpenForms.Count == 0) && (TheException.Message == "DragDrop registration did not succeed.")) { // This happens during testing because the apartment model is MTA // Do nothing because we do not want to show a dialog } else { // MessageBox.Show( // "TUnhandledThreadExceptionHandler.OnThreadException Unhandled Exception: \r\n\r\n" + TheException.ToString()); ExceptionHandling.LogException(TheException, "Reported by TUnhandledThreadExceptionHandler.OnThreadException"); UEDialogue = new TUnhandledExceptionForm(); UEDialogue.NonRecoverable = false; UEDialogue.TheException = TheException; //Would normally use the code below but cannot due to circular referencing. //Form MainMenuForm = TFormsList.GFormsList.MainMenuForm; if (Application.OpenForms.Count != 0) // in the Main Menu Form Test this will be false... { Form MainMenuForm = Application.OpenForms[0]; // This gets the first ever opened Form, which is the Main Menu // Ensure UEDialogue is shown on the UI Thread! if (MainMenuForm.InvokeRequired) { MainMenuForm.Invoke((MethodInvoker) delegate { UEDialogue.ShowDialog(); }); } else { UEDialogue.ShowDialog(); } } else { UEDialogue.ShowDialog(); } } }
private void AsyncProgressCheckThread() { String OldLoggingText; DateTime startTime; String ErrorMessage = null; Exception ServersideException; OldLoggingText = ""; startTime = DateTime.Now; while (FKeepUpProgressCheck) { TProgressState state = FReportingGenerator.Progress; if (state.JobFinished) { this.Duration = DateTime.Now - startTime; if (FReportingGenerator.GetSuccess() == true) { this.Parameters.LoadFromDataTable(FReportingGenerator.GetParameter()); this.Results.LoadFromDataTable(FReportingGenerator.GetResult()); this.Results.SetMaxDisplayColumns(this.Parameters.Get("MaxDisplayColumns").ToInt()); } else { ErrorMessage = FReportingGenerator.GetErrorMessage(out ServersideException); if (ErrorMessage != null) { if (ErrorMessage != String.Empty) { if (!ErrorMessage.StartsWith( SharedConstants.NO_PARALLEL_EXECUTION_OF_XML_REPORTS_PREFIX, StringComparison.InvariantCulture)) { TLogging.Log(ErrorMessage, FStatusBarProcedure); } else { FStatusBarProcedure(ErrorMessage.Substring( SharedConstants.NO_PARALLEL_EXECUTION_OF_XML_REPORTS_PREFIX.Length)); } } else { // We get here e.g. when Report Generation was cancelled: this clears anything that the // Status Bar has previously shown. FStatusBarProcedure(String.Empty); } // Let any Exception that happened server-side escalate to the 'Unhandled Exception Handler' // to give it visibility if (ServersideException != null) { if (TDBExceptionHelper.IsTransactionSerialisationException(ServersideException)) { FStatusBarProcedure(string.Empty); TConcurrentServerTransactions.ShowTransactionSerializationExceptionDialog(); } else { throw ServersideException; } } } } FKeepUpProgressCheck = false; } else { if ((state.StatusMessage != null) && (!OldLoggingText.Equals(state.StatusMessage))) { TLogging.Log(state.StatusMessage, TLoggingType.ToStatusBar, FStatusBarProcedure); OldLoggingText = state.StatusMessage; } } if (FKeepUpProgressCheck) { // Sleep for some time. Then check again for latest progress information Thread.Sleep(500); } } }
public static bool ImportPartnerTaxCodes( Hashtable AParameters, String AImportString, out TVerificationResultCollection AErrorMessages, out List <string> AOutputLines, out bool AExtractCreated, out int AExtractId, out int AExtractKeyCount, out int AImportedCodeCount, out int ADeletedCodeCount, out int ATaxCodeMismatchCount) { TProgressTracker.InitProgressTracker(DomainManager.GClientID.ToString(), Catalog.GetString("Importing Partner Tax Codes"), 100); TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), Catalog.GetString("Initialising"), 5); TVerificationResultCollection errorMessages = new TVerificationResultCollection(); List <string> outputLines = new List <string>(); List <long> partnerTaxCodesImported = new List <long>(); List <long> partnerTaxCodesDeleted = new List <long>(); int taxCodeMismatchCount = 0; bool extractCreated = false; int extractId = -1; int extractKeyCount = 0; string delimiter = Convert.ToString(AParameters["Delimiter"]); bool firstRowIsHeader = Convert.ToBoolean(AParameters["FirstRowIsHeader"]); bool failIfNotPerson = Convert.ToBoolean(AParameters["FailIfNotPerson"]); bool failIfInvalidPartner = Convert.ToBoolean(AParameters["FailIfInvalidPartner"]); bool overwriteExistingTaxCode = Convert.ToBoolean(AParameters["OverwriteExistingTaxCode"]); bool createExtract = Convert.ToBoolean(AParameters["CreateExtract"]); bool createOutputFile = Convert.ToBoolean(AParameters["CreateOutFile"]); bool includePartnerDetails = Convert.ToBoolean(AParameters["IncludePartnerDetails"]); int emptyTaxCodeAction = Convert.ToInt32(AParameters["EmptyTaxCode"]); string taxCodeType = Convert.ToString(AParameters["TaxCodeType"]); string extractName = Convert.ToString(AParameters["ExtractName"]); string extractDescription = Convert.ToString(AParameters["ExtractDescription"]); StringReader sr = new StringReader(AImportString); int rowNumber = 0; bool cancelledByUser = false; bool doneHeaderRow = (firstRowIsHeader == false); TDBTransaction transaction = null; bool submissionOK = false; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, 3, ref transaction, ref submissionOK, delegate { try { PTaxTable taxTable = PTaxAccess.LoadAll(transaction); string importLine = sr.ReadLine(); int percentDone = 10; int previousPercentDone = 0; int initialTextLength = AImportString.Length; int totalRows = AImportString.Split('\n').Length; if (delimiter.Length < 1) { // should not happen delimiter = ","; } while (importLine != null) { rowNumber++; percentDone = 10 + ((rowNumber * 80) / totalRows); // skip empty lines and commented lines if ((importLine.Trim().Length == 0) || importLine.StartsWith("/*") || importLine.StartsWith("#")) { importLine = sr.ReadLine(); continue; } int numberOfElements = StringHelper.GetCSVList(importLine, delimiter).Count; if (numberOfElements < 2) { // That is a critical error TVerificationResult errorMsg = new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, rowNumber), Catalog.GetString("Wrong number of columns. There must be at least 2"), TResultSeverity.Resv_Critical); errorMessages.Add(errorMsg); outputLines.Add(string.Format("\"Wrong number of columns in Line {0}\"", rowNumber)); importLine = sr.ReadLine(); continue; } if (!doneHeaderRow) { // Skip a header row doneHeaderRow = true; importLine = sr.ReadLine(); continue; } int preParseMessageCount = errorMessages.Count; importLine = importLine.TrimStart(' '); // TCommonImport.ImportInt64 does not remove leading spaces before optional quotes Int64 partnerKey = TCommonImport.ImportInt64(ref importLine, delimiter, null, null, rowNumber, errorMessages, null); importLine = importLine.TrimStart(' '); // TCommonImport.ImportString does not remove leading spaces before optional quotes string taxCode = TCommonImport.ImportString(ref importLine, delimiter, null, null, rowNumber, errorMessages, false); if (errorMessages.Count > preParseMessageCount) { outputLines.Add(string.Format("\"Error reading Line {0}\"", rowNumber)); importLine = sr.ReadLine(); continue; } // Ok so we have a good key and a code, which might be null // See if the partner exists PartnerFindTDS partner = TSimplePartnerFindWebConnector.FindPartners(partnerKey, true); PartnerFindTDSSearchResultTable result = partner.SearchResult; if (result.DefaultView.Count == 0) { // We don't have the partner if (failIfInvalidPartner) { TVerificationResult errorMsg = new TVerificationResult(String.Format(MCommonConstants.StrImportValidationErrorInLine, rowNumber), Catalog.GetString("Could not find the specified partner"), TResultSeverity.Resv_Critical); errorMessages.Add(errorMsg); outputLines.Add(string.Format("\"Error\"{0}{1}{0}{0}{0}{0}\"Partner not found\"", delimiter, partnerKey)); } else { outputLines.Add(string.Format("\"Skipped\"{0}{1}{0}{0}{0}{0}\"Partner not found\"", delimiter, partnerKey)); } importLine = sr.ReadLine(); continue; } // We already have this partner PartnerFindTDSSearchResultRow row = (PartnerFindTDSSearchResultRow)result.DefaultView[0].Row; string partnerClass = row.PartnerClass; string partnerDetails = string.Empty; if (includePartnerDetails) { string shortName = row.PartnerShortName; string bestAddress = string.Empty; PLocationTable locationTable; string country; if (TAddressTools.GetBestAddress(partnerKey, out locationTable, out country, transaction)) { if ((locationTable != null) && (locationTable.Rows.Count > 0)) { bestAddress = Calculations.DetermineLocationString((PLocationRow)locationTable.Rows[0], Calculations.TPartnerLocationFormatEnum.plfCommaSeparated); } } partnerDetails = string.Format("{0}\"{1}\"{0}\"{2}\"", delimiter, shortName, bestAddress); } if (partnerClass != "PERSON") { if (failIfNotPerson) { TVerificationResult errorMsg = new TVerificationResult(String.Format(MCommonConstants.StrImportValidationErrorInLine, rowNumber), Catalog.GetString("Partner is not a PERSON"), TResultSeverity.Resv_Critical); errorMessages.Add(errorMsg); outputLines.Add(string.Format("\"Error\"{0}{1}{0}\"{2}\"{3}{0}\"{4}\"", delimiter, partnerKey, taxCode, partnerDetails, "Partner is not a PERSON")); } else { outputLines.Add(string.Format("\"Skipped\"{0}{1}{0}\"{2}\"{3}{0}\"{4}\"", delimiter, partnerKey, taxCode, partnerDetails, "Partner is not a PERSON")); } importLine = sr.ReadLine(); continue; } bool deleteExistingRow = false; if (taxCode == null) { // what to do if the code is not supplied? if ((emptyTaxCodeAction == 0) || (emptyTaxCodeAction == 1)) { if (emptyTaxCodeAction == 0) { // Fail TVerificationResult errorMsg = new TVerificationResult(String.Format(MCommonConstants.StrImportValidationErrorInLine, rowNumber), Catalog.GetString("No tax code specified"), TResultSeverity.Resv_Critical); errorMessages.Add(errorMsg); outputLines.Add(string.Format("\"Error\"{0}{1}{0}{2}{0}\"{3}\"", delimiter, partnerKey, partnerDetails, "No tax code specified")); } else { outputLines.Add(string.Format("\"Skipped\"{0}{1}{0}{2}{0}\"{3}\"", delimiter, partnerKey, partnerDetails, "No tax code specified")); } importLine = sr.ReadLine(); continue; } else if (emptyTaxCodeAction == 2) { deleteExistingRow = true; } else { throw new Exception("Developer error! Unknown action for an empty tax code..."); } } // See if there is a tax code already for this partner PTaxRow taxRow = null; taxTable.DefaultView.RowFilter = string.Format("{0}={1} AND {2}='{3}'", PTaxTable.GetPartnerKeyDBName(), partnerKey, PTaxTable.GetTaxTypeDBName(), taxCodeType); if (taxTable.DefaultView.Count == 0) { if (deleteExistingRow) { // The tax code is null and we can only delete if the row already exists in the tax table outputLines.Add(string.Format("\"Skipped\"{0}{1}{0}\"{2}\"{3}{0}\"{4}\"", delimiter, partnerKey, taxCode, partnerDetails, "Cannot delete. The partner is not in the tax table.")); } else { // Add a new row taxRow = taxTable.NewRowTyped(true); taxRow.PartnerKey = partnerKey; taxRow.TaxType = taxCodeType; taxRow.TaxRef = taxCode; taxTable.Rows.Add(taxRow); outputLines.Add(string.Format("\"Added\"{0}{1}{0}\"{2}\"{3}", delimiter, partnerKey, taxCode, partnerDetails)); partnerTaxCodesImported.Add(partnerKey); } } else { // the row exists already. We expect there to only be one row per tax code type for a given partner // If partners can have multiple codes of a specified type the code below will need to change! taxRow = (PTaxRow)taxTable.DefaultView[0].Row; string currentCode = taxRow.TaxRef; if (deleteExistingRow) { if ((taxRow.RowState != DataRowState.Detached) && (taxRow.RowState != DataRowState.Deleted)) { taxRow.Delete(); } outputLines.Add(string.Format("\"Deleted\"{0}{1}{0}\"{2}\"{3}", delimiter, partnerKey, currentCode, partnerDetails)); partnerTaxCodesDeleted.Add(partnerKey); } else { // Check if it is the same if (string.Compare(currentCode, taxCode, false) == 0) { // they are the same outputLines.Add(string.Format("\"Unchanged\"{0}{1}{0}\"{2}\"{3}", delimiter, partnerKey, taxCode, partnerDetails)); partnerTaxCodesImported.Add(partnerKey); // this counts as an import } else { // They are different if (overwriteExistingTaxCode) { // Overwrite the old value taxRow.TaxRef = taxCode; outputLines.Add(string.Format("\"Modified\"{0}{1}{0}\"{2}\"{3}{0}\"{4}\"", delimiter, partnerKey, taxCode, partnerDetails, "Previous code was: " + currentCode)); partnerTaxCodesImported.Add(partnerKey); } else { // Do nothing on this row outputLines.Add(string.Format("\"Skipped\"{0}{1}{0}\"{2}\"{3}{0}\"{4}\"", delimiter, partnerKey, currentCode, partnerDetails, "WARNING!! File and Database codes differ. New code is: " + taxCode)); taxCodeMismatchCount++; } } } if (TProgressTracker.GetCurrentState(DomainManager.GClientID.ToString()).CancelJob == true) { cancelledByUser = true; break; } if (errorMessages.HasCriticalErrors && (errorMessages.Count > 100)) { // This probably means that it is a big file and the user has made the same mistake many times over break; } // Update progress tracker every few percent if ((percentDone - previousPercentDone) > 3) { TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), String.Format(Catalog.GetString("Importing row {0}"), rowNumber), (percentDone > 90) ? 90 : percentDone); previousPercentDone = percentDone; } } importLine = sr.ReadLine(); } // No more lines in the file - or cancelled by the user if (cancelledByUser) { errorMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation, "The import was cancelled by the user.", TResultSeverity.Resv_Critical)); outputLines.Add("\"Import cancelled by user\""); } if (errorMessages.HasCriticalErrors) { submissionOK = false; partnerTaxCodesImported.Clear(); } else { PTaxAccess.SubmitChanges(taxTable, transaction); submissionOK = true; } // Now create the optional extract if (submissionOK && (partnerTaxCodesImported.Count > 0) && createExtract) { // we have more server work to do so we reset submission OK to false submissionOK = false; TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), Catalog.GetString("Creating new Extract ..."), 97); DataTable table = new DataTable(); table.Columns.Add(new DataColumn()); for (int i = 0; i < partnerTaxCodesImported.Count; i++) { DataRow row = table.NewRow(); row[0] = partnerTaxCodesImported[i]; table.Rows.Add(row); } List <long> ignoredKeys; extractCreated = TExtractsHandling.CreateExtractFromListOfPartnerKeys(extractName, extractDescription, out extractId, table, 0, false, out extractKeyCount, out ignoredKeys); submissionOK = true; } } catch (Exception ex) { TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), Catalog.GetString("Exception Occurred"), 0); if (TDBExceptionHelper.IsTransactionSerialisationException(ex)) { errorMessages.Add(new TVerificationResult("ImportPartnerTaxCodes", ErrorCodeInventory.RetrieveErrCodeInfo(PetraErrorCodes.ERR_DB_SERIALIZATION_EXCEPTION))); } else { errorMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, rowNumber), ex.Message, TResultSeverity.Resv_Critical)); } partnerTaxCodesImported.Clear(); } finally { TProgressTracker.FinishJob(DomainManager.GClientID.ToString()); } }); AErrorMessages = errorMessages; AOutputLines = outputLines; AExtractCreated = extractCreated; AExtractId = extractId; AExtractKeyCount = extractKeyCount; AImportedCodeCount = partnerTaxCodesImported.Count; ADeletedCodeCount = partnerTaxCodesDeleted.Count; ATaxCodeMismatchCount = taxCodeMismatchCount; return(submissionOK); }
/// <summary> /// run the report /// </summary> private void Run(string ASessionID) { // need to initialize the database session TSession.InitThread(ASessionID); IsolationLevel Level; FSuccess = false; TDataBase db = DBAccess.Connect("TReportGeneratorUIConnector"); TDBTransaction Transaction = new TDBTransaction(); try { db.ReadTransaction(ref Transaction, delegate { if (FDatacalculator.GenerateResult(ref FParameterList, ref FHTMLOutput, out FHTMLDocument, ref FErrorMessage, ref FException, Transaction)) { FSuccess = true; } else { TLogging.Log(FErrorMessage); } }); } catch (Exception Exc) { TLogging.Log("Problem calculating report: " + Exc.ToString()); TLogging.Log(Exc.StackTrace, TLoggingType.ToLogfile); FSuccess = false; FErrorMessage = Exc.Message; FException = Exc; } if (TDBExceptionHelper.IsTransactionSerialisationException(FException)) { // do nothing - we want this exception to bubble up } else if (FException is Exception && FException.InnerException is EOPDBException) { EOPDBException DbExc = (EOPDBException)FException.InnerException; if (DbExc.InnerException is Exception) { if (DbExc.InnerException is PostgresException) { PostgresException PgExc = (PostgresException)DbExc.InnerException; if (PgExc.SqlState == "57014") // SQL statement timeout problem { FErrorMessage = Catalog.GetString( "Error - Database took too long to respond. Try different parameters to return fewer results."); } } else { FErrorMessage = DbExc.InnerException.Message; } FException = null; } } TProgressTracker.FinishJob(FProgressID); }