200826PX Made PaymentReceipts more general as it depends on the template and installed pdf converter versions
This commit is contained in:
parent
63680d6f7e
commit
dcf3b05fff
|
@ -7,26 +7,37 @@ using dezentrale.model.money;
|
|||
|
||||
namespace dezentrale.core
|
||||
{
|
||||
public enum IntermediateFormat
|
||||
{
|
||||
Text,
|
||||
SvgInkscape092,
|
||||
SvgInkscapeNew,
|
||||
Latex
|
||||
}
|
||||
|
||||
public interface IPaymentReceiptProcessData
|
||||
{
|
||||
string SvgTemplate { get; set; }
|
||||
string OutputDirectory { get; set; }
|
||||
string FileNamePattern { get; set; }
|
||||
DateTime StartDate { get; set; }
|
||||
DateTime EndDate { get; set; }
|
||||
string DataTemplate { get; set; }
|
||||
IntermediateFormat DataFormat { get; set; }
|
||||
|
||||
string OutputDirectory { get; set; }
|
||||
string FileNamePattern { get; set; }
|
||||
DateTime StartDate { get; set; }
|
||||
DateTime EndDate { get; set; }
|
||||
}
|
||||
|
||||
//In order to be able to ReplaceReflect, we need to have the SvgData and SvgFileName field separated in a class
|
||||
class SvgFile : ReplaceReflectEntity<SvgFile>
|
||||
class IntermediateFile : ReplaceReflectEntity<IntermediateFile>
|
||||
{
|
||||
public string SvgFileName { get; set; } = "";
|
||||
public string SvgData { get; set; } = "";
|
||||
|
||||
public SvgFile() { }
|
||||
public SvgFile(string fileName)
|
||||
public string FileName { get; set; } = "";
|
||||
public string Data { get; set; } = "";
|
||||
|
||||
public IntermediateFile() { }
|
||||
public IntermediateFile(string fileName)
|
||||
{
|
||||
SvgFileName = fileName;
|
||||
SvgData = File.ReadAllText(fileName);
|
||||
FileName = fileName;
|
||||
Data = File.ReadAllText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,12 +66,12 @@ namespace dezentrale.core
|
|||
uint step = 0;
|
||||
try
|
||||
{
|
||||
List<string> svgOutputFiles = new List<string>();
|
||||
List<string> intermediateFiles = new List<string>();
|
||||
|
||||
LogTarget.StepStarted(step, "Loading source SVG template");
|
||||
SvgFile svgTemplate = new SvgFile(data.SvgTemplate);
|
||||
svgTemplate.SvgFileName = data.FileNamePattern;
|
||||
LogTarget.LogLine($"Loaded \"{data.SvgTemplate}\" ({svgTemplate.SvgData.Length} characters) into memory.", LogEvent.ELogLevel.Info, "PaymentReceiptProcess");
|
||||
IntermediateFile svgTemplate = new IntermediateFile(data.DataTemplate);
|
||||
svgTemplate.FileName = data.FileNamePattern;
|
||||
LogTarget.LogLine($"Loaded \"{data.DataTemplate}\" ({svgTemplate.Data.Length} characters) into memory.", LogEvent.ELogLevel.Info, "PaymentReceiptProcess");
|
||||
|
||||
|
||||
LogTarget.StepStarted(++step, "Filtering MoneyTransfers for the given timeframe");
|
||||
|
@ -86,16 +97,28 @@ namespace dezentrale.core
|
|||
LogTarget.LogLine($"Member {m.Nickname} ({m.Number}) doesn't reference MoneyTransfer {mt.Id} (from {mt.ValutaDate})", LogEvent.ELogLevel.Error, "PaymentReceiptProcess");
|
||||
continue;
|
||||
}
|
||||
SvgFile output = svgTemplate.ReplaceReflect(mt).ReplaceReflect(m);
|
||||
LogTarget.LogLine($"Generating file \"{output.SvgFileName}\"", LogEvent.ELogLevel.Info, "PaymentReceiptProcess");
|
||||
File.WriteAllText(output.SvgFileName, output.SvgData);
|
||||
svgOutputFiles.Add(output.SvgFileName);
|
||||
IntermediateFile output = svgTemplate.ReplaceReflect(mt).ReplaceReflect(m);
|
||||
LogTarget.LogLine($"Generating file \"{output.FileName}\"", LogEvent.ELogLevel.Info, "PaymentReceiptProcess");
|
||||
File.WriteAllText(output.FileName, output.Data);
|
||||
intermediateFiles.Add(output.FileName);
|
||||
}
|
||||
|
||||
LogTarget.StepStarted(++step, "Converting SVGs to PDF using Inkscape");
|
||||
foreach (string svg in svgOutputFiles)
|
||||
LogTarget.StepStarted(++step, "Converting intermediate files to PDF using Inkscape");
|
||||
foreach (string iFile in intermediateFiles)
|
||||
{
|
||||
ImportExportBase.RunProcess("inkscape", $"{svg} --export-filename={svg}.pdf ", ".", LogTarget);
|
||||
switch(data.DataFormat)
|
||||
{
|
||||
case IntermediateFormat.Text: break;
|
||||
case IntermediateFormat.SvgInkscape092:
|
||||
ImportExportBase.RunProcess("inkscape", $"{iFile} --export-pdf={iFile}.pdf", ".", LogTarget);
|
||||
break;
|
||||
case IntermediateFormat.SvgInkscapeNew:
|
||||
ImportExportBase.RunProcess("inkscape", $"{iFile} --export-type=pdf --export-filename={iFile}.pdf", ".", LogTarget);
|
||||
break;
|
||||
case IntermediateFormat.Latex:
|
||||
ImportExportBase.RunProcess("pdflatex", $"{iFile}", ".", LogTarget);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LogTarget.StepStarted(++step, "E-Mail the PDFs to the members");
|
||||
|
|
|
@ -4,10 +4,11 @@ using System.Linq;
|
|||
using System.Net.Mail;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using dezentrale.core;
|
||||
|
||||
namespace dezentrale.model
|
||||
{
|
||||
public class FormMail
|
||||
public class FormMail : ReplaceReflectEntity<FormMail>
|
||||
{
|
||||
public string To { get; set; } = "{Nickname} <{EMail}>";
|
||||
public string Subject { get; set; }
|
||||
|
@ -25,7 +26,7 @@ namespace dezentrale.model
|
|||
}
|
||||
}
|
||||
|
||||
public FormMail ReplaceReflect(object o)
|
||||
/*public FormMail ReplaceReflect(object o)
|
||||
{
|
||||
FormMail ret = new FormMail(this);
|
||||
|
||||
|
@ -69,7 +70,7 @@ namespace dezentrale.model
|
|||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}*/
|
||||
|
||||
public LogSubEvent Send(object replaceReflect = null, List<string> files = null)
|
||||
{
|
||||
|
|
|
@ -241,14 +241,15 @@ namespace dezentrale.view
|
|||
}
|
||||
private void mnuMain_Payments_Receipts(object sender, EventArgs e)
|
||||
{
|
||||
frmPaymentReceipts receipts = new frmPaymentReceipts();
|
||||
frmPaymentReceipts receipts = new frmPaymentReceipts()
|
||||
{
|
||||
StartDate = new DateTime(2020, 01, 01),
|
||||
EndDate = new DateTime(2020, 12, 31),
|
||||
FileNamePattern = "Member{MemberNumber}-{ValutaDateString}-{AmountString}{Currency}"
|
||||
};
|
||||
DialogResult dr = receipts.ShowDialog();
|
||||
if(dr == DialogResult.OK)
|
||||
{
|
||||
receipts.SvgTemplate = "dezentrale-beitragsquittung-template.svg";
|
||||
receipts.StartDate = new DateTime(2020, 01, 01);
|
||||
receipts.EndDate = new DateTime(2020, 12, 31);
|
||||
receipts.FileNamePattern = "Member{MemberNumber}-{ValutaDateString}-{AmountString}{Currency}.svg";
|
||||
{
|
||||
PaymentReceiptProcess rec = new PaymentReceiptProcess(receipts);
|
||||
frmProcessWithLog frmRec = new frmProcessWithLog(rec, true);
|
||||
dr = frmRec.ShowDialog();
|
||||
|
|
|
@ -12,14 +12,16 @@ namespace dezentrale.view
|
|||
public class frmPaymentReceipts : FormWithOkCancel, IPaymentReceiptProcessData
|
||||
{
|
||||
|
||||
public string SvgTemplate { get; set; } = "";
|
||||
public string OutputDirectory { get; set; } = "";
|
||||
public string FileNamePattern { get; set; } = "{Number}-{Date}";
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public string DataTemplate { get; set; } = "";
|
||||
public IntermediateFormat DataFormat { get; set; } = IntermediateFormat.Text;
|
||||
public string OutputDirectory { get; set; } = "";
|
||||
public string FileNamePattern { get; set; } = "{Number}-{Date}";
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
|
||||
|
||||
private TextBox tbSvgTemplate;
|
||||
private TextBox tbTemplate;
|
||||
private ComboBox cbDataFormat;
|
||||
private TextBox tbOutputDirectory;
|
||||
private TextBox tbFileNamePattern;
|
||||
private DateTimePicker dtStartDate;
|
||||
|
@ -27,11 +29,117 @@ namespace dezentrale.view
|
|||
|
||||
public frmPaymentReceipts()
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
this.StartPosition = FormStartPosition.CenterParent;
|
||||
this.Size = new System.Drawing.Size(500, 400);
|
||||
this.Text = "Generate payment receipts";
|
||||
this.Controls.Add(new Label()
|
||||
{
|
||||
Text = "Input template:",
|
||||
Location = new Point(lm, 0 * line + tm + labelOffs),
|
||||
Size = new Size(110, labelHeight),
|
||||
TextAlign = ContentAlignment.BottomRight,
|
||||
});
|
||||
this.Controls.Add(tbTemplate = new TextBox()
|
||||
{
|
||||
Location = new Point(lm + 113, 0 * line + tm),
|
||||
Width = 200,
|
||||
});
|
||||
Button btnBrowseTemplate;
|
||||
this.Controls.Add(btnBrowseTemplate = new Button()
|
||||
{
|
||||
Text = "...",
|
||||
Location = new Point(lm + 333, 0 * line + tm),
|
||||
Width = 40,
|
||||
});
|
||||
btnBrowseTemplate.Click += btnBrowseTemplate_Click;
|
||||
|
||||
this.Controls.Add(new Label()
|
||||
{
|
||||
Text = "Data format:",
|
||||
Location = new Point(lm, 1 * line + tm + labelOffs),
|
||||
Size = new Size(110, labelHeight),
|
||||
TextAlign = ContentAlignment.BottomRight,
|
||||
});
|
||||
this.Controls.Add(cbDataFormat = new ComboBox()
|
||||
{
|
||||
DropDownStyle = ComboBoxStyle.DropDownList,
|
||||
Location = new Point(lm + 113, 1 * line + tm),
|
||||
Width = 200,
|
||||
});
|
||||
foreach (IntermediateFormat fmt in Enum.GetValues(typeof(IntermediateFormat)))
|
||||
cbDataFormat.Items.Add(fmt);
|
||||
|
||||
this.Controls.Add(new Label()
|
||||
{
|
||||
Text = "Output directory:",
|
||||
Location = new Point(lm, 2 * line + tm + labelOffs),
|
||||
Size = new Size(110, labelHeight),
|
||||
TextAlign = ContentAlignment.BottomRight,
|
||||
});
|
||||
this.Controls.Add(tbOutputDirectory = new TextBox()
|
||||
{
|
||||
Location = new Point(lm + 113, 2 * line + tm),
|
||||
Width = 200,
|
||||
});
|
||||
Button btnBrowseOutputDir;
|
||||
this.Controls.Add(btnBrowseOutputDir = new Button()
|
||||
{
|
||||
Text = "...",
|
||||
Location = new Point(lm + 333, 2 * line + tm),
|
||||
Width = 40,
|
||||
});
|
||||
btnBrowseOutputDir.Click += btnBrowseOutputDir_Click;
|
||||
|
||||
this.Controls.Add(new Label()
|
||||
{
|
||||
Text = "Filename pattern:",
|
||||
Location = new Point(lm, 3 * line + tm + labelOffs),
|
||||
Size = new Size(110, labelHeight),
|
||||
TextAlign = ContentAlignment.BottomRight,
|
||||
});
|
||||
this.Controls.Add(tbFileNamePattern = new TextBox()
|
||||
{
|
||||
Location = new Point(lm + 113, 3 * line + tm),
|
||||
Width = 240,
|
||||
});
|
||||
|
||||
|
||||
AddOkCancel(this, btnOK_Click, btnCancel_Click);
|
||||
|
||||
//We must run the filling of the data fields in the load event, as they
|
||||
//might have been changed after the constructor is executed
|
||||
this.Shown += (sender, e) =>
|
||||
{
|
||||
tbTemplate.Text = DataTemplate;
|
||||
cbDataFormat.SelectedItem = DataFormat;
|
||||
tbOutputDirectory.Text = OutputDirectory;
|
||||
};
|
||||
}
|
||||
|
||||
private void btnBrowseTemplate_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog();
|
||||
DialogResult dr = ofd.ShowDialog();
|
||||
if(dr == DialogResult.OK)
|
||||
{
|
||||
tbTemplate.Text = ofd.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnBrowseOutputDir_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderBrowserDialog fbd = new FolderBrowserDialog();
|
||||
DialogResult dr = fbd.ShowDialog();
|
||||
if (dr == DialogResult.OK)
|
||||
{
|
||||
tbOutputDirectory.Text = fbd.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
DataTemplate = tbTemplate.Text;
|
||||
DialogResult = DialogResult.OK;
|
||||
this.Close();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue