public override BalanceChanges GetBalanceChanges(TransactionBlock previousBlock) { var bc = new BalanceChanges(); // transfer unchanged token balances from the previous block foreach (var prevKvp in previousBlock.Balances) { decimal amount; if (Balances.ContainsKey(prevKvp.Key)) { amount = (prevKvp.Value - Balances[prevKvp.Key]).ToBalanceDecimal(); } else { // all spent. zero. ommit amount = prevKvp.Value.ToBalanceDecimal(); } if (prevKvp.Key == FeeCode) { amount -= Fee; } if (amount != 0) { bc.Changes.Add(prevKvp.Key, amount); } } bc.FeeCode = this.FeeCode; bc.FeeAmount = this.Fee; return(bc); }
private Transaction CreateTransaction(Match match, Stock userStock, Stock externalStock, TransactionType defaultOutcome, TransactionType defaultIncome) { int day = int.Parse(match.Groups["Day"].Value); int month = int.Parse(match.Groups["Month"].Value); int year = int.Parse(match.Groups["Year"].Value); int id = int.Parse(match.Groups["Id"].Value); string operationType = match.Groups["OperationType"].Value.Trim(); var noteLines = match.Groups["Note"].Value.Split('\n'); string title = match.Groups["Title"].Value.Trim(); string currency = match.Groups["Currency"].Value.Trim(); bool negativeSign = match.Groups["Sign"].Value.Equals("-"); int bigValue = int.Parse(match.Groups["ValueWithSpaces"].Value.Replace(" ", string.Empty)); int smallValue = int.Parse(match.Groups["ValueAfterComma"].Value); decimal value = bigValue + smallValue / 100m; var date = new DateTime(year, month, day); string note = $"{id} - {string.Join(" ", noteLines.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()))} {operationType}"; bool isBalanceNote = match.Groups["BalanceValueWithSpaces"].Success; if (isBalanceNote) { int bigValueBalance = int.Parse(match.Groups["BalanceValueWithSpaces"].Value.Replace(" ", string.Empty)); int smallValueBalance = int.Parse(match.Groups["BalanceValueAfterComma"].Value); decimal balance = bigValueBalance + smallValueBalance / 100m; note = $"{note} saldo: {balance:#,##0.00} ({currency})"; if (!Balances.ContainsKey(userStock)) { Balances[userStock] = new Dictionary <DateTime, decimal>(); } if (!Balances[userStock].ContainsKey(date)) { Balances[userStock][date] = balance; } } var transactionType = negativeSign ? defaultOutcome : defaultIncome; var position = new Position(title, value); return(new Transaction(transactionType, date, title, note, new List <Position> { position }, userStock, externalStock)); }
private bool MatchRule(Rule rule, string[] elements, Transaction transaction, TransactionType defaultIncome, TransactionType defaultOutcome, Stock defaultUserStock, bool generateMissingStocks) { if (elements.Length < rule.Column) { return(false); } try { string stringValue = elements[rule.Index].Trim(); switch (rule.Property) { case TransactionField.Title: transaction.Title = stringValue; if (string.IsNullOrWhiteSpace(transaction.Title)) { return(false); } break; case TransactionField.Note: if (string.IsNullOrWhiteSpace(stringValue) && !rule.IsOptional) { return(false); } transaction.Notes.Add(stringValue); break; case TransactionField.BookDate: if (rule.IsOptional && string.IsNullOrWhiteSpace(stringValue)) { transaction.BookDate = DateTime.Today; } else { transaction.BookDate = DateTime.Parse(stringValue); } if (transaction.TransactionSourceCreationDate == DateTime.MinValue) { transaction.TransactionSourceCreationDate = transaction.BookDate; } break; case TransactionField.CreationDate: if (rule.IsOptional && string.IsNullOrWhiteSpace(stringValue)) { transaction.TransactionSourceCreationDate = DateTime.Today; } else { transaction.TransactionSourceCreationDate = DateTime.Parse(stringValue); } if (transaction.BookDate == DateTime.MinValue) { transaction.BookDate = transaction.TransactionSourceCreationDate; } break; case TransactionField.PositionTitle: transaction.Positions[0].Title = stringValue; if (string.IsNullOrWhiteSpace(transaction.Positions[0].Title)) { if (rule.IsOptional) { transaction.Positions[0].Title = "position 1"; } else { return(false); } } break; case TransactionField.Value: { decimal value = decimal.Parse(stringValue.Replace(".", ",")); transaction.Type = value >= 0 ? defaultIncome : defaultOutcome; transaction.Positions[0].Value.GrossValue = Math.Abs(value); } break; case TransactionField.ValueAsLost: { if (string.IsNullOrWhiteSpace(stringValue)) { return(true); } decimal value = decimal.Parse(stringValue.Replace(".", ",")); if (value == 0) { return(true); } if (value < 0) { value = Math.Abs(value); } transaction.Type = defaultOutcome; transaction.Positions[0].Value.GrossValue = Math.Abs(value); } break; case TransactionField.ValueAsProfit: { if (string.IsNullOrWhiteSpace(stringValue)) { return(true); } decimal value = decimal.Parse(stringValue.Replace(".", ",")); if (value == 0) { return(true); } if (transaction.Positions[0].Value.GrossValue > 0 && transaction.Type != null) { decimal sum = transaction.Type.Outcome ? value - transaction.Positions[0].Value.GrossValue : value + transaction.Positions[0].Value.GrossValue; transaction.Type = sum > 0m ? defaultIncome : defaultOutcome; transaction.Positions[0].Value.GrossValue = Math.Abs(sum); } else { transaction.Type = value >= 0 ? defaultIncome : defaultOutcome; transaction.Positions[0].Value.GrossValue = Math.Abs(value); } } break; case TransactionField.UserStock: if (_stocks != null && _stocks.Any()) { var matching = _stocks.FirstOrDefault(x => x.Name.ToLower().Equals(stringValue.ToLower())); transaction.UserStock = matching; } if (transaction.UserStock == null || (!transaction.UserStock.Name?.Equals(stringValue) ?? true)) { transaction.UserStock = generateMissingStocks ? new Stock(stringValue.GenerateGuid()) { Name = stringValue, IsUserStock = true } : defaultUserStock; } break; case TransactionField.Balance: if (!Balances.ContainsKey(transaction.UserStock)) { Balances[transaction.UserStock] = new Dictionary <DateTime, decimal>(); } var balance = Balances[transaction.UserStock]; if (!balance.ContainsKey(transaction.TransactionSourceCreationDate)) { balance[transaction.TransactionSourceCreationDate] = decimal.Parse(stringValue.Replace(".", ",")); } break; case TransactionField.Currency: //todo: break; } } catch (Exception e) { _logger.Value.Debug($"Parsing failed{Environment.NewLine}{string.Join(";", elements)}", e); return(false); } return(true); }