Przeglądaj źródła

fix FormatBatch to works with new structure

Dalibor Votruba 1 rok temu
rodzic
commit
6b63906f31

+ 10 - 10
App.config

@@ -8,31 +8,28 @@
     <userSettings>
         <qdr.app.studiou.orders2printpack.Properties.AppSettings>
             <setting name="CSVDelimiter" serializeAs="String">
-                <value>;</value>
+                <value>,</value>
             </setting>
             <setting name="LastOutputDir" serializeAs="String">
                 <value />
             </setting>
             <setting name="MapColOrderNo" serializeAs="String">
-                <value>order_no</value>
+                <value>Order No</value>
             </setting>
             <setting name="MapColProductCat" serializeAs="String">
-                <value>prod_cat</value>
+                <value>Prod Cat</value>
             </setting>
             <setting name="MapColUri" serializeAs="String">
-                <value>prod_img_url</value>
+                <value>Prod Img Url</value>
             </setting>
             <setting name="MapColQuantity" serializeAs="String">
-                <value>qty</value>
+                <value>Qty</value>
             </setting>
             <setting name="SourceSearchPattern" serializeAs="String">
                 <value>*.jpg</value>
             </setting>
-            <setting name="OutputFileMask" serializeAs="String">
-                <value>{prod_var}\{order_no}_{prod_name}_{ordinal}{ext}</value>
-            </setting>
             <setting name="MapColProductFormat" serializeAs="String">
-                <value>prod_var</value>
+                <value>Prod Var Type</value>
             </setting>
             <setting name="LastSourceDir" serializeAs="String">
                 <value />
@@ -60,7 +57,10 @@
                 <value>{category} ve formátu {variant}.</value>
             </setting>
             <setting name="MapColProductName" serializeAs="String">
-                <value>prod_name</value>
+                <value>Prod Name</value>
+            </setting>
+            <setting name="OutputFileMask" serializeAs="String">
+                <value>{prod_var_type}\{order_no}_{prod_name}_{ordinal}{ext}</value>
             </setting>
         </qdr.app.studiou.orders2printpack.Properties.AppSettings>
     </userSettings>

+ 180 - 0
Extensions/CsvUtils.cs

@@ -0,0 +1,180 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.IO.Abstractions;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace qdr.app.studiou.orders2printpack.Extensions
+{
+public static class CsvUtils
+{
+    public static DataTable CsvToDataTable(IFileSystem fs, string csvFile, string delimiter = ",", bool hasHeaderRow = true)
+    {
+        if (!fs.File.Exists(csvFile))
+        {
+            throw new FileNotFoundException("File '" + csvFile + "' not found!", csvFile);
+        }
+
+        DataTable dataTable = new DataTable();
+        using (StreamReader streamReader = fs.File.OpenText(csvFile))
+        {
+            string[] array = null;
+            if (hasHeaderRow)
+            {
+                array = ParseCsvLine(streamReader.ReadLine(), delimiter);
+                if (array == null)
+                {
+                    return dataTable;
+                }
+
+                string[] array2 = array;
+                foreach (string text in array2)
+                {
+                    dataTable.Columns.Add(text.Trim());
+                }
+            }
+
+            while (!streamReader.EndOfStream)
+            {
+                string[] array3 = ParseCsvLine(streamReader.ReadLine(), delimiter);
+                if (array3 == null)
+                {
+                    continue;
+                }
+
+                if (array == null)
+                {
+                    array = new string[array3.Length];
+                    for (int j = 0; j < array3.Length; j++)
+                    {
+                        array[j] = $"Column{j + 1}";
+                        dataTable.Columns.Add(array[j]);
+                    }
+                }
+
+                DataRow dataRow = dataTable.NewRow();
+                for (int k = 0; k < Math.Min(array.Length, array3.Length); k++)
+                {
+                    dataRow[k] = array3[k];
+                }
+
+                dataTable.Rows.Add(dataRow);
+            }
+        }
+
+        return dataTable;
+    }
+
+    private static string[]? ParseCsvLine(string? line, string delimiter)
+    {
+        if (string.IsNullOrEmpty(line))
+        {
+            return null;
+        }
+
+        List<string> list = new List<string>();
+        StringBuilder stringBuilder = new StringBuilder();
+        bool flag = false;
+        for (int i = 0; i < line.Length; i++)
+        {
+            if (flag)
+            {
+                if (line[i] == '"' && (i + 1 == line.Length || line[i + 1] != '"'))
+                {
+                    flag = false;
+                }
+                else if (line[i] == '"' && i + 1 < line.Length && line[i + 1] == '"')
+                {
+                    stringBuilder.Append('"');
+                    i++;
+                }
+                else
+                {
+                    stringBuilder.Append(line[i]);
+                }
+            }
+            else if (line[i] == '"')
+            {
+                flag = true;
+            }
+            else if (line.Substring(i).StartsWith(delimiter))
+            {
+                list.Add(stringBuilder.ToString().Trim());
+                stringBuilder.Clear();
+                i += delimiter.Length - 1;
+            }
+            else
+            {
+                stringBuilder.Append(line[i]);
+            }
+        }
+
+        list.Add(stringBuilder.ToString().Trim());
+        return list.ToArray();
+    }
+
+    public static void DataTableToCsv(IFileSystem fs, DataTable dataTable, string filePath, string delimiter = ",", Func<string, string>? processColumnCallback = null)
+    {
+        string delimiter2 = delimiter;
+        using StreamWriter streamWriter = fs.File.CreateText(filePath);
+        streamWriter.WriteLine(string.Join(delimiter2, from DataColumn column in dataTable.Columns
+                                                       select QuoteValue(processColumnCallback == null ? column.ColumnName : processColumnCallback(column.ColumnName), delimiter2)));
+        foreach (DataRow row in dataTable.Rows)
+        {
+            streamWriter.WriteLine(string.Join(delimiter2, row.ItemArray.Select((object field) => QuoteValue(field?.ToString(), delimiter2))));
+        }
+    }
+
+    public static List<Dictionary<string, string>> CsvToDictionaryList(IFileSystem fs, string csvFile, string delimiter = ",")
+    {
+        if (!fs.File.Exists(csvFile))
+        {
+            throw new FileNotFoundException("File '" + csvFile + "' not found!", csvFile);
+        }
+
+        List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
+        using (StreamReader streamReader = new StreamReader(csvFile))
+        {
+            string[] array = ParseCsvLine(streamReader.ReadLine(), delimiter);
+            if (array == null)
+            {
+                return list;
+            }
+
+            while (!streamReader.EndOfStream)
+            {
+                string[] array2 = ParseCsvLine(streamReader.ReadLine(), delimiter);
+                if (array2 != null)
+                {
+                    Dictionary<string, string> dictionary = new Dictionary<string, string>();
+                    for (int i = 0; i < array.Length; i++)
+                    {
+                        dictionary[array[i].Trim()] = ((i < array2.Length) ? array2[i] : string.Empty);
+                    }
+
+                    list.Add(dictionary);
+                }
+            }
+        }
+
+        return list;
+    }
+
+    private static string QuoteValue(string? value, string delimiter)
+    {
+        if (string.IsNullOrEmpty(value))
+        {
+            return string.Empty;
+        }
+
+        if (value.Contains(delimiter) || value.Contains("\"") || value.Contains("\r") || value.Contains("\n"))
+        {
+            return "\"" + value.Replace("\"", "\"\"") + "\"";
+        }
+
+        return value;
+    }
+}
+}

+ 26 - 0
Extensions/StringExt.cs

@@ -0,0 +1,26 @@
+namespace qdr.app.studiou.orders2printpack.Extensions
+{
+    public static class StringExt
+    {
+        public static string ToQuotedString(this string str)
+        {
+            if (str == null)
+                return string.Empty;
+            return ToDecoratedString(str, "\"");
+        }
+
+        public static string ToDecoratedString(this string str, string leftDecoration, string rightDecoration)
+        {
+            if (str == null)
+                return string.Empty;
+            return leftDecoration + str + rightDecoration;
+        }
+
+        public static string ToDecoratedString(this string str, string bothDecoration)
+        {
+            if (str == null)
+                return string.Empty;
+            return ToDecoratedString(str, bothDecoration, bothDecoration);
+        }
+    }
+}

+ 25 - 5
FormBatch.cs

@@ -1,4 +1,5 @@
-using qdr.app.studiou.orders2printpack.Properties;
+using qdr.app.studiou.orders2printpack.Extensions;
+using qdr.app.studiou.orders2printpack.Properties;
 using Quadarax.Foundation.Core.Data;
 using Quadarax.Foundation.Core.IO;
 using Quadarax.Foundation.Core.Value;
@@ -233,9 +234,24 @@ namespace qdr.app.studiou.orders2printpack
                 _source.Columns.Add(new DataColumn(CS_COL_OUTPUT, typeof(string)));
                 _source.Columns.Add(new DataColumn(CS_COL_EXTERNALORDER, typeof(string)));
                 _source.Columns.Add(new DataColumn(CS_COL_EXTERNALORDERDATE, typeof(string)));
+               
+
                 _sourceColOrdinals.Clear();
                 for (int i = 0; i < _source.Columns.Count; i++)
                     _sourceColOrdinals.Add(_source.Columns[i].ColumnName.Replace("\"", ""), i);
+
+                 var invalidRows = new List<DataRow>();
+                foreach (DataRow row in _source.Rows)
+                {
+                    if (string.Equals(row[_sourceColOrdinals[AppSettings.Default.MapColUri]]?.ToString(),"null", StringComparison.CurrentCultureIgnoreCase))
+                        invalidRows.Add(row);
+                }
+
+                foreach(var row in invalidRows)
+                _source.Rows.Remove(row);
+
+                Log($"{invalidRows.Count} položek ignorováno, nebylo vyplněno URL");
+
                 var cntId = 0;
                 foreach (DataRow row in _source.Rows)
                     row.SetField(_sourceColOrdinals[CS_COL_ID], cntId++);
@@ -261,7 +277,7 @@ namespace qdr.app.studiou.orders2printpack
 
                 Log($"Procházím všechny soubory {AppSettings.Default.SourceSearchPattern} ve složce '{pathToSourceFolder}'...");
                 Log("Tato operace může chvíli trvat!");
-                var files = fsrch.Search([AppSettings.Default.SourceSearchPattern]);
+                var files = fsrch.Search(new[] {AppSettings.Default.SourceSearchPattern, "*" });
                 if (files.Length == 0)
                     throw new Exception($"Nenalezeny žádné soubory pro zpracování ve složce '{pathToSourceFolder}'.");
 
@@ -337,8 +353,12 @@ namespace qdr.app.studiou.orders2printpack
                     for (int i = 0; i < qty; i++)
                     {
                         outputFileNameBuilder.AddOrSetParameter(CS_TAG_ORDINAL, i.ToString().PadLeft(3, '0'));
-                        var outputFileName = FileUtils.SanitizedFileName(_fs, outputFileNameBuilder.ToString());
-                        var outputPath = _fs.Path.Combine(_outputPath, outputFileName);
+                        var outputFileName = _fs.Path.GetFileName(outputFileNameBuilder.ToString());
+                        var outputFilePath = _fs.Path.GetDirectoryName(outputFileNameBuilder.ToString())!;
+
+                        var outputFileNameSanitized = FileUtils.SanitizedFileName(_fs, outputFileName);
+                        var outputPath = _fs.Path.Combine(_outputPath, _fs.Path.Combine(outputFilePath, outputFileNameSanitized));
+                        _fs.Directory.CreateDirectory(_fs.Path.GetDirectoryName(outputPath)!);
                         _fs.File.Copy(sourcePath!, outputPath, true);
                         Log($"Soubor '{outputPath}' vytvořen.");
                         row.SetField(_sourceColOrdinals[CS_COL_OUTPUT], outputPath);
@@ -362,7 +382,7 @@ namespace qdr.app.studiou.orders2printpack
                     row.SetField(_sourceColOrdinals[CS_COL_EXTERNALORDERDATE], externalOrderDate.ToFileUtcString());
                 }
                 Log($"Generuji protokol ...");
-                CsvHelper.DataTableToCsv(_fs, _source, protocolFile, AppSettings.Default.CSVDelimiter);
+                CsvUtils.DataTableToCsv(_fs, _source, protocolFile, ";", (column) => { return NormalizeColumnName(column);});
                 Log($"Protokol uložen do souboru '{protocolFile}'.");
             });
         }

+ 19 - 19
Properties/AppSettings.Designer.cs

@@ -25,7 +25,7 @@ namespace qdr.app.studiou.orders2printpack.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute(";")]
+        [global::System.Configuration.DefaultSettingValueAttribute(",")]
         public string CSVDelimiter {
             get {
                 return ((string)(this["CSVDelimiter"]));
@@ -49,7 +49,7 @@ namespace qdr.app.studiou.orders2printpack.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("order_no")]
+        [global::System.Configuration.DefaultSettingValueAttribute("Order No")]
         public string MapColOrderNo {
             get {
                 return ((string)(this["MapColOrderNo"]));
@@ -61,7 +61,7 @@ namespace qdr.app.studiou.orders2printpack.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("prod_cat")]
+        [global::System.Configuration.DefaultSettingValueAttribute("Prod Cat")]
         public string MapColProductCat {
             get {
                 return ((string)(this["MapColProductCat"]));
@@ -73,7 +73,7 @@ namespace qdr.app.studiou.orders2printpack.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("prod_img_url")]
+        [global::System.Configuration.DefaultSettingValueAttribute("Prod Img Url")]
         public string MapColUri {
             get {
                 return ((string)(this["MapColUri"]));
@@ -85,7 +85,7 @@ namespace qdr.app.studiou.orders2printpack.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("qty")]
+        [global::System.Configuration.DefaultSettingValueAttribute("Qty")]
         public string MapColQuantity {
             get {
                 return ((string)(this["MapColQuantity"]));
@@ -109,19 +109,7 @@ namespace qdr.app.studiou.orders2printpack.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("{prod_var}\\{order_no}_{prod_name}_{ordinal}{ext}")]
-        public string OutputFileMask {
-            get {
-                return ((string)(this["OutputFileMask"]));
-            }
-            set {
-                this["OutputFileMask"] = value;
-            }
-        }
-        
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("prod_var")]
+        [global::System.Configuration.DefaultSettingValueAttribute("Prod Var Type")]
         public string MapColProductFormat {
             get {
                 return ((string)(this["MapColProductFormat"]));
@@ -230,7 +218,7 @@ namespace qdr.app.studiou.orders2printpack.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("prod_name")]
+        [global::System.Configuration.DefaultSettingValueAttribute("Prod Name")]
         public string MapColProductName {
             get {
                 return ((string)(this["MapColProductName"]));
@@ -239,5 +227,17 @@ namespace qdr.app.studiou.orders2printpack.Properties {
                 this["MapColProductName"] = value;
             }
         }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("{prod_var_type}\\{order_no}_{prod_name}_{ordinal}{ext}")]
+        public string OutputFileMask {
+            get {
+                return ((string)(this["OutputFileMask"]));
+            }
+            set {
+                this["OutputFileMask"] = value;
+            }
+        }
     }
 }

+ 10 - 10
Properties/AppSettings.settings

@@ -3,31 +3,28 @@
   <Profiles />
   <Settings>
     <Setting Name="CSVDelimiter" Type="System.String" Scope="User">
-      <Value Profile="(Default)">;</Value>
+      <Value Profile="(Default)">,</Value>
     </Setting>
     <Setting Name="LastOutputDir" Type="System.String" Scope="User">
       <Value Profile="(Default)" />
     </Setting>
     <Setting Name="MapColOrderNo" Type="System.String" Scope="User">
-      <Value Profile="(Default)">order_no</Value>
+      <Value Profile="(Default)">Order No</Value>
     </Setting>
     <Setting Name="MapColProductCat" Type="System.String" Scope="User">
-      <Value Profile="(Default)">prod_cat</Value>
+      <Value Profile="(Default)">Prod Cat</Value>
     </Setting>
     <Setting Name="MapColUri" Type="System.String" Scope="User">
-      <Value Profile="(Default)">prod_img_url</Value>
+      <Value Profile="(Default)">Prod Img Url</Value>
     </Setting>
     <Setting Name="MapColQuantity" Type="System.String" Scope="User">
-      <Value Profile="(Default)">qty</Value>
+      <Value Profile="(Default)">Qty</Value>
     </Setting>
     <Setting Name="SourceSearchPattern" Type="System.String" Scope="User">
       <Value Profile="(Default)">*.jpg</Value>
     </Setting>
-    <Setting Name="OutputFileMask" Type="System.String" Scope="User">
-      <Value Profile="(Default)">{prod_var}\{order_no}_{prod_name}_{ordinal}{ext}</Value>
-    </Setting>
     <Setting Name="MapColProductFormat" Type="System.String" Scope="User">
-      <Value Profile="(Default)">prod_var</Value>
+      <Value Profile="(Default)">Prod Var Type</Value>
     </Setting>
     <Setting Name="LastSourceDir" Type="System.String" Scope="User">
       <Value Profile="(Default)" />
@@ -55,7 +52,10 @@
       <Value Profile="(Default)">{category} ve formátu {variant}.</Value>
     </Setting>
     <Setting Name="MapColProductName" Type="System.String" Scope="User">
-      <Value Profile="(Default)">prod_name</Value>
+      <Value Profile="(Default)">Prod Name</Value>
+    </Setting>
+    <Setting Name="OutputFileMask" Type="System.String" Scope="User">
+      <Value Profile="(Default)">{prod_var_type}\{order_no}_{prod_name}_{ordinal}{ext}</Value>
     </Setting>
   </Settings>
 </SettingsFile>