Merge branch 'dev' into feature/email_notifications

This commit is contained in:
on.nemtina 2023-07-28 11:42:50 +05:00
commit cbca56ca28
15 changed files with 8540 additions and 66 deletions

View File

@ -1,3 +1,6 @@
using System.Collections;
using System.Collections.Generic;
namespace AsbCloudApp.Data.AutogeneratedDailyReport; namespace AsbCloudApp.Data.AutogeneratedDailyReport;
/// <summary> /// <summary>
@ -14,15 +17,15 @@ public class AutoGeneratedDailyReportDto : AutoGeneratedDailyReportInfoDto
/// <summary> /// <summary>
/// Блок подсистем /// Блок подсистем
/// </summary> /// </summary>
public SubsystemRecordDto[] Subsystems { get; set; } = null!; public IEnumerable<SubsystemRecordDto> Subsystems { get; set; } = null!;
/// <summary> /// <summary>
/// Блок ограничивающих параметров /// Блок ограничивающих параметров
/// </summary> /// </summary>
public LimitingParameterRecordDto[] LimitingParameters { get; set; } = null!; public IEnumerable<LimitingParameterRecordDto> LimitingParameters { get; set; } = null!;
/// <summary> /// <summary>
/// Баланс времени /// Баланс времени
/// </summary> /// </summary>
public TimeBalanceRecordDto[] TimeBalance { get; set; } = null!; public IEnumerable<TimeBalanceRecordDto> TimeBalance { get; set; } = null!;
} }

View File

@ -45,5 +45,13 @@ namespace AsbCloudApp.Services
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> DeleteAsync(int userId, string key, CancellationToken token); Task<int> DeleteAsync(int userId, string key, CancellationToken token);
/// <summary>
/// Удалить ВСЕ настройки пользователя
/// </summary>
/// <param name="userId"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> DeleteAsync(int userId, CancellationToken token);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
public partial class Add_Permission_UserSettings_delete : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.InsertData(
table: "t_permission",
columns: new[] { "id", "description", "name" },
values: new object[] { 522, "Разрешить удаление всех настроек пользователя", "UserSettings.delete" });
migrationBuilder.InsertData(
table: "t_relation_user_role_permission",
columns: new[] { "id_permission", "id_user_role" },
values: new object[] { 522, 1 });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "t_relation_user_role_permission",
keyColumns: new[] { "id_permission", "id_user_role" },
keyValues: new object[] { 522, 1 });
migrationBuilder.DeleteData(
table: "t_permission",
keyColumn: "id",
keyValue: 522);
}
}
}

View File

@ -19,7 +19,7 @@ namespace AsbCloudDb.Migrations
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.UseCollation("Russian_Russia.1251") .UseCollation("Russian_Russia.1251")
.HasAnnotation("ProductVersion", "6.0.19") .HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack"); NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
@ -2162,6 +2162,12 @@ namespace AsbCloudDb.Migrations
Id = 521, Id = 521,
Description = "Разрешить создание справок по страницам", Description = "Разрешить создание справок по страницам",
Name = "HelpPage.edit" Name = "HelpPage.edit"
},
new
{
Id = 522,
Description = "Разрешить удаление всех настроек пользователя",
Name = "UserSettings.delete"
}); });
}); });
@ -3744,6 +3750,11 @@ namespace AsbCloudDb.Migrations
{ {
IdUserRole = 1, IdUserRole = 1,
IdPermission = 521 IdPermission = 521
},
new
{
IdUserRole = 1,
IdPermission = 522
}); });
}); });

View File

@ -153,7 +153,9 @@
new (){ Id = 519, Name="WellContact.get", Description="Разрешение просматривать список контактов"}, new (){ Id = 519, Name="WellContact.get", Description="Разрешение просматривать список контактов"},
new (){ Id = 520, Name="WellContact.edit", Description="Разрешение редактировать список контактов"}, new (){ Id = 520, Name="WellContact.edit", Description="Разрешение редактировать список контактов"},
new() { Id = 521, Name = "HelpPage.edit", Description = "Разрешить создание справок по страницам" } new() { Id = 521, Name = "HelpPage.edit", Description = "Разрешить создание справок по страницам"},
new() { Id = 522, Name = "UserSettings.delete", Description = "Разрешить удаление всех настроек пользователя"},
}; };
} }
} }

View File

@ -46,6 +46,7 @@ namespace AsbCloudInfrastructure.Repository
return await context.SaveChangesAsync(token); return await context.SaveChangesAsync(token);
} }
public async Task<int> DeleteAsync(int userId, string key, CancellationToken token) public async Task<int> DeleteAsync(int userId, string key, CancellationToken token)
{ {
var set = context.Set<UserSetting>(); var set = context.Set<UserSetting>();
@ -58,5 +59,15 @@ namespace AsbCloudInfrastructure.Repository
set.Remove(removingItem); set.Remove(removingItem);
return await context.SaveChangesAsync(token); return await context.SaveChangesAsync(token);
} }
public async Task<int> DeleteAsync(int userId, CancellationToken token)
{
var set = context.Set<UserSetting>();
var removingItems = set
.Where(s => s.IdUser == userId);
set.RemoveRange(removingItems);
return await context.SaveChangesAsync(token);
}
} }
} }

View File

@ -94,13 +94,13 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
for (int day = result.Skip; (day - result.Skip) < result.Take && (datesRange.From.AddDays(day)) <= datesRange.To; day++) for (int day = result.Skip; (day - result.Skip) < result.Take && (datesRange.From.AddDays(day)) <= datesRange.To; day++)
{ {
var dateFrom = datesRange.From.AddDays(day); var reportDate = DateOnly.FromDateTime(datesRange.From.AddDays(day));
reports.Add(new AutoGeneratedDailyReportDto reports.Add(new AutoGeneratedDailyReportInfoDto
{ {
FileName = string.Format(fileNameTemplate, well.Caption, well.Cluster, DateOnly.FromDateTime(dateFrom)), FileName = string.Format(fileNameTemplate, well.Caption, well.Cluster, reportDate),
ReportDate = DateOnly.FromDateTime(dateFrom), ReportDate = reportDate,
FileSize = GetFileSize() / 1024, FileSize = GetFileSize(reportDate, idWell),
}); });
} }
@ -121,15 +121,15 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
if (!well.IdTelemetry.HasValue) if (!well.IdTelemetry.HasValue)
throw new ArgumentInvalidException("Телеметрия для скважины отсутствует", nameof(idWell)); throw new ArgumentInvalidException("Телеметрия для скважины отсутствует", nameof(idWell));
var factOperations = (await GetFactOperationsAsync(well.Id, startDate, finishDate, var factOperations = await GetFactOperationsAsync(well.Id, startDate, finishDate,
cancellationToken)).ToArray(); cancellationToken);
var report = new AutoGeneratedDailyReportDto var report = new AutoGeneratedDailyReportDto
{ {
FileName = string.Format(fileNameTemplate, well.Caption, well.Cluster, reportDate), FileName = string.Format(fileNameTemplate, well.Caption, well.Cluster, reportDate),
FileSize = GetFileSize() / 1024, FileSize = GetFileSize(reportDate, idWell),
ReportDate = reportDate, ReportDate = reportDate,
Head = CreateHeadBlock(well, reportDate, factOperations), Head = CreateHeadBlock(well, factOperations),
Subsystems = (await CreateSubsystemBlockAsync(idWell, startDate, finishDate, cancellationToken)).ToArray(), Subsystems = (await CreateSubsystemBlockAsync(idWell, startDate, finishDate, cancellationToken)).ToArray(),
LimitingParameters = (await CreateLimitingParameterBlockAsync(idWell, startDate, finishDate, cancellationToken)).ToArray(), LimitingParameters = (await CreateLimitingParameterBlockAsync(idWell, startDate, finishDate, cancellationToken)).ToArray(),
TimeBalance = factOperations.GroupBy(w => w.CategoryName).Select(x => new TimeBalanceRecordDto TimeBalance = factOperations.GroupBy(w => w.CategoryName).Select(x => new TimeBalanceRecordDto
@ -144,18 +144,19 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
return (report.FileName, stream); return (report.FileName, stream);
} }
private HeadBlockDto CreateHeadBlock(WellDto well, DateOnly reportDate, WellOperationDto[] factOperations) private HeadBlockDto CreateHeadBlock(WellDto well, IEnumerable<WellOperationDto> factOperations)
{ {
var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1); var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1);
var sortedFactOperations = factOperations.OrderBy(o => o.DateStart);
return new HeadBlockDto return new HeadBlockDto
{ {
Customer = customer?.Caption ?? string.Empty, Customer = customer?.Caption ?? string.Empty,
Deposit = well.Deposit ?? string.Empty, Deposit = well.Deposit ?? string.Empty,
Cluster = well.Cluster ?? string.Empty, Cluster = well.Cluster ?? string.Empty,
Well = well.Caption, Well = well.Caption,
DepthFrom = factOperations.FirstOrDefault()?.DepthStart ?? 0.00, DepthFrom = sortedFactOperations.FirstOrDefault()?.DepthStart ?? 0.00,
DepthTo = factOperations.LastOrDefault()?.DepthEnd ?? 0.00 DepthTo = sortedFactOperations.LastOrDefault()?.DepthEnd ?? 0.00
}; };
} }
@ -188,12 +189,12 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
startDate, finishDate, cancellationToken)).ToArray(); startDate, finishDate, cancellationToken)).ToArray();
var sumDepths = limitingParameterStats.Sum(x => x.Depth); var sumDepths = limitingParameterStats.Sum(x => x.Depth);
return limitingParameterStats.Select(l => new LimitingParameterRecordDto return limitingParameterStats.Select(l => new LimitingParameterRecordDto
{ {
NameFeedRegulator = l.NameFeedRegulator, NameFeedRegulator = l.NameFeedRegulator,
Hours = l.TotalMinutes, Hours = l.TotalMinutes,
PercentDepth = l.Depth / sumDepths, PercentDepth = sumDepths != 0 ? l.Depth / sumDepths : 0,
Depth = l.Depth, Depth = l.Depth,
}); });
} }
@ -239,10 +240,11 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
return limitingParameterService.GetStatAsync(request, cancellationToken); return limitingParameterService.GetStatAsync(request, cancellationToken);
} }
private int GetFileSize() private int GetFileSize(DateOnly reportDate, int idWell)
{ {
const int fileSizeTemplate = 10240; const int fileSizeTemplate = 10240;
// TODO: Добавку размера сделать более предсказуемой на основе даты рапорта. что то типа `(Date.Ticks * idWell) % (fileSizeTemplate / 10)` long ticks = 1L * reportDate.Year * reportDate.Month * reportDate.Day * idWell;
return new Random().Next(1, 8193) + fileSizeTemplate; int remainder = (int)(ticks % (fileSizeTemplate / 10));
return fileSizeTemplate + remainder;
} }
} }

View File

@ -15,17 +15,14 @@ public class LimitingParameterExcelBlockWriter : IExcelBlockWriter
public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report) public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report)
{ {
if(!report.LimitingParameters.Any()) var i = 1;
return; foreach (var limitingParameter in report.LimitingParameters)
for (int i = 0; i < report.LimitingParameters.Length; i++)
{ {
var row = sheet.Row(1 + i + rowHeaderBlock); var row = sheet.Row( i++ + rowHeaderBlock);
row.Cell(columnNameFeedRegulator).Value = limitingParameter.NameFeedRegulator;
row.Cell(columnNameFeedRegulator).Value = report.LimitingParameters[i].NameFeedRegulator; row.Cell(columnDepth).Value = limitingParameter.Depth;
row.Cell(columnDepth).Value = report.LimitingParameters[i].Depth; row.Cell(columnTotalHours).Value = limitingParameter.Hours;
row.Cell(columnTotalHours).Value = report.LimitingParameters[i].Hours; row.Cell(columnPercentDepth).Value = limitingParameter.PercentDepth;
row.Cell(columnPercentDepth).Value = report.LimitingParameters[i].PercentDepth;
} }
} }
} }

View File

@ -15,17 +15,14 @@ public class SubsystemExcelBlockWriter : IExcelBlockWriter
public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report) public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report)
{ {
if(!report.Subsystems.Any()) var i = 1;
return; foreach( var subsystem in report.Subsystems )
for (int i = 0; i < report.Subsystems.Length; i++)
{ {
var row = sheet.Row(1 + i + rowHeaderBlock); var row = sheet.Row(i++ + rowHeaderBlock);
row.Cell(columnName).Value = subsystem.Name;
row.Cell(columnName).Value = report.Subsystems[i].Name; row.Cell(columnKUsage).Value = subsystem.KUsage;
row.Cell(columnKUsage).Value = report.Subsystems[i].KUsage; row.Cell(columnDepth).Value = subsystem.Depth;
row.Cell(columnDepth).Value = report.Subsystems[i].Depth; row.Cell(columnUsedTimeHours).Value = subsystem.UsedTimeHours;
row.Cell(columnUsedTimeHours).Value = report.Subsystems[i].UsedTimeHours;
} }
} }
} }

View File

@ -13,22 +13,18 @@ public class TimeBalanceExcelBlockWriter : IExcelBlockWriter
public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report) public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report)
{ {
if(!report.TimeBalance.Any()) var i = 1;
return; foreach(var timeBalance in report.TimeBalance)
for (int i = 0; i < report.TimeBalance.Length; i++)
{ {
var row = sheet.Row(1 + i + rowHeaderBlock); var row = sheet.Row(i++ + rowHeaderBlock);
row.Cell(columnName).Value = timeBalance.Name;
row.Cell(columnName).Value = report.TimeBalance[i].Name; row.Cell(columnDurationHours).Value = timeBalance.DurationHours;
row.Cell(columnDurationHours).Value = report.TimeBalance[i].DurationHours; AddBorderToCell(row.Cell(columnName));
AddBorderToCell(row.Cell(columnDurationHours));
AddBorderToCell(row.Cell(columnName));
AddBorderToCell(row.Cell(columnDurationHours));
} }
} }
private void AddBorderToCell(IXLCell cell) private static void AddBorderToCell(IXLCell cell)
{ {
cell.Style.Border.TopBorder = XLBorderStyleValues.Thin; cell.Style.Border.TopBorder = XLBorderStyleValues.Thin;
cell.Style.Border.BottomBorder = XLBorderStyleValues.Thin; cell.Style.Border.BottomBorder = XLBorderStyleValues.Thin;

View File

@ -43,10 +43,15 @@ namespace AsbCloudInfrastructure.Services
List<LimitingParameterDto> result = new List<LimitingParameterDto>(data.Count()); List<LimitingParameterDto> result = new List<LimitingParameterDto>(data.Count());
foreach (var item in data) foreach (var item in data)
{ {
var trimData = TrimLimitingParameters(item, request); var trimData = TrimLimitingParameters(item, request).ToArray();
var allItemDepths = trimData.Sum(x => x.DepthEnd - x.DepthStart); //TODO: временный фикс, нужно избежать отрицательных значений в ограничивающих параметрах.
var allItemDates = trimData.Sum(x => (x.DateEnd - x.DateStart).TotalMinutes); //Проблема возникает при при формировании LimitingParameter в LimitingParameterCalcWorkFactory.
//Начальная глубина ограничивающего параметра не может быть больше конечной.
var allItemDepths = trimData.Where(x => x.DepthStart < x.DepthEnd)
.Sum(x => x.DepthEnd - x.DepthStart);
var allItemDates = trimData.Where(x => x.DepthStart < x.DepthEnd)
.Sum(x => (x.DateEnd - x.DateStart).TotalMinutes);
result.Add(new LimitingParameterDto result.Add(new LimitingParameterDto
{ {

View File

@ -343,14 +343,15 @@ public class ProcessMapPlanImportService : IProcessMapPlanImportService
private static T GetCellValue<T>(IXLRow row, int columnNumber) private static T GetCellValue<T>(IXLRow row, int columnNumber)
{ {
var cell = row.Cell(columnNumber); try
if (cell.Value is T cellValue)
{ {
return cellValue; var cell = row.Cell(columnNumber);
return (T)Convert.ChangeType(cell.Value, typeof(T));
}
catch
{
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. Ячейка: ({row.RowNumber()},{columnNumber}) содержит некорректное значение");
} }
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. Ячейка:{columnNumber},{row.RowNumber()} содержит некорректное значение");
} }
} }

View File

@ -85,5 +85,20 @@ namespace AsbCloudWebApi.Controllers
return BadRequest(ArgumentInvalidException.MakeValidationError(nameof(key), "not found")); return BadRequest(ArgumentInvalidException.MakeValidationError(nameof(key), "not found"));
return Ok(result); return Ok(result);
} }
/// <summary>
/// Удалить ВСЕ настройки пользователя. Для админки.
/// </summary>
/// <param name="idUser"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpDelete("/api/admin/user/{idUser}/settings")]
[Permission]
public virtual async Task<ActionResult<int>> DeleteAsync(int idUser, CancellationToken token)
{
var result = await service.DeleteAsync(idUser, token).ConfigureAwait(false);
return Ok(result);
}
} }
} }