public async Task <(bool Success, string Error, byte[] FileBytes, string FileName)> ExportLoanScheduleByReceiptIdAsync(int clientReceiptId) { var success = false; var error = ""; byte[] fileBytes = null; var fileName = ""; try { // fetch client info var receiptInfo = await _clientReceiptRepository.FetchFullByIdAsync(clientReceiptId); if (receiptInfo != null && receiptInfo.Client != null) { // fetch timezone for conversion var timeZone = _dateTimeService.FetchTimeZoneInfo(Constants.System.TimeZone); var receiptDate = _dateTimeService.ConvertUtcToDateTime(receiptInfo.CreatedUtc, timeZone); // prepare belonging list var belongingsList = await _clientBelongingRepository.ListClientBelongingByReceiptIdAsync(clientReceiptId); decimal loanAmount = 0; if (belongingsList?.Any() == true) { // order by name belongingsList = belongingsList.OrderBy(b => b.Metal).ToList(); foreach (var item in belongingsList) { if (item.TransactionAction == Constants.TransactionAction.Loan) { loanAmount += item.FinalPrice ?? 0; } } } var pdfLoanSchedule = new LoanSchedule(billDate: receiptDate, clientNumber: receiptInfo.Client.ReferenceNumber, receiptNumber: receiptInfo.ReceiptNumber, clientName: $"{receiptInfo.Client.FirstName } {receiptInfo.Client.LastName}", clientAddress: Encryption.Decrypt(receiptInfo.Client.AddressEncrypted, receiptInfo.Client.AddressUniqueKey), phoneNumber: Classes.Helper.FormatPhoneNumber(Encryption.Decrypt(receiptInfo.Client.ContactNumberEncrypted, receiptInfo.Client.ContactNumberUniqueKey)), emailAddress: receiptInfo.Client.EmailAddress, rootPath: _env.WebRootPath, loanAmount: loanAmount, loanPercent: _globalOptions.LoanPercentForCalc); // Create the document using MigraDoc. var pdfLoanScheduleDocument = pdfLoanSchedule.CreateDocument(); pdfLoanScheduleDocument.UseCmykColor = true; // Create a renderer for PDF that uses Unicode font encoding. var pdfRenderer = new PdfDocumentRenderer(true); // Set the MigraDoc document. pdfRenderer.Document = pdfLoanScheduleDocument; // Create the PDF document. pdfRenderer.RenderDocument(); // Save the loan schedule document... using (var stream = new MemoryStream()) { pdfRenderer.Save(stream, false); fileBytes = stream.ToArray(); } fileName = $"{receiptInfo.Client.FirstName}_{receiptInfo.Client.LastName}_{receiptInfo.ReceiptNumber}_LoanSchedule.pdf"; success = true; } else { error = "Unable to locate receipt information"; } } catch (Exception ex) { error = "Somethong went wrong while processing your request."; _logger.LogError("ClientService.ExportLoanScheduleByReceiptIdAsync - exception:{@Ex}", args: new object[] { ex }); } return(Success : success, Error : error, FileBytes : fileBytes, FileName : fileName); }
public async Task <(bool Success, string Error, byte[] FileBytes, string FileName)> ExportReceiptByReceiptIdAsync(int clientReceiptId) { var success = false; var error = ""; byte[] resultBytes = null; var fileName = ""; byte[] receiptBytes = null; byte[] loanScheduleBytes = null; try { var extension = "pdf"; // fetch client info var receiptInfo = await _clientReceiptRepository.FetchFullByIdAsync(clientReceiptId); if (receiptInfo != null && receiptInfo.Client != null) { // fetch timezone for conversion var timeZone = _dateTimeService.FetchTimeZoneInfo(Constants.System.TimeZone); var receiptDate = _dateTimeService.ConvertUtcToDateTime(receiptInfo.CreatedUtc, timeZone); // prepare belonging list var belongingsList = await _clientBelongingRepository.ListClientBelongingByReceiptIdAsync(clientReceiptId); decimal clientPays = 0; decimal clientGets = 0; decimal billAmount = 0; decimal loanAmount = 0; bool clientPaysFinal = false; decimal totalPurchase = 0; decimal totalSell = 0; decimal hstTotal = 0; if (belongingsList?.Any() == true) { // order by name to print in receipt belongingsList = belongingsList.OrderBy(b => b.Metal).ToList(); foreach (var item in belongingsList) { // calculate bill amount if (item.BusinessGetsMoney) { clientPays += item.FinalPrice ?? 0; } if (item.BusinessPaysMoney) { clientGets += item.FinalPrice ?? 0; } billAmount = Math.Abs(clientPays - clientGets); clientPaysFinal = clientPays > clientGets; // determine total loan amount from receipt if (item.TransactionAction == Constants.TransactionAction.Loan) { loanAmount += item.FinalPrice ?? 0; } // determine total purchase amount from receipt if (item.TransactionAction == Constants.TransactionAction.Sell) { // if business sells an item, it is purchase for client totalPurchase += item.FinalPrice ?? 0; } // determine total sell amount from receipt if (item.TransactionAction == Constants.TransactionAction.Purchase) { // if business purchases an item, it is sell for client totalSell += item.FinalPrice ?? 0; } hstTotal += item.HstAmount ?? 0; } } // prepare viewmodel ReceiptViewModel model = new ReceiptViewModel { BillDate = receiptDate, ClientNumber = receiptInfo.Client.ReferenceNumber, ReceiptNumber = receiptInfo.ReceiptNumber, ClientName = $"{receiptInfo.Client.FirstName} {receiptInfo.Client.LastName}", Address = Encryption.Decrypt(receiptInfo.Client.AddressEncrypted, receiptInfo.Client.AddressUniqueKey), ContactNumber = Classes.Helper.FormatPhoneNumber(Encryption.Decrypt(receiptInfo.Client.ContactNumberEncrypted, receiptInfo.Client.ContactNumberUniqueKey)), EmailAddress = receiptInfo.Client.EmailAddress, ClientPaysFinal = clientPaysFinal, PrincipalLoanAmount = loanAmount, PurchaseTotal = totalPurchase, SellTotal = totalSell, Belongings = belongingsList, HstTotal = hstTotal }; // calculate final total model.BillAmount = (model.HstTotal + model.PrincipalLoanAmount + model.PurchaseTotal) - model.SellTotal; // generate receipt var pdfReceipt = new Reports.ClientReceipt(model, _env.WebRootPath); // Create the document using MigraDoc. var pdfReceiptDocument = pdfReceipt.CreateDocument(); pdfReceiptDocument.UseCmykColor = true; // Create a renderer for PDF that uses Unicode font encoding. var pdfRenderer = new PdfDocumentRenderer(true) { // Set the MigraDoc document. Document = pdfReceiptDocument }; // Create the PDF document. pdfRenderer.RenderDocument(); // Save the receipt document... using (var stream = new MemoryStream()) { pdfRenderer.Save(stream, false); receiptBytes = stream.ToArray(); } // assign receipt bytes to result in case there is no loan schedule to add resultBytes = receiptBytes; // generate loan schedule and zip multiple documents, if required if (loanAmount > 0) { var pdfLoanSchedule = new LoanSchedule(billDate: receiptDate, clientNumber: receiptInfo.Client.ReferenceNumber, receiptNumber: receiptInfo.ReceiptNumber, clientName: $"{receiptInfo.Client.FirstName} {receiptInfo.Client.LastName}", clientAddress: Encryption.Decrypt(receiptInfo.Client.AddressEncrypted, receiptInfo.Client.AddressUniqueKey), phoneNumber: Classes.Helper.FormatPhoneNumber(Encryption.Decrypt(receiptInfo.Client.ContactNumberEncrypted, receiptInfo.Client.ContactNumberUniqueKey)), emailAddress: receiptInfo.Client.EmailAddress, rootPath: _env.WebRootPath, loanAmount: loanAmount, loanPercent: _globalOptions.LoanPercentForCalc); // Create the document using MigraDoc. var pdfLoanScheduleDocument = pdfLoanSchedule.CreateDocument(); pdfLoanScheduleDocument.UseCmykColor = true; // Create a renderer for PDF that uses Unicode font encoding. pdfRenderer = new PdfDocumentRenderer(true) { // Set the MigraDoc document. Document = pdfLoanScheduleDocument }; // Create the PDF document. pdfRenderer.RenderDocument(); // Save the loan schedule document... using (var stream = new MemoryStream()) { pdfRenderer.Save(stream, false); loanScheduleBytes = stream.ToArray(); } // zip both documents using (var compressedFileStream = new MemoryStream()) { //Create an archive and store the stream in memory. using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false)) { // add receipt if (receiptBytes != null) { var receiptEntry = zipArchive.CreateEntry($"{receiptInfo.Client.FirstName}_{receiptInfo.Client.LastName}_{receiptInfo.ReceiptNumber}_Receipt.pdf"); //Get the stream of the attachment using (var receiptStream = new MemoryStream(receiptBytes)) { using (var zipEntryStream = receiptEntry.Open()) { //Copy the attachment stream to the zip entry stream receiptStream.CopyTo(zipEntryStream); } } } // add loan schedule if (loanScheduleBytes != null) { var loanScheduleEntry = zipArchive.CreateEntry($"{receiptInfo.Client.FirstName}_{receiptInfo.Client.LastName}_{receiptInfo.ReceiptNumber}_LoanSchedule.pdf"); //Get the stream of the attachment using (var loanScheduleStream = new MemoryStream(loanScheduleBytes)) { using (var zipEntryStream = loanScheduleEntry.Open()) { //Copy the attachment stream to the zip entry stream loanScheduleStream.CopyTo(zipEntryStream); } } } } // override file bytes with zip file resultBytes = compressedFileStream.ToArray(); extension = "zip"; } } fileName = $"{receiptInfo.Client.FirstName}_{receiptInfo.Client.LastName}_{receiptInfo.ReceiptNumber}_Receipt.{extension}"; success = true; } else { error = "Unable to locate receipt information"; } } catch (Exception ex) { error = "Somethong went wrong while processing your request."; _logger.LogError("ClientService.ExportReceiptByReceiptIdAsync - exception:{@Ex}", args: new object[] { ex }); } return(Success : success, Error : error, FileBytes : resultBytes, FileName : fileName); }