Parcourir la source

优化统计增减量/定时执行方法跨年时间计算异常问题。

Li il y a 2 ans
Parent
commit
d82eba67c9

+ 2 - 1
TEAMModelBI/Controllers/BITest/TestController.cs

@@ -1749,6 +1749,7 @@ namespace TEAMModelBI.Controllers.BITest
         /// 每天执行一次
         /// </summary>
         /// <returns></returns>
+        [HttpPost("set-statszero")]
         public async Task<IActionResult> SetStatsZero() 
         {
             await BIStats.SetStatsZeroPoint(_azureCosmos, _dingDing);
@@ -1764,7 +1765,7 @@ namespace TEAMModelBI.Controllers.BITest
         public async Task<IActionResult> SetStats(JsonElement json)
         {
             var cosmosClient = _azureCosmos.GetCosmosClient();
-            await BIStats.SetTypeAddStats(cosmosClient, _dingDing, "gmjh", "Less", 1, careDate: 1672709351527);
+            await BIStats.SetTypeAddStats(cosmosClient, _dingDing, "hbcn", "Vote", 1, careDate: 1672729701791);
 
             return Ok(new { state = 200 });
         }

+ 389 - 79
TEAMModelOS.SDK/Models/Service/BI/BIStats.cs

@@ -3,8 +3,10 @@ using Azure.Storage.Blobs;
 using DocumentFormat.OpenXml.Math;
 using MathNet.Numerics.LinearAlgebra.Double;
 using Microsoft.Azure.Cosmos.Table;
+using NUnit.Framework.Constraints;
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
 using System.Text;
 using System.Text.Json;
@@ -14,6 +16,7 @@ using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models.Cosmos.BI;
 using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
+using TEAMModelOS.SDK.Models.Cosmos.BI.BITable;
 
 namespace TEAMModelOS.SDK.Models.Service.BI
 {
@@ -72,6 +75,10 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                 {
                     using var fileJson = await JsonDocument.ParseAsync(resStsInfo.ContentStream);
                     statsInfo = fileJson.ToObject<StatsInfo>();
+                    if (string.IsNullOrEmpty(statsInfo.schoolId))
+                    {
+                        statsInfo.schoolId = scId;
+                    }
                 }
                 else
                 {
@@ -82,6 +89,7 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                         statsInfo = fileJson.ToObject<StatsInfo>();
                         statsInfo.id = $"{dateOff.Year}-{scId}";
                         statsInfo.year = dateOff.Year;
+                        statsInfo.schoolId = scId;
                         statsInfo.stuYear = new double[366].ToList();
                         statsInfo.tchYear = new double[366].ToList();
                         statsInfo.lesson.year = new double[366].ToList();
@@ -131,28 +139,62 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                         else
                             statsInfo.lesson.less += count;
 
-                        statsInfo.lesson.lastDay = ((int)statsInfo.lesson.year[lastDay.DayOfYear - 1]);
-                        statsInfo.lesson.day = ((int)statsInfo.lesson.year[dateOff.DayOfYear - 1]);
-
                         var lessList = DenseMatrix.OfColumns(new List<List<double>>() { statsInfo.lesson.year });
-                        statsInfo.lesson.lastWeek = ((int)lessList.SubMatrix(lWeekDayS.DayOfYear - 1, lWeekDayE.DayOfYear - lWeekDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
-                        statsInfo.lesson.week = ((int)lessList.SubMatrix(weekDayS.DayOfYear - 1, (dateOff.DayOfYear - weekDayS.DayOfYear + 1), 0, lessList.ColumnCount).ColumnSums().Sum());
+                        DenseMatrix lastLesson = null;
+                        DenseMatrix lastInter = null;
 
                         StatsInfo lastStats = null;
-                        var resLast = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{lTermDayS.Year}-{scId}", new PartitionKey("Statistics"));
-                        if (resLast.Status == 200)
+                        var resLastStats = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{dateOff.Year - 1}-{scId}", new PartitionKey("Statistics"));
+                        if (resLastStats.Status == 200)
                         {
-                            using var fileJson = await JsonDocument.ParseAsync(resLast.ContentStream);
+                            using var fileJson = await JsonDocument.ParseAsync(resLastStats.ContentStream);
                             lastStats = fileJson.ToObject<StatsInfo>();
+                            lastLesson = DenseMatrix.OfColumns(new List<List<double>>() { lastStats.lesson.year });
+                            lastInter = DenseMatrix.OfColumns(new List<List<double>>() { lastStats.lesson.yearInters });
+                        }
+
+                        int lastDayCnt = 0;
+                        if (lastDay.Year < dateOff.Year)
+                        {
+                            lastDayCnt = ((int)lastStats.lesson.year[lastDay.DayOfYear - 1]);
+                        }
+                        else
+                        {
+                            lastDayCnt = ((int)statsInfo.lesson.year[lastDay.DayOfYear - 1]);
+                        }
+
+                        statsInfo.lesson.lastDay = lastDayCnt;
+                        statsInfo.lesson.day = ((int)statsInfo.lesson.year[dateOff.DayOfYear - 1]);
+
+                        int lastWeek = 0;
+                        if (lWeekDayS.Year != dateOff.Year)
+                        {
+                            if (lastLesson != null)
+                            {
+                                lastWeek += ((int)lastLesson.SubMatrix(lWeekDayS.DayOfYear - 1, lastLesson.RowCount - lWeekDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            }
+                            lastWeek += ((int)lessList.SubMatrix(0, lWeekDayE.DayOfYear, 0, lessList.ColumnCount).ColumnSums().Sum());
                         }
+                        else
+                        {
+                            lastWeek = ((int)lessList.SubMatrix(lWeekDayS.DayOfYear - 1, lWeekDayE.DayOfYear - lWeekDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+                        }
+                        statsInfo.lesson.lastWeek = lastWeek;
+                        statsInfo.lesson.week = ((int)lessList.SubMatrix(weekDayS.DayOfYear - 1, (dateOff.DayOfYear - weekDayS.DayOfYear + 1), 0, lessList.ColumnCount).ColumnSums().Sum());
+
+                        //var resLast = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{lTermDayS.Year}-{scId}", new PartitionKey("Statistics"));
+                        //if (resLast.Status == 200)
+                        //{
+                        //    using var fileJson = await JsonDocument.ParseAsync(resLast.ContentStream);
+                        //    lastStats = fileJson.ToObject<StatsInfo>();
+                        //}
 
                         int lastTerm = 0;
                         if (lTermDayS.Year < dateOff.Year)
                         {
-                            if (lastStats != null)
+                            if (lastLesson != null)
                             {
-                                var actYer = DenseMatrix.OfColumns(new List<List<double>>() { lastStats.lesson.year });
-                                lastTerm += ((int)actYer.SubMatrix(lTermDayS.DayOfYear - 1, lastStats.lesson.year.Count - lTermDayS.DayOfYear + 1, 0, 1).ColumnSums().Sum());
+                                lastTerm += ((int)lastLesson.SubMatrix(lTermDayS.DayOfYear - 1, lastStats.lesson.year.Count - lTermDayS.DayOfYear + 1, 0, 1).ColumnSums().Sum());
                             }
                             lastTerm += ((int)lessList.SubMatrix(0, lTermDayE.DayOfYear, 0, lessList.ColumnCount).ColumnSums().Sum());
                         }
@@ -166,32 +208,82 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                         if (termDayE.Year > dateOff.Year)
                         {
                             if (lastStats != null)
+                            {
                                 term = ((int)lessList.SubMatrix(termDayS.DayOfYear - 1, (statsInfo.lesson.year.Count - termDayS.DayOfYear + 1), 0, lessList.ColumnCount).ColumnSums().Sum());
+                            }
                         }
                         else
                         {
-                            term = ((int)lessList.SubMatrix(termDayS.DayOfYear - 1, termDayE.DayOfYear - termDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            if (termDayS.Year <  dateOff.Year) 
+                            {
+                                if (lastLesson != null)
+                                {
+                                    term += ((int)lastLesson.SubMatrix(termDayS.DayOfYear - 1, lastStats.lesson.year.Count - termDayS.DayOfYear + 1, 0, 1).ColumnSums().Sum());
+                                }
+                                term += ((int)lessList.SubMatrix(0, termDayE.DayOfYear, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            }
+                            else
+                            {
+                                term = ((int)lessList.SubMatrix(termDayS.DayOfYear - 1, termDayE.DayOfYear - termDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            }
                         }
                         statsInfo.lesson.term = term;
 
-                        statsInfo.lesson.lastMonth = ((int)lessList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, lessList.ColumnCount).ColumnSums().Sum());
-                        statsInfo.lesson.month += ((int)lessList.SubMatrix(monthDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, lessList.ColumnCount).ColumnSums().Sum());
+                        int lastMonth = 0;
+                        if (lMonthS.Year < dateOff.Year)
+                        {
+                            if (lastLesson != null)
+                            {
+                                lastMonth = ((int)lastLesson.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, lastLesson.ColumnCount).ColumnSums().Sum());
+                            }
+                        }
+                        else
+                        {
+                            lastMonth = ((int)lessList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, lessList.ColumnCount).ColumnSums().Sum());
+                        }
+
+                        statsInfo.lesson.lastMonth = lastMonth;
+                        statsInfo.lesson.month = ((int)lessList.SubMatrix(monthDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, lessList.ColumnCount).ColumnSums().Sum());
 
                         //课例互动
                         statsInfo.lesson.yearInters[dateOff.DayOfYear - 1] += interaction;
                         statsInfo.lesson.allInter += interaction;
-                        statsInfo.lesson.lastDayInter = ((int)statsInfo.lesson.yearInters[lastDay.DayOfYear - 1]);
+                        int lastDayInter = 0;
+                        if (lastDay.Year < dateOff.Year)
+                        {
+                            lastDayInter = ((int)lastStats.lesson.yearInters[lastDay.DayOfYear - 1]);
+                        }
+                        else
+                        {
+                            lastDayInter = ((int)statsInfo.lesson.yearInters[lastDay.DayOfYear - 1]);
+                        }
+
+                        statsInfo.lesson.lastDayInter = lastDayInter;
                         statsInfo.lesson.dayInter = ((int)statsInfo.lesson.yearInters[dateOff.DayOfYear - 1]);
 
                         var interList = DenseMatrix.OfColumns(new List<List<double>>() { statsInfo.lesson.yearInters });
-                        statsInfo.lesson.lastMonthInter = ((int)interList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, interList.ColumnCount).ColumnSums().Sum());
-                        statsInfo.lesson.monthInter += ((int)interList.SubMatrix(monthDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, interList.ColumnCount).ColumnSums().Sum());
+                        int lastMonthInter = 0;
+                        if (lMonthS.Year < dateOff.Year)
+                        {
+                            if (lastInter != null)
+                            {
+                                lastMonthInter = ((int)lastInter.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, lastInter.ColumnCount).ColumnSums().Sum());
+                            }
+                        }
+                        else
+                        {
+                            lastMonthInter = ((int)interList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, interList.ColumnCount).ColumnSums().Sum());
+                        }
+                        statsInfo.lesson.lastMonthInter = lastMonthInter;
+                        statsInfo.lesson.monthInter = ((int)interList.SubMatrix(monthDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, interList.ColumnCount).ColumnSums().Sum());
 
                         int lastTermI = 0;
                         if (lastStats != null)
                         {
-                            var actYer = DenseMatrix.OfColumns(new List<List<double>>() { lastStats.lesson.year });
-                            lastTermI += ((int)actYer.SubMatrix(0, lastStats.lesson.year.Count, 0, actYer.ColumnCount).ColumnSums().Sum());
+                            if (lastInter != null)
+                            {
+                                lastTermI = ((int)lastInter.SubMatrix(0, lastStats.lesson.year.Count, 0, lastInter.ColumnCount).ColumnSums().Sum());
+                            }
                         }
                         statsInfo.lesson.lastYearInter = lastTermI;
 
@@ -231,26 +323,55 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                         {
                             statsInfo.activity.year[dateOff.DayOfYear - 1] += count;
                             DenseMatrix matris = DenseMatrix.OfColumns(new List<List<double>>() { statsInfo.activity.year });
-                            statsInfo.activity.lastDay = ((int)statsInfo.activity.year[lastDay.DayOfYear - 1]);
-                            statsInfo.activity.dayCnt = ((int)statsInfo.activity.year[dateOff.DayOfYear - 1]);
-                            statsInfo.activity.lastWeek = ((int)matris.SubMatrix(lWeekDayS.DayOfYear - 1, lWeekDayE.DayOfYear - lWeekDayS.DayOfYear + 1, 0, matris.ColumnCount).ColumnSums().Sum());
-                            statsInfo.activity.week = ((int)matris.SubMatrix(weekDayS.DayOfYear - 1, dateOff.DayOfYear - weekDayS.DayOfYear + 1, 0, matris.ColumnCount).ColumnSums().Sum());
-
+                            DenseMatrix lastAct = null;
                             StatsInfo lastStats = null;
-                            var resLast = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{lTermDayS.Year}-{scId}", new PartitionKey("Statistics"));
-                            if (resLast.Status == 200)
+                            var resLastStats = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{dateOff.Year - 1}-{scId}", new PartitionKey("Statistics"));
+                            if (resLastStats.Status == 200)
                             {
-                                using var fileJson = await JsonDocument.ParseAsync(resLast.ContentStream);
+                                using var fileJson = await JsonDocument.ParseAsync(resLastStats.ContentStream);
                                 lastStats = fileJson.ToObject<StatsInfo>();
+                                lastAct  = DenseMatrix.OfColumns(new List<List<double>>() { lastStats.activity.year });
+                            }
+
+                            int lastDayCnt = 0;
+                            if (lastDay.Year < dateOff.Year)
+                            {
+                                if (lastStats != null)
+                                {
+                                    lastDayCnt = ((int)lastStats.activity.year[lastDay.DayOfYear - 1]);
+                                }
+                            }
+                            else
+                            {
+                                lastDayCnt = ((int)statsInfo.activity.year[lastDay.DayOfYear - 1]);
                             }
 
+                            statsInfo.activity.lastDay = lastDayCnt;
+                            statsInfo.activity.dayCnt = ((int)statsInfo.activity.year[dateOff.DayOfYear - 1]);
+
+                            int lastWeek = 0;
+                            if (lWeekDayS.Year < dateOff.Year)
+                            {
+                                if (lastAct != null)
+                                {
+                                    lastWeek += ((int)lastAct.SubMatrix(lWeekDayS.DayOfYear - 1, lastAct.RowCount - lWeekDayS.DayOfYear + 1, 0, lastAct.ColumnCount).ColumnSums().Sum());
+                                }
+                                lastWeek += ((int)matris.SubMatrix(0, lWeekDayE.DayOfYear, 0, matris.ColumnCount).ColumnSums().Sum());
+                            }
+                            else
+                            {
+                                lastWeek = ((int)matris.SubMatrix(lWeekDayS.DayOfYear - 1, lWeekDayE.DayOfYear - lWeekDayS.DayOfYear + 1, 0, matris.ColumnCount).ColumnSums().Sum());
+                            }
+
+                            statsInfo.activity.lastWeek = lastWeek;
+                            statsInfo.activity.week = ((int)matris.SubMatrix(weekDayS.DayOfYear - 1, dateOff.DayOfYear - weekDayS.DayOfYear + 1, 0, matris.ColumnCount).ColumnSums().Sum());
+
                             int lastTerm = 0;
                             if (lTermDayS.Year < dateOff.Year)
                             {
                                 if (lastStats != null)
                                 {
-                                    var actYer = DenseMatrix.OfColumns(new List<List<double>>() { lastStats.lesson.year });
-                                    lastTerm += ((int)actYer.SubMatrix(lTermDayS.DayOfYear - 1, lastStats.lesson.year.Count - lTermDayS.DayOfYear + 1, 0, 1).ColumnSums().Sum());
+                                    lastTerm += ((int)lastAct.SubMatrix(lTermDayS.DayOfYear - 1, lastStats.activity.year.Count - lTermDayS.DayOfYear + 1, 0, lastAct.ColumnCount).ColumnSums().Sum());
                                 }
                                 lastTerm += ((int)matris.SubMatrix(0, lTermDayE.DayOfYear, 0, matris.ColumnCount).ColumnSums().Sum());
                             }
@@ -260,30 +381,49 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                             }
                             statsInfo.activity.lastTerm = lastTerm;
 
-
                             int term = 0;
                             if (termDayS.Year > dateOff.Year)
                             {
-                                if (lastStats != null)
+                                if (lastAct != null)
                                 {
-                                    var actYer = DenseMatrix.OfColumns(new List<List<double>>() { lastStats.lesson.year });
-                                    term += ((int)actYer.SubMatrix(termDayS.DayOfYear - 1, lastStats.lesson.year.Count - termDayS.DayOfYear + 1, 0, 1).ColumnSums().Sum());
+                                    term += ((int)lastAct.SubMatrix(termDayS.DayOfYear - 1, lastStats.activity.year.Count - termDayS.DayOfYear + 1, 0, lastAct.ColumnCount).ColumnSums().Sum());
                                 }
                                 term += ((int)matris.SubMatrix(0, termDayE.DayOfYear + 1, 0, matris.ColumnCount).ColumnSums().Sum());
                             }
                             else
                             {
-                                term += ((int)matris.SubMatrix(termDayS.DayOfYear - 1, termDayE.DayOfYear - termDayS.DayOfYear + 1, 0, matris.ColumnCount).ColumnSums().Sum());
+                                if (lTermDayS.Year < dateOff.Year)
+                                {
+                                    if (lastAct != null)
+                                    {
+                                        term += ((int)lastAct.SubMatrix(termDayS.DayOfYear - 1, lastStats.activity.year.Count - termDayS.DayOfYear + 1, 0, 1).ColumnSums().Sum());
+                                    }
+                                    term += ((int)matris.SubMatrix(0, termDayE.DayOfYear, 0, lastAct.ColumnCount).ColumnSums().Sum());
+                                }
+                                else
+                                {
+                                    term += ((int)matris.SubMatrix(termDayS.DayOfYear - 1, termDayE.DayOfYear - termDayS.DayOfYear + 1, 0, matris.ColumnCount).ColumnSums().Sum());
+                                }
                             }
                             statsInfo.activity.term = term;
-
-                            statsInfo.activity.lastMonth = ((int)matris.SubMatrix(lMonthS.DayOfYear, lmthDay, 0, matris.ColumnCount).ColumnSums().Sum());
+                            int lastMonth = 0;
+                            if (lMonthS.Year < dateOff.Year) 
+                            {
+                                if (lastAct != null) 
+                                {
+                                    lastMonth = ((int)lastAct.SubMatrix(lMonthS.DayOfYear-1, lmthDay, 0, matris.ColumnCount).ColumnSums().Sum());
+                                }
+                            }
+                            else
+                            {
+                                lastMonth = ((int)matris.SubMatrix(lMonthS.DayOfYear-1, lmthDay, 0, matris.ColumnCount).ColumnSums().Sum());
+                            }
+                            statsInfo.activity.lastMonth = lastMonth;
                             statsInfo.activity.month += ((int)matris.SubMatrix(monthDayS.DayOfYear, (dateOff.DayOfYear - monthDayS.DayOfYear), 0, matris.ColumnCount).ColumnSums().Sum());
                             statsInfo.activity.upTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                         }
                     }
                 }
-
                 if (resStsInfo.Status == 200)
                 {
                     statsInfo = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<StatsInfo>(statsInfo, statsInfo.id, new PartitionKey("Statistics"));
@@ -437,11 +577,22 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                 var lastDay = dateOff.AddDays(-1);
                 int lmthDay = TimeHelper.GetDateDay(lMonthE);
 
-                int termDay = 0;
-
                 List<Task<ItemResponse<StatsInfo>>> statsInfos = new();
                 List<StatsInfo> tempStatsInfos = new();
-                await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<StatsInfo>(queryText: "select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
+                StringBuilder statsSql = new($"select value(c) from c where c.year={dateOff.Year}");
+                List<string> scIds = new();
+
+                await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<string>(queryText: $"select value(c.id)  from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("BIRel") }))
+                {
+                    scIds.Add(item);
+                }
+
+                if (scIds.Count > 0)
+                {
+                    statsSql.Append($" and {BICommonWay.ManyScSql("c.id", scIds, $"{dateOff.Year}-")}");
+                }
+
+                await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<StatsInfo>(queryText: statsSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
                 {
                     tempStatsInfos.Add(item);
                 }
@@ -450,94 +601,253 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                 {
                     foreach (var item in tempStatsInfos)
                     {
-                        if (termDayE.Year == dateOff.Year)
-                            termDay = dateOff.DayOfYear;
-                        else
-                            termDay = item.activity.year.Count;
-                        StatsInfo lastStatsInfo = null;
-
+                        StatsInfo lastStatsInfo = null; 
+                        DenseMatrix lastTch = null;
+                        DenseMatrix lastStu = null;
+                        DenseMatrix lastLesson = null;
+                        DenseMatrix lastInter = null;
+                        DenseMatrix lastAct = null;
                         var lastSts = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{dateOff.Year - 1}-{item.schoolId}", new PartitionKey("Statistics"));
                         if (lastSts.Status == 200)
                         {
                             using var fileJson = await JsonDocument.ParseAsync(lastSts.ContentStream);
                             lastStatsInfo = fileJson.ToObject<StatsInfo>();
+                            lastTch = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.tchYear });
+                            lastStu = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.stuYear});
+                            lastLesson = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.lesson.year });
+                            lastInter = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.lesson.yearInters });
+                            lastAct = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.activity.year });
                         }
 
                         var tchList = DenseMatrix.OfColumns(new List<List<double>>() { item.tchYear });
-                        item.dayTch = ((int)item.tchYear[lastDay.DayOfYear - 1]);
-                        item.weekTch = ((int)tchList.SubMatrix(weekDayS.DayOfYear - 1, 7, 0, tchList.ColumnCount).ColumnSums().Sum());
+                        var stuList = DenseMatrix.OfColumns(new List<List<double>>() { item.stuYear });
+                        int dayTch = 0;
+                        int dayStu = 0;
+                        int lastDayLesson = 0;
+                        int lastDayAct = 0;
+                        if (lastDay.Year < dateOff.Year) 
+                        {
+                            if (lastStatsInfo != null) 
+                            {
+                                dayTch =((int)lastStatsInfo.tchYear[lastDay.DayOfYear - 1]);
+                                dayStu = ((int)lastStatsInfo.stuYear[lastDay.DayOfYear - 1]);
+                                lastDayLesson = ((int)lastStatsInfo.lesson.year[lastDay.DayOfYear - 1]);
+                                lastDayAct = ((int)lastStatsInfo.activity.year[lastDay.DayOfYear - 1]);
+                            }
+                        }
+                        else
+                        {
+                            dayTch = ((int)item.tchYear[lastDay.DayOfYear - 1]);
+                            dayStu = ((int)item.stuYear[lastDay.DayOfYear - 1]);
+                            lastDayLesson = ((int)item.lesson.year[lastDay.DayOfYear - 1]);
+                            lastDayAct =((int)item.activity.year[lastDay.DayOfYear - 1]);
+                        }
+                        item.dayTch = dayTch;
+                        int weekTch = 0;
+                        int weekStu = 0;
+                        if (weekDayS.Year < dateOff.Year) 
+                        {
+                            if (lastTch != null)
+                            {
+                                weekTch += ((int)lastTch.SubMatrix(weekDayS.DayOfYear - 1, lastTch.RowCount - weekDayS.DayOfYear + 1, 0, lastTch.ColumnCount).ColumnSums().Sum());
+                            }
+                            weekTch += ((int)tchList.SubMatrix(0, weekDayE.DayOfYear + 1, 0, tchList.ColumnCount).ColumnSums().Sum());
+
+                            if (lastStu != null)
+                            {
+                                weekStu += ((int)lastStu.SubMatrix(weekDayS.DayOfYear - 1, lastStu.RowCount - weekDayS.DayOfYear + 1, 0, lastStu.ColumnCount).ColumnSums().Sum());
+                            }
+                            weekStu += ((int)lastStu.SubMatrix(0, weekDayE.DayOfYear + 1, 0, lastStu.ColumnCount).ColumnSums().Sum());
+                        }
+                        else
+                        {
+                            weekTch = ((int)tchList.SubMatrix(weekDayS.DayOfYear - 1, 7, 0, tchList.ColumnCount).ColumnSums().Sum());
+                            weekStu = ((int)stuList.SubMatrix(weekDayS.DayOfYear - 1, 7, 0, stuList.ColumnCount).ColumnSums().Sum());
+                        }
+                        item.weekTch = weekTch;
                         item.monthTch = ((int)tchList.SubMatrix(monthDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, tchList.ColumnCount).ColumnSums().Sum());
                         item.tchUpTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
 
-                        var stuList = DenseMatrix.OfColumns(new List<List<double>>() { item.stuYear });
-                        item.dayStu = ((int)item.stuYear[lastDay.DayOfYear - 1]);
-                        item.weekStu = ((int)stuList.SubMatrix(weekDayS.DayOfYear - 1, 7, 0, stuList.ColumnCount).ColumnSums().Sum());
+                        item.dayStu = dayStu;
+                        item.weekStu = weekStu;
                         item.monthStu = ((int)stuList.SubMatrix(monthDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, stuList.ColumnCount).ColumnSums().Sum());
                         item.stuUpTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
 
                         var lessList = DenseMatrix.OfColumns(new List<List<double>>() { item.lesson.year });
-                        item.lesson.lastDay = item.lesson.day;
-                        item.lesson.lastWeek = ((int)lessList.SubMatrix(lWeekDayS.DayOfYear - 1, 7, 0, lessList.ColumnCount).ColumnSums().Sum());
+                        var interList = DenseMatrix.OfColumns(new List<List<double>>() { item.lesson.yearInters });
+                        var actList = DenseMatrix.OfColumns(new List<List<double>>() { item.activity.year });
+                        item.lesson.lastDay = lastDayLesson;
+
+                        int lastWeekLesson = 0;
+                        int lastWeekAct = 0;
+                        if (lWeekDayS.Year != dateOff.Year)
+                        {
+                            if (lastLesson != null)
+                            {
+                                lastWeekLesson += ((int)lastLesson.SubMatrix(lWeekDayS.DayOfYear - 1, lastLesson.RowCount - lWeekDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            }
+                            lastWeekLesson += ((int)lessList.SubMatrix(0, lWeekDayE.DayOfYear, 0, lessList.ColumnCount).ColumnSums().Sum());
+
+                            if (lastAct !=null)
+                            {
+                                lastWeekAct += ((int)lastAct.SubMatrix(lWeekDayS.DayOfYear - 1, lastAct.RowCount - lWeekDayS.DayOfYear + 1, 0, lastAct.ColumnCount).ColumnSums().Sum());
+                            }
+                            lastWeekAct += ((int)lastAct.SubMatrix(0, lWeekDayE.DayOfYear, 0, lastAct.ColumnCount).ColumnSums().Sum());
+                        }
+                        else
+                        {
+                            lastWeekLesson = ((int)lessList.SubMatrix(lWeekDayS.DayOfYear - 1, lWeekDayE.DayOfYear - lWeekDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            lastWeekAct = ((int)actList.SubMatrix(lWeekDayS.DayOfYear - 1, 7, 0, actList.ColumnCount).ColumnSums().Sum());
+                        }
+                        item.lesson.lastWeek = lastWeekLesson;
                         item.lesson.week = ((int)lessList.SubMatrix(weekDayS.DayOfYear - 1, (dateOff.DayOfYear - weekDayS.DayOfYear + 1), 0, lessList.ColumnCount).ColumnSums().Sum());
 
+                        int lastTerm = 0;
                         if (lTermDayS.Year < dateOff.Year)
                         {
-                            if (lastStatsInfo != null)
+                            if (lastLesson != null)
                             {
-                                var lessYer = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.lesson.year, item.lesson.year });
-                                item.lesson.lastTerm = ((int)lessYer.SubMatrix(lTermDayS.DayOfYear - 1, lTermDayE.DayOfYear + 1, 0, 1).ColumnSums().Sum());
+                                lastTerm += ((int)lastLesson.SubMatrix(lTermDayS.DayOfYear - 1, lastStatsInfo.lesson.year.Count - lTermDayS.DayOfYear + 1, 0, 1).ColumnSums().Sum());
                             }
+                            lastTerm += ((int)lessList.SubMatrix(0, lTermDayE.DayOfYear, 0, lessList.ColumnCount).ColumnSums().Sum());
                         }
-                        item.lesson.term = ((int)lessList.SubMatrix(termDayS.DayOfYear - 1, termDay + 1, 0, 1).ColumnSums().Sum());
+                        else
+                        {
+                            lastTerm += ((int)lessList.SubMatrix(lTermDayS.DayOfYear - 1, lTermDayE.DayOfYear - lTermDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+                        }
+                        item.lesson.lastTerm = lastTerm;
 
+                        int term = 0;
+                        if (termDayE.Year > dateOff.Year)
+                        {
+                            if (lessList != null)
+                            {
+                                term = ((int)lessList.SubMatrix(termDayS.DayOfYear - 1, (lessList.RowCount - termDayS.DayOfYear + 1), 0, lessList.ColumnCount).ColumnSums().Sum());
+                            }
+                        }
+                        else
+                        {
+                            if (termDayS.Year < dateOff.Year)
+                            {
+                                if (lastLesson != null)
+                                {
+                                    term += ((int)lastLesson.SubMatrix(termDayS.DayOfYear - 1, lastLesson.RowCount - termDayS.DayOfYear + 1, 0, lastLesson.ColumnCount).ColumnSums().Sum());
+                                }
+                                term += ((int)lessList.SubMatrix(0, termDayE.DayOfYear, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            }
+                            else
+                            {
+                                term = ((int)lessList.SubMatrix(termDayS.DayOfYear - 1, termDayE.DayOfYear - termDayS.DayOfYear + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            }
+                        }
+                        item.lesson.term = term;
                         item.lesson.day = 0;
-                        item.lesson.lastMonth = ((int)lessList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay + 1, 0, lessList.ColumnCount).ColumnSums().Sum());
+
+                        int lastMonth = 0;
+                        int lastMonthInter = 0;
+                        int lastMonthAct = 0;
+                        if (lMonthS.Year < dateOff.Year)
+                        {
+                            if (lastLesson != null)
+                            {
+                                lastMonth = ((int)lastLesson.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, lastLesson.ColumnCount).ColumnSums().Sum());
+                            }
+
+                            if (lastInter != null)
+                            {
+                                lastMonthInter = ((int)lastInter.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, lastInter.ColumnCount).ColumnSums().Sum());
+                            }
+
+                            if (lastAct != null)
+                            {
+                                lastMonthAct = ((int)lastAct.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, lastAct.ColumnCount).ColumnSums().Sum());
+                            }
+                        }
+                        else
+                        {
+                            lastMonth = ((int)lessList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, lessList.ColumnCount).ColumnSums().Sum());
+                            lastMonthInter = ((int)interList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, interList.ColumnCount).ColumnSums().Sum());
+                            lastMonthAct = ((int)actList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay, 0, actList.ColumnCount).ColumnSums().Sum());
+                        }
+                        item.lesson.lastMonth = lastMonth;
                         item.lesson.month += ((int)lessList.SubMatrix(monthDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, lessList.ColumnCount).ColumnSums().Sum());
                         item.lesson.upTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
 
-                        var interList = DenseMatrix.OfColumns(new List<List<double>>() { item.lesson.yearInters });
-                        item.lesson.lastDayInter = ((int)item.lesson.yearInters[lastDay.DayOfYear - 1]);
+                        int lastDayInter = 0;
+                        if (lastDay.Year < dateOff.Year) 
+                        {
+                            if (lastStatsInfo.lesson.yearInters.Count > 0) 
+                            {
+                                lastDayInter = ((int)lastStatsInfo.lesson.yearInters[lastDay.DayOfYear - 1]);
+                            }
+                        }
+                        else
+                        {
+                            lastDayInter = ((int)item.lesson.yearInters[lastDay.DayOfYear - 1]);
+                        }
+                        item.lesson.lastDayInter = lastDayInter;
                         item.lesson.dayInter = 0;
-                        item.lesson.lastMonthInter = ((int)interList.SubMatrix(lMonthS.DayOfYear - 1, lmthDay + 1, 0, interList.ColumnCount).ColumnSums().Sum());
+                        
+                        item.lesson.lastMonthInter = lastMonthInter;
                         item.lesson.monthInter = ((int)interList.SubMatrix(monthDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, interList.ColumnCount).ColumnSums().Sum());
 
                         if (lastStatsInfo != null)
                         {
-                            var actYer = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.lesson.yearInters });
-                            item.lesson.lastYearInter = ((int)actYer.SubMatrix(lTermDayS.DayOfYear - 1, actYer.RowCount, 0, actYer.ColumnCount).ColumnSums().Sum());
+                            if (lastInter != null)
+                            {
+                                item.lesson.lastYearInter = ((int)lastInter.SubMatrix(0, lastInter.RowCount, 0, lastInter.ColumnCount).ColumnSums().Sum());
+                            }
                         }
 
                         item.lesson.yearInter = ((int)item.lesson.yearInters.Sum());
 
                         item.activity.dayCnt = ((int)item.activity.year[dateOff.DayOfYear - 1]);
-                        item.activity.lastDay = ((int)item.activity.year[lastDay.DayOfYear - 1]);
-                        var actList = DenseMatrix.OfColumns(new List<List<double>>() { item.activity.year });
-                        item.activity.lastWeek = ((int)actList.SubMatrix(lWeekDayS.DayOfYear - 1, 7, 0, actList.ColumnCount).ColumnSums().Sum());
+                        item.activity.lastDay = lastDayAct;
+                        item.activity.lastWeek = lastWeekAct;
                         item.activity.week = ((int)actList.SubMatrix(weekDayS.DayOfYear - 1, (dateOff.DayOfYear - monthDayS.DayOfYear + 1), 0, actList.ColumnCount).ColumnSums().Sum());
 
-                        if (lMonthS.Year == dateOff.Year)
+                        item.activity.lastMonth = lastMonthAct;
+
+                        int lastTermAct = 0;
+                        if (lTermDayS.Year < dateOff.Year)
                         {
-                            item.activity.lastMonth = ((int)actList.SubMatrix(lMonthS.DayOfYear - 1, lMonthE.DayOfYear + 1, 0, actList.ColumnCount).ColumnSums().Sum());
+                            if (lastAct != null)
+                            {
+                                lastTermAct += ((int)lastAct.SubMatrix(lTermDayS.DayOfYear - 1, lastStatsInfo.activity.year.Count - lTermDayS.DayOfYear + 1, 0, lastAct.ColumnCount).ColumnSums().Sum());
+                            }
+                            lastTermAct += ((int)actList.SubMatrix(0, lTermDayE.DayOfYear, 0, actList.ColumnCount).ColumnSums().Sum());
                         }
                         else
                         {
-                            var lastMthYer = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.activity.year });
-                            item.activity.lastMonth = ((int)lastMthYer.SubMatrix(lMonthS.DayOfYear - 1, lMonthE.DayOfYear + 1, 0, actList.ColumnCount).ColumnSums().Sum());
+                            lastTermAct += ((int)actList.SubMatrix(lTermDayS.DayOfYear - 1, lTermDayE.DayOfYear - lTermDayS.DayOfYear + 1, 0, actList.ColumnCount).ColumnSums().Sum());
                         }
-                        if (monthDayE.Year > dateOff.Year)
+                        item.activity.lastTerm = lastTerm;
+
+                        int termAct = 0;
+                        if (termDayS.Year > dateOff.Year)
                         {
-                            item.activity.month = ((int)actList.SubMatrix(monthDayS.DayOfYear - 1, actList.RowCount, 0, actList.ColumnCount).ColumnSums().Sum());
+                            if (lastAct != null)
+                            {
+                                termAct += ((int)lastAct.SubMatrix(termDayS.DayOfYear - 1, lastStatsInfo.activity.year.Count - termDayS.DayOfYear + 1, 0, lastAct.ColumnCount).ColumnSums().Sum());
+                            }
+                            termAct += ((int)actList.SubMatrix(0, termDayE.DayOfYear + 1, 0, actList.ColumnCount).ColumnSums().Sum());
                         }
                         else
                         {
-                            item.activity.month = ((int)actList.SubMatrix(monthDayS.DayOfYear - 1, monthDayE.DayOfYear + 1, 0, actList.ColumnCount).ColumnSums().Sum());
-                        }
-
-                        if (lastStatsInfo != null)
-                        {
-                            var actYer = DenseMatrix.OfColumns(new List<List<double>>() { lastStatsInfo.activity.year });
-                            item.activity.lastTerm = ((int)actYer.SubMatrix(lTermDayS.DayOfYear - 1, lTermDayE.DayOfYear + 1, 0, 1).ColumnSums().Sum());
+                            if (lTermDayS.Year < dateOff.Year)
+                            {
+                                if (lastAct != null)
+                                {
+                                    termAct += ((int)lastAct.SubMatrix(termDayS.DayOfYear - 1, lastStatsInfo.lesson.year.Count - termDayS.DayOfYear + 1, 0, 1).ColumnSums().Sum());
+                                }
+                                termAct += ((int)actList.SubMatrix(0, termDayE.DayOfYear, 0, lastAct.ColumnCount).ColumnSums().Sum());
+                            }
+                            else
+                            {
+                                termAct += ((int)actList.SubMatrix(termDayS.DayOfYear - 1, termDayE.DayOfYear - termDayS.DayOfYear + 1, 0, actList.ColumnCount).ColumnSums().Sum());
+                            }
                         }
+                        item.activity.term = term;
 
                         item.activity.upTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();