1206 lines
40 KiB
C#
1206 lines
40 KiB
C#
using Gremlin_BlazorServer.Data.EntityClasses;
|
|
using Gremlin_BlazorServer.Services;
|
|
using Gremlin_BlazorServer.Services.GUClasses;
|
|
using Microsoft.VisualBasic.FileIO;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using static Gremlin_BlazorServer.Data.EntityClasses.Enums;
|
|
|
|
namespace Gremlin_BlazorServer.Data.DBClasses
|
|
{
|
|
public static class GenericImporter
|
|
{
|
|
//Private members
|
|
private static readonly DateTime FarInTheFuture = DateTime.Parse("2050-12-31t00:00:00.000000z", CultureInfo.CurrentCulture);
|
|
|
|
private static Encoding encoding = Encoding.UTF8;
|
|
private static TextFieldParser csvParser = new(Filepath, encoding, true);
|
|
private static string filepath = string.Empty;
|
|
internal static GremlinContext db = new();
|
|
|
|
//Public properties
|
|
public static string Filepath
|
|
{
|
|
get => filepath;
|
|
set
|
|
{
|
|
filepath = value;
|
|
if (encoding != null)
|
|
{
|
|
TextFieldParser _csvParser = new(Filepath, encoding, true);
|
|
_csvParser.SetDelimiters(Separators);
|
|
_csvParser.HasFieldsEnclosedInQuotes = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static string[] Separators
|
|
{
|
|
get => csvParser.Delimiters!;
|
|
set
|
|
{
|
|
if (value.Length > 0)
|
|
{
|
|
csvParser.SetDelimiters(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool DataHasHeadings { get; set; }
|
|
|
|
public static Encoding Encoding
|
|
{
|
|
get => encoding;
|
|
set
|
|
{
|
|
encoding = value;
|
|
ResetParser();
|
|
}
|
|
}
|
|
|
|
////Constructors
|
|
//public GenericImporter(string filepath)
|
|
//{
|
|
// Filepath = filepath;
|
|
// _dataHasHeadings = true;
|
|
// _encoding = FileIO.GetEncoding(Filepath);
|
|
// TextFieldParser _csvParser = new(Filepath, _encoding);
|
|
// _csvParser.SetDelimiters(Separators);
|
|
// _csvParser.HasFieldsEnclosedInQuotes = true;
|
|
//}
|
|
|
|
//public GenericImporter(string filepath, Encoding encoding)
|
|
//{
|
|
// Filepath = filepath;
|
|
// _dataHasHeadings = true;
|
|
// _encoding = encoding;
|
|
// TextFieldParser _csvParser = new(Filepath, _encoding);
|
|
// _csvParser.SetDelimiters(Separators);
|
|
// _csvParser.HasFieldsEnclosedInQuotes = true;
|
|
//}
|
|
|
|
//public GenericImporter(string filepath, string[] separators)
|
|
//{
|
|
// Filepath = filepath;
|
|
// _dataHasHeadings = true;
|
|
// _encoding = FileIO.GetEncoding(Filepath);
|
|
// TextFieldParser _csvParser = new(Filepath, _encoding);
|
|
// Separators = separators;
|
|
// _csvParser.HasFieldsEnclosedInQuotes = true;
|
|
//}
|
|
//public GenericImporter(string filepath, Encoding encoding, string[] separators)
|
|
//{
|
|
// Filepath = filepath;
|
|
// _encoding = encoding;
|
|
// _dataHasHeadings = true;
|
|
// TextFieldParser _csvParser = new(Filepath, _encoding);
|
|
// Separators = separators;
|
|
// _csvParser.HasFieldsEnclosedInQuotes = true;
|
|
//}
|
|
|
|
|
|
//Public methods
|
|
public static void SetFilepath()
|
|
{
|
|
//Filepath = FileIO.GetFilepathFromUser();
|
|
}
|
|
|
|
public static void ResetParser()
|
|
{
|
|
if (Filepath != "")
|
|
{
|
|
TextFieldParser _newParser = new(Filepath, encoding);
|
|
_newParser.SetDelimiters(Separators);
|
|
_newParser.HasFieldsEnclosedInQuotes = true;
|
|
csvParser = _newParser;
|
|
}
|
|
}
|
|
|
|
public static bool Run(string filepath, string separator, string encoding)
|
|
{
|
|
GenericImporter.filepath = filepath.Replace(@"\\", @"\");
|
|
try
|
|
{
|
|
Encoding = Encoding.GetEncoding(encoding);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
Encoding = FileService.GetEncoding(GenericImporter.filepath);
|
|
}
|
|
Separators = new string[] { separator };
|
|
|
|
return ImportFile();
|
|
}
|
|
|
|
public static async Task<bool> RunAsync(string filepath, string separator, string encoding)
|
|
{
|
|
if (filepath is "" or null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
GenericImporter.filepath = filepath.Replace(@"\\", @"\");
|
|
try
|
|
{
|
|
Encoding = Encoding.GetEncoding(encoding);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
Encoding = FileService.GetEncoding(GenericImporter.filepath);
|
|
}
|
|
Separators = new string[] { separator };
|
|
|
|
return await Task.Run(ImportFile);
|
|
}
|
|
|
|
public static string GuessSeparator(string filepath)//, string encoding)
|
|
{
|
|
if (filepath is "" or null)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
string[] candidates = new string[] { "|", ",", ";" };
|
|
int numberOfCandidates = candidates.Length;
|
|
int numberOfLinesToEvaluate = 100;
|
|
int[,] score = new int[numberOfLinesToEvaluate, numberOfCandidates];
|
|
|
|
GenericImporter.filepath = filepath.Replace(@"\\", @"\");
|
|
//if (csvParser == null)
|
|
//{
|
|
// try
|
|
// {
|
|
// Encoding = Encoding.GetEncoding(encoding);
|
|
// }
|
|
// catch (Exception)
|
|
// {
|
|
// Encoding = FileIO.GetEncoding(GenericImporter.filepath);
|
|
// }
|
|
//}
|
|
|
|
using (csvParser)
|
|
{
|
|
string line;
|
|
for (int i = 0; i < numberOfLinesToEvaluate; i++)
|
|
{
|
|
if (!csvParser.EndOfData)
|
|
{
|
|
line = csvParser.ReadLine()!;
|
|
for (int j = 0; j < numberOfCandidates; j++)
|
|
{
|
|
score[i, j] = line.Split(candidates[j]).Length;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
List<(string, int, float)> scoreBoard = new(); //Item1 = Separator, Item2 = Score (Anzahl aufeinanderfolgender Zeilen mit gleicher Anzahl von Fields), Item3 = Count (durchschnittliche Anzahl von Fields in Zeile)
|
|
int x;
|
|
float average;
|
|
for (int j = 0; j < numberOfCandidates; j++)
|
|
{
|
|
x = 0;
|
|
average = 0;
|
|
for (int i = 0; i < numberOfLinesToEvaluate - 1; i++)
|
|
{
|
|
if (score[i, j] == score[i + 1, j] && score[i, j] > 1)
|
|
{
|
|
x++;
|
|
}
|
|
average += score[i, j];
|
|
}
|
|
average += score[numberOfLinesToEvaluate - 1, j];
|
|
average /= numberOfLinesToEvaluate;
|
|
scoreBoard.Add((candidates[j], x, average));
|
|
}
|
|
|
|
ResetParser();
|
|
return scoreBoard.Find(f => f.Item2 == scoreBoard.Max(x => x.Item2) && f.Item3 == scoreBoard.Max(x => x.Item3)).Item1;
|
|
}
|
|
|
|
public static bool ImportFile()
|
|
//Ein (möglichst) generischer Importer
|
|
//1. Dateipfad erfassen
|
|
//2. Column <-> Property Mapping
|
|
//3. Typ der zu importierenden Daten herausfinden
|
|
//4. Daten einlesen, konvertieren, validieren, Metadaten setzen und alles in Liste(n) speichern
|
|
//5. Datenliste(n) in DB speichern
|
|
{
|
|
if (filepath == "")
|
|
{
|
|
SetFilepath();
|
|
}
|
|
|
|
if (filepath == "")
|
|
{
|
|
return false;
|
|
}
|
|
|
|
using (csvParser)
|
|
{
|
|
//für geneerischen Code:
|
|
//int numberOfLines = File.ReadAllLines(filepath).Length;
|
|
//Assembly Gremlin = Assembly.GetExecutingAssembly();
|
|
|
|
|
|
//dynamische Spaltenzuordnung in Dictonary speichern
|
|
string[] fields = csvParser.ReadFields()!;
|
|
Dictionary<string, string> MappingDictionary = ReadMappingDictionaryFromFile();
|
|
Dictionary<string, int> mappingTable = MapDataHeading(fields, MappingDictionary);
|
|
|
|
//determine data type to be imported
|
|
DataIdentificator dataIdentificator = new(mappingTable);
|
|
List<string> detectedDataTypes = dataIdentificator.Identify();
|
|
|
|
//check for detectedDataTypes = empty (possible when DataIdentificator.Identify(MustMatchAllQualifer = true) and no dataset matches all qualifiers of a type)
|
|
if (detectedDataTypes.Count == 0)
|
|
{
|
|
Debug.WriteLine($"DataIdentificator.Identify() konnte die Datenart nicht bestimmen!{Environment.NewLine}Versuchen Sie den Import mit einer dezidierten Importerfunktion.");
|
|
return false;
|
|
}
|
|
|
|
return detectedDataTypes[0] switch
|
|
{
|
|
"ProductLine" => ImportProductLine(csvParser, mappingTable),
|
|
"AccountType" => ImportAccountType(csvParser, mappingTable),
|
|
"SubMarket" => ImportSubMarket(csvParser, mappingTable),
|
|
"Account" => ImportAccounts(mappingTable),
|
|
"Contact" => ImportContacts(mappingTable),
|
|
"LSAG" => ImportLSAG(mappingTable),
|
|
"Product" => ImportProducts(mappingTable),
|
|
"CustomDescription" => ImportCustomDescriptions(),// mappingTable);
|
|
_ => false,
|
|
};
|
|
}
|
|
}
|
|
|
|
public static bool ImportFile(string filepath)
|
|
{
|
|
GenericImporter.filepath = filepath;
|
|
return ImportFile();
|
|
}
|
|
|
|
private static bool ImportCustomDescriptions()//Dictionary<string, int> mappingTable)
|
|
{
|
|
List<CustomDescription> cDsReadFromFile = new(2500);
|
|
Encoding = Encoding.GetEncoding("UTF-8"); //Custom-Descriptions-CSV hat festes Encoding.
|
|
using (csvParser)
|
|
{
|
|
// Skip the row with the column names:
|
|
_ = csvParser.ReadLine();
|
|
|
|
while (!csvParser.EndOfData)
|
|
{
|
|
// Read current line fields, pointer moves to the next line.
|
|
string[] fields = csvParser.ReadFields()!;
|
|
CustomDescription ImportedCD = new()
|
|
{
|
|
ProductNumber = fields[0],
|
|
OptionNumber = fields[1],
|
|
Heading = fields[3],
|
|
DescriptionText = fields[4],
|
|
CoverletterText = fields[5],
|
|
Notes = fields[6],
|
|
DataModificationByUser = "Importer",
|
|
DataStatus = Status.Active.ToString(),
|
|
DataValidUntil = FarInTheFuture,
|
|
DataVersionComment = "Initial Importer by CD-ImporterFomCsv",
|
|
Products = new List<Product>(),
|
|
Supplier = new()
|
|
{
|
|
AccountName = fields[2] is "" or "RB" ? "Agilent Technologies" : fields[2]
|
|
}
|
|
};
|
|
ImportedCD.DataCreationDate = ImportedCD.DataValidFrom = ImportedCD.DataModificationDate = DateTime.Now;
|
|
ImportedCD.DataVersionNumber = 1;
|
|
|
|
cDsReadFromFile.Add(ImportedCD);
|
|
}
|
|
|
|
//Eingelesenen Custum Desciptions in DB schreiben:
|
|
//Check for 3PPs that not yet in the db.
|
|
//Step 1a: Add 3PP-Products from CD-List to list
|
|
//Step 1b: Add list to db.
|
|
//Step 2: Add CDs to products.
|
|
|
|
using (GremlinContext db = new())
|
|
{
|
|
//Step 1a
|
|
List<Product> thirdPartyProductsFromImportedCDs = new();
|
|
foreach (CustomDescription CD in cDsReadFromFile)
|
|
{
|
|
if (CD.Supplier.AccountName != "Agilent Technologies")
|
|
{
|
|
Product new3PPProduct = new()
|
|
{
|
|
CustomDescription = CD,
|
|
HasBreakPrices = false,
|
|
ListPrice = 0,
|
|
ProductNumber = CD.ProductNumber,
|
|
OptionNumber = CD.OptionNumber,
|
|
ProductStatus = Status.Active.ToString(),
|
|
SapLongDescription = "",
|
|
SapShortDescription = "",
|
|
Weight = 0,
|
|
IntroductionDate = DateTime.Now.Date,
|
|
BreakRangeFrom = 0,
|
|
BreakRangeTo = 0,
|
|
ProductLine = DbHelper.ResolveProductLine(db, "3P")
|
|
};
|
|
new3PPProduct.CustomDescription.Supplier = DbHelper.ResolveAccountByName(db, new3PPProduct.CustomDescription.Supplier.AccountName);
|
|
_ = MetaDataSetter.ForImport(new3PPProduct, "GenericImporter-Method", "Created at import from Custom Descriptions.");
|
|
thirdPartyProductsFromImportedCDs.Add(new3PPProduct);
|
|
}
|
|
};
|
|
|
|
//Step 1b
|
|
db.Products.AddRange(thirdPartyProductsFromImportedCDs); //Imports both the products and the associated custom descriptions!
|
|
_ = db.SaveChanges();
|
|
|
|
// Produkt aus DB laden, damit der Datensatz vom Context verfolgt wird und EF Core nicht versucht, diesen standardmäßig neu anzulegen.
|
|
//Step 2
|
|
List<CustomDescription> importedCDsWithEFReferences = new(100000);
|
|
List<CustomDescription> cDsWithoutEFReferences = new(100); //nur zur Kontrolle, wird nicht verwendet.
|
|
List<Product> productsInDb = db.Products.ToList();
|
|
Account agilent = db.Accounts.Where(a => a.AccountName == "Agilent Technologies").Single();
|
|
foreach (CustomDescription cD in cDsReadFromFile)
|
|
{
|
|
if (cD.Products == null) { continue; }
|
|
|
|
//Skip Desciptions, if it has been already imported above (as part from 3PP)
|
|
if (thirdPartyProductsFromImportedCDs.Intersect(cD.Products).Any()) { continue; }
|
|
|
|
//Establish EF Reference. If no PN/Opt found, then skip this custom description.
|
|
//CD.Product = GetProduct(db, CD.ProductNumber, CD.OptionNumber); //ResolveXY-functions return null, if no match is found in db.
|
|
cD.Products = productsInDb.Where(product => product.ProductNumber == cD.ProductNumber && product.OptionNumber == cD.OptionNumber).ToList();
|
|
if (cD.Products == null)
|
|
{
|
|
cDsWithoutEFReferences.Add(cD);
|
|
continue;
|
|
}
|
|
|
|
//Establish EF Reference: If no Supplier-Account found, then skip this custom description (shouldn't happen), else set Supplier to Agilent (3PP-Supplier have been processed before and their products should not be part of this list).
|
|
if (cD.Supplier == null)
|
|
{
|
|
cDsWithoutEFReferences.Add(cD);
|
|
continue;
|
|
}
|
|
cD.Supplier = agilent;
|
|
|
|
//prepare properties
|
|
_ = MetaDataSetter.ForImport(cD, "GenericImporter-Method", "Initial import by CSV Importer (Function GenericImporter.ImportCustomDescriptions)");
|
|
|
|
//add to final list of CDs, that will go into the db.
|
|
importedCDsWithEFReferences.Add(cD);
|
|
}
|
|
|
|
db.CustomDescriptions.AddRange(importedCDsWithEFReferences);
|
|
_ = db.SaveChanges();
|
|
//Bestätigung senden
|
|
Debug.WriteLine($"Es wurden {importedCDsWithEFReferences.Count} eigene Beschreibungen erfolgreich der Datenbank hinzugefügt.{Environment.NewLine}Es wurden {thirdPartyProductsFromImportedCDs.Count} 3PP-Produkte neu angelegt.");
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private static bool ImportProducts(Dictionary<string, int> mappingTable)
|
|
{
|
|
List<Product> ProductsReadFromFile = new(ParseProductFile(mappingTable));
|
|
return InsertProducts(ProductsReadFromFile);
|
|
}
|
|
|
|
private static bool InsertProducts(List<Product> products)
|
|
{
|
|
using (GremlinContext db = new())
|
|
{
|
|
List<ProductLine> productLines = db.ProductLines.ToList();
|
|
foreach (Product product in products)
|
|
{
|
|
//var query = db.ProductLines
|
|
// .Where(a => a.ProductLineAbbreviation == product.ProductLine.ProductLineAbbreviation)
|
|
// .First();
|
|
//product.ProductLine = query;
|
|
|
|
//product.ProductLine = ResolveProductLine(db, product.ProductLine.ProductLineAbbreviation);
|
|
product.ProductLine = productLines.Find(x => x.ProductLineCode == product.ProductLine.ProductLineCode) ?? new ProductLine();
|
|
_ = MetaDataSetter.ForImport(product, "GenericImporter-Method");
|
|
}
|
|
|
|
db.Products.AddRange(products);
|
|
_ = db.SaveChanges();
|
|
//Bestätigung senden
|
|
Debug.WriteLine($"Es wurden {products.Count} Produkte erfolgreich der Datenbank hinzugefügt.");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private static List<Product> ParseProductFile(Dictionary<string, int> columnNumberOf)
|
|
///Importiert Produkt-Daten aus CSV (erstellt aus PriceSurfer-CPL)
|
|
/// - Encoding: Latin1
|
|
/// - Separator = ;
|
|
/// - fixe Spaltenzahl und -folge (Überschriften werden nicht untersucht/verwendet):
|
|
/// 1) Position = ID/PK
|
|
/// 2) Partnumber
|
|
/// 3) Option
|
|
/// 4) (Short) Description
|
|
/// 5) Current Month Price (EUR)
|
|
/// 6) ProductLineID
|
|
/// 7) Status
|
|
/// 8) (Long) Description
|
|
///Kommentarzeichen: # (hardcoded, string array)
|
|
{
|
|
List<Product> results = new(100000);
|
|
using (csvParser)
|
|
{
|
|
while (!csvParser.EndOfData)
|
|
{
|
|
// Read current line fields, pointer moves to the next line.
|
|
Product ImportedProduct = new()
|
|
{
|
|
ProductLine = new()
|
|
};
|
|
string[] fields = csvParser.ReadFields()!;
|
|
|
|
//Kontrolle, ob Trennzeichen in Daten vorhanden ist:
|
|
if (fields.Length > 27) //27 ist der Normalfall
|
|
{
|
|
//Sonderfall "EnVisionTM G|2":
|
|
//suche fields[x], das auf " G" endet und auf das field[x+1] mit "2 " beginnt, kombiniere die beiden und schiebe alle darauffolgenden Felder in diesem Datensatz eins nach links.
|
|
for (int i = 0; i < fields.Length - 1; i++) //fields.Length - 1, um durch i+1 nicht aus dem Index zu laufen
|
|
{
|
|
if (fields[i].EndsWith(" G"))
|
|
{
|
|
if (fields[i + 1].StartsWith("2 "))
|
|
{
|
|
fields[i] = fields[i] + fields[i + 1];
|
|
for (int j = i + 2; j < fields.Length; j++)
|
|
{
|
|
fields[j - 1] = fields[j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//NICHT ausgewertete Felder:
|
|
//fields[0] = Position [in CPL]
|
|
//fields[8] = Warranty
|
|
//fields[10] = PH Code
|
|
//fields[11] = PH Description
|
|
//fields[15] = Country of Manufacturing
|
|
//fields[16] = ECCL
|
|
//fields[17] = M41
|
|
//fields[18] = First Supplier Code
|
|
//fields[19] = Harmonized Tarif Schedule
|
|
//fields[20] = Hazardous Good Flag
|
|
//fields[21] = Order instructions
|
|
//fields[23] = End of Production Date
|
|
//fields[24] = End of Support Date
|
|
|
|
ImportedProduct.ProductNumber = fields[columnNumberOf["ProductNumber"]];
|
|
|
|
if (fields[columnNumberOf["OptionNumber"]].Length == 4) //Optionsnummer mit führendem Apostroph
|
|
{
|
|
ImportedProduct.OptionNumber = fields[columnNumberOf["OptionNumber"]].Substring(1); //schneidet erstes Zeichen/Apostroph weg
|
|
}
|
|
else if (fields[columnNumberOf["OptionNumber"]].Length == 3) //3-stellige Optionsnummer übernehmen; keine Aktion bei leerem Feld (keine Optionsnummer)
|
|
{
|
|
ImportedProduct.OptionNumber = fields[columnNumberOf["OptionNumber"]];
|
|
}
|
|
|
|
ImportedProduct.SapShortDescription = fields[columnNumberOf["SapShortDescription"]];
|
|
|
|
ImportedProduct.ListPrice = decimal.Parse(fields[columnNumberOf["ListPrice"]], new CultureInfo("de-de")); //parsing! compare with old value (either from CSV or from DB) -> price change?
|
|
|
|
//if (fields[columnNumberOf["ListPrice"]] != "")
|
|
// if (decimal.Parse(fields[columnNumberOf["ListPrice"]], new CultureInfo("de-de")) != ImportedProduct.ListPrice)
|
|
// listpriceHasChanged = true;
|
|
|
|
ImportedProduct.BreakRangeFrom = fields[columnNumberOf["BreakRangeFrom"]] == "" ? 0 : Convert.ToInt32(fields[columnNumberOf["BreakRangeFrom"]]);
|
|
ImportedProduct.HasBreakPrices = ImportedProduct.BreakRangeFrom > 0;
|
|
ImportedProduct.BreakRangeTo = fields[columnNumberOf["BreakRangeTo"]] is "" or "+" ? 0 : Convert.ToInt32(fields[columnNumberOf["BreakRangeTo"]]); //erfasst sowohl Produkte ohne Break-Preise ("") als auch "+" bei Mengenangaben a la "100+" (= von 100 bis unendlich)
|
|
|
|
ImportedProduct.ProductLine.ProductLineCode = fields[columnNumberOf["ProductLineCode"]];
|
|
|
|
switch (fields[columnNumberOf["ProductStatus"]])
|
|
{
|
|
case "Active":
|
|
ImportedProduct.DataStatus = Status.Active.ToString();
|
|
ImportedProduct.ProductStatus = Status.Active.ToString();
|
|
break;
|
|
case "New Product" or "New":
|
|
ImportedProduct.DataStatus = Status.Active.ToString();
|
|
ImportedProduct.ProductStatus = Status.New.ToString();
|
|
break;
|
|
case "Price Changed":
|
|
ImportedProduct.DataStatus = Status.Active.ToString();
|
|
ImportedProduct.ProductStatus = Status.PriceUpdated.ToString();
|
|
break;
|
|
default:
|
|
ImportedProduct.DataStatus = Status.StatusUpdated.ToString();
|
|
break;
|
|
}
|
|
|
|
if (fields[columnNumberOf["Weight"]] != null)
|
|
{
|
|
ImportedProduct.Weight = ParseWeight(fields[columnNumberOf["Weight"]]);
|
|
}
|
|
|
|
if (fields[columnNumberOf["WeightUnit"]] == "G")
|
|
{
|
|
ImportedProduct.Weight /= 1000; //Umrechnung g in kg
|
|
}
|
|
|
|
if (fields[columnNumberOf["IntroductionDate"]] != "")
|
|
{
|
|
ImportedProduct.IntroductionDate = DateTime.Parse(fields[columnNumberOf["IntroductionDate"]]);
|
|
}
|
|
|
|
ImportedProduct.SapLongDescription = fields[columnNumberOf["SapLongDescription"]];
|
|
|
|
results.Add(ImportedProduct);
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
private static float ParseWeight(string input)
|
|
{
|
|
StringBuilder sb = new();
|
|
if (input.StartsWith("."))
|
|
{
|
|
input = sb.Append(0).Append(input).ToString();
|
|
}
|
|
|
|
try
|
|
{
|
|
return float.Parse(input, new CultureInfo("en-us"));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine(ex, "Unhandled Error in Function 'ParseWeight'");
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
private static bool ImportLSAG(Dictionary<string, int> mappingTable)
|
|
{
|
|
bool result;
|
|
result = ImportAccounts(mappingTable);
|
|
ResetParser();
|
|
_ = csvParser.ReadFields(); //Skip Heading
|
|
result = result && ImportContacts(mappingTable);
|
|
return result;
|
|
}
|
|
|
|
public static bool ImportContacts(Dictionary<string, int> columnNumberOf)
|
|
{
|
|
List<Contact> ContactsReadFromFile = new(8000);
|
|
using (csvParser)
|
|
{
|
|
while (!csvParser.EndOfData)
|
|
{
|
|
Contact ImportedContact = new();
|
|
string[] fields = csvParser.ReadFields()!;
|
|
|
|
//No conversion
|
|
ImportedContact.AcademicTitle = fields[columnNumberOf["AcademicTitle"]];
|
|
ImportedContact.FirstName = fields[columnNumberOf["FirstName"]];
|
|
ImportedContact.LastName = fields[columnNumberOf["LastName"]];
|
|
ImportedContact.EMail = fields[columnNumberOf["EMail"]];
|
|
ImportedContact.Department = fields[columnNumberOf["Department"]];
|
|
ImportedContact.Room = fields[columnNumberOf["Room"]];
|
|
ImportedContact.PhoneNumber = fields[columnNumberOf["PhoneNumber"]];
|
|
ImportedContact.Function = fields[columnNumberOf["Function"]];
|
|
ImportedContact.MobileNumber = fields[columnNumberOf["MobileNumber"]];
|
|
|
|
//Convert Gender
|
|
ImportedContact.Gender = fields[columnNumberOf["Gender"]] == "M"
|
|
? (byte)Gender.Male
|
|
: fields[columnNumberOf["Gender"]] == "F"
|
|
? (byte)Gender.Female
|
|
: (byte)Gender.Unknown;
|
|
|
|
//Convert OptIn Status
|
|
ImportedContact.OptInStatus = fields[columnNumberOf["OptInStatus"]] switch
|
|
{
|
|
"Opt In" => true,
|
|
"Opt Out" => false,
|
|
_ => false,
|
|
};
|
|
|
|
//Convert "SAP Contact Number"
|
|
try
|
|
{
|
|
ImportedContact.SAPContactNumber = Convert.ToInt32(fields[columnNumberOf["SAPContactNumber"]], CultureInfo.CurrentCulture);
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
//errorhandling here: "Unable to parse input: " + field[0] + " as uint"
|
|
//Zeilennummer, Feld und Wert in Liste speichern, um am Ende gesammelt auszugeben
|
|
string errorRaiser = fields[columnNumberOf["SAPContactNumber"]];
|
|
if (errorRaiser == "")
|
|
{
|
|
errorRaiser = "No Contact Number in this row!";
|
|
}
|
|
|
|
DbHelper.DisplayErrorDetails(ex, errorRaiser);
|
|
return false;
|
|
}
|
|
catch (OverflowException ex)
|
|
{
|
|
//errorhandling here: "Number cannot fit in an Uint."
|
|
//Zeilennummer, Feld und Wert in Liste speichern, um am Ende gesammelt auszugeben
|
|
string errorRaiser = fields[columnNumberOf["SAPContactNumber"]];
|
|
if (errorRaiser == "")
|
|
{
|
|
errorRaiser = "No Contact Number in this row!";
|
|
}
|
|
|
|
DbHelper.DisplayErrorDetails(ex, errorRaiser);
|
|
return false;
|
|
}
|
|
|
|
//Convert "Account Created on"
|
|
int year = Convert.ToInt32(fields[columnNumberOf["SAPContactCreationDate"]].Substring(0, 4), CultureInfo.CurrentCulture);
|
|
int month = Convert.ToInt32(fields[columnNumberOf["SAPContactCreationDate"]].Substring(4, 2), CultureInfo.CurrentCulture);
|
|
int day = Convert.ToInt32(fields[columnNumberOf["SAPContactCreationDate"]].Substring(6, 2), CultureInfo.CurrentCulture);
|
|
ImportedContact.SAPContactCreationDate = new DateTime(year, month, day);
|
|
|
|
//Convert "No Phone Calls"
|
|
if (fields[columnNumberOf["NoPhoneCalls"]] == "1")
|
|
{
|
|
ImportedContact.NoPhoneCalls = true;
|
|
}
|
|
|
|
//Convert "No Hardcopy Mailing"
|
|
if (fields[columnNumberOf["NoHardcopyMailing"]] == "1")
|
|
{
|
|
ImportedContact.NoHardcopyMailing = true;
|
|
}
|
|
|
|
//SAPAccountID in Contact.Notes speichern, um den entsprechenden Account aus DB heraussuchen zu können:
|
|
ImportedContact.Notes = fields[columnNumberOf["SAPAccountNumber"]];
|
|
|
|
ContactsReadFromFile.Add(ImportedContact);
|
|
}
|
|
|
|
//Eingelesenen Account in DB schreiben:
|
|
using (GremlinContext db = new())
|
|
{
|
|
foreach (Contact contact in ContactsReadFromFile)
|
|
{
|
|
// AccountID aus DB laden, damit der Datensatz vom Context verfolgt wird und EF Core nicht versucht, diesen standardmäßig neu anzulegen.
|
|
contact.Account = DbHelper.ResolveAccountById(db, Convert.ToUInt32(contact.Notes));
|
|
contact.Notes = "";
|
|
|
|
_ = MetaDataSetter.ForImport(contact, "GenericImporter-Method");
|
|
}
|
|
|
|
db.Contacts.AddRange(ContactsReadFromFile);
|
|
_ = db.SaveChanges();
|
|
}
|
|
}
|
|
//Bestätigung senden
|
|
Debug.WriteLine($"Es wurden {ContactsReadFromFile.Count} Contacts erfolgreich der Datenbank hinzugefügt.");
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool ImportAccounts(Dictionary<string, int> columnNumberOf)
|
|
///Importiert Account Daten aus CSV (erstellt aus LSAG_Contact_List_Tool.xlsx)
|
|
///
|
|
/// - Encoding: Latin1/ISO-8859-1
|
|
/// - fixe Spaltenzahl und -folge (Überschriften werden nicht untersucht/verwendet):
|
|
/// 1) SAPAccountNumber
|
|
/// 2) AccountName
|
|
/// 3) ZIP
|
|
/// 4) City
|
|
/// 5) Street
|
|
/// 6) AccountSubMarketCode
|
|
/// 7) AccountTypeCode
|
|
/// 8) PhoneNumber
|
|
/// 9) AccountsCreatedInSAP
|
|
///Kommentarzeichen: # (hardcoded, string array)
|
|
///Rückgabe 'false' bei Fehler oder User-Abbruch, ansonsten 'true'.
|
|
///
|
|
///Argumente:
|
|
/// 1.
|
|
|
|
{
|
|
List<Account> AccountsReadFromFile = new(1000);
|
|
|
|
while (!csvParser.EndOfData)
|
|
{
|
|
bool DataHasError = false;
|
|
|
|
// Read current line fields, pointer moves to the next line.
|
|
Account ImportedAccount = new();
|
|
{
|
|
ImportedAccount.SubMarket = new();
|
|
ImportedAccount.AccountType = new();
|
|
ImportedAccount.Contacts = new List<Contact>();
|
|
}
|
|
string[] fields = csvParser.ReadFields()!;
|
|
|
|
//Konvertierung erforderlich:
|
|
try
|
|
{
|
|
ImportedAccount.SAPAccountNumber = Convert.ToUInt32(fields[columnNumberOf["SAPAccountNumber"]]);
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
//errorhandling here: "Unable to parse input: " + field[0] + " as uint"
|
|
//Zeilennummer, Feld und Wert in Liste speichern, um am Ende gesammelt auszugeben
|
|
string errorRaiser = fields[columnNumberOf["SAPAccountNumber"]];
|
|
if (errorRaiser == "")
|
|
{
|
|
errorRaiser = "No Account Number in this row!";
|
|
}
|
|
|
|
DbHelper.DisplayErrorDetails(ex, errorRaiser);
|
|
return false;
|
|
}
|
|
catch (OverflowException ex)
|
|
{
|
|
//errorhandling here: "Number cannot fit in an Uint."
|
|
//Zeilennummer, Feld und Wert in Liste speichern, um am Ende gesammelt auszugeben
|
|
string errorRaiser = fields[columnNumberOf["SAPAccountNumber"]];
|
|
if (errorRaiser == "")
|
|
{
|
|
errorRaiser = "No Account Number in this row!";
|
|
}
|
|
|
|
DbHelper.DisplayErrorDetails(ex, errorRaiser);
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
ImportedAccount.ZIP = Convert.ToUInt32(fields[columnNumberOf["ZIP"]]);
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
//errorhandling here: "Unable to parse input: " + field[0] + " as uint"
|
|
//Zeilennummer, Feld und Wert in Liste speichern, um am Ende gesammelt auszugeben
|
|
string errorRaiser = fields[columnNumberOf["ZIP"]];
|
|
if (errorRaiser == "")
|
|
{
|
|
errorRaiser = "No ZIP in this row!";
|
|
}
|
|
|
|
DbHelper.DisplayErrorDetails(ex, errorRaiser);
|
|
return false;
|
|
}
|
|
catch (OverflowException ex)
|
|
{
|
|
//errorhandling here: "Number cannot fit in an Uint."
|
|
//Zeilennummer, Feld und Wert in Liste speichern, um am Ende gesammelt auszugeben
|
|
string errorRaiser = fields[columnNumberOf["ZIP"]];
|
|
if (errorRaiser == "")
|
|
{
|
|
errorRaiser = "No ZIP in this row!";
|
|
}
|
|
|
|
DbHelper.DisplayErrorDetails(ex, errorRaiser);
|
|
return false;
|
|
}
|
|
|
|
//Konvertierung für AccountCreatedinSAPOn Property:
|
|
//Test auf Inhalt bzw. Eintrag in der Mapping-Table (optionales Feld)
|
|
if (columnNumberOf.TryGetValue("AccountCreatedinSAPOn", out int columnNumber))
|
|
{
|
|
if (fields[columnNumberOf["AccountCreatedinSAPOn"]].Length != 0)
|
|
{
|
|
int year = Convert.ToInt32(fields[columnNumber].Substring(0, 4));
|
|
int month = Convert.ToInt32(fields[columnNumber].Substring(4, 2));
|
|
int day = Convert.ToInt32(fields[columnNumber].Substring(6, 2));
|
|
ImportedAccount.AccountCreatedInSAPOn = new DateTime(year, month, day);
|
|
}
|
|
}
|
|
|
|
//Convert City von Großschreibung zu Normalschreibung
|
|
ImportedAccount.City = fields[columnNumberOf["City"]].First().ToString() + fields[columnNumberOf["City"]].Substring(1).ToLower();
|
|
|
|
//keine Konvertierung nötig:
|
|
ImportedAccount.AccountName = fields[columnNumberOf["AccountName"]];
|
|
ImportedAccount.Street = fields[columnNumberOf["Street"]];
|
|
ImportedAccount.SubMarket.SubMarketCode = fields[columnNumberOf["SubMarketCode"]];
|
|
ImportedAccount.SubMarket.DataStatus = Status.Active.ToString();
|
|
ImportedAccount.AccountType.AccountTypeCode = fields[columnNumberOf["AccountTypeCode"]];
|
|
ImportedAccount.AccountType.DataStatus = Status.Active.ToString();
|
|
ImportedAccount.PhoneNumber = fields[columnNumberOf["PhoneNumber"]];
|
|
ImportedAccount.DataStatus = Status.Active.ToString();
|
|
|
|
//Validierungen:
|
|
if (ImportedAccount.AccountName == ""
|
|
|| ImportedAccount.City == ""
|
|
|| ImportedAccount.Street == ""
|
|
|| ImportedAccount.SubMarket.SubMarketCode == ""
|
|
|| ImportedAccount.AccountType.AccountTypeCode == ""
|
|
|| ImportedAccount.SAPAccountNumber == 0)
|
|
{
|
|
DataHasError = true;
|
|
}
|
|
|
|
//Validierten Account der Liste hinzufügen:
|
|
if (DataHasError == false)
|
|
{
|
|
_ = ImportedAccount.AddIfUniqueTo(AccountsReadFromFile);
|
|
}
|
|
}
|
|
|
|
//Eingelesenen Account in DB schreiben:
|
|
DateTime now = DateTime.Now;
|
|
|
|
foreach (Account account in AccountsReadFromFile)
|
|
{
|
|
// AccountType aus DB laden, damit der Datensatz vom Context verfolgt wird und EF Core nicht versucht, diesen standardmäßig neu anzulegen.
|
|
AccountType accountType = db.AccountTypes
|
|
.Where(a => a.AccountTypeCode == account.AccountType.AccountTypeCode)
|
|
.First();
|
|
|
|
account.AccountType = accountType;
|
|
account.AccountType = DbHelper.ResolveAccountType(db, account.AccountType.AccountTypeCode);
|
|
|
|
SubMarket subMarket = db.SubMarkets
|
|
.Where(a => a.SubMarketCode == account.SubMarket.SubMarketCode)
|
|
.First();
|
|
|
|
account.SubMarket = subMarket;
|
|
account.SubMarket = DbHelper.ResolveSubmarket(db, account.SubMarket.SubMarketCode);
|
|
|
|
_ = MetaDataSetter.ForImport(account, "GenericImporter-Method");
|
|
//account.DataVersionComment = "Initial import by CSV Importer (Function DbHelper.ImportAccountsFromCSV)";
|
|
}
|
|
|
|
db.Accounts.AddRange(AccountsReadFromFile);
|
|
_ = db.SaveChanges();
|
|
|
|
//Bestätigung senden
|
|
Debug.WriteLine($"Es wurden {AccountsReadFromFile.Count} Accounts erfolgreich der Datenbank hinzugefügt.");
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
public static bool ImportProductLine(TextFieldParser csvParser, Dictionary<string, int> mappingTable)
|
|
{
|
|
//foreach line in file:
|
|
//read seed data, parse/split, save to object with metadata
|
|
//add object to list
|
|
//add list to context, savechanges
|
|
|
|
List<ProductLine> productLinesReadFromFile = new(50);
|
|
using (csvParser)
|
|
{
|
|
while (!csvParser.EndOfData)
|
|
{
|
|
ProductLine importedProductLine = new();
|
|
string[] fields = csvParser.ReadFields()!;
|
|
importedProductLine.ProductLineCode = fields[mappingTable["ProductLineCode"]];
|
|
importedProductLine.ProductLineDescription = fields[mappingTable["ProductLineDescription"]];
|
|
productLinesReadFromFile.Add(importedProductLine);
|
|
_ = MetaDataSetter.ForImport(importedProductLine, "GenericImporter-Method");
|
|
}
|
|
}
|
|
|
|
db.ProductLines.AddRange(productLinesReadFromFile);
|
|
_ = db.SaveChanges();
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool ImportAccountType(TextFieldParser csvParser, Dictionary<string, int> mappingTable)
|
|
{
|
|
//foreach line in file:
|
|
//read seed data, parse/split, save to object with metadata
|
|
//add object to list
|
|
//add list to context, savechanges
|
|
|
|
List<AccountType> accountTypesReadFromFile = new(20);
|
|
using (csvParser)
|
|
{
|
|
while (!csvParser.EndOfData)
|
|
{
|
|
AccountType importedAccountType = new();
|
|
string[] fields = csvParser.ReadFields()!;
|
|
importedAccountType.AccountTypeCode = fields[mappingTable["AccountTypeCode"]];
|
|
importedAccountType.AccountTypeDescription = fields[mappingTable["AccountTypeDescription"]];
|
|
accountTypesReadFromFile.Add(importedAccountType);
|
|
_ = MetaDataSetter.ForImport(importedAccountType, "GenericImporter-Method");
|
|
}
|
|
}
|
|
|
|
db.AccountTypes.AddRange(accountTypesReadFromFile);
|
|
_ = db.SaveChanges();
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool ImportSubMarket(TextFieldParser csvParser, Dictionary<string, int> mappingTable)
|
|
{
|
|
//foreach line in file:
|
|
//read seed data, parse/split, save to object with metadata
|
|
//add object to list
|
|
//add list to context, savechanges
|
|
|
|
List<SubMarket> subMarketsReadFromFile = new(20);
|
|
using (csvParser)
|
|
{
|
|
while (!csvParser.EndOfData)
|
|
{
|
|
SubMarket importedSubMarket = new();
|
|
string[] fields = csvParser.ReadFields()!;
|
|
importedSubMarket.SubMarketCode = fields[mappingTable["SubMarketCode"]];
|
|
importedSubMarket.SubMarketDescription = fields[mappingTable["SubMarketDescription"]];
|
|
subMarketsReadFromFile.Add(importedSubMarket);
|
|
_ = MetaDataSetter.ForImport(importedSubMarket, "GenericImporter-Method");
|
|
}
|
|
}
|
|
|
|
db.SubMarkets.AddRange(subMarketsReadFromFile);
|
|
_ = db.SaveChanges();
|
|
|
|
return true;
|
|
}
|
|
|
|
//private static void SetProperty(object gremlinEntity, PropertyInfo propertyInfo, string value)
|
|
//{
|
|
// propertyInfo.SetValue(gremlinEntity, value);
|
|
//}
|
|
|
|
//private static Array GetNewGremlinTypeArray(Assembly assembly, string detectedDataType, int length)
|
|
//{
|
|
// Type GremlinType = GetNewGremlinType(assembly, detectedDataType).GetType();
|
|
// //Create an one-dimensional array with n+1 or n+2 elements (n = number of datasets, plus heading and/or emptyline at EOF):
|
|
// return Array.CreateInstance(GremlinType, length);
|
|
|
|
|
|
// //Das geht alles nicht:
|
|
// //List<GremlinType> test = new();
|
|
// //List<typeof(GremlinType)> test = new();
|
|
// //List<GremlinType.GetType()> test = new();
|
|
|
|
// ////Das geht:
|
|
// ////Create iList:
|
|
// //Type listType = typeof(List<>).MakeGenericType(GremlinType);
|
|
// //var list = (IList)Activator.CreateInstance(listType);
|
|
// //list.Add(new Account() { AccountName = "Test" });
|
|
// //list.Add(GremlinClassObject);
|
|
|
|
//}
|
|
|
|
//private static object GetNewGremlinType(Assembly Gremlin, string detectedDataType)
|
|
//{
|
|
// return Activator.CreateInstance(Gremlin.ToString(), "Gremlin." + detectedDataType).Unwrap();
|
|
//}
|
|
|
|
public static Dictionary<string, string> ReadMappingDictionaryFromFile()
|
|
{
|
|
Dictionary<string, string> result = new();
|
|
string fileInput = FileService.ReadResource("MappingDictionary.txt");
|
|
string[] lines = fileInput.Split(Environment.NewLine);
|
|
foreach (string line in lines)
|
|
{
|
|
string[] fields;
|
|
fields = line.Split("|");
|
|
result.Add(fields[0], fields[1]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static Dictionary<string, int> MapDataHeading(string[] headings, Dictionary<string, string> columnPropertyMapping)
|
|
{
|
|
Dictionary<string, int> result = new();
|
|
for (int i = 0; i < headings.Length; i++)
|
|
{
|
|
string heading = headings[i].ToLower(CultureInfo.CurrentCulture)
|
|
.Trim()
|
|
.Replace(" ", "")
|
|
.Replace("-", "")
|
|
.Replace("_", "")
|
|
.Replace(".", "")
|
|
.Replace(":", "");
|
|
|
|
if (columnPropertyMapping.TryGetValue(heading, out string? value))
|
|
{
|
|
result.Add(value, i);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//private static void BasimodosCodeDump()
|
|
//{
|
|
// //Unfertiger, generischer Code aus der ImportFile() Methode.
|
|
// //Aufbewahren für später, wenn Zeit ist, das ordentlich zu machen.
|
|
|
|
|
|
// //while (!csvParser.EndOfData)
|
|
// //{
|
|
// // //read
|
|
// // //new data instance
|
|
// // //convert
|
|
// // //validate
|
|
// // //set metadata: SetMetadataForImport(IMetadata)
|
|
// // //add to list
|
|
|
|
// // fields = csvParser.ReadFields(); // Read current line fields, pointer moves to the next line.
|
|
// // if (fields[0] == "") break; // Am Ende hängt eine leere Zeile, die im Parser einen Fehler auslösen würde.
|
|
|
|
|
|
// // //TO DO: vor der foreach "Account" bevorzugt behandeln (Sonderfall bei LSAG: Liste deduplizieren, und als erstes importieren, da sonst keine Contacts importiert werden können).
|
|
|
|
|
|
// // foreach (string detectedDataType in detectedDataTypes)
|
|
// // {
|
|
// // //"Account" überspringen, da das vor der foreach schon verarbeitet worden ist.
|
|
// // if (detectedDataType == "Account") continue;
|
|
|
|
// // Array GremlinTypeArray = GetNewGremlinTypeArray(Gremlin, detectedDataType, numberOfLines);
|
|
// // Type GremlinType = GetNewGremlinType(Gremlin, detectedDataType).GetType();
|
|
// // PropertyInfo[] GremlinTypeProperties = GremlinType.GetProperties();
|
|
|
|
// // foreach (PropertyInfo property in GremlinTypeProperties)
|
|
// // {
|
|
// // if (mappingTable.TryGetValue(property.Name, out int columnNumber))
|
|
// // {
|
|
// // //convert:
|
|
// // GremlinTypeConverter.Convert(fields[columnNumber]);
|
|
// // }
|
|
// // }
|
|
// // }
|
|
|
|
// //}
|
|
|
|
// //using (GremlinContext db = new())
|
|
// //{
|
|
// // //add to context
|
|
// // //savechanges
|
|
// //}
|
|
//}
|
|
|
|
|
|
|
|
//#########################################################################################
|
|
//Kann gelöscht werden, sobald die generische Funktion zuverlässig funktioniert:
|
|
//#########################################################################################
|
|
//private static string RecognizeDataStatic(Dictionary<string, int> mappingDictionary)
|
|
//{
|
|
// //Logik zur Kategorisierung des Datensatzes:
|
|
// //Alle verpflichtenden Angaben zu einer Klasse vorhanen?
|
|
// //Alle vom Importer erwarteten Angaben vorhanden?
|
|
// //Bei den Enums zusätzlich noch proüfem, dass nur zwei Spalten vorhanden sind, sonst könnten LSAG-Daten falsch identifiziert werden.
|
|
// //
|
|
// //
|
|
|
|
// //Products
|
|
// if (//required by DB:
|
|
// mappingDictionary.ContainsKey("ProductNumber")
|
|
// && mappingDictionary.ContainsKey("ListPrice")
|
|
// //required by importer:
|
|
// && mappingDictionary.ContainsKey("Weight")
|
|
// //unique identifier:
|
|
// && mappingDictionary.ContainsKey("BreakRangeFrom")
|
|
// )
|
|
// {
|
|
// return "Product";
|
|
// }
|
|
|
|
// //LSAG Contact List Tool List
|
|
// if (//required by DB:
|
|
// mappingDictionary.ContainsKey("SAPAccountNumber")
|
|
// && mappingDictionary.ContainsKey("SAPContactNumber")
|
|
// && mappingDictionary.ContainsKey("AccountTypeCode")
|
|
// && mappingDictionary.ContainsKey("SubMarketCode")
|
|
// && mappingDictionary.ContainsKey("LastName")
|
|
// && mappingDictionary.ContainsKey("AccountName")
|
|
// //required by importer:
|
|
|
|
// //unique identifier:
|
|
// && mappingDictionary.ContainsKey("MA_ProductInterests")
|
|
// )
|
|
// {
|
|
// return "LSAG Contact List Tool List";
|
|
// }
|
|
|
|
// //Accounts
|
|
// if (//required by DB:
|
|
// mappingDictionary.ContainsKey("AccountName")
|
|
// && mappingDictionary.ContainsKey("Street")
|
|
// && mappingDictionary.ContainsKey("ZIP")
|
|
// && mappingDictionary.ContainsKey("City")
|
|
// && mappingDictionary.ContainsKey("PhoneNumber")
|
|
// && mappingDictionary.ContainsKey("SAPAccountNumber")
|
|
// && mappingDictionary.ContainsKey("AccountCreatedInSAPOn")
|
|
// && mappingDictionary.ContainsKey("AccountTypeCode")
|
|
// && mappingDictionary.ContainsKey("SubMarketCode")
|
|
// //required by importer:
|
|
// )
|
|
// {
|
|
// return "Account";
|
|
// }
|
|
|
|
// //Contacts
|
|
// if (//required by DB:
|
|
// mappingDictionary.ContainsKey("LastName")
|
|
// && mappingDictionary.ContainsKey("SAPContactNumber")
|
|
// //required by importer:
|
|
// && mappingDictionary.ContainsKey("FirstName")
|
|
// && mappingDictionary.ContainsKey("Gender")
|
|
// )
|
|
// {
|
|
// return "Contact";
|
|
// }
|
|
|
|
// //Custom Description
|
|
// if (//required by DB:
|
|
// mappingDictionary.ContainsKey("Heading")
|
|
// //required by importer:
|
|
// && mappingDictionary.ContainsKey("ProductNumber")
|
|
// && mappingDictionary.ContainsKey("OptionNumber")
|
|
// && mappingDictionary.ContainsKey("DescriptionText")
|
|
// //unique identifier:
|
|
// && mappingDictionary.ContainsKey("CoverletterText")
|
|
// )
|
|
// {
|
|
// return "CustomDescription";
|
|
// }
|
|
|
|
|
|
// //Pseudo-Enums AccountTypes, SubMarkets, ProductLines for DB-initializing
|
|
// if (mappingDictionary.Count == 2)
|
|
// {
|
|
// if (mappingDictionary.ContainsKey("AccountTypeCode")
|
|
// && mappingDictionary.ContainsKey("AccountTypeDescription")
|
|
// && mappingDictionary.Count == 2)
|
|
// {
|
|
// return "AccountType";
|
|
// }
|
|
|
|
// if (mappingDictionary.ContainsKey("SubMarketCode")
|
|
// && mappingDictionary.ContainsKey("SubMarketDescription")
|
|
// && mappingDictionary.Count == 2)
|
|
// {
|
|
// return "SubMarket";
|
|
// }
|
|
|
|
// if (mappingDictionary.ContainsKey("ProductLineCode")
|
|
// && mappingDictionary.ContainsKey("ProductLineDescription")
|
|
// && mappingDictionary.Count == 2)
|
|
// {
|
|
// return "ProductLine";
|
|
// }
|
|
// }
|
|
|
|
// return "No entity type unambigiously identified!";
|
|
|
|
//}
|
|
}
|
|
}
|