Ejemplo n.º 1
0
        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);
            }));
        }