2022-01-24 21:04:24 +00:00
using System ;
using System.IO ;
using dezentrale.model ;
using System.Collections.Generic ;
using dezentrale.model.money ;
namespace dezentrale.core
{
public class CsvImportProcess : BackgroundProcess
{
2022-02-18 21:34:28 +00:00
public string FileName { get ; set ; } = "" ;
public CsvImportProcess ( )
2022-01-24 21:04:24 +00:00
{
Caption = "Import CSV Money Transfers" ;
2022-02-18 21:34:28 +00:00
Steps = 5 ;
2022-01-24 21:04:24 +00:00
}
protected override bool Run ( )
{
uint step = 0 ;
2022-02-18 21:34:28 +00:00
LogTarget . LogLine ( $"Importing from {FileName}" , LogEvent . ELogLevel . Info , "CsvImportProcess" ) ;
2022-01-24 21:04:24 +00:00
List < BankTransfer > tmpList = new List < BankTransfer > ( ) ;
List < string > headlineFields = null ;
List < Member > changedMembers = new List < Member > ( ) ;
CsvFile csv = new CsvFile ( ) { FieldSeparator = ';' } ;
try
{
LogTarget . StepStarted ( + + step , "Reading file..." ) ;
try
{
2022-02-18 21:34:28 +00:00
csv . ReadFile ( FileName ) ;
2022-01-24 21:04:24 +00:00
LogTarget . StepCompleted ( step , "Done reading file." , true ) ;
} catch ( Exception ex )
{
LogTarget . LogLine ( $"Error: {ex.Message}" , LogEvent . ELogLevel . Error , "CsvImportProcess" ) ;
return false ;
}
List < List < string > > contents = csv . FileContents ;
LogTarget . StepStarted ( + + step , $"Parsing file ({contents.Count} csv lines, including headline)..." ) ;
for ( int csvLine = 0 ; csvLine < contents . Count ; csvLine + + )
{
List < string > l = contents [ csvLine ] ;
if ( headlineFields = = null )
{
//The first line is expected to have the headline field first, describing the contents
headlineFields = l ;
string fields = "" ;
foreach ( string s in l )
{
fields + = $"\" { s } \ "," ;
}
LogTarget . LogLine ( $"Headline fields: {fields}" , LogEvent . ELogLevel . Info , "CsvImportProcess" ) ;
continue ;
}
2022-02-18 21:34:28 +00:00
BankTransfer bt = new BankTransfer ( headlineFields , l , FileName , csvLine ) ;
2022-01-24 21:04:24 +00:00
MoneyTransfer duplicate = Program . MoneyTransfers . FindEqualEntry ( bt ) ;
if ( duplicate ! = null )
{
LogTarget . LogLine ( $"Line {csvLine}: is duplicate of MoneyTransfer {duplicate.Id} (ValutaDate {duplicate.ValutaDateString})" , LogEvent . ELogLevel . Info , "CsvImportProcess" ) ;
LogTarget . LogLine ( $" ValutaDate: {bt.ValutaDate}, Amount = {bt.AmountString} {bt.Currency}, Reason = \" { bt . TransferReason . Replace ( '\r' , '\\' ) . Replace ( '\n' , '\\' ) } \ "" , LogEvent . ELogLevel . Info , "CsvImportProcess" ) ;
}
else
{
Program . MoneyTransfers . AddEntry ( bt ) ;
tmpList . Add ( bt ) ;
}
}
LogTarget . StepCompleted ( step , $"Done parsing entries." , true ) ;
LogTarget . StepStarted ( + + step , $"Assigning found {tmpList.Count} entries to members" ) ;
//try to assign transfers to the members
foreach ( BankTransfer bt in tmpList )
{
if ( bt . Amount < 0 )
{
bt . TransferType = MoneyTransfer . eTransferType . RunningCost ;
LogTarget . LogLine ( $"{bt.Id}: (from CSV line {bt.CsvLine}): Amount = {bt.AmountString} --> RunningCost" , LogEvent . ELogLevel . Info , "CsvImportProcess" ) ;
continue ;
}
foreach ( Member m in Program . members . Entries )
{
if ( m . CheckBankTransfer ( bt ) )
{
LogTarget . LogLine ( $"{bt.Id}: (from CSV line {bt.CsvLine}): adding to member {m}" , LogEvent . ELogLevel . Info , "CsvImportProcess" ) ;
bt . TransferType = MoneyTransfer . eTransferType . MembershipPayment ;
changedMembers . Add ( m ) ;
m . StartLogEvent ( "Incoming bank transfer" , LogEvent . eEventType . MembershipPayment , "automatic" ) ;
m . ApplyMoneyTransfer ( bt ) ; //this also stores the member entry
bt . AssignFixed = true ;
break ; //this is important. We don't want to assign this to multiple members.
}
}
if ( ! bt . AssignFixed )
{
//bt matches no member!
}
}
LogTarget . StepCompleted ( step , $"Done assigning entries." , true ) ;
LogTarget . StepStarted ( + + step , $"Storing money transfers" ) ;
//Store bank transfer list
Program . MoneyTransfers . Entries . Sort ( ) ;
if ( ! Program . MoneyTransfers . SaveToFile ( ) )
return false ;
LogTarget . StepCompleted ( step , "" , true ) ;
return true ;
}
catch ( Exception ex )
{
2022-02-18 21:34:28 +00:00
LogTarget . LogLine ( $"Error while processing csv file \" { FileName } \ ": {ex.Message}" , LogEvent . ELogLevel . Error , "CsvImportProcess" ) ;
2022-01-24 21:04:24 +00:00
return false ;
}
}
}
}