private bool Scenario1(List <List <OracleRecord> > recordsGroup) { var valid = true; foreach (var group in recordsGroup) { var sumGroup = group.Sum(x => { decimal monto; decimal.TryParse(x.InvoiceAmount, out monto); return(monto); }); foreach (var record in group) { try { if (!_dbRecords.ContainsKey(record.UuidCfdi.ToUpper())) { if ((_isPermisoUuid && !string.IsNullOrEmpty(record.UuidCfdi)) || _isExtranjero || (_isPermisoUuid && !string.IsNullOrEmpty(record.UuidCfdi))) { _reporte.AddRecord(record); LogUtilities.ShowMessage("[OK=RowNumber:" + record.RowNumber + ",UUID:" + record.UuidCfdi + "]", 1); continue; } throw new Exception("El UUID no existe en el portal"); } decimal dMontoXml; var montoXml = _dbRecords[record.UuidCfdi.ToUpper()].ElementAt(1); var rfcXml = _dbRecords[record.UuidCfdi.ToUpper()].ElementAt(0); decimal.TryParse(montoXml, out dMontoXml); if (sumGroup != dMontoXml && Math.Abs(sumGroup - dMontoXml) > Convert.ToDecimal(0.99)) { throw new Exception("La sumatoria de los registros de Oracle en el xls (" + sumGroup + ") no coincide con el total del xml asociado (" + montoXml + ")"); } if (!record.SupplierNum.Equals(rfcXml)) { throw new Exception("El RFC en el registro de Oracle en el xls (" + record.SupplierNum + ") no coincide con el RFC del xml asociado (" + rfcXml + ")"); } _reporte.AddRecord(record); LogUtilities.ShowMessage("[OK=RowNumber:" + record.RowNumber + ",UUID:" + record.UuidCfdi + "]", 1); } catch (Exception ex) { var pair = new KeyValuePair <OracleRecord, string>(record, ex.Message); _failRecords.Add(pair); valid = false; LogUtilities.ShowMessage("[FAIL=RowNumber:" + record.RowNumber + ",UUID:" + record.UuidCfdi + "]: " + ex.Message, 3); } finally { LogUtilities.ShowNewLine(); } } } return(valid); }
/// <summary> /// Crea una nueva interfaz con los registros fallidos pero aprobados /// </summary> /// <param name="newRecords">Lista de nuevos registros a agregar</param> /// <returns></returns> public bool WriteApproved(List <OracleRecord> newRecords) { var estado = false; try { LogUtilities.ShowMessage("Procesando " + newRecords.Count + " archivos aprobados", 1); var reporte = new OutputInterface(); reporte.AddRecords(newRecords); var outputFile = DateTime.Now.ToString("dd-MM-yyyyThh-mm-ss") + "_output.csv"; reporte.Save(outputFile); estado = true; } catch (Exception ex) { LogUtilities.ShowMessage(ex.ToString(), 1, false); } return(estado); }
/// <summary> /// Inicia el proceso del xls /// </summary> /// <param name="fileName">Ruta del archivo xls temporal</param> /// <param name="isExtranjero">Determina si el xls es extranjero o local</param> /// <param name="isPermisoUuid">Determina si se debe saltar la validacion del uuid del portal</param> /// <returns>Lista de los reistros fallidos</returns> public List <KeyValuePair <OracleRecord, string> > Iniciar(string fileName, bool isExtranjero = false, bool isPermisoUuid = false) { _isExtranjero = isExtranjero; _isPermisoUuid = isPermisoUuid; var fi = new FileInfo(fileName); _validations = new Validations(); LogUtilities.ShowMessage("Procesando archivo " + fi.Name, 1); //while (archivoEnUso(fi.FullName)) //{ // LogUtilities.ShowMessage("[FAIL] El archivo está en uso, se procesará nuevamente...", 2); // Thread.Sleep(100); //} if (LeerXls(fi.FullName)) { LogUtilities.ShowMessage("[FINISH]", 1); try { fi.Delete(); } catch { LogUtilities.ShowMessage("[FAIL] El archivo no se pudo eliminar, se procesará nuevamente...", 2); } } else { try { if (File.Exists(fi.FullName + ".err")) { File.Delete(fi.FullName + ".err"); } File.Move(fi.FullName, fi.FullName + ".err"); LogUtilities.ShowMessage("[FAIL] Uno o más registros en el archivo tuvieron errores, se cambiará la extension a \".err\" para futuras referencias...", 2, false); } catch (Exception) { LogUtilities.ShowMessage("[FAIL] No se pudo cambiar la extensión al archivo, se procesará nuevamente...", 2, false); } } var output = _validations.GetInterfaceSalida(); _outputFile = Path.GetFileNameWithoutExtension(fi.FullName).Replace(" ", "_") + "_" + DateTime.Now.ToString("dd-MM-yyyyThh-mm-ss") + "_output.csv"; output.Save(_outputFile, _logFileName); LogUtilities.ShowNewLine(); return(_validations.GetFailedRecords()); }
private bool LeerXls(string filePath) { bool control; var records = new List <OracleRecord>(); try { records = Transform(filePath); } catch (Exception ex) { LogUtilities.ShowMessage("[EX] " + ex.Message, 3); LogUtilities.ShowNewLine(); } _logFileName = "LoadXlsOTM_" + Path.GetFileNameWithoutExtension(filePath).Replace(" ", "_") + "_" + DateTime.Now.ToString("dd-MM-yyyyThh-mm-ss") + ".log"; LogUtilities.SetLogFileName(_logFileName, false); control = _validations.Validate(records, _isExtranjero, _isPermisoUuid); LogUtilities.SetLogFileName(null); return(control); }
/// <summary> /// Valida el registro dependiendo del número de escenario (revisar documentación) /// </summary> /// <param name="records">Lista de registros de Oracle consecutivos del mismo RecordType</param> /// <param name="isExtranjero">Define si el xls es extranjero</param> /// <param name="isPermisoUuid">Define si se salta la validación contra la base de datos</param> /// <returns>El resultado de la validación de los registros</returns> public bool Validate(List <OracleRecord> records, bool isExtranjero = false, bool isPermisoUuid = false) { _isExtranjero = isExtranjero; _isPermisoUuid = isPermisoUuid; var control = true; _records = FillBlanks(records); var adjacentRecords = _records.GroupAdjacent(record => record.RecordType).ToList(); foreach (var recordGroup in adjacentRecords) { var recordType = recordGroup.Key; foreach (var record in recordGroup) { try { var regex = new Regex(@"[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}"); if (!string.IsNullOrEmpty(record.UuidCfdi.ToUpper()) && regex.IsMatch(record.UuidCfdi.ToUpper())) { if (_isExtranjero) { throw new Exception("El registro es extranjero, no se puede comparar el UUID"); } //else if (!_dbRecords.ContainsKey(record.UuidCfdi)) //{ // if (!_isPermisoUuid) // { // throw new Exception("El UUID no existe en el portal"); // } //} } } catch (Exception ex) { var pair = new KeyValuePair <OracleRecord, string>(record, ex.Message); _failRecords.Add(pair); LogUtilities.ShowMessage(ex.Message, 3); } } List <List <OracleRecord> > groupedList; if (recordType.Equals("1")) { groupedList = recordGroup.GroupBy(u => u.UuidCfdi).Select(grp => grp.ToList()).ToList(); } else { groupedList = recordGroup.GroupBy(u => u.InvoiceNum).Select(grp => grp.ToList()).ToList(); } switch (recordType) { case "1": control &= Scenario1(groupedList); break; case "2": control &= Scenarios23(groupedList, 2); break; case "3": control &= Scenarios23(groupedList, 3); break; case "4": control &= Scenarios23(groupedList, 4); break; } } return(control); }
private bool Scenarios23(List <List <OracleRecord> > recordsGroup, int scenario) { var valid = true; decimal invoiceAmountGroup; decimal amountGroupCc = 0; var recordsCc = new List <OracleRecord>(); var regex = new Regex(@"[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}"); foreach (var recordGroup in recordsGroup) { var adjacentRecords = recordGroup.GroupAdjacent(record => record.Cc).Select(grp => grp.ToList()).ToList(); if (scenario == 3 || scenario == 4) { adjacentRecords = FillBlanksScenario3(adjacentRecords); } for (var i = 0; i < adjacentRecords.Count; i++) { var group = adjacentRecords[i]; var invoiceNum = group.First().InvoiceNum; var uuids = string.Join(",", group.Select(x => x.UuidCfdi)); try { #region Valida que el UUID exista en el portal si es que no tiene permisos, que el MontoTotal corresponda con el del portal, que el RFC corresponda con el del portal y que el UUID tenga una estructura válida foreach (var record in group) { if (_isExtranjero) { continue; } else if (record.NoInvDetail2.Equals("Y")) { continue; } else if (scenario == 2 && !regex.IsMatch(record.UuidCfdi.ToUpper())) { continue; } else if (!_dbRecords.ContainsKey(record.UuidCfdi.ToUpper())) { if (_isPermisoUuid && !string.IsNullOrEmpty(record.UuidCfdi)) { continue; } throw new Exception(record.UuidCfdi + "||" + "El UUID no existe en el portal"); } decimal dMontoRecord; decimal dMontoXml; //var montoRecord = Regex.Replace(record.MontoTotal, @"[^(\d|,|\.)]", ""); var montoRecord = record.MontoTotal; var montoXml = _dbRecords[record.UuidCfdi.ToUpper()].ElementAt(1); var rfcXml = _dbRecords[record.UuidCfdi.ToUpper()].ElementAt(0); decimal.TryParse(montoRecord, out dMontoRecord); decimal.TryParse(montoXml, out dMontoXml); if (dMontoRecord != dMontoXml && Math.Abs(dMontoRecord - dMontoXml) > Convert.ToDecimal(0.99)) { throw new Exception(record.UuidCfdi + "||" + "El monto del registro de Oracle en el xls (" + montoRecord + ") no coincide con el monto del xml asociado (" + montoXml + ")"); } if (scenario != 3 && scenario != 4 && !record.SupplierNum.Equals(rfcXml)) { throw new Exception(record.UuidCfdi + "||" + "El RFC en el registro de Oracle en el xls (" + record.SupplierNum + ") no coincide con el RFC del xml asociado (" + rfcXml + ")"); } } #endregion if (scenario == 3 || scenario == 4) { #region Valida que los InvoiceAmount de los registros del InvoiceNum sean iguales decimal.TryParse(group.First().InvoiceAmount, out invoiceAmountGroup); var valor = group.Sum(x => decimal.Parse(x.InvoiceAmount)); // var equals = group.All(x => decimal.Parse(x.InvoiceAmount) == invoiceAmountGroup); var equals = group.Sum(x => decimal.Parse(x.InvoiceAmount)) == invoiceAmountGroup; if (!equals) { throw new Exception("El InvoiceAmount de los registros del InvoiceNum \"" + invoiceNum + "\" no son iguales"); } #endregion #region Valida que la sumatoria de los MontoTotal sea igual al InvoiceAmount var sumGroup = group.Sum(x => { decimal monto; decimal.TryParse(x.MontoTotal, out monto); return(monto); }); // if (sumGroup != invoiceAmountGroup && Math.Abs(sumGroup - invoiceAmountGroup) > Convert.ToDecimal(0.9)) if (sumGroup != invoiceAmountGroup && (sumGroup - invoiceAmountGroup) > Convert.ToDecimal(0.9)) { throw new Exception("La sumatoria del MontoTotal de los registros del InvoiceNum \"" + invoiceNum + "\" (" + sumGroup + ") no coincide con el InvoiceAmount (" + invoiceAmountGroup + ")"); } #endregion #region Valida que la sumatoria de los Amount sea igual al Invoice if (scenario == 4) { amountGroupCc += sumGroup = group.Sum(x => { decimal monto; decimal.TryParse(x.Amount, out monto); return(monto); }); recordsCc.AddRange(group.ToList()); var cont = i + 1; if ((i + 1) == adjacentRecords.Count) { if (amountGroupCc != invoiceAmountGroup && Math.Abs(amountGroupCc - invoiceAmountGroup) > Convert.ToDecimal(0.9)) { throw new Exception("La sumatoria del Amount de los registros del InvoiceNum \"" + invoiceNum + "\" (" + sumGroup + ") no coincide con el InvoiceAmount (" + invoiceAmountGroup + ")"); } } } #endregion } if (scenario == 4) { #region Agrega todos los Records agrupados por el CC if ((i + 1) == adjacentRecords.Count) { _reporte.AddRecords(recordsCc); LogUtilities.ShowMessage("[OK=RowNumbers:" + recordsCc.First().RowNumber + "-" + recordsCc.Last().RowNumber + ", UUIDs:" + uuids + "]", 1); } #endregion } else { #region Agrega todos los Records del grupo _reporte.AddRecords(group.ToList()); LogUtilities.ShowMessage("[OK=RowNumbers:" + group.First().RowNumber + "-" + group.Last().RowNumber + ", UUIDs:" + uuids + "]", 1); #endregion } } catch (Exception ex) { foreach (var record in group) { var mensaje = ex.Message; try { var split = ex.Message.Split(new char[] { '|', '|' }, StringSplitOptions.RemoveEmptyEntries); var uuid = split.FirstOrDefault(); var msg = split.LastOrDefault(); if (record.UuidCfdi.Equals(uuid)) { mensaje = msg; } else { mensaje = "Error heredado del UUID " + uuid; } } catch { } var pair = new KeyValuePair <OracleRecord, string>(record, mensaje); _failRecords.Add(pair); } valid = false; LogUtilities.ShowMessage("[FAIL=RowNumbers:" + group.First().RowNumber + "-" + group.Last().RowNumber + ", UUIDs:" + uuids + "]: " + ex.Message, 3); } finally { LogUtilities.ShowNewLine(); } } } return(valid); }