143 lines
5.4 KiB
C#
143 lines
5.4 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using System.IO;
|
|
using Elwig.Helpers;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using System.Linq;
|
|
|
|
namespace Elwig.Documents {
|
|
public abstract partial class Document : IDisposable {
|
|
|
|
private TempFile? _pdfFile = null;
|
|
private string? _renderedHtml = null;
|
|
|
|
public bool ShowFoldMarks = App.Config.Debug;
|
|
|
|
public string DataPath;
|
|
public int CurrentNextSeason;
|
|
public string? DocumentId;
|
|
public string Title;
|
|
public string Author;
|
|
public string Header;
|
|
public string Footer;
|
|
public DateTime Date;
|
|
|
|
public Document(string title) {
|
|
var c = App.Client;
|
|
DataPath = App.DataPath;
|
|
CurrentNextSeason = Utils.CurrentNextSeason;
|
|
Title = title;
|
|
Author = c.NameFull;
|
|
Header = $"<div class='name'>{c.Name}</div><div class='suffix'>{c.NameSuffix}</div>";
|
|
Footer = Utils.GenerateFooter("<br/>", " \u00b7 ")
|
|
.Item(c.NameFull).NextLine()
|
|
.Item(c.Address).Item($"{c.Plz} {c.Ort}").Item("Österreich").Item("Tel.", c.PhoneNr).Item("Fax", c.FaxNr).NextLine()
|
|
.Item(c.EmailAddress).Item(c.Website).Item("Betriebs-Nr.", c.LfbisNr).Item("UID", c.UstIdNr).NextLine()
|
|
.Item("BIC", c.Bic).Item("IBAN", c.Iban)
|
|
.ToString();
|
|
Date = DateTime.Today;
|
|
}
|
|
|
|
[GeneratedRegex(@"</body>.*?</footer>\s*</div>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled)]
|
|
private static partial Regex GeneratedDocumentHeaderRegex();
|
|
private static readonly Regex DocumentHeaderRegex = GeneratedDocumentHeaderRegex();
|
|
|
|
[GeneratedRegex(@"<style>.*?/style>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled)]
|
|
private static partial Regex GeneratedHtmlStyleRegex();
|
|
private static readonly Regex HtmlStyleRegex = GeneratedHtmlStyleRegex();
|
|
|
|
[GeneratedRegex(@"<link[^>]*>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled)]
|
|
private static partial Regex GeneratedHtmlLinkRegex();
|
|
private static readonly Regex HtmlLinkRegex = GeneratedHtmlLinkRegex();
|
|
|
|
~Document() {
|
|
Dispose();
|
|
}
|
|
|
|
public void Dispose() {
|
|
_pdfFile?.Dispose();
|
|
_pdfFile = null;
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public static async Task<Document> Merge(IEnumerable<Document> docs) {
|
|
string html = "";
|
|
var styles = new List<string>();
|
|
foreach (var d in docs) {
|
|
var h = await d.Render();
|
|
var s = HtmlStyleRegex.Matches(h).Select(m => m.Value).ToList();
|
|
var l = HtmlLinkRegex.Matches(h).Select(m => m.Value).ToList();
|
|
if (s.All(styles.Contains)) {
|
|
h = HtmlStyleRegex.Replace(h, "");
|
|
} else {
|
|
styles.AddRange(s);
|
|
}
|
|
if (l.All(styles.Contains)) {
|
|
h = HtmlLinkRegex.Replace(h, "");
|
|
} else {
|
|
styles.AddRange(l);
|
|
}
|
|
html += h;
|
|
}
|
|
html = DocumentHeaderRegex.Replace(html, "<div class='document-break'/>");
|
|
return new InternalDocument("Mehrere Dokumente") {
|
|
_renderedHtml = html,
|
|
};
|
|
}
|
|
|
|
private async Task<string> Render() {
|
|
if (_renderedHtml != null)
|
|
return _renderedHtml;
|
|
string name;
|
|
if (this is BusinessLetter) {
|
|
name = "BusinessLetter";
|
|
} else if (this is DeliveryNote) {
|
|
name = "DeliveryNote";
|
|
} else if (this is CreditNote) {
|
|
name = "CreditNote";
|
|
} else if (this is DeliveryJournal) {
|
|
name = "DeliveryJournal";
|
|
} else if (this is Letterhead) {
|
|
name = "Letterhead";
|
|
} else {
|
|
throw new InvalidOperationException("Invalid document object");
|
|
}
|
|
return await Render(name);
|
|
}
|
|
|
|
private async Task<string> Render(string name) {
|
|
_renderedHtml = await Html.CompileRenderAsync(name, this);
|
|
return _renderedHtml;
|
|
}
|
|
|
|
public async Task Generate() {
|
|
var pdf = new TempFile("pdf");
|
|
using (var tmpHtml = new TempFile("html")) {
|
|
await File.WriteAllTextAsync(tmpHtml.FilePath, await Render(), Utils.UTF8);
|
|
await Pdf.Convert(tmpHtml.FilePath, pdf.FilePath);
|
|
}
|
|
_pdfFile = pdf;
|
|
}
|
|
|
|
public void SaveTo(string pdfPath) {
|
|
if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
|
|
File.Copy(_pdfFile.FilePath, pdfPath);
|
|
}
|
|
|
|
public async Task Print(int copies = 1) {
|
|
if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
|
|
await Pdf.Print(_pdfFile.FilePath, copies);
|
|
}
|
|
|
|
public void Show() {
|
|
if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
|
|
Pdf.Show(_pdfFile.NewReference(), Title);
|
|
}
|
|
|
|
private class InternalDocument : Document {
|
|
public InternalDocument(string title) : base(title) { }
|
|
}
|
|
}
|
|
}
|