private static async Task ImportMoneyForwardDataCore(DateTime from, DateTime to, ILogger log) { log.LogInformation($"{from:yyyy/MM/dd}から{to:yyyy/MM/dd}の期間のデータを取得します。"); var id = Configuration.GetValue <string>("MAIL"); log.LogInformation($"アカウント[{id}]の情報を取得してデータベースに保存します。"); var password = Configuration.GetValue <string>("PASSWORD"); var mfs = new MoneyForwardScraper(id, password); var dbContext = GetDbContext(); await using var transaction = await dbContext.Database.BeginTransactionAsync(); // 取引履歴登録 await foreach (var mt in mfs.GetTransactions(from, to)) { var ids = mt.Select(x => x.TransactionId).ToArray(); var deleteTransactionList = dbContext.MfTransactions.Where(t => ids.Contains(t.TransactionId)); dbContext.MfTransactions.RemoveRange(deleteTransactionList); await dbContext.MfTransactions.AddRangeAsync(mt); log.LogInformation($"{mt.First()?.Date:yyyy/MM}取引履歴{mt.Count()}件登録"); } // 資産推移登録 await foreach (var ma in mfs.GetAssets(from, to)) { var assets = ma.GroupBy(x => new { x.Date, x.Institution, x.Category }) .Select(x => new MfAsset { Date = x.Key.Date, Institution = x.Key.Institution, Category = x.Key.Category, Amount = x.Sum(a => a.Amount) }).ToArray(); var deleteAssetList = dbContext.MfAssets.Where(a => a.Date == assets.First().Date); dbContext.MfAssets.RemoveRange(deleteAssetList); await dbContext.MfAssets.AddRangeAsync(assets); log.LogInformation($"{ma.First().Date:yyyy/MM/dd}資産推移{assets.Count()}件登録"); } await dbContext.SaveChangesAsync(); await transaction.CommitAsync(); ; log.LogInformation($"完了"); }
public async Task ImportFromMoneyForward(DateTime from, DateTime to) { var mfs = new MoneyForwardScraper(this.Id.Value, this.Password.Value); await using var transaction = await this._dbContext.Database.BeginTransactionAsync(); // 取引履歴登録 await foreach (var mt in mfs.GetTransactions(from, to)) { var ids = mt.Select(x => x.TransactionId).ToArray(); var deleteTransactionList = this._dbContext.MfTransactions.Where(t => ids.Contains(t.TransactionId)); this._dbContext.MfTransactions.RemoveRange(deleteTransactionList); await this._dbContext.MfTransactions.AddRangeAsync(mt); this.ProcessingText.Value = $"{mt.First()?.Date:yyyy/MM}取引履歴{mt.Length}件登録"; } // 資産推移登録 await foreach (var ma in mfs.GetAssets(from, to)) { var assets = ma.GroupBy(x => new { x.Date, x.Institution, x.Category }) .Select(x => new MfAsset { Date = x.Key.Date, Institution = x.Key.Institution, Category = x.Key.Category, Amount = x.Sum(a => a.Amount) }).ToArray(); var dates = assets.Select(x => x.Date).ToArray(); var deleteAssetList = this._dbContext.MfAssets.Where(a => dates.Contains(a.Date)); this._dbContext.MfAssets.RemoveRange(deleteAssetList); await this._dbContext.MfAssets.AddRangeAsync(assets); this.ProcessingText.Value = $"{ma.First().Date:yyyy/MM/dd}資産推移{assets.Length}件登録"; } await this._dbContext.SaveChangesAsync(); await transaction.CommitAsync(); await this.LoadTransactions(); await this.LoadAssets(); this.ProcessingText.Value = ""; }
/// <summary> /// 更新処理開始 /// </summary> /// <param name="from">取得対象開始日</param> /// <param name="to">取得対象終了日</param> /// <returns>更新キー</returns> public int Update(DateTime from, DateTime to) { return(this._updater.Update(async progress => { // 進捗率計算の分母 var denominator = Math.Max(1, to.Ticks - from.Ticks); progress.Report(1); this._logger.LogInformation($"{from}-{to}の財務データベース更新開始"); var db = this._scope.ServiceProvider.GetService <HomeServerDbContext>(); if (db == null) { throw new Exception($"{typeof(HomeServerDbContext).FullName}取得失敗"); } var setting = await Utility.GetUseSetting(db); var mfs = new MoneyForwardScraper(setting.MoneyForwardId, setting.MoneyForwardPassword); await using var tran = await db.Database.BeginTransactionAsync(); // 資産推移 var maCount = 0; await foreach (var ma in mfs.GetAssets(from, to)) { var assets = ma.GroupBy(x => new { x.Date, x.Institution, x.Category }) .Select(x => new LockableMfAsset { Date = x.Key.Date, Institution = x.Key.Institution, Category = x.Key.Category, Amount = x.Sum(a => a.Amount), IsLocked = false }).ToArray(); var existsRecords = db.MfAssets.Where(a => a.Date == assets.First().Date); var deleteAssetList = existsRecords.Where(x => !x.IsLocked); db.MfAssets.RemoveRange(deleteAssetList); await db.MfAssets.AddRangeAsync(assets.Where(x => existsRecords .Where(er => er.IsLocked) .All(er => er.Institution != x.Institution || er.Category != x.Category))); this._logger.LogDebug($"{ma.First().Date:yyyy/MM/dd}資産推移{assets.Length}件登録"); maCount += assets.Length; progress.Report(1 + ((ma.First().Date.Ticks - from.Ticks) * 89 / denominator)); } this._logger.LogInformation($"資産推移 計{maCount}件登録"); // 取引履歴 var mtCount = 0; await foreach (var mt in mfs.GetTransactions(from, to)) { var ids = mt.Select(x => x.TransactionId).ToArray(); var existsRecords = db.MfTransactions.Where(t => ids.Contains(t.TransactionId)); var deleteTransactionList = existsRecords.Where(x => !x.IsLocked); db.MfTransactions.RemoveRange(deleteTransactionList); await db.MfTransactions.AddRangeAsync( mt.Select(x => new LockableMfTransaction(x)) .Where(x => existsRecords .Where(er => er.IsLocked) .All(er => er.TransactionId != x.TransactionId))); this._logger.LogInformation($"{mt.First()?.Date:yyyy/MM}取引履歴{mt.Length}件登録"); mtCount += mt.Length; progress.Report(90 + ((mt.First().Date.Ticks - from.Ticks) * 9 / denominator)); } this._logger.LogInformation($"取引履歴 計{mtCount}件登録"); progress.Report(99); await db.SaveChangesAsync(); this._logger.LogDebug("SaveChanges"); await tran.CommitAsync(); this._logger.LogDebug("Commit"); this._logger.LogInformation($"{from}-{to}の財務データベース更新正常終了"); progress.Report(100); })); }