Enable nullable on DetectedOperation DrillingProgramPart FileCategory FileInfo FileMark

This commit is contained in:
ngfrolov 2023-02-17 17:36:25 +05:00
parent 61bee21ad9
commit 2b0e36d68c
Signed by untrusted user who does not match committer: ng.frolov
GPG Key ID: E99907A0357B29A7
20 changed files with 7138 additions and 89 deletions

View File

@ -1,8 +1,10 @@
using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Data.DetectedOperation
{
#nullable enable
/// <summary>
/// Автоматически определяемая операция
/// </summary>
@ -11,12 +13,12 @@ namespace AsbCloudApp.Data.DetectedOperation
/// <summary>
/// Список всех операций
/// </summary>
public IEnumerable<DetectedOperationDto> Operations { get; set; }
public IEnumerable<DetectedOperationDto> Operations { get; set; } = Enumerable.Empty<DetectedOperationDto>();
/// <summary>
/// Статистика по бурильщикам
/// </summary>
public IEnumerable<DetectedOperationDrillersStatDto> Stats { get; set; }
public IEnumerable<DetectedOperationDrillersStatDto> Stats { get; set; } = Enumerable.Empty<DetectedOperationDrillersStatDto>();
}
#nullable disable
}

View File

@ -1,7 +1,9 @@
using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Data
{
#nullable enable
/// <summary>
/// Часть программы бурения
/// </summary>
@ -10,7 +12,7 @@ namespace AsbCloudApp.Data
/// <summary>
/// Название
/// </summary>
public string Name { get; set; }
public string Name { get; set; } = string.Empty;
/// <summary>
/// ИД категории файла
@ -27,12 +29,12 @@ namespace AsbCloudApp.Data
/// <summary>
/// Публикаторы. Могут загружать файл этой категории
/// </summary>
public IEnumerable<UserDto> Publishers { get; set; }
public IEnumerable<UserDto> Publishers { get; set; } = Enumerable.Empty<UserDto>();
/// <summary>
/// Согласованты. Могут согласовывать загруженные файлы этой категории
/// </summary>
public IEnumerable<UserDto> Approvers { get; set; }
public IEnumerable<UserDto> Approvers { get; set; } = Enumerable.Empty<UserDto>();
/// <summary>
/// Разрешение для текущего пользователя согласовывать документ
@ -47,6 +49,6 @@ namespace AsbCloudApp.Data
/// <summary>
/// Ссылка на документ.
/// </summary>
public FileInfoDto File { get; set; }
public FileInfoDto? File { get; set; }
}
}

View File

@ -1,7 +1,9 @@
using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Data
{
#nullable enable
/// <summary>
/// DTO состояния формирования программы бурения
/// </summary>
@ -18,12 +20,12 @@ namespace AsbCloudApp.Data
/// <summary>
/// Ошибка при формировании
/// </summary>
public DrillingProgramCreateError Error { get; set; }
public DrillingProgramCreateError? Error { get; set; }
/// <summary>
/// Файл сформированной программы бурения
/// </summary>
public FileInfoDto Program { get; set; }
public FileInfoDto? Program { get; set; }
/// <summary>
/// Разрешение редактировать части программы бурения
@ -33,7 +35,7 @@ namespace AsbCloudApp.Data
/// <summary>
/// Список частей программы бурения
/// </summary>
public IEnumerable<DrillingProgramPartDto> Parts { get; set; }
public IEnumerable<DrillingProgramPartDto> Parts { get; set; } = Enumerable.Empty<DrillingProgramPartDto>();
}
/// <summary>
@ -44,11 +46,11 @@ namespace AsbCloudApp.Data
/// <summary>
/// Текст ошибки для отображения пользователю
/// </summary>
public string Message { get; set; }
public string Message { get; set; } = string.Empty;
/// <summary>
/// Текст ошибки для разработчика
/// </summary>
public string Exception { get; set; }
public string Exception { get; set; } = string.Empty;
}
}

View File

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Data
{
#nullable enable
/// <summary>
/// DTO информации о файле. Используется для загрузки файла.
/// </summary>
@ -27,7 +29,7 @@ namespace AsbCloudApp.Data
/// <summary>
/// имя файла
/// </summary>
public string Name { get; set; }
public string Name { get; set; } = null!;
/// <summary>
/// дата загрузки
@ -47,11 +49,11 @@ namespace AsbCloudApp.Data
/// <summary>
/// DTO автора
/// </summary>
public UserDto Author { get; set; }
public UserDto? Author { get; set; }
/// <summary>
/// список отметок файла
/// </summary>
public IEnumerable<FileMarkDto> FileMarks { get; set; }
public IEnumerable<FileMarkDto> FileMarks { get; set; } = Enumerable.Empty<FileMarkDto>();
}
}

View File

@ -2,6 +2,7 @@ using System;
namespace AsbCloudApp.Data
{
#nullable enable
/// <summary>
/// Отметка для файла
/// </summary>
@ -30,17 +31,17 @@ namespace AsbCloudApp.Data
/// <summary>
/// Полезный комментарий
/// </summary>
public string Comment { get; set; }
public string? Comment { get; set; }
/// <summary>
/// признак удаления отметки
/// </summary>
public bool IsDeleted { get; set; }
/// <summary>
/// Пользователь создающий отметку.
/// Необязательно указывать в запросе на создание.
/// </summary>
public UserDto User { get; set; }
public UserDto? User { get; set; }
}
}

View File

@ -1,5 +1,6 @@
namespace AsbCloudApp.Data
{
#nullable enable
/// <summary>
/// Well related DTO
/// </summary>

View File

@ -0,0 +1,59 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
public partial class Enable_nullable_on_DetectedOperation_DrillingProgramPart_FileCategory_FileInfo_FileMark : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "name",
table: "t_file_info",
type: "text",
nullable: false,
defaultValue: "",
comment: "Название файла",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true,
oldComment: "Название файла");
migrationBuilder.AlterColumn<string>(
name: "name",
table: "t_file_category",
type: "text",
nullable: false,
defaultValue: "",
comment: "Название категории",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true,
oldComment: "Название категории");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "name",
table: "t_file_info",
type: "text",
nullable: true,
comment: "Название файла",
oldClrType: typeof(string),
oldType: "text",
oldComment: "Название файла");
migrationBuilder.AlterColumn<string>(
name: "name",
table: "t_file_category",
type: "text",
nullable: true,
comment: "Название категории",
oldClrType: typeof(string),
oldType: "text",
oldComment: "Название категории");
}
}
}

View File

@ -342,6 +342,7 @@ namespace AsbCloudDb.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name")
.HasComment("Название категории");
@ -721,6 +722,7 @@ namespace AsbCloudDb.Migrations
.HasComment("Удален ли файл");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name")
.HasComment("Название файла");

View File

@ -6,7 +6,6 @@ using System.Text.Json.Serialization;
namespace AsbCloudDb.Model
{
#nullable disable
[Table("t_detected_operation"), Comment("автоматически определенные операции по телеметрии")]
public class DetectedOperation
{
@ -46,11 +45,11 @@ namespace AsbCloudDb.Model
[JsonIgnore]
[ForeignKey(nameof(IdTelemetry))]
public virtual Telemetry Telemetry { get; set; }
public virtual Telemetry Telemetry { get; set; } = null!;
[JsonIgnore]
[ForeignKey(nameof(IdCategory))]
public virtual WellOperationCategory OperationCategory { get; set; }
public virtual WellOperationCategory OperationCategory { get; set; } = null!;
public override string ToString()
=> $"{IdCategory}\t{DateStart:G}\t{DateEnd:G}\t{DurationMinutes:#0.#}\t{DepthStart:#0.#}\t{DepthEnd:#0.#}";

View File

@ -5,7 +5,6 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace AsbCloudDb.Model
{
#nullable disable
[Table("t_drilling_program_part"), Comment("части программ бурения")]
public class DrillingProgramPart
{
@ -20,12 +19,12 @@ namespace AsbCloudDb.Model
public int IdFileCategory { get; set; }
[ForeignKey(nameof(IdWell))]
public Well Well { get; set; }
public Well Well { get; set; } = null!;
[ForeignKey(nameof(IdFileCategory))]
public FileCategory FileCategory { get; set; }
public FileCategory FileCategory { get; set; } = null!;
[InverseProperty(nameof(RelationUserDrillingProgramPart.DrillingProgramPart))]
public virtual ICollection<RelationUserDrillingProgramPart> RelatedUsers { get; set; }
public virtual ICollection<RelationUserDrillingProgramPart> RelatedUsers { get; set; } = null!;
}
}

View File

@ -4,7 +4,6 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace AsbCloudDb.Model
{
#nullable disable
[Table("t_file_category"), Comment("Категории файлов")]
public class FileCategory : IId
{
@ -13,9 +12,9 @@ namespace AsbCloudDb.Model
public int Id { get; set; }
[Column("name"), Comment("Название категории")]
public string Name { get; set; }
public string Name { get; set; } = null!;
[Column("short_name"), Comment("Короткое название категории")]
public string ShortName { get; set; }
public string? ShortName { get; set; }
}
}

View File

@ -7,7 +7,6 @@ using System.Text.Json.Serialization;
namespace AsbCloudDb.Model
{
#nullable disable
[Table("t_file_info"), Comment("Файлы всех категорий")]
public class FileInfo : IId, IWellRelated
{
@ -25,7 +24,7 @@ namespace AsbCloudDb.Model
public int IdCategory { get; set; }
[Column("name"), Comment("Название файла")]
public string Name { get; set; }
public string Name { get; set; } = null!;
[Column("date", TypeName = "timestamp with time zone")]
public DateTimeOffset UploadDate { get; set; }
@ -38,17 +37,17 @@ namespace AsbCloudDb.Model
[JsonIgnore]
[ForeignKey(nameof(IdWell))]
public virtual Well Well { get; set; }
public virtual Well Well { get; set; } = null!;
[JsonIgnore]
[ForeignKey(nameof(IdAuthor))]
public virtual User Author { get; set; }
public virtual User? Author { get; set; }
[JsonIgnore]
[ForeignKey(nameof(IdCategory))]
public virtual FileCategory FileCategory { get; set; }
public virtual FileCategory FileCategory { get; set; } = null!;
[InverseProperty(nameof(FileMark.FileInfo))]
public virtual ICollection<FileMark> FileMarks { get; set; }
public virtual ICollection<FileMark> FileMarks { get; set; } = null!;
}
}

View File

@ -6,7 +6,6 @@ using System.Text.Json.Serialization;
namespace AsbCloudDb.Model
{
#nullable disable
[Table("t_file_mark"), Comment("Действия с файлами.")]
public class FileMark
{
@ -28,17 +27,17 @@ namespace AsbCloudDb.Model
[Column("comment"), Comment("Комментарий")]
[StringLength(255)]
public string Comment { get; set; }
public string? Comment { get; set; }
[Column("is_deleted"), Comment("Помечен ли файл как удаленный")]
public bool IsDeleted { get; set; }
[JsonIgnore]
[ForeignKey(nameof(IdUser))]
public virtual User User { get; set; }
public virtual User User { get; set; } = null!;
[JsonIgnore]
[ForeignKey(nameof(IdFile))]
public virtual FileInfo FileInfo { get; set; }
public virtual FileInfo FileInfo { get; set; } = null!;
}
}

View File

@ -1,12 +0,0 @@
using System;
namespace AsbCloudDb.Model
{
#nullable disable
public class FilePublishInfo
{
public int IdPublisher { get; set; }
public DateTimeOffset Date { get; set; }
public string WebStorageFileUrl { get; set; }
}
}

View File

@ -110,7 +110,7 @@ namespace AsbCloudInfrastructure.Repository
Wells = gCluster.Select(well =>
{
var dto = well.Adapt<WellDto>();
dto.WellType = well.WellType?.Caption;
dto.WellType = well.WellType.Caption;
dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id).DateTime;
dto.Cluster = gCluster.Key.Caption;
dto.Deposit = gDeposit.Key.Caption;

View File

@ -24,7 +24,7 @@ namespace AsbCloudInfrastructure.Repository
this.db = db;
this.dbSetConfigured = db.Files
.Include(f => f.Author)
.ThenInclude(u => u.Company)
.ThenInclude(u => u!.Company)
.ThenInclude(c => c.CompanyType)
.Include(f => f.FileMarks)
.ThenInclude(m => m.User)
@ -46,7 +46,7 @@ namespace AsbCloudInfrastructure.Repository
query = query.Where(x => x.IsDeleted == request.IsDeleted);
if (request.CompanyNamePart is not null)
query = query.Where(e => e.Author.Company.Caption.ToLower().Contains(request.CompanyNamePart.ToLower()));
query = query.Where(e => e.Author != null && e.Author.Company.Caption.ToLower().Contains(request.CompanyNamePart.ToLower()));
if (request.FileNamePart is not null)
query = query.Where(e => e.Name.ToLower().Contains(request.FileNamePart.ToLower()));
@ -186,7 +186,7 @@ namespace AsbCloudInfrastructure.Repository
newFileMark.Id = default;
newFileMark.DateCreated = DateTime.UtcNow;
newFileMark.IdUser = idUser;
newFileMark.User = null;
newFileMark.User = null!;
db.FileMarks.Add(newFileMark);
return await db.SaveChangesAsync(token);

View File

@ -173,7 +173,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
public async Task<int> AddFile(int idWell, int idFileCategory, int idUser, string fileFullName, Stream fileStream, CancellationToken token = default)
{
if (!IsFileExtensionValid(fileFullName))
throw new FileFormatException($"Файл {fileFullName} - неподдерживаемого формата. Файл не может быть загружен.");
throw new FileFormatException($"Файл {fileFullName} - не поддерживаемого формата. Файл не может быть загружен.");
var part = await context.DrillingProgramParts
.Include(p => p.RelatedUsers)
@ -318,7 +318,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
fileMarkDto.User = user.Adapt<UserDto>();
var oldMarksIds = fileInfo.FileMarks
?.Where(m => m.User.Id == idUser)
.Where(m => m.User?.Id == idUser)
.Select(m => m.Id);
if (oldMarksIds?.Any() == true)
@ -339,7 +339,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
.Where(u => u.IdUserRole == idUserRoleApprover);
if (approvers
.All(user => fileInfo.FileMarks
?.Any(mark => (mark.IdMarkType == idMarkTypeApprove && mark.User.Id == user.IdUser && !mark.IsDeleted)) == true ||
?.Any(mark => (mark.IdMarkType == idMarkTypeApprove && mark.User?.Id == user.IdUser && !mark.IsDeleted)) == true ||
(fileMarkDto.IdMarkType == idMarkTypeApprove && user.IdUser == idUser)))
{
await NotifyPublisherOnFullAccepAsync(fileMarkDto, token);
@ -369,7 +369,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
{
var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token);
var well = await wellService.GetOrDefaultAsync(file!.IdWell, token);
var user = file.Author;
var user = file.Author!;
var factory = new DrillingMailBodyFactory(configuration);
var subject = factory.MakeSubject(well, "Загруженный вами документ полностью согласован");
var body = factory.MakeMailBodyForPublisherOnFullAccept(well, user.Name, file.Id, file.Name);
@ -381,7 +381,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
{
var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token);
var well = await wellService.GetOrDefaultAsync(file!.IdWell, token);
var user = file.Author;
var user = file.Author!;
var factory = new DrillingMailBodyFactory(configuration);
var subject = factory.MakeSubject(well, "Загруженный вами документ отклонен");
var body = factory.MakeMailBodyForPublisherOnReject(well, user.Name, file.Id, file.Name, fileMark);
@ -440,8 +440,8 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
part.File = new FileInfoDto
{
Id = fileEntity.Id,
Author = fileEntity.Author.Adapt<UserDto>(),
IdAuthor = fileEntity.Author.Id,
Author = fileEntity.Author?.Adapt<UserDto>(),
IdAuthor = fileEntity.Author?.Id,
IdCategory = fileEntity.IdCategory,
IdWell = fileEntity.IdWell,
Name = fileEntity.Name,
@ -488,7 +488,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
{
var context = serviceProvider.GetRequiredService<IAsbCloudDbContext>();
var fileService = serviceProvider.GetRequiredService<FileService>();
var files = state.Parts.Select(p => fileService.GetUrl(p.File));
var files = state.Parts.Select(p => fileService.GetUrl(p.File!));
await ConvertToPdf.GetConverteAndMergedFileAsync(files, tempResultFilePath, convertedFilesDir, token);
await fileService.MoveAsync(idWell, null, idFileCategoryDrillingProgram, resultFileName, tempResultFilePath, token);
};

View File

@ -21,7 +21,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
totalDate = fileMarks.Max(f => f.DateCreated);
acceptDirectionDirector = fileMarks
.OrderByDescending(f => f.DateCreated)
.FirstOrDefault(f => f.User.Position == directionDirectorPositionName);
.FirstOrDefault(f => f.User?.Position == directionDirectorPositionName);
acceptsOthers = fileMarks
.Where(f => f.Id != acceptDirectionDirector?.Id)
.OrderBy(f => f.DateCreated)
@ -60,7 +60,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
private void DrawTopRightSign(IXLWorksheet sheet)
{
if (acceptDirectionDirector is null)
if (acceptDirectionDirector?.User is null)
return;
var user = acceptDirectionDirector.User;
@ -72,7 +72,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
.SetValue(user.Position);
sheet.Cell(3, 5)
.SetValue(user.Company?.Caption);
.SetValue(user.Company.Caption);
sheet.Cell(4, 5)
.SetValue($"{user.Surname} {user.Name} {user.Patronymic}");
@ -120,11 +120,15 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
.SetValue("Утверждаю:");
}
private void DrawAccept(IXLWorksheet sheet, FileMarkDto mark, (int row, int col) startAddress)
{
private static void DrawAccept(IXLWorksheet sheet, FileMarkDto mark, (int row, int col) startAddress)
{
var user = mark.User;
if(user is null)
return;
int startRow = startAddress.row;
int startCol = startAddress.col;
var user = mark.User;
sheet.Cell(startRow, startCol)
.SetValue("Должность");
@ -137,7 +141,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
sheet.Range(startRow + 2, startCol + 1, startRow + 3, startCol + 1)
.Merge()
.SetValue(user.Company?.Caption);
.SetValue(user.Company.Caption);
sheet.Range(startRow + 4, startCol, startRow + 4, startCol + 1)
.Merge()

View File

@ -1,21 +0,0 @@
using AsbCloudApp.Data;
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AsbCloudWebApi.Controllers
{
/// <summary>
/// Категорий документов файлов
/// </summary>
[Route("api/[Controller]")]
[ApiController]
[Authorize]
public class FileCategoryController : CrudController<FileCategoryDto, ICrudRepository<FileCategoryDto>>
{
public FileCategoryController(ICrudRepository<FileCategoryDto> service, IFileCategoryService fileCategoryService)
: base(service)
{
}
}
}