diff --git a/Kotlib.test/Kotlib_452.test.csproj b/Kotlib.test/Kotlib_452.test.csproj index c65779a..22514c0 100644 --- a/Kotlib.test/Kotlib_452.test.csproj +++ b/Kotlib.test/Kotlib_452.test.csproj @@ -12,7 +12,7 @@ Properties False - v0.1-alpha.1 + v0.1-alpha.3 x86 diff --git a/Kotlib.test/Program.cs b/Kotlib.test/Program.cs index ca7e647..8f78a9d 100644 --- a/Kotlib.test/Program.cs +++ b/Kotlib.test/Program.cs @@ -277,16 +277,27 @@ public static void Main(string[] args) Console.WriteLine(); Console.WriteLine("Exportation des mouvements de tous les éléments bancaires au format CSV:"); - var csvs = fi2.Accounts.Export2CSV(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), fi2.Accounts.Select(a => a.Id).ToList(), DateTime.MinValue, DateTime.MaxValue); + var csvs = fi2.ToCSV(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), fi2.Accounts.Select(a => a.Id).ToList(), DateTime.MinValue, DateTime.MaxValue); foreach(var csv in csvs) Console.WriteLine("- {0} : {1}", fi2.Accounts.GetById(csv.Item1).Name, csv.Item2); Console.WriteLine(); Console.WriteLine("Exportation des mouvements de tous les éléments bancaires au format HTML:"); - var htmls = fi2.Export2Html(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), fi2.Accounts.Select(a => a.Id).ToList(), DateTime.MinValue, DateTime.MaxValue); + var htmls = fi2.ToHtml(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), fi2.Accounts.Select(a => a.Id).ToList(), DateTime.MinValue, DateTime.MaxValue); foreach (KeyValuePair html in htmls) Console.WriteLine("- {0} : {1}", fi2.Accounts.GetById(html.Key).Name, html.Value); + Console.WriteLine(); + Console.WriteLine("Exportation des mouvements de tous les éléments bancaires au format OFX:"); + var ofxs = fi2.ToOfx(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), fi2.Accounts.Select(a => a.Id).ToList(), DateTime.MinValue, DateTime.MaxValue); + foreach (KeyValuePair ofx in ofxs) + Console.WriteLine("- {0} : {1}", fi2.Accounts.GetById(ofx.Key).Name, ofx.Value); + + Console.WriteLine(); + Console.WriteLine("Exportation des mouvements de tous les éléments bancaires au format QIF:"); + var qif = fi2.ToQif(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), fi2.Accounts.Select(a => a.Id).ToList(), DateTime.MinValue, DateTime.MaxValue); + Console.WriteLine("- {0}", qif); + Console.ReadLine(); } diff --git a/Kotlib/Financial.cs b/Kotlib/Financial.cs index f710dc8..b290c49 100644 --- a/Kotlib/Financial.cs +++ b/Kotlib/Financial.cs @@ -27,14 +27,16 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using System.Security; using System.Text; -using System.Threading; using System.Threading.Tasks; using System.Xml; using System.Xml.Serialization; using Kotlib.Objects; using Kotlib.Tools; using System.Reflection; +using System.Linq.Expressions; + namespace Kotlib { @@ -886,18 +888,136 @@ public Tuple GetEventsInfosAt(Guid accountID, DateTime st } /// - /// Exporte les mouvements des éléments bancaires souhaités entre les dates spécifiées. + /// Exporte les mouvements d'un élément bancaire au format CSV /// /// - /// Liste des fichiers html résultants: - /// - Key: Identifiant unique de l'élément bancaire - /// - Value: Chemin du fichier HTML correspondant + /// Liste de structures comprenant chacune: + /// - Item 1: Identifiant unique de l'élément bancaire + /// - Item 2: Chemin du fichier CSV. /// /// Chemin du répertoire recevant les fichiers CSV. /// Liste d'identifiants uniques correspondant aux éléments bancaires à traiter. /// Date de début des mouvements pris en compte. /// Date de fin des mouvements pris en compte. - public Dictionary Export2Html(string directory, List accountsId, DateTime startDate, DateTime endDate) + /// Délimiteur de colones CSV. + /// Délimiteur des décimales. + /// Format des dates enregistrées. + public List> ToCSV(string directory, List accountsId, DateTime startDate, DateTime endDate, string delimiter = ";", string decimalSeparator = ",", string dateFormat = "dd/MM/yyyy") + { + var d = directory.Trim().Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.Personal)); + if (!Directory.Exists(d)) + throw new DirectoryNotFoundException(); + + var filenames = new List>(); + + var columns = new string[] { "Date", "Débit", "Crédit", "Libellé" }; + foreach (var uid in accountsId) + { + var a = Accounts.GetById(uid); + if (a == null || a.Equals(default(Account))) + continue; + + var operations = a.Operations.Items + .Where(o => o.Active && o.Date.Date >= startDate.Date && o.Date.Date <= endDate.Date) + .Select(o => new Dictionary() + { + ["Sorter"] = o.Date.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), + [columns[0]] = o.Date.Date.ToString(dateFormat), + [columns[1]] = (o.Amount < 0m) ? Math.Round(o.Amount, 2).ToString("0.00").Replace(".", decimalSeparator) : "0.00", + [columns[2]] = (o.Amount >= 0m) ? Math.Round(o.Amount, 2).ToString("0.00").Replace(".", decimalSeparator) : "0.00", + [columns[3]] = o.Name + }) + .ToList(); + + var transfersOut = Accounts.Transfers.Items + .Where(t => t.Active && t.FromAccountId.Equals(a.Id) && t.Date.Date >= startDate.Date && t.Date.Date <= endDate.Date) + .Select(t => new Dictionary() + { + ["Sorter"] = t.Date.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), + [columns[0]] = t.Date.Date.ToString(dateFormat), + [columns[1]] = "-" + Math.Round(Math.Abs(t.Amount), 2).ToString("0.00").Replace(".", decimalSeparator), + [columns[2]] = "0.00", + [columns[3]] = t.Name + }) + .ToList(); + + var transfersIn = Accounts.Transfers.Items + .Where(t => t.Active && t.ToAccountId.Equals(a.Id) && t.Date.Date >= startDate.Date && t.Date.Date <= endDate.Date) + .Select(t => new Dictionary() + { + ["Sorter"] = t.Date.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), + [columns[0]] = t.Date.Date.ToString(dateFormat), + [columns[1]] = "0.00", + [columns[2]] = Math.Round(Math.Abs(t.Amount), 2).ToString("0.00").Replace(".", decimalSeparator), + [columns[3]] = t.Name + }) + .ToList(); + + var mvts = new List>(); + mvts.AddRange(operations); + mvts.AddRange(transfersIn); + mvts.AddRange(transfersOut); + + mvts.Sort((mvt1, mvt2) => + { + var d1 = DateTime.ParseExact(mvt1["Sorter"], "yyyy-MM-dd", CultureInfo.InvariantCulture); + var d2 = DateTime.ParseExact(mvt2["Sorter"], "yyyy-MM-dd", CultureInfo.InvariantCulture); + + if (d2 > d1) + return -1; + + if (d2 < d1) + return 1; + + return 0; + }); + + var lines = new List() { string.Join(delimiter, columns.ToArray()) }; + foreach (var m in mvts) + { + var lColumns = new List(); + foreach (var c in columns) + { + if (m.Keys.Contains(c)) + lColumns.Add(m[c]); + else + lColumns.Add(""); + } + lines.Add(string.Join(delimiter, lColumns.ToArray())); + } + + var filename = String.Join("_", a.Name.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); + + var fp = Path.Combine(d, filename) + ".csv"; + fp = Path.GetFullPath(fp); + + using (StreamWriter sw = new StreamWriter(File.Open(fp, FileMode.Create), Encoding.UTF8)) + { + foreach (var line in lines) + sw.WriteLine(line); + } + lines.Clear(); + + filenames.Add(new Tuple(a.Id, fp)); + } + + return filenames; + } + + /// + /// Exporte les mouvements des éléments bancaires souhaités entre les dates spécifiées. + /// + /// + /// Liste des fichiers HTML résultants: + /// - Key: Identifiant unique de l'élément bancaire + /// - Value: Chemin du fichier HTML correspondant + /// + /// Chemin du répertoire recevant les fichiers HTML. + /// Liste d'identifiants uniques correspondant aux éléments bancaires à traiter. + /// Date de début des mouvements pris en compte. + /// Date de fin des mouvements pris en compte. + /// true, retourne le contenu HTML sans crééer de fichier HTML, sinon, false + public Dictionary ToHtml(string directory, List accountsId, DateTime startDate, DateTime endDate, bool contentReturns = false) { var d = directory.Trim().Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.Personal)); if (!Directory.Exists(d)) @@ -905,7 +1025,7 @@ public Dictionary Export2Html(string directory, List account var filenames = new Dictionary(); - var lst = Accounts.Export2List(directory, accountsId, startDate, endDate); + var lst = Accounts.GetAccountStatements(directory, accountsId, startDate, endDate); foreach (KeyValuePair>> kvp in lst) { @@ -924,7 +1044,7 @@ public Dictionary Export2Html(string directory, List account {4} {5} {6} - ", + ", CultureName, a.Name, "Dénomination", "Note", "Type", "Débit", "Crédit"); var mvts = kvp.Value.OrderByDescending(i => i.Key); @@ -935,7 +1055,7 @@ public Dictionary Export2Html(string directory, List account html += string.Format(@" {0} {1} {2} - ", + ", kvp2.Key.ToLongDateString(), "solde:", Currency.Format(amount), (amount < 0m ? "red" : "black")); foreach (var ot in kvp2.Value) @@ -976,11 +1096,178 @@ public Dictionary Export2Html(string directory, List account } } - html += string.Format(@"

{0} {1}

", + html += string.Format(@"

{0} {1}

", GetType().Assembly.GetName().Name, GetType().Assembly.GetName().Version); + if (!contentReturns) + { + using (StreamWriter sw = new StreamWriter(File.Open(fp, FileMode.Create), Encoding.UTF8)) + sw.Write(html); + + filenames.Add(a.Id, fp); + } + else + filenames.Add(a.Id, html); + + } + + return filenames; + } + + /// + /// Exporte les mouvements des éléments bancaires souhaités entre les dates spécifiées. + /// + /// + /// Liste des fichiers OFX résultants: + /// - Key: Identifiant unique de l'élément bancaire + /// - Value: Chemin du fichier OFX correspondant + /// + /// Chemin du répertoire recevant les fichiers OFX. + /// Liste d'identifiants uniques correspondant aux éléments bancaires à traiter. + /// Date de début des mouvements pris en compte. + /// Date de fin des mouvements pris en compte. + public Dictionary ToOfx(string directory, List accountsId, DateTime startDate, DateTime endDate) + { + var d = directory.Trim().Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.Personal)); + if (!Directory.Exists(d)) + throw new DirectoryNotFoundException(); + + var filenames = new Dictionary(); + + var lst = Accounts.GetAccountStatements(directory, accountsId, startDate, endDate); + foreach (KeyValuePair>> kvp in lst) + { + var a = Accounts.GetById(kvp.Key); + var filename = String.Join("_", a.Name.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); + var fp = Path.Combine(d, filename) + ".ofx"; + fp = Path.GetFullPath(fp); + + var utcNow = DateTime.UtcNow; + + var ofx = @"OFXHEADER:100" + "\n"; + ofx += @"DATA:OFXSGML" + "\n"; + ofx += @"VERSION:102" + "\n"; + ofx += @"SECURITY:NONE" + "\n"; + ofx += @"ENCODING:UTF-8" + "\n"; + ofx += @"CHARSET:1252" + "\n"; + ofx += @"COMPRESSION:NONE" + "\n"; + ofx += @"OLDFILEUID:NONE" + "\n"; + ofx += @"NEWFILEUID:NONE" + "\n"; + ofx += "\n"; + ofx += @"" + "\n"; + ofx += "\t" + @"" + "\n"; + ofx += "\t\t" + @"" + "\n"; + ofx += "\t\t\t" + @"" + "\n"; + ofx += "\t\t\t\t" + @"0" + "\n"; + ofx += "\t\t\t\t" + @"INFO" + "\n"; + ofx += "\t\t\t" + @"" + "\n"; + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t" + @"{0}" + "\n", + utcNow.ToString("yyyyMMdd") + "000000"); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t" + @"{0}" + "\n", + CultureInfo.GetCultureInfo(CultureName).ThreeLetterISOLanguageName.ToUpper()); + ofx += "\t\t" + @"" + "\n"; + ofx += "\t" + @"" + "\n"; + ofx += "\t" + @"" + "\n"; + ofx += "\t\t" + @"" + "\n"; + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t" + @"{0}" + "\n", + utcNow.ToString("yyyyMMdd") + "000000"); + ofx += "\t\t\t" + @"" + "\n"; + ofx += "\t\t\t\t" + @"0" + "\n"; + ofx += "\t\t\t\t" + @"INFO" + "\n"; + ofx += "\t\t\t" + @"" + "\n"; + ofx += "\t\t\t" + @"" + "\n"; + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t" + @"{0}" + "\n", + Currency.Name.ToUpper()); + ofx += "\t\t\t\t" + @"" + "\n"; + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t" + @"{0}" + "\n", + startDate.ToUniversalTime().ToString("yyyyMMdd") + "000000"); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t" + @"{0}" + "\n", + endDate.ToUniversalTime().ToString("yyyyMMdd") + "000000"); + + var mvts = kvp.Value.OrderByDescending(i => i.Key); + foreach (KeyValuePair> kvp2 in mvts) + { + var mvtDate = kvp2.Key; + foreach (var ot in kvp2.Value) + { + ofx += "\t\t\t\t\t" + @"" + "\n"; + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t\t" + @"{0}" + "\n", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? (ot as Operation).Amount < 0 + ? "DEBIT" + : "CREDIT" + : ot.GetType() == typeof(Transfer) + ? (ot as Transfer).FromAccountId.Equals(a.Id) + ? "DEBIT" + : (ot as Transfer).ToAccountId.Equals(a.Id) + ? "CREDIT" + : "OTHER" + : "OTHER"); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t\t" + @"{0}" + "\n", + mvtDate.ToUniversalTime().ToString("yyyyMMdd")); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t\t" + @"{0}" + "\n", + mvtDate.ToUniversalTime().ToString("yyyyMMdd")); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t\t" + @"{0:F}" + "\n", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? (ot as Operation).Amount + : ot.GetType() == typeof(Transfer) + ? (ot as Transfer).FromAccountId.Equals(a.Id) + ? -Math.Abs((ot as Transfer).Amount) + : (ot as Transfer).ToAccountId.Equals(a.Id) + ? Math.Abs((ot as Transfer).Amount) + : 0 + : 0); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t\t" + @"{0}" + "\n", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? (ot as Operation).Id.ToString("N").ToUpper() + : ot.GetType() == typeof(Transfer) + ? (ot as Transfer).Id.ToString("N").ToUpper() + : Guid.NewGuid().ToString("N")); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t\t" + @"{0}" + "\n", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? SecurityElement.Escape((ot as Operation).Name) + : ot.GetType() == typeof(Transfer) + ? SecurityElement.Escape((ot as Transfer).Name) + : ""); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t\t" + @"{0}" + "\n", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? SecurityElement.Escape((ot as Operation).Note) + : ot.GetType() == typeof(Transfer) + ? SecurityElement.Escape((ot as Transfer).Note) + : ""); + ofx += "\t\t\t\t\t" + @"" + "\n"; + } + } + + ofx += "\t\t\t\t" + @"" + "\n"; + ofx += "\t\t\t\t" + @"" + "\n"; + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t" + @"{0:F}" + "\n", + AmountAt(a, endDate, true)); + ofx += string.Format(CultureInfo.InvariantCulture, + "\t\t\t\t\t" + @"{0}" + "\n", + endDate.ToUniversalTime().ToString("yyyyMMdd")); + ofx += "\t\t\t\t" + @"" + "\n"; + ofx += "\t\t\t" + @"" + "\n"; + ofx += "\t\t" + @"" + "\n"; + ofx += "\t" + @"" + "\n"; + ofx += @"" + "\n"; + using (StreamWriter sw = new StreamWriter(File.Open(fp, FileMode.Create), Encoding.UTF8)) - sw.Write(html); + sw.Write(ofx); filenames.Add(a.Id, fp); } @@ -988,10 +1275,152 @@ public Dictionary Export2Html(string directory, List account return filenames; } + /// + /// Exporte les mouvements des éléments bancaires souhaités entre les dates spécifiées. + /// + /// + /// Chemin du fichier QIF correspondant + /// + /// Chemin du répertoire recevant les fichiers QIF. + /// Liste d'identifiants uniques correspondant aux éléments bancaires à traiter. + /// Date de début des mouvements pris en compte. + /// Date de fin des mouvements pris en compte. + public string ToQif(string directory, List accountsId, DateTime startDate, DateTime endDate) + { + var d = directory.Trim().Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.Personal)); + if (!Directory.Exists(d)) + throw new DirectoryNotFoundException(); + + var filename = String.Join("_", GetType().Assembly.GetName().Name.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); + var fp = Path.Combine(d, filename) + ".qif"; + fp = Path.GetFullPath(fp); + string qif = ""; - } + qif += "!Type:Cat\n"; + void scrib(Category cat, string sParent) + { + var sFullName = string.Join(":", new string[] { sParent, cat.Name }); + var sName = string.Format(CultureInfo.InvariantCulture, "{0}", + SecurityElement.Escape(sFullName)); + + qif += "N" + sName + "\n"; + qif += "^\n"; + + cat.Childs.Items.ForEach(ccat => scrib(ccat, sFullName)); + } + Categories.Items.ForEach(cat => scrib(cat, "")); + + var lst = Accounts.GetAccountStatements(directory, accountsId, startDate, endDate); + foreach (KeyValuePair>> kvp in lst) + { + var a = Accounts.GetById(kvp.Key); + + var sType = "Bank"; + if (a.GetType() == typeof(Paycard)) + sType = "CCard"; + else if (a.GetType() == typeof(Wallet)) + sType = "Cash"; + + qif += "!Account\n"; + qif += string.Format(CultureInfo.InvariantCulture, "N{0}\n", + SecurityElement.Escape(a.Name)); + qif += string.Format(CultureInfo.InvariantCulture, "D{0}\n", + SecurityElement.Escape(a.Note)); + qif += string.Format(CultureInfo.InvariantCulture, "T{0}\n", + sType); + qif += string.Format(CultureInfo.InvariantCulture, "/{0}\n", + endDate.ToUniversalTime().ToString("dd/MM/yyyy")); + qif += string.Format(CultureInfo.InvariantCulture, "${0}\n", + AmountAt(a, endDate, true)); + qif += "^\n"; + + if (kvp.Value.Any()) + { + qif += string.Format(CultureInfo.InvariantCulture, "!Type:{0}\n", + sType); + + var mvts = kvp.Value.OrderByDescending(i => i.Key); + foreach (KeyValuePair> kvp2 in mvts) + { + var mvtDate = kvp2.Key; + var sMvtDate = string.Format(CultureInfo.InvariantCulture, "{0}", + mvtDate.ToUniversalTime().ToString("yyyyMMdd")); + foreach (var ot in kvp2.Value) + { + var sAmount = string.Format(CultureInfo.InvariantCulture, "{0:F}", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? (ot as Operation).Amount + : ot.GetType() == typeof(Transfer) + ? (ot as Transfer).FromAccountId.Equals(a.Id) + ? -Math.Abs((ot as Transfer).Amount) + : (ot as Transfer).ToAccountId.Equals(a.Id) + ? Math.Abs((ot as Transfer).Amount) + : 0 + : 0); + + var sId = ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? (ot as Operation).Id.ToString("N").ToUpper() + : ot.GetType() == typeof(Transfer) + ? (ot as Transfer).Id.ToString("N").ToUpper() + : Guid.NewGuid().ToString("N"); + + var sName = string.Format(CultureInfo.InvariantCulture, "{0}", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? SecurityElement.Escape((ot as Operation).Name) + : ot.GetType() == typeof(Transfer) + ? SecurityElement.Escape((ot as Transfer).Name) + : ""); + + var sMemo = string.Format(CultureInfo.InvariantCulture, "{0}", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? SecurityElement.Escape((ot as Operation).Note) + : ot.GetType() == typeof(Transfer) + ? SecurityElement.Escape((ot as Transfer).Note) + : ""); + + var sCategory = string.Format(CultureInfo.InvariantCulture, "{0}", + ot.GetType() == typeof(Operation) && (ot as Operation).ToId.Equals(a.Id) + ? Categories.GetById((ot as Operation).CategoryId).Name + : ot.GetType() == typeof(Transfer) + ? "Transfert" + : ""); + + var sState = "*"; + + qif += "D" + sMvtDate + "\n"; + qif += "T" + sAmount + "\n"; + qif += "P" + sName + "\n"; + qif += "M" + sMemo + "\n"; + qif += "N" + sId + "\n"; + qif += "L" + sCategory + "\n"; + qif += "N" + sState + "\n"; + qif += "^\n"; + } + } + } + + } + using (StreamWriter sw = new StreamWriter(File.Open(fp, FileMode.Create), Encoding.UTF8)) + sw.Write(qif); + + return fp; + } + + + + + + + + + + + + + + } } diff --git a/Kotlib/Kotlib_452.csproj b/Kotlib/Kotlib_452.csproj index b95d194..7ffa500 100644 --- a/Kotlib/Kotlib_452.csproj +++ b/Kotlib/Kotlib_452.csproj @@ -38,7 +38,7 @@ Kotlib, Librairie, Finance, Personnelle, Gestion, Compte Kotlib.Net Librairie .Net pour la gestion assistée par ordinateur des finances personnelles. - v0.1-alpha.1 + v0.1-alpha.3
AnyCPU @@ -115,11 +115,25 @@ - - + + PreserveNewest + + + PreserveNewest + - - + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + \ No newline at end of file diff --git a/Kotlib/Objects/AccountList.cs b/Kotlib/Objects/AccountList.cs index e60fa10..64a4dd3 100644 --- a/Kotlib/Objects/AccountList.cs +++ b/Kotlib/Objects/AccountList.cs @@ -281,132 +281,14 @@ public static List> GetAvaillableAccounts() return l; } - /// - /// Nettoie la liste des transferts. - /// Supprime tous les transferts ayant un compte émetteur ou destinataure inconnu. - /// - public void CleanTransfers() - { - var actIdList = Items.Select(a => a.Id).ToList(); - Transfers.RemoveAll(a => !actIdList.Contains(a.FromAccountId) || !actIdList.Contains(a.ToAccountId)); - } - /// - /// Exporte les mouvements d'un élément bancaire au format CSV + /// Nettoie la liste des transferts. + /// Supprime tous les transferts ayant un compte émetteur ou destinataure inconnu. /// - /// - /// Liste des fichiers nouvellement créés. - /// Structure comprenant: - /// - Item 1: Identifiant unique de l'élément bancaire - /// - Item 2: Chemin du fichier CSV. - /// - /// Chemin du répertoire recevant les fichiers CSV. - /// Liste d'identifiants uniques correspondant aux éléments bancaires à traiter. - /// Date de début des mouvements pris en compte. - /// Date de fin des mouvements pris en compte. - /// Délimiteur de colones CSV. - /// Délimiteur des décimales. - /// Format des dates enregistrées. - public List> Export2CSV(string directory, List accountsId, DateTime startDate, DateTime endDate, string delimiter = ";", string decimalSeparator = ",", string dateFormat = "dd/MM/yyyy") + public void CleanTransfers() { - var d = directory.Trim().Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.Personal)); - if (!Directory.Exists(d)) - throw new DirectoryNotFoundException(); - - var filenames = new List>(); - - var columns = new string[] { "Date", "Débit", "Crédit", "Libellé" }; - foreach (var uid in accountsId) - { - var a = GetById(uid); - if (a == null || a.Equals(default(Account))) - continue; - - var operations = a.Operations.Items - .Where(o => o.Active && o.Date.Date >= startDate.Date && o.Date.Date <= endDate.Date) - .Select(o => new Dictionary() - { - ["Sorter"] = o.Date.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), - [columns[0]] = o.Date.Date.ToString(dateFormat), - [columns[1]] = (o.Amount < 0m) ? Math.Round(o.Amount, 2).ToString("0.00").Replace(".", decimalSeparator) : "0.00", - [columns[2]] = (o.Amount >= 0m) ? Math.Round(o.Amount, 2).ToString("0.00").Replace(".", decimalSeparator) : "0.00", - [columns[3]] = o.Name - }) - .ToList(); - - var transfersOut = Transfers.Items - .Where(t => t.Active && t.FromAccountId.Equals(a.Id) && t.Date.Date >= startDate.Date && t.Date.Date <= endDate.Date) - .Select(t => new Dictionary() - { - ["Sorter"] = t.Date.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), - [columns[0]] = t.Date.Date.ToString(dateFormat), - [columns[1]] = "-" + Math.Round(Math.Abs(t.Amount), 2).ToString("0.00").Replace(".", decimalSeparator), - [columns[2]] = "0.00", - [columns[3]] = t.Name - }) - .ToList(); - - var transfersIn = Transfers.Items - .Where(t => t.Active && t.ToAccountId.Equals(a.Id) && t.Date.Date >= startDate.Date && t.Date.Date <= endDate.Date) - .Select(t => new Dictionary() - { - ["Sorter"] = t.Date.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), - [columns[0]] = t.Date.Date.ToString(dateFormat), - [columns[1]] = "0.00", - [columns[2]] = Math.Round(Math.Abs(t.Amount), 2).ToString("0.00").Replace(".", decimalSeparator), - [columns[3]] = t.Name - }) - .ToList(); - - var mvts = new List>(); - mvts.AddRange(operations); - mvts.AddRange(transfersIn); - mvts.AddRange(transfersOut); - - mvts.Sort((mvt1, mvt2) => - { - var d1 = DateTime.ParseExact(mvt1["Sorter"], "yyyy-MM-dd", CultureInfo.InvariantCulture); - var d2 = DateTime.ParseExact(mvt2["Sorter"], "yyyy-MM-dd", CultureInfo.InvariantCulture); - - if (d2 > d1) - return -1; - - if (d2 < d1) - return 1; - - return 0; - }); - - var lines = new List() { string.Join(delimiter, columns.ToArray()) }; - foreach (var m in mvts) - { - var lColumns = new List(); - foreach (var c in columns) - { - if (m.Keys.Contains(c)) - lColumns.Add(m[c]); - else - lColumns.Add(""); - } - lines.Add(string.Join(delimiter, lColumns.ToArray())); - } - - var filename = String.Join("_", a.Name.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); - - var fp = Path.Combine(d, filename) + ".csv"; - fp = Path.GetFullPath(fp); - - using (StreamWriter sw = new StreamWriter(File.Open(fp, FileMode.Create), Encoding.UTF8)) - { - foreach (var line in lines) - sw.WriteLine(line); - } - lines.Clear(); - - filenames.Add(new Tuple(a.Id, fp)); - } - - return filenames; + var actIdList = Items.Select(a => a.Id).ToList(); + Transfers.RemoveAll(a => !actIdList.Contains(a.FromAccountId) || !actIdList.Contains(a.ToAccountId)); } /// @@ -423,7 +305,7 @@ public void CleanTransfers() /// Liste d'identifiants uniques correspondant aux éléments bancaires à traiter. /// Date de début des mouvements pris en compte. /// Date de fin des mouvements pris en compte. - public Dictionary>> Export2List(string directory, List accountsId, DateTime startDate, DateTime endDate) + public Dictionary>> GetAccountStatements(string directory, List accountsId, DateTime startDate, DateTime endDate) { var result = new Dictionary>>(); diff --git a/Kotlib_452.sln b/Kotlib_452.sln index 4962012..79af2fb 100644 --- a/Kotlib_452.sln +++ b/Kotlib_452.sln @@ -28,6 +28,6 @@ Global $0.StandardHeader = $2 $2.Text = @//\n// ${FileName}\n//\n// Author:\n// ${AuthorName} <${AuthorEmail}>\n//\n// ${CopyrightHolder}\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see . description = Librairie pour la gestion assistée par ordinateur des finances personnelles. - version = v0.1-alpha.1 + version = v0.1-alpha.3 EndGlobalSection EndGlobal