@ -1,21 +1,14 @@
// using DocumentFormat.OpenXml.Packaging;
// using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml.Packaging ;
using DocumentFormat.OpenXml.Wordprocessing ;
using Gremlin_BlazorServer.Data.EntityClasses ;
using Gremlin_BlazorServer.Utilities ;
using Microsoft.EntityFrameworkCore ;
using Microsoft.VisualBasic.FileIO ;
using MySqlConnector ;
using System ;
using System.Collections.Generic ;
using System.Data ;
using System.Diagnostics ;
using System.Globalization ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
using System.Windows ;
using static Gremlin_BlazorServer . Data . EntityClasses . Enums ;
namespace Gremlin_BlazorServer.Data.DBClasses
@ -1332,157 +1325,157 @@ namespace Gremlin_BlazorServer.Data.DBClasses
}
}
public static bool ImportCustomDescriptionsFromDocx ( string filepath = "" )
/// Importiert Eigene Beschreibungen aus Word-Dokument
/// Abkürzung: CD = CustomDescriptions
{
if ( filepath = = "" )
{
//filepath = FileIO.GetFilepathFromUser("Word-Dokument|*.doc; *.docx; *.docm"); //Pfad abfragen über Dtei-Öffnen-Dialog:
}
if ( filepath = = "" )
{
return false ; //Wenn keine Datei ausgewählt (Cancel geklickt), dann Abbruch:
}
List < CustomDescription > importedCDs = new ( 2500 ) ;
WordprocessingDocument CDDoc = WordprocessingDocument . Open ( filepath , false ) ; //alternativ in using-Block packen, dann kann man nicht das Document.Close vergessen.
Table CDTable = CDDoc . MainDocumentPart . Document . Body . Elements < Table > ( ) . ElementAt ( 0 ) ; //alternativ: Elements<Table>.First()
if ( CDTable ! = null )
{
CDTable . Descendants < TableRow > ( ) . First ( ) . Remove ( ) ; //Überschriften löschen
foreach ( TableRow aRow in CDTable . Descendants < TableRow > ( ) ) //einmal durch den XML-Baum wandern: WordprocessingDocument -> MainDocumentPart -> Document -> Body -> Table -> TableRow -> TableCell -> Paragraph -> Run -> Text
{
CustomDescription importedCD = new ( ) ;
List < string > stringsRead = new ( ) ;
foreach ( TableCell aCell in aRow . Descendants < TableCell > ( ) )
{
StringBuilder sb = new ( ) ;
StringBuilder note = new ( ) ;
foreach ( Paragraph aParagraph in aCell . Descendants < Paragraph > ( ) )
{
foreach ( Run aRun in aParagraph . Descendants < Run > ( ) )
{
foreach ( Text aText in aRun . Descendants < Text > ( ) )
{
string temp = "" ;
temp = aParagraph . Descendants < Run > ( )
. Where ( r = > r . RunProperties . Vanish ! = null )
. Aggregate ( "" , ( text , r ) = > text + = r . InnerText ) ; //nach hidden Text filtern, diesen in "note" speichern
_ = note . Append ( temp ) ;
if ( temp = = "" ) //true, falls kein hidden Text => normalen Text verketten...
{
_ = sb . Append ( aText . InnerText ) ;
}
}
}
}
stringsRead . Add ( sb . ToString ( ) ) ; //...und zellenweise abspeichern
if ( note . ToString ( ) ! = "" )
{
importedCD . Notes = note . ToString ( ) ;
}
}
importedCD . ProductNumber = stringsRead . ElementAt ( 0 ) ;
importedCD . OptionNumber = stringsRead . ElementAt ( 1 ) = = "" ? null : stringsRead . ElementAt ( 1 ) ;
importedCD . Supplier . AccountName = stringsRead . ElementAt ( 2 ) is "" or "RB" ? "Agilent Technologies" : stringsRead . ElementAt ( 2 ) ;
importedCD . Heading = stringsRead . ElementAt ( 3 ) ;
importedCD . DescriptionText = stringsRead . ElementAt ( 4 ) ;
importedCD . CoverletterText = stringsRead . ElementAt ( 5 ) ;
importedCDs . Add ( importedCD ) ;
//if (importedCDs.Count >= 1200 && importedCDs.Count % 100 == 0) MessageBox.Show(importedCDs.Count.ToString()); //DEBUGGING
}
}
//MessageBox.Show(importedCDs.Count.ToString()); //DEBUGGING
CDDoc . Close ( ) ;
//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 importedCDs )
{
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 = null ,
SapShortDescription = null ,
Weight = 0 ,
IntroductionDate = DateTime . Now . Date ,
BreakRangeFrom = 0 ,
BreakRangeTo = 0 ,
ProductLine = ResolveProductLine ( db , "3P" )
} ;
new3PPProduct . CustomDescription . Supplier = ResolveAccountByName ( db , new3PPProduct . CustomDescription . Supplier . AccountName ) ;
_ = MetaDataSetter . ForImport ( new3PPProduct , "Custom Desciption Importer" , "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 ( ) ;
List < CustomDescription > CDsWithoutEFReferences = new ( ) ; //nur zur Kontrolle, wird nicht verwendet.
foreach ( CustomDescription CD in importedCDs )
{
//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 . Products . Add ( ResolveProduct ( db , CD . ProductNumber , CD . OptionNumber ) ) ; //ResolveXY-functions return null, if no match is found in db.
if ( CD . Products = = null )
{
CDsWithoutEFReferences . Add ( CD ) ;
continue ;
}
//Establish EF Reference. If no Supplier-Account found, then skip this custom description.
CD . Supplier = ResolveAccountByName ( db , CD . Supplier . AccountName ) ; //ResolveXY-functions return null, if no match is found in db.
if ( CD . Supplier = = null )
{
CDsWithoutEFReferences . Add ( CD ) ;
continue ;
}
_ = MetaDataSetter . ForImport ( CD , "DocxImporter" , "Initial import by CSV Importer (Function DbHelper.ImportCustomDescriptionsFromDocx)" ) ;
//add to final list of CDs, that will go into the db.
importedCDsWithEFReferences . Add ( CD ) ;
}
db . CustomDescriptions . AddRange ( importedCDsWithEFReferences ) ;
_ = db . SaveChanges ( ) ;
}
return true ;
}
//public static bool ImportCustomDescriptionsFromDocx(string filepath = "" )
/// // Importiert Eigene Beschreibungen aus Word-Dokument
/// // Abkürzung: CD = CustomDescriptions
// {
// if (filepath == "")
// {
// //filepath = FileIO.GetFilepathFromUser("Word-Dokument|*.doc; *.docx; *.docm"); //Pfad abfragen über Dtei-Öffnen-Dialog:
// }
// if (filepath == "")
// {
// return false; //Wenn keine Datei ausgewählt (Cancel geklickt), dann Abbruch:
// }
// List<CustomDescription> importedCDs = new(2500);
// WordprocessingDocument CDDoc = WordprocessingDocument.Open(filepath, false); //alternativ in using-Block packen, dann kann man nicht das Document.Close vergessen.
// Table CDTable = CDDoc.MainDocumentPart.Document.Body.Elements<Table>().ElementAt(0); //alternativ: Elements<Table>.First()
// if (CDTable != null)
// {
// CDTable.Descendants<TableRow>().First().Remove(); //Überschriften löschen
// foreach (TableRow aRow in CDTable.Descendants<TableRow>()) //einmal durch den XML-Baum wandern: WordprocessingDocument -> MainDocumentPart -> Document -> Body -> Table -> TableRow -> TableCell -> Paragraph -> Run -> Text
// {
// CustomDescription importedCD = new();
// List<string> stringsRead = new();
// foreach (TableCell aCell in aRow.Descendants<TableCell>())
// {
// StringBuilder sb = new();
// StringBuilder note = new();
// foreach (Paragraph aParagraph in aCell.Descendants<Paragraph>())
// {
// foreach (Run aRun in aParagraph.Descendants<Run>())
// {
// foreach (Text aText in aRun.Descendants<Text>())
// {
// string temp = "";
// temp = aParagraph.Descendants<Run>()
// .Where(r => r.RunProperties.Vanish != null)
// .Aggregate("", (text, r) => text += r.InnerText); //nach hidden Text filtern, diesen in "note" speichern
// _ = note.Append(temp);
// if (temp == "") //true, falls kein hidden Text => normalen Text verketten...
// {
// _ = sb.Append(aText.InnerText);
// }
// }
// }
// }
// stringsRead.Add(sb.ToString()); //...und zellenweise abspeichern
// if (note.ToString() != "")
// {
// importedCD.Notes = note.ToString();
// }
// }
// importedCD.ProductNumber = stringsRead.ElementAt(0);
// importedCD.OptionNumber = stringsRead.ElementAt(1) == "" ? null : stringsRead.ElementAt(1);
// importedCD.Supplier.AccountName = stringsRead.ElementAt(2) is "" or "RB" ? "Agilent Technologies" : stringsRead.ElementAt(2);
// importedCD.Heading = stringsRead.ElementAt(3);
// importedCD.DescriptionText = stringsRead.ElementAt(4);
// importedCD.CoverletterText = stringsRead.ElementAt(5);
// importedCDs.Add(importedCD);
// //if (importedCDs.Count >= 1200 && importedCDs.Count % 100 == 0) MessageBox.Show(importedCDs.Count.ToString()); //DEBUGGING
// }
// }
// //MessageBox.Show(importedCDs.Count.ToString()); //DEBUGGING
// CDDoc.Close();
// //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 importedCDs)
// {
// 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 = null,
// SapShortDescription = null,
// Weight = 0,
// IntroductionDate = DateTime.Now.Date,
// BreakRangeFrom = 0,
// BreakRangeTo = 0,
// ProductLine = ResolveProductLine(db, "3P")
// };
// new3PPProduct.CustomDescription.Supplier = ResolveAccountByName(db, new3PPProduct.CustomDescription.Supplier.AccountName);
// _ = MetaDataSetter.ForImport(new3PPProduct, "Custom Desciption Importer", "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();
// List<CustomDescription> CDsWithoutEFReferences = new(); //nur zur Kontrolle, wird nicht verwendet.
// foreach (CustomDescription CD in importedCDs)
// {
// //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.Products.Add(ResolveProduct(db, CD.ProductNumber, CD.OptionNumber)); //ResolveXY-functions return null, if no match is found in db.
// if (CD.Products == null)
// {
// CDsWithoutEFReferences.Add(CD);
// continue;
// }
// //Establish EF Reference. If no Supplier-Account found, then skip this custom description.
// CD.Supplier = ResolveAccountByName(db, CD.Supplier.AccountName); //ResolveXY-functions return null, if no match is found in db.
// if (CD.Supplier == null)
// {
// CDsWithoutEFReferences.Add(CD);
// continue;
// }
// _ = MetaDataSetter.ForImport(CD, "DocxImporter", "Initial import by CSV Importer (Function DbHelper.ImportCustomDescriptionsFromDocx)");
// //add to final list of CDs, that will go into the db.
// importedCDsWithEFReferences.Add(CD);
// }
// db.CustomDescriptions.AddRange(importedCDsWithEFReferences);
// _ = db.SaveChanges();
// }
// return true;
// }
public static bool UpdateProductsFromCsv ( string filepath = "" , string separator = "|" , bool dataHasHeading = true )
{
@ -2023,10 +2016,10 @@ namespace Gremlin_BlazorServer.Data.DBClasses
return await Task . Run ( ( ) = > ImportProductsFromCsv ( ) ) ;
}
public static async Task < bool > ImportCustomDescriptionsFromDocxAsync ( )
{
return await Task . Run ( ( ) = > ImportCustomDescriptionsFromDocx ( ) ) ;
}
//public static async Task<bool> ImportCustomDescriptionsFromDocxAsync( )
// {
// return await Task.Run(() => ImportCustomDescriptionsFromDocx());
// }
public static async Task < bool > ImportCustomDescriptionsFromCsvAsync ( )
{
@ -2091,5 +2084,23 @@ namespace Gremlin_BlazorServer.Data.DBClasses
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ;
return new string ( Enumerable . Repeat ( chars , length ) . Select ( s = > s [ random . Next ( s . Length ) ] ) . ToArray ( ) ) ;
}
public static Contact GetContact ( GremlinContext context , string lastName )
{
try { return context . Contacts . Where ( contact = > contact . LastName = = lastName ) . First ( ) ; }
catch { return null ; }
}
public static Contact GetContact ( GremlinContext context , uint contactId )
{
try { return context . Contacts . Where ( contact = > contact . ContactId = = contactId ) . First ( ) ; }
catch { return null ; }
}
internal static List < Contact > GetAllContacts ( GremlinContext context )
{
try { return context . Contacts . Where ( contact = > contact . LastName ! = "" ) . ToList ( ) ; }
catch { return null ; }
}
}
}