private async Task fireAndForgetAsync(PayrollStampingParams payrollStampingParams, Overdraft overdraftToStamp, List <PayrollCompanyConfiguration> payrollConfigurations, BlobStorageUtil blobStorageUtil, ISendMailProvider sendMailProvider, Guid UUID, string XML) { try { //7. Save XML to BlobStorage await blobStorageUtil.UploadDocumentAsync($"{UUID}.xml", XML); ////8. Transforma el XML a HTML y PDF var resultTransformation = await xmlTransformationAsync(payrollStampingParams, overdraftToStamp, XML); ////Save PDF to BlobStorage await blobStorageUtil.UploadDocumentAsync($"{UUID}.pdf", resultTransformation.PreviewTransformResultDetails.FirstOrDefault().TransformPDFResult); ////9. Send email with the payroll to Employee await sendMailAsync(overdraftToStamp, UUID, XML, resultTransformation.PreviewTransformResultDetails.FirstOrDefault().TransformPDFResult, sendMailProvider, payrollConfigurations); } catch (Exception ex) { Trace.TraceError($"No fue posible transformar / enviar el comprobante al colaborador. {ex.Message}"); } }
public async Task <JsonResult> Stamping(List <Guid> overdrafstList, Guid periodDetailID) { try { Trace.WriteLine("Llega al controller"); if (!overdrafstList.Any()) { throw new CotorraException(102, "102", "No existe ninguna nómina a timbrar.", null); } var detailsList = new List <PayrollStampingDetail>(); for (int i = 0; i < overdrafstList.Count(); i++) { var odID = overdrafstList[i]; detailsList.Add(new PayrollStampingDetail() { Folio = String.Empty, Series = String.Empty, PaymentDate = DateTime.Now, RFCOriginEmployer = String.Empty, OverdraftID = odID, }); } var stampingParams = new PayrollStampingParams { Detail = detailsList, Currency = Currency.MXN, FiscalStampingVersion = FiscalStampingVersion.CFDI33_Nom12, PeriodDetailID = periodDetailID, IdentityWorkID = SessionModel.CompanyID, InstanceID = SessionModel.InstanceID, }; Trace.WriteLine("Invoka al cliente"); var stampProcess = await stampingClient.PayrollStampingAsync(stampingParams); var result = from psr in stampProcess.PayrollStampingResultDetails select new { psr.HistoricEmployeeID, psr.OverdraftID, psr.PeriodDetailID, psr.UUID, psr.PayrollStampingResultStatus, psr.Message }; return(Json(result)); } catch (Exception ex) { Trace.WriteLine(ex.ToString()); throw; } }
private (byte[], byte[], string) Crypto(PayrollStampingParams payrollStampingParams, string certificateCER, string certificateKey, string certPassword) { var clsCryptoToCreate = new ClsCrypto( payrollStampingParams.IdentityWorkID.ToString().ToLower().Replace("-", ""), payrollStampingParams.InstanceID.ToString().ToLower().Replace("-", ""), payrollStampingParams.InstanceID.ToString().ToLower().Replace("-", "").Substring(0, 19)); var certificatebytesCER = Convert.FromBase64String(clsCryptoToCreate.Decrypt(certificateCER)); var certificatebytesKEY = Convert.FromBase64String(clsCryptoToCreate.Decrypt(certificateKey)); var certPasswordToResult = StringCipher.Decrypt(certPassword); return(certificatebytesCER, certificatebytesKEY, certPasswordToResult); }
private async Task <PreviewTransformResult> xmlTransformationAsync(PayrollStampingParams payrollStampingParams, Overdraft overdraftToStamp, string XML) { var fiscalPreviewManager = new FiscalPreviewerManager(); var previewTransformParams = new PreviewTransformParams(); previewTransformParams.FiscalStampingVersion = payrollStampingParams.FiscalStampingVersion; previewTransformParams.InstanceID = payrollStampingParams.InstanceID; previewTransformParams.IdentityWorkID = payrollStampingParams.IdentityWorkID; previewTransformParams.PreviewTransformParamsDetails.Add(new PreviewTransformParamsDetail() { OverdraftID = overdraftToStamp.ID, Overdraft = overdraftToStamp, XML = XML }); var resultTransformation = await fiscalPreviewManager.TransformAsync(previewTransformParams); return(resultTransformation); }
public async Task <PayrollStampingResult> PayrollStampingAsync(PayrollStampingParams payrollStampingParams) { var manager = new PayrollStampingManager(); return(await manager.PayrollStampingAsync(payrollStampingParams)); }
public async Task Should_Stamp_Payroll_CFDI_Valid() { var xmlCancelacion = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Acuse xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" Fecha=\"2020-07-02T16:02:07.2838838\" RfcEmisor=\"KAHO641101B39\"> <Folios xmlns=\"http://cancelacfd.sat.gob.mx\"> <UUID>3377E0AA-C54B-4E9E-BFF2-1D8BA96D5DD4</UUID> <EstatusUUID>201</EstatusUUID> </Folios> <Signature Id=\"SelloSAT\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\"> <SignedInfo> <CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /> <SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#hmac-sha512\" /> <Reference URI=\"\"> <Transforms> <Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xpath-19991116\"> <XPath>not(ancestor-or-self::*[local-name()='Signature'])</XPath> </Transform> </Transforms> <DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha512\" /> <DigestValue>BThmOyTf26Ax25v8Li0oqcP3wyrhW3kjjxOcO1zamRYasNIPcHSnBiRyxmJ449a3gdgAWaz/UKVil3pqcper+g==</DigestValue> </Reference> </SignedInfo> <SignatureValue>6qDGoWoHW5tK2MGNiXU7fI6hfpkbrYTMHafVvIsGRkl9xq2H2YQRvId4CO7B9GGJFbuVMku2IBkpKU/Tscqo9Q==</SignatureValue> <KeyInfo> <KeyName>BF66E582888CC845</KeyName> <KeyValue> <RSAKeyValue> <Modulus>n5YsGT0w5Z70ONPbqszhExfJU+KY3Bscftc2jxUn4wxpSjEUhnCuTd88OK5QbDW3Mupoc61jr83lRhUCjchFAmCigpC10rEntTfEU+7qtX8ud/jJJDB1a9lTIB6bhBN//X8IQDjhmHrfKvfen3p7RxLrFoxzWgpwKriuGI5wUlU=</Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> </KeyValue> </KeyInfo> </Signature></Acuse>"; var acuse = SerializerXml.DeserializeObject <Schema.CFDI33Nom12.Acuse>(xmlCancelacion); using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled); try { var identityWorkId = Guid.NewGuid(); var instanceID = Guid.NewGuid(); var overdraft = await new PayrollStampingManagerUT().CreateRealOverdraftAsync(identityWorkId, instanceID); var periodDetailID = overdraft.PeriodDetailID; //Recalculate var calculateParams = new CalculateOverdraftParams() { DeleteAccumulates = true, IdentityWorkID = identityWorkId, InstanceID = instanceID, OverdraftID = overdraft.ID, ResetCalculation = true, SaveOverdraft = true, UserID = Guid.Empty }; var calculationResult = await new OverdraftCalculationManager().CalculateAsync(calculateParams); overdraft = (calculationResult as CalculateOverdraftResult).OverdraftResult; Assert.True(overdraft.OverdraftDetails.Sum(p => p.Amount) > 0); //Autorización de la nómina var authorizationManager = new AuthorizationManager(); var authorizationParams = new AuthorizationParams() { IdentityWorkID = identityWorkId, InstanceID = instanceID, PeriodDetailIDToAuthorize = periodDetailID, ResourceID = Guid.Empty, user = Guid.Empty }; //autorizacion de la nómina var historicOverdrafts = await authorizationManager.AuthorizationAsync(authorizationParams); //Timbrado var overdraftManager = new MiddlewareManager <Overdraft>(new BaseRecordManager <Overdraft>(), new OverdraftValidator()); var overdraftsPrevious = await overdraftManager.FindByExpressionAsync(p => p.PeriodDetailID == periodDetailID, identityWorkId); var manager = new PayrollStampingManager(); var dateTime = DateTime.Now; var stampingParms = new PayrollStampingParams() { FiscalStampingVersion = FiscalStampingVersion.CFDI33_Nom12, IdentityWorkID = identityWorkId, InstanceID = instanceID, PeriodDetailID = periodDetailID, Detail = new List <PayrollStampingDetail>() { new PayrollStampingDetail() { Folio = "2020", Series = "S1", PaymentDate = dateTime.AddDays(-2), RFCOriginEmployer = null, SNCFEntity = null, OverdraftID = overdraftsPrevious.FirstOrDefault().ID, } }, Currency = Currency.MXN }; var payrollStampingResult = await manager.PayrollStampingAsync(stampingParms); Assert.Contains(payrollStampingResult.PayrollStampingResultDetails, p => p.PayrollStampingResultStatus == PayrollStampingResultStatus.Success); //cancel payroll var cancelStampingManager = new CancelStampingManager(); var cancelParams = new CancelPayrollStampingParams() { FiscalStampingVersion = FiscalStampingVersion.CFDI33_Nom12, IdentityWorkID = identityWorkId, InstanceID = instanceID, OverdraftIDs = overdraftsPrevious.Select(p => p.ID).ToList(), user = Guid.Empty }; await Task.Delay(10000); var cancelationResult = await cancelStampingManager.CancelPayrollStampingAsync(cancelParams); Assert.False(cancelationResult.WithErrors); var cancelManager = new MiddlewareManager <CancelationFiscalDocument>(new BaseRecordManager <CancelationFiscalDocument>(), new CancelationFiscalDocumentValidator()); var cancelations = await cancelManager.FindByExpressionAsync(p => p.InstanceID == instanceID, identityWorkId, new string[] { "CancelationFiscalDocumentDetails" }); Assert.True(cancelations.Any()); var overIds = overdraftsPrevious.Select(p => p.ID).ToList(); var olderOverdrafts = await overdraftManager.FindByExpressionAsync(p => overIds.Contains(p.ID), identityWorkId); Assert.False(olderOverdrafts.Any(p => p.OverdraftStatus != OverdraftStatus.Canceled)); var newOverdrafts = await overdraftManager.FindByExpressionAsync(p => overIds.Contains(p.OverdraftPreviousCancelRelationshipID.Value), identityWorkId); Assert.False(newOverdrafts.Any(p => p.OverdraftPreviousCancelRelationshipID == null)); } catch (Exception ex) { var t = ex.ToString(); Assert.True(false, ex.ToString()); } }
public async Task <PayrollStampingResult> PayrollStampingAsync(PayrollStampingParams payrollStampingParams) { return(await _client.PayrollStampingAsync(payrollStampingParams)); }
public async Task <PayrollStampingResult> PayrollStampingAsync(PayrollStampingParams payrollStampingParams) { throw new NotImplementedException(); }
public async Task Should_Stamp_Payroll_CFDI_Valid() { using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled); try { var identityWorkId = Guid.NewGuid(); var instanceID = Guid.NewGuid(); var overdraft = await CreateRealOverdraftAsync(identityWorkId, instanceID); var periodDetailID = overdraft.PeriodDetailID; //Recalculate var calculateParams = new CalculateOverdraftParams() { DeleteAccumulates = true, IdentityWorkID = identityWorkId, InstanceID = instanceID, OverdraftID = overdraft.ID, ResetCalculation = true, SaveOverdraft = true, UserID = Guid.Empty }; var calculationResult = await new OverdraftCalculationManager().CalculateAsync(calculateParams); overdraft = (calculationResult as CalculateOverdraftResult).OverdraftResult; Assert.True(overdraft.OverdraftDetails.Sum(p => p.Amount) > 0); //Autorización de la nómina var authorizationManager = new AuthorizationManager(); var authorizationParams = new AuthorizationParams() { IdentityWorkID = identityWorkId, InstanceID = instanceID, PeriodDetailIDToAuthorize = periodDetailID, ResourceID = Guid.Empty, user = Guid.Empty }; //autorizacion de la nómina var historicOverdrafts = await authorizationManager.AuthorizationAsync(authorizationParams); //Timbrado var overdraftManager = new MiddlewareManager <Overdraft>(new BaseRecordManager <Overdraft>(), new OverdraftValidator()); var overdraftsPrevious = await overdraftManager.FindByExpressionAsync(p => p.PeriodDetailID == periodDetailID, identityWorkId); var manager = new PayrollStampingManager(); var dateTime = DateTime.Now; var stampingParms = new PayrollStampingParams() { FiscalStampingVersion = FiscalStampingVersion.CFDI33_Nom12, IdentityWorkID = identityWorkId, InstanceID = instanceID, PeriodDetailID = periodDetailID, Detail = new List <PayrollStampingDetail>() { new PayrollStampingDetail() { Folio = "2020", Series = "S1", PaymentDate = dateTime.AddDays(-2), RFCOriginEmployer = null, SNCFEntity = null, OverdraftID = overdraftsPrevious.FirstOrDefault().ID, } }, Currency = Currency.MXN }; var payrollStampingResult = await manager.PayrollStampingAsync(stampingParms); Assert.Contains(payrollStampingResult.PayrollStampingResultDetails, p => p.PayrollStampingResultStatus == PayrollStampingResultStatus.Success); var uuid = payrollStampingResult.PayrollStampingResultDetails.FirstOrDefault().Overdraft.UUID; var fiscalManager = FiscalPreviewFactory.CreateInstance(FiscalStampingVersion.CFDI33_Nom12); var resultUrls = await fiscalManager.GetPreviewUrlByUUIDAsync(instanceID, uuid); HttpClient client = new HttpClient(); var pdfBytes = await client.GetByteArrayAsync(resultUrls.PDFUri); //Save XML to FileSystem var xmlFilePath = Path.Combine(DirectoryUtil.AssemblyDirectory, "example.xml"); await File.WriteAllTextAsync(xmlFilePath, payrollStampingResult.PayrollStampingResultDetails.FirstOrDefault().XML); Assert.True(File.Exists(xmlFilePath)); //Save PDF to FileSystem var outPDFFilePath = Path.Combine(DirectoryUtil.AssemblyDirectory, "example.pdf"); await File.WriteAllBytesAsync(outPDFFilePath, pdfBytes); Assert.True(File.Exists(outPDFFilePath)); } catch (Exception ex) { var t = ex.ToString(); Assert.True(false, ex.ToString()); } }
private async Task saveOverdraftStampedAsync(PayrollStampingParams payrollStampingParams, PayrollStampingResult payrollStampingResult) { var details = payrollStampingResult.PayrollStampingResultDetails .Where(p => p.PayrollStampingResultStatus == PayrollStampingResultStatus.Success); using (var connection = new SqlConnection(ConnectionManager.ConfigConnectionString)) { if (connection.State != ConnectionState.Open) { await connection.OpenAsync(); } using (var command = connection.CreateCommand()) { command.CommandType = CommandType.StoredProcedure; command.CommandText = STORED_PROCEDURE_SAVEOVERDRAFT; //PeriodDetails Parameter var periodDetailIds = details .Select(p => p.PeriodDetailID).ToList(); if (periodDetailIds.Any()) { DataTable dtGuidList = new DataTable(); dtGuidList.Columns.Add("ID", typeof(string)); periodDetailIds.ForEach(p => { dtGuidList.Rows.Add(p); }); SqlParameter param = new SqlParameter("@PeriodDetailIds", SqlDbType.Structured) { TypeName = "dbo.guidlisttabletype", Value = dtGuidList }; command.Parameters.Add(param); //OverdraftIds Parameter var overdraftIds = details .Select(p => new { p.OverdraftID, p.UUID }).ToList(); DataTable dtOverdraftGuidList = new DataTable(); dtOverdraftGuidList.Columns.Add("ID", typeof(string)); dtOverdraftGuidList.Columns.Add("UUID", typeof(string)); overdraftIds.ForEach(p => { dtOverdraftGuidList.Rows.Add(p.OverdraftID, p.UUID); }); SqlParameter paramOverdraftIdsTable = new SqlParameter("@OverdraftIds", SqlDbType.Structured) { TypeName = "dbo.stampoverdrafttabletype", Value = dtOverdraftGuidList }; command.Parameters.Add(paramOverdraftIdsTable); command.Parameters.AddWithValue("@InstanceId", payrollStampingParams.InstanceID); command.Parameters.AddWithValue("@company", payrollStampingParams.IdentityWorkID); command.Parameters.AddWithValue("@user", payrollStampingParams.user); //Execute SP de autorización await command.ExecuteNonQueryAsync(); } } } }
public async Task <PayrollStampingResult> PayrollStampingAsync(PayrollStampingParams payrollStampingParams) { Trace.WriteLine("Llega al PayrollStampingAsync"); //Obtiene todos los historic overdrafts del periodo seleccionado var historicOverdraftManager = new MiddlewareManager <Overdraft>(new BaseRecordManager <Overdraft>(), new OverdraftValidator()); var incidentsManager = new MiddlewareManager <Incident>(new BaseRecordManager <Incident>(), new IncidentValidator()); var inhabilitiesManager = new MiddlewareManager <Inhability>( new BaseRecordManager <Inhability>(), new InhabilityValidator()); List <Overdraft> historicOverdraftsToStamp = null; List <Incident> incidents = null; List <Inhability> inhabilities = null; List <EmployerFiscalInformation> employerFiscalInformations = null; List <PayrollCompanyConfiguration> payrollConfigurations = null; if (payrollStampingParams.Detail.Any()) { var overdraftsIds = payrollStampingParams.Detail.Select(p => p.OverdraftID); historicOverdraftsToStamp = await historicOverdraftManager.FindByExpressionAsync(p => p.company == payrollStampingParams.IdentityWorkID && p.InstanceID == payrollStampingParams.InstanceID && p.PeriodDetailID == payrollStampingParams.PeriodDetailID && overdraftsIds.Contains(p.ID) && p.OverdraftStatus == OverdraftStatus.Authorized && p.Active, payrollStampingParams.IdentityWorkID, new string[] { "OverdraftPreviousCancelRelationship", "OverdraftDetails", "OverdraftDetails.ConceptPayment", "PeriodDetail", "PeriodDetail.Period", "HistoricEmployee", "HistoricEmployee.Employee", "HistoricEmployee.Employee.Workshift", "HistoricEmployee.Employee.EmployerRegistration" }); incidents = await incidentsManager.FindByExpressionAsync(p => p.PeriodDetailID == payrollStampingParams.PeriodDetailID && p.InstanceID == payrollStampingParams.InstanceID, payrollStampingParams.IdentityWorkID, new string[] { "IncidentType" }); var initialDate = historicOverdraftsToStamp.FirstOrDefault().PeriodDetail.InitialDate; var finalDate = historicOverdraftsToStamp.FirstOrDefault().PeriodDetail.FinalDate; //Incapacidades dentro del periodo inhabilities = await inhabilitiesManager.FindByExpressionAsync(p => p.InstanceID == payrollStampingParams.InstanceID && ( (p.InitialDate >= initialDate && p.InitialDate.AddDays(p.AuthorizedDays - 1) <= finalDate) || (p.InitialDate >= initialDate && p.InitialDate.AddDays(p.AuthorizedDays - 1) > finalDate) || (p.InitialDate < initialDate && p.InitialDate.AddDays(p.AuthorizedDays - 1) <= finalDate) || (p.InitialDate <initialDate && p.InitialDate.AddDays(p.AuthorizedDays - 1)> finalDate) ), payrollStampingParams.IdentityWorkID); //Obtiene la información fiscal del patrón, certificados var employerFiscalInformationManager = new MiddlewareManager <EmployerFiscalInformation>(new BaseRecordManager <EmployerFiscalInformation>(), new EmployerFiscalInformationValidator()); employerFiscalInformations = await employerFiscalInformationManager.FindByExpressionAsync(p => p.company == payrollStampingParams.IdentityWorkID && p.InstanceID == payrollStampingParams.InstanceID, payrollStampingParams.IdentityWorkID); if (!employerFiscalInformations.Any()) { throw new CotorraException(105, "105", "No se han configurado los certificados (CSD) de la empresa para poder timbrar. Ve al menú Catálogos -> Certificados -> Agregar nuevo", null); } //Obtiene la configuración general de la empresa var payrollCompanyConfigurationManager = new MiddlewareManager <PayrollCompanyConfiguration>(new BaseRecordManager <PayrollCompanyConfiguration>(), new PayrollCompanyConfigurationValidator()); payrollConfigurations = await payrollCompanyConfigurationManager.FindByExpressionAsync(p => p.company == payrollStampingParams.IdentityWorkID && p.InstanceID == payrollStampingParams.InstanceID, payrollStampingParams.IdentityWorkID, new string[] { "Address" }); } else { throw new CotorraException(101, "101", "No se proporcionó los detalles correspondientes para timbrar.", null); } if (!historicOverdraftsToStamp.Any()) { throw new CotorraException(101, "101", "No hay ningún sobrerecibo a timbrar en estatus autorizado, con los parámetros proporcionados.", null); } return(await payrollStampingCoreAsync(payrollStampingParams, historicOverdraftsToStamp, incidents, inhabilities, employerFiscalInformations, payrollConfigurations)); }
private async Task <PayrollStampingResult> payrollStampingCoreAsync(PayrollStampingParams payrollStampingParams, List <Overdraft> historicOverdraftsToStamp, List <Incident> incidents, List <Inhability> inhabilities, List <EmployerFiscalInformation> employerFiscalInformations, List <PayrollCompanyConfiguration> payrollConfigurations) { var payrollStampingResult = new PayrollStampingResult(); List <string> zipCodesToFind = historicOverdraftsToStamp.Select(p => p.HistoricEmployee.EmployerRegistrationZipCode).ToList(); zipCodesToFind.AddRange(payrollConfigurations.Select(p => p.Address?.ZipCode)); //Obtener los zipCodes var zipCodeMiddlewareManager = new MiddlewareManager <catCFDI_CodigoPostal>( new BaseRecordManager <catCFDI_CodigoPostal>(), new catCFDI_CodigoPostalValidator()); var zipCodes = await zipCodeMiddlewareManager.FindByExpressionAsync(p => zipCodesToFind.Contains(p.c_CodigoPostal) , payrollStampingParams.IdentityWorkID); //Round for currency var roundUtil = new RoundUtil(payrollStampingParams.Currency.ToString()); //Zip Code manager var zipCodeManager = new ZipCodeManager(zipCodes); //Blob Storage Util var blobStorageUtil = new BlobStorageUtil(payrollStampingParams.InstanceID); await blobStorageUtil.InitializeAsync(); ISendMailProvider sendMailProvider = FactoryMailProvider.CreateInstance(SendMailProvider.SendGrid); var tasks = new List <Task <List <PayrollStampingResultDetail> > >(); foreach (var overdraftToStamp in historicOverdraftsToStamp) { tasks.Add(doWorkAsync(overdraftToStamp, roundUtil, zipCodeManager, payrollStampingParams, blobStorageUtil, sendMailProvider, incidents, inhabilities, employerFiscalInformations, payrollConfigurations)); } ConcurrentBag <PayrollStampingResultDetail> payrollStampingDetails = new ConcurrentBag <PayrollStampingResultDetail>(); foreach (var task in await Task.WhenAll(tasks)) { foreach (var insideTask in task) { payrollStampingDetails.Add(insideTask); } } payrollStampingResult.PayrollStampingResultDetails = payrollStampingDetails.ToList(); //Update DB indicate that Overdraft was stamped correctly / PeriodDetail await saveOverdraftStampedAsync(payrollStampingParams, payrollStampingResult); //Errors preparation if (payrollStampingResult.PayrollStampingResultDetails.Any(p => p.PayrollStampingResultStatus == PayrollStampingResultStatus.Fail)) { var errorMessages = payrollStampingResult.PayrollStampingResultDetails.Select(p => p.Message); throw new CotorraException(109, "109", string.Join("\n", errorMessages), null); } return(payrollStampingResult); }
private async Task <List <PayrollStampingResultDetail> > doWorkAsync(Overdraft overdraftToStamp, RoundUtil roundUtil, ZipCodeManager zipCodeManager, PayrollStampingParams payrollStampingParams, BlobStorageUtil blobStorageUtil, ISendMailProvider sendMailProvider, List <Incident> incidents, List <Inhability> inhabilities, List <EmployerFiscalInformation> employerFiscalInformations, List <PayrollCompanyConfiguration> payrollConfigurations) { var payrollStampingResultDetail = new PayrollStampingResultDetail(); var payrollStampingResultDetails = new List <PayrollStampingResultDetail>(); //Obtiene los xmls de los comprobantes segun la version de CFDI especificada IFiscalStamping fiscalStamping = FiscalStampingFactory.CreateInstance(payrollStampingParams.FiscalStampingVersion); //1. Get totals var overdraftResults = new OverdraftManager().GetTotals(overdraftToStamp, roundUtil); //1.1 Datetime for zipCode (var zipcode, var datetimeFromZipCode) = await zipCodeManager.GetZipCode(overdraftToStamp, payrollConfigurations.FirstOrDefault()); //2. Get XML - Creates comprobante var payrolllStampingDetail = payrollStampingParams.Detail .FirstOrDefault(detail => detail.OverdraftID == overdraftToStamp.ID); ICFDINomProvider cfdi = null; try { cfdi = fiscalStamping.CreateComprobante(new CreateComprobanteParams() { PayrollStampingDetail = payrolllStampingDetail, PayrollStampingParams = payrollStampingParams, Overdraft = overdraftToStamp, OverdraftResults = overdraftResults, PayrollCompanyConfiguration = payrollConfigurations.FirstOrDefault(), CFDIDateTimeStamp = datetimeFromZipCode, ZipCode = zipcode, RoundUtil = roundUtil, Incidents = incidents, Inhabilities = inhabilities }); } catch (Exception ex) { //Errores en validaciónes de armado / fiscales payrollStampingResultDetail.Message = ex.Message; payrollStampingResultDetail.PayrollStampingResultStatus = PayrollStampingResultStatus.Fail; payrollStampingResultDetail.HistoricEmployeeID = overdraftToStamp.HistoricEmployeeID.Value; payrollStampingResultDetail.EmployeeID = overdraftToStamp.HistoricEmployee.EmployeeID; payrollStampingResultDetail.OverdraftID = overdraftToStamp.ID; payrollStampingResultDetail.Overdraft = overdraftToStamp; payrollStampingResultDetail.PeriodDetailID = overdraftToStamp.PeriodDetailID; payrollStampingResultDetail.PeriodDetail = overdraftToStamp.PeriodDetail; payrollStampingResultDetails.Add(payrollStampingResultDetail); return(payrollStampingResultDetails); } //3. Sign XML var certificateCER = employerFiscalInformations.FirstOrDefault().CertificateCER; var certificateKey = employerFiscalInformations.FirstOrDefault().CertificateKEY; var certPassword = employerFiscalInformations.FirstOrDefault().CertificatePwd; //Decrypt (var certificatebytesCER, var certificatebytesKEY, var certPasswordResult) = Crypto(payrollStampingParams, certificateCER, certificateKey, certPassword); var stampingResult = fiscalStamping.SignDocument(cfdi, certificatebytesCER, certificatebytesKEY, certPasswordResult); //Set the employer stampingResult.EmployerRFC = payrollConfigurations.FirstOrDefault().RFC; //4. Stamp XML stampingResult = await fiscalStamping.StampDocumetAsync(stampingResult); if (stampingResult.WithErrors) { //error en el timbrado var errrorMessage = $"\nPara el empleado <strong>'{overdraftToStamp.HistoricEmployee.FullName}'</strong> encontramos los siguientes errores de timbrado: '{stampingResult.Details}'"; payrollStampingResultDetail.Message = errrorMessage; payrollStampingResultDetail.PayrollStampingResultStatus = PayrollStampingResultStatus.Fail; } else { //5. Return the complete XML stampingResult.XML = fiscalStamping.CreateXml <ICFDINomProvider>(stampingResult.CFDI, true); //5.5 Fill the result data payrollStampingResultDetail.Message = String.Empty; payrollStampingResultDetail.UUID = stampingResult.UUID; payrollStampingResultDetail.XML = stampingResult.XML; payrollStampingResultDetail.PayrollStampingResultStatus = PayrollStampingResultStatus.Success; //6. Fill the result data overdraftToStamp.UUID = stampingResult.UUID; overdraftToStamp.OverdraftStatus = OverdraftStatus.Stamped; //Fire and forget convertion and sending email fireAndForgetAsync(payrollStampingParams, overdraftToStamp, payrollConfigurations, blobStorageUtil, sendMailProvider, payrollStampingResultDetail.UUID, payrollStampingResultDetail.XML); //Fill the result object payrollStampingResultDetail.HistoricEmployeeID = overdraftToStamp.HistoricEmployeeID.Value; payrollStampingResultDetail.EmployeeID = overdraftToStamp.HistoricEmployee.EmployeeID; payrollStampingResultDetail.OverdraftID = overdraftToStamp.ID; payrollStampingResultDetail.Overdraft = overdraftToStamp; payrollStampingResultDetail.PeriodDetailID = overdraftToStamp.PeriodDetailID; payrollStampingResultDetail.PeriodDetail = overdraftToStamp.PeriodDetail; } payrollStampingResultDetails.Add(payrollStampingResultDetail); return(payrollStampingResultDetails); }