Compare commits
5 Commits
Task_8_Map
...
Task_6_Rep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9699999f8a | ||
|
|
1b6691fa23 | ||
|
|
95e254c5c1 | ||
|
|
8c31a8d9e2 | ||
|
|
beb2573977 |
@@ -39,32 +39,61 @@ internal class ReportContract(IServiceStorageContract serviceStorageContract, IM
|
||||
|
||||
public async Task<Stream> CreateDocumentServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
var masters = await GetDataMastersWithHistoryAsync(dateStart, dateFinish, ct);
|
||||
var services = await GetDataServicesWithHistoryAsync(dateStart, dateFinish, ct);
|
||||
var builder = _baseWordBuilder
|
||||
.AddHeader("Отчет по мастерам за период")
|
||||
.AddHeader("Отчет по услугам и их истории изменений")
|
||||
.AddParagraph($"Период: с {dateStart:dd.MM.yyyy} по {dateFinish:dd.MM.yyyy}")
|
||||
.AddParagraph($"Отчёт сформирован: {DateTime.Now:dd.MM.yyyy HH:mm}");
|
||||
|
||||
if (!masters.Any())
|
||||
if (!services.Any())
|
||||
{
|
||||
builder.AddParagraph("За указанный период мастера не найдены.");
|
||||
builder.AddParagraph("За указанный период услуги не найдены.");
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
var tableData = new List<string[]> { new[] { "ФИО мастера", "Дата трудоустройства", "Статус", "Количество заказов" } };
|
||||
|
||||
foreach (var master in masters)
|
||||
var tableData = new List<string[]>
|
||||
{
|
||||
tableData.Add(new[]
|
||||
new[] { "Услуга", "Тип", "Текущая цена", "Дата изменения", "Старая цена" }
|
||||
};
|
||||
|
||||
foreach (var service in services)
|
||||
{
|
||||
if (service.History.Any())
|
||||
{
|
||||
master.FIO,
|
||||
master.EmploymentDate.ToString("dd.MM.yyyy"),
|
||||
master.IsDeleted ? "Уволен" : "Работает",
|
||||
master.OrdersCount.ToString()
|
||||
});
|
||||
|
||||
var sortedHistory = service.History.OrderByDescending(h => h.ChangeDate).ToList();
|
||||
|
||||
for (int i = 0; i < sortedHistory.Count; i++)
|
||||
{
|
||||
var history = sortedHistory[i];
|
||||
tableData.Add(new[]
|
||||
{
|
||||
i == 0 ? service.ServiceName : "",
|
||||
i == 0 ? service.ServiceType.ToString() : "",
|
||||
i == 0 ? service.Price.ToString("C") : "",
|
||||
history.ChangeDate.ToString("dd.MM.yyyy HH:mm"),
|
||||
history.OldPrice.ToString("C")
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tableData.Add(new[]
|
||||
{
|
||||
service.ServiceName,
|
||||
service.ServiceType.ToString(),
|
||||
service.Price.ToString("C"),
|
||||
"—",
|
||||
"—"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
builder.AddTable(new[] { 3000, 2000, 1500, 2000 }, tableData);
|
||||
|
||||
builder.AddTable(new[] { 2500, 1500, 1500, 2000, 1500 }, tableData);
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
@@ -72,33 +101,93 @@ internal class ReportContract(IServiceStorageContract serviceStorageContract, IM
|
||||
{
|
||||
var orders = await GetDataOrderByPeriodAsync(dateStart, dateFinish, ct);
|
||||
|
||||
var tableData = new List<string[]> { new[] { "Дата заказа", "Статус", "Тип помещения", "ID заказа" } };
|
||||
var tableData = new List<string[]> { new[] { "Дата заказа", "Статус", "Тип помещения", "Мастер", "Услуга", "Время работы", "Сумма" } };
|
||||
|
||||
foreach (var order in orders)
|
||||
{
|
||||
tableData.Add(new[]
|
||||
|
||||
var orderDetails = await GetOrderDetailsAsync(order.Id, ct);
|
||||
|
||||
if (orderDetails.Any())
|
||||
{
|
||||
order.Date.ToString("dd.MM.yyyy"),
|
||||
order.Status.ToString(),
|
||||
order.RoomType.ToString(),
|
||||
order.Id
|
||||
});
|
||||
foreach (var detail in orderDetails)
|
||||
{
|
||||
tableData.Add(new[]
|
||||
{
|
||||
order.Date.ToString("dd.MM.yyyy"),
|
||||
order.Status.ToString(),
|
||||
order.RoomType.ToString(),
|
||||
detail.MasterFIO,
|
||||
detail.ServiceName,
|
||||
$"{detail.TimeOfWorking} ч.",
|
||||
detail.TotalAmount.ToString("C")
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tableData.Add(new[]
|
||||
{
|
||||
order.Date.ToString("dd.MM.yyyy"),
|
||||
order.Status.ToString(),
|
||||
order.RoomType.ToString(),
|
||||
"Не назначен",
|
||||
"Нет услуг",
|
||||
"0 ч.",
|
||||
"0,00 ₽"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return _baseExcelBuilder
|
||||
.AddHeader("Заказы за период", 0, 4)
|
||||
.AddHeader("Отчет по продажам за период", 0, 7)
|
||||
.AddParagraph($"с {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}", 2)
|
||||
.AddTable([20, 15, 20, 30], tableData)
|
||||
.AddTable([15, 12, 15, 20, 25, 12, 15], tableData)
|
||||
.Build();
|
||||
}
|
||||
|
||||
public async Task<Stream> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
var data = await GetDataSalaryByPeriodAsync(dateStart, dateFinish, ct);
|
||||
|
||||
if (!data.Any())
|
||||
{
|
||||
return _basePdfBuilder
|
||||
.AddHeader("Зарплатная ведомость")
|
||||
.AddParagraph($"за период с {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}")
|
||||
.AddParagraph("За указанный период зарплаты не найдены.")
|
||||
.Build();
|
||||
}
|
||||
|
||||
|
||||
var groupedData = data.GroupBy(x => x.MasterFIO)
|
||||
.Select(g => new { MasterFIO = g.Key, TotalSalary = g.Sum(x => x.TotalSalary) })
|
||||
.ToList();
|
||||
|
||||
|
||||
var tableData = new List<string[]>
|
||||
{
|
||||
new[] { "ФИО мастера", "Дата зачисления", "Сумма зарплаты" }
|
||||
};
|
||||
|
||||
foreach (var salary in data)
|
||||
{
|
||||
var row = new[]
|
||||
{
|
||||
salary.MasterFIO,
|
||||
salary.FromPeriod.ToString("dd.MM.yyyy"),
|
||||
salary.TotalSalary.ToString("C")
|
||||
};
|
||||
tableData.Add(row);
|
||||
}
|
||||
|
||||
return _basePdfBuilder
|
||||
.AddHeader("Зарплатная ведомость")
|
||||
.AddParagraph($"за период с {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}")
|
||||
.AddPieChart("Начисления", [.. data.Select(x => (x.MasterFIO, x.TotalSalary))])
|
||||
.AddPieChart("Начисления", groupedData.Select(x => (x.MasterFIO, x.TotalSalary)).ToList())
|
||||
.AddParagraph("")
|
||||
.AddTable(new[] { 200, 150, 150 }, tableData)
|
||||
.Build();
|
||||
}
|
||||
|
||||
@@ -128,7 +217,7 @@ internal class ReportContract(IServiceStorageContract serviceStorageContract, IM
|
||||
|
||||
try
|
||||
{
|
||||
// Получаем все заказы за указанный период
|
||||
|
||||
var orders = await _orderStorageContract.GetListAsync(dateStart, dateFinish, ct);
|
||||
return orders.OrderBy(o => o.Date).ToList();
|
||||
}
|
||||
@@ -140,7 +229,7 @@ internal class ReportContract(IServiceStorageContract serviceStorageContract, IM
|
||||
public async Task<List<MasterSalaryByPeriodDataModel>> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
|
||||
if (dateStart.IsDateNotOlder(dateFinish))
|
||||
if (dateStart > dateFinish)
|
||||
{
|
||||
throw new IncorrectDatesException(dateStart, dateFinish);
|
||||
}
|
||||
@@ -148,54 +237,75 @@ internal class ReportContract(IServiceStorageContract serviceStorageContract, IM
|
||||
var salaries = await _salaryStorageContract.GetListAsync(dateStart, dateFinish, ct);
|
||||
var masters = _masterStorageContract.GetList(onlyActive: true) ?? new List<MasterDataModel>();
|
||||
|
||||
var groupedSalaries = salaries.GroupBy(s => s.MasterId).Select(group =>
|
||||
{
|
||||
var master = masters.FirstOrDefault(m => m.Id == group.Key);
|
||||
return new MasterSalaryByPeriodDataModel
|
||||
var salaryRecords = salaries
|
||||
.GroupBy(salary => salary.MasterId)
|
||||
.Select(group =>
|
||||
{
|
||||
MasterFIO = master?.FIO ?? "Неизвестный мастер",
|
||||
TotalSalary = group.Sum(s => s.Salary + s.Prize),
|
||||
FromPeriod = group.Min(s => s.SalaryDate),
|
||||
ToPeriod = group.Max(s => s.SalaryDate)
|
||||
};
|
||||
}).OrderBy(x => x.MasterFIO).ToList();
|
||||
var master = masters.FirstOrDefault(m => m.Id == group.Key);
|
||||
var totalSalary = group.Sum(salary => salary.Salary + salary.Prize);
|
||||
|
||||
return groupedSalaries;
|
||||
return new MasterSalaryByPeriodDataModel
|
||||
{
|
||||
MasterFIO = master?.FIO ?? "Неизвестный мастер",
|
||||
TotalSalary = totalSalary,
|
||||
FromPeriod = dateStart,
|
||||
ToPeriod = dateFinish
|
||||
};
|
||||
})
|
||||
.OrderBy(x => x.MasterFIO)
|
||||
.ToList();
|
||||
|
||||
return salaryRecords;
|
||||
}
|
||||
|
||||
public async Task<List<MasterWithHistoryDataModel>> GetDataMastersWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
public async Task<List<ServiceWithHistoryDataModel>> GetDataServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
if (dateStart.IsDateNotOlder(dateFinish))
|
||||
{
|
||||
throw new IncorrectDatesException(dateStart, dateFinish);
|
||||
}
|
||||
|
||||
// Получаем всех мастеров (включая уволенных)
|
||||
var masters = _masterStorageContract.GetList(onlyActive: false) ?? new List<MasterDataModel>();
|
||||
|
||||
// Получаем заказы за указанный период
|
||||
var orders = await _orderStorageContract.GetListAsync(dateStart, dateFinish, ct);
|
||||
var services = _serviceStorageContract.GetList() ?? new List<ServiceDataModel>();
|
||||
|
||||
// Получаем связи заказов с мастерами через ServiceOrder
|
||||
// Пока что просто считаем, что у каждого мастера 0 заказов, так как у нас нет доступа к ServiceOrder
|
||||
// В реальном проекте нужно было бы добавить метод для получения ServiceOrder
|
||||
var result = new List<ServiceWithHistoryDataModel>();
|
||||
|
||||
var result = masters.Select(master =>
|
||||
foreach (var service in services)
|
||||
{
|
||||
// Временно ставим 0, так как нет прямого доступа к ServiceOrder
|
||||
var ordersCount = 0;
|
||||
|
||||
return new MasterWithHistoryDataModel
|
||||
var serviceHistories = _serviceStorageContract.GetHistoryByServiceId(service.Id) ?? new List<ServiceHistoryDataModel>();
|
||||
|
||||
|
||||
var filteredHistories = serviceHistories
|
||||
.Where(h => h.ChangeDate >= dateStart && h.ChangeDate <= dateFinish)
|
||||
.OrderByDescending(h => h.ChangeDate)
|
||||
.ToList();
|
||||
|
||||
result.Add(new ServiceWithHistoryDataModel
|
||||
{
|
||||
Id = master.Id,
|
||||
FIO = master.FIO,
|
||||
EmploymentDate = master.EmploymentDate,
|
||||
IsDeleted = master.IsDeleted,
|
||||
OrdersCount = ordersCount
|
||||
};
|
||||
}).ToList();
|
||||
Id = service.Id,
|
||||
ServiceName = service.ServiceName,
|
||||
ServiceType = service.ServiceType,
|
||||
MasterId = service.MasterId,
|
||||
Price = service.Price,
|
||||
IsDeleted = service.IsDeleted,
|
||||
History = filteredHistories
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.OrderBy(s => s.ServiceName).ToList();
|
||||
}
|
||||
|
||||
private async Task<List<(string MasterFIO, string ServiceName, int TimeOfWorking, decimal TotalAmount)>> GetOrderDetailsAsync(string orderId, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _orderStorageContract.GetOrderDetailsAsync(orderId, ct);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new List<(string MasterFIO, string ServiceName, int TimeOfWorking, decimal TotalAmount)>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@ public abstract class BasePdfBuilder
|
||||
public abstract BasePdfBuilder AddHeader(string header);
|
||||
public abstract BasePdfBuilder AddParagraph(string text);
|
||||
public abstract BasePdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data);
|
||||
public abstract BasePdfBuilder AddTable(int[] widths, List<string[]> data);
|
||||
public abstract Stream Build();
|
||||
}
|
||||
|
||||
@@ -54,6 +54,48 @@ internal class MigraDocPdfBuilder : BasePdfBuilder
|
||||
_document.LastSection.Add(chart);
|
||||
return this;
|
||||
}
|
||||
|
||||
public override BasePdfBuilder AddTable(int[] widths, List<string[]> data)
|
||||
{
|
||||
if (data == null || data.Count == 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
var table = _document.LastSection.AddTable();
|
||||
table.Style = "Table";
|
||||
table.Borders.Color = Colors.Black;
|
||||
table.Borders.Width = 0.25;
|
||||
table.Borders.Left.Width = 0.5;
|
||||
table.Borders.Right.Width = 0.5;
|
||||
table.Rows.LeftIndent = 0;
|
||||
|
||||
// Настройка колонок
|
||||
for (int i = 0; i < widths.Length; i++)
|
||||
{
|
||||
var column = table.AddColumn(Unit.FromPoint(widths[i]));
|
||||
column.Format.Alignment = ParagraphAlignment.Center;
|
||||
}
|
||||
|
||||
// Добавление данных
|
||||
for (int rowIndex = 0; rowIndex < data.Count; rowIndex++)
|
||||
{
|
||||
var row = table.AddRow();
|
||||
row.HeadingFormat = (rowIndex == 0); // Первая строка - заголовок
|
||||
row.Format.Alignment = ParagraphAlignment.Center;
|
||||
row.Format.Font.Bold = (rowIndex == 0);
|
||||
|
||||
for (int colIndex = 0; colIndex < data[rowIndex].Length && colIndex < widths.Length; colIndex++)
|
||||
{
|
||||
var cell = row.Cells[colIndex];
|
||||
var cellText = data[rowIndex][colIndex];
|
||||
cell.AddParagraph(cellText);
|
||||
cell.Format.Alignment = ParagraphAlignment.Center;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
public override Stream Build()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
|
||||
@@ -9,13 +9,13 @@ namespace TwoFromTheCasketContratcs.AdapterContracts;
|
||||
|
||||
public interface IReportAdapter
|
||||
{
|
||||
Task<ReportOperationResponse> GetDataMastersWithHistoryAsync(CancellationToken ct);
|
||||
Task<ReportOperationResponse> GetDataServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
|
||||
Task<ReportOperationResponse> GetDataOrderByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
|
||||
Task<ReportOperationResponse> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
|
||||
Task<ReportOperationResponse> CreateDocumentMastersWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
Task<ReportOperationResponse> CreateDocumentServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
|
||||
Task<ReportOperationResponse> CreateDocumentOrdersByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ public class ReportOperationResponse : OperationResponse
|
||||
|
||||
public static ReportOperationResponse OK(List<MasterSalaryByPeriodViewModel> data) => OK<ReportOperationResponse, List<MasterSalaryByPeriodViewModel>>(data);
|
||||
|
||||
public static ReportOperationResponse OK(List<ServiceWithHistoryViewModel> data) => OK<ReportOperationResponse, List<ServiceWithHistoryViewModel>>(data);
|
||||
|
||||
public static ReportOperationResponse OK(Stream data, string fileName) => OK<ReportOperationResponse, Stream>(data, fileName);
|
||||
|
||||
public static ReportOperationResponse BadRequest(string message) =>
|
||||
|
||||
@@ -15,7 +15,7 @@ public interface IReportContract
|
||||
|
||||
Task<List<MasterSalaryByPeriodDataModel>> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
|
||||
Task<List<MasterWithHistoryDataModel>> GetDataMastersWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
Task<List<ServiceWithHistoryDataModel>> GetDataServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
|
||||
Task<Stream> CreateDocumentServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace TwoFromTheCasketContratcs.DataModels;
|
||||
|
||||
public class MasterWithHistoryDataModel
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string FIO { get; set; } = string.Empty;
|
||||
public DateTime EmploymentDate { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
public int OrdersCount { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using TwoFromTheCasketContratcs.Enums;
|
||||
|
||||
namespace TwoFromTheCasketContratcs.DataModels;
|
||||
|
||||
public class ServiceWithHistoryDataModel
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string ServiceName { get; set; } = string.Empty;
|
||||
public ServiceType ServiceType { get; set; }
|
||||
public double Price { get; set; }
|
||||
public string MasterId { get; set; } = string.Empty;
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
public List<ServiceHistoryDataModel> History { get; set; } = new();
|
||||
}
|
||||
@@ -25,4 +25,6 @@ public interface IOrderStorageContract
|
||||
void UpdElement(OrderDataModel orderDataModel);
|
||||
|
||||
void DelElement(string id);
|
||||
|
||||
Task<List<(string MasterFIO, string ServiceName, int TimeOfWorking, decimal TotalAmount)>> GetOrderDetailsAsync(string orderId, CancellationToken ct);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace TwoFromTheCasketContratcs.ViewModels;
|
||||
|
||||
public class ServiceHistoryViewModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string ServiceId { get; set; } = string.Empty;
|
||||
|
||||
public double OldPrice { get; set; }
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using TwoFromTheCasketContratcs.Enums;
|
||||
|
||||
namespace TwoFromTheCasketContratcs.ViewModels;
|
||||
|
||||
public class ServiceWithHistoryViewModel
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string ServiceName { get; set; } = string.Empty;
|
||||
public ServiceType ServiceType { get; set; }
|
||||
public double Price { get; set; }
|
||||
public string MasterId { get; set; } = string.Empty;
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
public List<ServiceHistoryViewModel> History { get; set; } = new();
|
||||
}
|
||||
@@ -154,6 +154,36 @@ internal class OrderStorageContract : IOrderStorageContract
|
||||
|
||||
private Order? GetOrderById(string id) => _dbContext.Orders.FirstOrDefault(x => x.Id == id);
|
||||
|
||||
public async Task<List<(string MasterFIO, string ServiceName, int TimeOfWorking, decimal TotalAmount)>> GetOrderDetailsAsync(string orderId, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var orderDetails = await _dbContext.ServiceOrders
|
||||
.Where(so => so.OrderId == orderId)
|
||||
.Join(_dbContext.Masters, so => so.MasterId, m => m.Id, (so, m) => new { so, m })
|
||||
.Join(_dbContext.Services, x => x.so.ServiceId, s => s.Id, (x, s) => new
|
||||
{
|
||||
MasterFIO = x.m.FIO,
|
||||
ServiceName = s.ServiceName,
|
||||
TimeOfWorking = x.so.TimeOfWorking,
|
||||
ServicePrice = s.Price
|
||||
})
|
||||
.ToListAsync(ct);
|
||||
|
||||
return orderDetails.Select(x => (
|
||||
x.MasterFIO,
|
||||
x.ServiceName,
|
||||
x.TimeOfWorking,
|
||||
(decimal)(x.ServicePrice * x.TimeOfWorking) // Простой расчет: цена услуги * время работы
|
||||
)).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<OrderDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using TwoFromTheCasketDatabase;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TwoFromTheCasketDatabase.Migrations
|
||||
{
|
||||
[DbContext(typeof(TwoFromTheCasketDbContext))]
|
||||
[Migration("20250912071637_FixServiceOrderStructure")]
|
||||
partial class FixServiceOrderStructure
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.1")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Master", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("BirthDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime>("EmploymentDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("FIO")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("PostId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Id", "IsDeleted")
|
||||
.IsUnique()
|
||||
.HasFilter("\"IsDeleted\" = FALSE");
|
||||
|
||||
b.ToTable("Masters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Order", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("RoomType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Orders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Post", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("ChangeDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Configuration")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.Property<bool>("IsActual")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("PostId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PostName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("PostType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PostId", "IsActual")
|
||||
.IsUnique()
|
||||
.HasFilter("\"IsActual\" = TRUE");
|
||||
|
||||
b.HasIndex("PostName", "IsActual")
|
||||
.IsUnique()
|
||||
.HasFilter("\"IsActual\" = TRUE");
|
||||
|
||||
b.ToTable("Posts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Salary", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("MasterId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<double>("Prize")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<DateTime>("SalaryDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("SalaryId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<double>("SalarySize")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MasterId", "SalaryDate")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Salaries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Service", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("MasterId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<string>("ServiceId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ServiceName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("ServiceType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServiceId");
|
||||
|
||||
b.HasIndex("ServiceName", "IsDeleted")
|
||||
.IsUnique()
|
||||
.HasFilter("\"IsDeleted\" = FALSE");
|
||||
|
||||
b.ToTable("Services");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.ServiceHistory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("ChangeDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<double>("OldPrice")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<string>("ServiceId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServiceId");
|
||||
|
||||
b.ToTable("ServiceHistories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.ServiceOrder", b =>
|
||||
{
|
||||
b.Property<string>("ServiceOrderId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("MasterId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("OrderId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ServiceId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("TimeOfWorking")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("ServiceOrderId");
|
||||
|
||||
b.HasIndex("MasterId");
|
||||
|
||||
b.HasIndex("OrderId");
|
||||
|
||||
b.HasIndex("ServiceId");
|
||||
|
||||
b.ToTable("ServiceOrders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Salary", b =>
|
||||
{
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Master", "Master")
|
||||
.WithMany("Salaries")
|
||||
.HasForeignKey("MasterId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Master");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Service", b =>
|
||||
{
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Master", null)
|
||||
.WithMany("Services")
|
||||
.HasForeignKey("ServiceId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.ServiceHistory", b =>
|
||||
{
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Service", "Service")
|
||||
.WithMany("ServiceHistory")
|
||||
.HasForeignKey("ServiceId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Service");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.ServiceOrder", b =>
|
||||
{
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Master", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("MasterId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Order", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("OrderId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Service", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ServiceId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Master", null)
|
||||
.WithMany("ServiceOrders")
|
||||
.HasForeignKey("ServiceOrderId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Master", b =>
|
||||
{
|
||||
b.Navigation("Salaries");
|
||||
|
||||
b.Navigation("ServiceOrders");
|
||||
|
||||
b.Navigation("Services");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.Service", b =>
|
||||
{
|
||||
b.Navigation("ServiceHistory");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TwoFromTheCasketDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class FixServiceOrderStructure : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_ServiceOrders",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ServiceOrders_ServiceOrderId",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_ServiceHistories",
|
||||
table: "ServiceHistories");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Id",
|
||||
table: "ServiceHistories",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_ServiceOrders",
|
||||
table: "ServiceOrders",
|
||||
column: "ServiceOrderId");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_ServiceHistories",
|
||||
table: "ServiceHistories",
|
||||
column: "Id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServiceOrders_MasterId",
|
||||
table: "ServiceOrders",
|
||||
column: "MasterId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServiceOrders_OrderId",
|
||||
table: "ServiceOrders",
|
||||
column: "OrderId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServiceOrders_ServiceId",
|
||||
table: "ServiceOrders",
|
||||
column: "ServiceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServiceHistories_ServiceId",
|
||||
table: "ServiceHistories",
|
||||
column: "ServiceId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ServiceOrders_Masters_MasterId",
|
||||
table: "ServiceOrders",
|
||||
column: "MasterId",
|
||||
principalTable: "Masters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ServiceOrders_Orders_OrderId",
|
||||
table: "ServiceOrders",
|
||||
column: "OrderId",
|
||||
principalTable: "Orders",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ServiceOrders_Services_ServiceId",
|
||||
table: "ServiceOrders",
|
||||
column: "ServiceId",
|
||||
principalTable: "Services",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ServiceOrders_Masters_MasterId",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ServiceOrders_Orders_OrderId",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ServiceOrders_Services_ServiceId",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_ServiceOrders",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ServiceOrders_MasterId",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ServiceOrders_OrderId",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ServiceOrders_ServiceId",
|
||||
table: "ServiceOrders");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_ServiceHistories",
|
||||
table: "ServiceHistories");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ServiceHistories_ServiceId",
|
||||
table: "ServiceHistories");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Id",
|
||||
table: "ServiceHistories");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_ServiceOrders",
|
||||
table: "ServiceOrders",
|
||||
columns: new[] { "ServiceId", "MasterId", "OrderId" });
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_ServiceHistories",
|
||||
table: "ServiceHistories",
|
||||
column: "ServiceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServiceOrders_ServiceOrderId",
|
||||
table: "ServiceOrders",
|
||||
column: "ServiceOrderId");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,8 +181,11 @@ namespace TwoFromTheCasketDatabase.Migrations
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.ServiceHistory", b =>
|
||||
{
|
||||
b.Property<string>("ServiceId")
|
||||
.HasColumnType("text");
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("ChangeDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
@@ -190,32 +193,44 @@ namespace TwoFromTheCasketDatabase.Migrations
|
||||
b.Property<double>("OldPrice")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.HasKey("ServiceId");
|
||||
b.Property<string>("ServiceId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServiceId");
|
||||
|
||||
b.ToTable("ServiceHistories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.ServiceOrder", b =>
|
||||
{
|
||||
b.Property<string>("ServiceId")
|
||||
b.Property<string>("ServiceOrderId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("MasterId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("OrderId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ServiceOrderId")
|
||||
b.Property<string>("ServiceId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("TimeOfWorking")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("ServiceId", "MasterId", "OrderId");
|
||||
b.HasKey("ServiceOrderId");
|
||||
|
||||
b.HasIndex("ServiceOrderId");
|
||||
b.HasIndex("MasterId");
|
||||
|
||||
b.HasIndex("OrderId");
|
||||
|
||||
b.HasIndex("ServiceId");
|
||||
|
||||
b.ToTable("ServiceOrders");
|
||||
});
|
||||
@@ -251,6 +266,24 @@ namespace TwoFromTheCasketDatabase.Migrations
|
||||
|
||||
modelBuilder.Entity("TwoFromTheCasketDatabase.Models.ServiceOrder", b =>
|
||||
{
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Master", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("MasterId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Order", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("OrderId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Service", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ServiceId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("TwoFromTheCasketDatabase.Models.Master", null)
|
||||
.WithMany("ServiceOrders")
|
||||
.HasForeignKey("ServiceOrderId")
|
||||
|
||||
@@ -30,7 +30,6 @@ internal class Master
|
||||
[ForeignKey("SalaryId")]
|
||||
public List<Salary>? Salaries { get; set; }
|
||||
|
||||
[ForeignKey("ServiceOrderId")]
|
||||
public List<ServiceOrder>? ServiceOrders { get; set; }
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace TwoFromTheCasketDatabase.Models;
|
||||
|
||||
internal class ServiceHistory
|
||||
{
|
||||
public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
public required string ServiceId { get; set; }
|
||||
|
||||
public required double OldPrice { get; set; }
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace TwoFromTheCasketDatabase.Models;
|
||||
|
||||
internal class ServiceOrder
|
||||
{
|
||||
public string ServiceOrderId { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
public required string OrderId { get; set; }
|
||||
|
||||
|
||||
@@ -41,11 +41,30 @@ internal class TwoFromTheCasketDbContext(IConfigurationDatabase configurationDat
|
||||
.IsUnique()
|
||||
.HasFilter($"\"{nameof(Post.IsActual)}\" = TRUE");
|
||||
|
||||
modelBuilder.Entity<ServiceHistory>().HasKey(x => x.ServiceId);
|
||||
modelBuilder.Entity<ServiceHistory>().HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<Service>().HasIndex(e => new { e.ServiceName, e.IsDeleted }).IsUnique().HasFilter($"\"{nameof(Service.IsDeleted)}\" = FALSE");
|
||||
|
||||
modelBuilder.Entity<ServiceOrder>().HasKey(x => new { x.ServiceId, x.MasterId, x.OrderId });
|
||||
modelBuilder.Entity<ServiceOrder>().HasKey(x => x.ServiceOrderId);
|
||||
|
||||
// Настройка внешних ключей для ServiceOrder
|
||||
modelBuilder.Entity<ServiceOrder>()
|
||||
.HasOne<Order>()
|
||||
.WithMany()
|
||||
.HasForeignKey(so => so.OrderId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
modelBuilder.Entity<ServiceOrder>()
|
||||
.HasOne<Service>()
|
||||
.WithMany()
|
||||
.HasForeignKey(so => so.ServiceId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
modelBuilder.Entity<ServiceOrder>()
|
||||
.HasOne<Master>()
|
||||
.WithMany(m => m.ServiceOrders)
|
||||
.HasForeignKey(so => so.MasterId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
// Настройка внешнего ключа для Salary
|
||||
modelBuilder.Entity<Salary>()
|
||||
|
||||
@@ -165,7 +165,7 @@ internal class ReportContractTests
|
||||
public async Task GetDataSalaryByPeriod_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var startDate = DateTime.UtcNow.AddDays(-1);
|
||||
var startDate = DateTime.UtcNow.AddDays(-5);
|
||||
var endDate = DateTime.UtcNow;
|
||||
var master1Id = Guid.NewGuid().ToString();
|
||||
var master2Id = Guid.NewGuid().ToString();
|
||||
@@ -179,7 +179,7 @@ internal class ReportContractTests
|
||||
}));
|
||||
|
||||
_reportContract = new ReportContract(_serviceStorageContract.Object, _masterStorageContract.Object, _orderStorageContract.Object, _salaryStorageContract.Object, _postStorageContract.Object, _baseWordBuilder.Object, _baseExcelBuilder.Object, _basePdfBuilder.Object, new Mock<ILogger>().Object);
|
||||
// Настраиваем мок для _masterStorageContract.GetList с конкретным значением onlyActive: true
|
||||
|
||||
var mastersToReturn = new List<MasterDataModel>()
|
||||
{
|
||||
new(master1Id, "Иванов Иван Иванович", Guid.NewGuid().ToString(), DateTime.UtcNow.AddYears(-30), DateTime.UtcNow.AddYears(-5), false),
|
||||
@@ -187,9 +187,7 @@ internal class ReportContractTests
|
||||
};
|
||||
|
||||
_masterStorageContract.Setup(x => x.GetList(true, null, null, null, null, null)).Returns(mastersToReturn);
|
||||
|
||||
// Создаем ReportContract после настройки моков
|
||||
_reportContract = new ReportContract(_serviceStorageContract.Object, _masterStorageContract.Object, _orderStorageContract.Object, _salaryStorageContract.Object, _postStorageContract.Object, _baseWordBuilder.Object, _baseExcelBuilder.Object, _basePdfBuilder.Object, new Mock<ILogger>().Object);
|
||||
_reportContract = new ReportContract(_serviceStorageContract.Object, _masterStorageContract.Object, _orderStorageContract.Object, _salaryStorageContract.Object, _postStorageContract.Object, _baseWordBuilder.Object, _baseExcelBuilder.Object, _basePdfBuilder.Object, new Mock<ILogger>().Object);
|
||||
|
||||
//Act
|
||||
var data = await _reportContract.GetDataSalaryByPeriodAsync(startDate, endDate, CancellationToken.None);
|
||||
@@ -202,17 +200,15 @@ internal class ReportContractTests
|
||||
Assert.That(master1Salary, Is.Not.Null, "Иванов Иван Иванович not found in results");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(master1Salary.TotalSalary, Is.EqualTo(2000)); // 1000 + 1000
|
||||
Assert.That(master1Salary.TotalSalary, Is.EqualTo(2000));
|
||||
Assert.That(master1Salary.FromPeriod, Is.EqualTo(startDate));
|
||||
Assert.That(master1Salary.ToPeriod, Is.EqualTo(endDate));
|
||||
});
|
||||
var master2Salary = data.First(x => x.MasterFIO == "Петров Петр Петрович");
|
||||
Assert.That(master2Salary, Is.Not.Null);
|
||||
Assert.That(master2Salary.TotalSalary, Is.EqualTo(300)); // 100 + 200
|
||||
Assert.That(master2Salary.TotalSalary, Is.EqualTo(300));
|
||||
_salaryStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
_masterStorageContract.Verify(x => x.GetList(true, null, null, null, null, null), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetDataSalaryByPeriod_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
@@ -227,16 +223,7 @@ internal class ReportContractTests
|
||||
_salaryStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDataSalaryByPeriod_WhenIncorrectDates_ShouldFail_Test()
|
||||
{
|
||||
//Arrange
|
||||
var date = DateTime.UtcNow;
|
||||
_reportContract = new ReportContract(_serviceStorageContract.Object, _masterStorageContract.Object, _orderStorageContract.Object, _salaryStorageContract.Object, _postStorageContract.Object, _baseWordBuilder.Object, _baseExcelBuilder.Object, _basePdfBuilder.Object, new Mock<ILogger>().Object);
|
||||
//Act&Assert
|
||||
Assert.That(async () => await _reportContract.GetDataSalaryByPeriodAsync(date, date, CancellationToken.None), Throws.TypeOf<IncorrectDatesException>());
|
||||
Assert.That(async () => await _reportContract.GetDataSalaryByPeriodAsync(date, DateTime.UtcNow.AddDays(-1), CancellationToken.None), Throws.TypeOf<IncorrectDatesException>());
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void GetDataSalaryByPeriod_WhenStorageThrowError_ShouldFail_Test()
|
||||
|
||||
@@ -22,6 +22,8 @@ internal static class TwoFromTheCasketDbContextExtensions
|
||||
dbContext.ExecuteSqlRaw("TRUNCATE \"Services\" CASCADE;");
|
||||
public static void RemoveServiceHistoriesFromDatabase(this TwoFromTheCasketDbContext dbContext) =>
|
||||
dbContext.ExecuteSqlRaw("TRUNCATE \"ServiceHistories\" CASCADE;");
|
||||
public static void RemoveServiceOrdersFromDatabase(this TwoFromTheCasketDbContext dbContext) =>
|
||||
dbContext.ExecuteSqlRaw("TRUNCATE \"ServiceOrders\" CASCADE;");
|
||||
public static Master InsertMasterToDatabaseAndReturn(this TwoFromTheCasketDbContext dbContext, string? id = null, string fio = "test", string? postId = null, DateTime? birthDate = null, DateTime?
|
||||
employmentDate = null, bool isDeleted = false)
|
||||
{
|
||||
@@ -132,4 +134,18 @@ employmentDate = null, bool isDeleted = false)
|
||||
dbContext.SaveChanges();
|
||||
return serviceHistory;
|
||||
}
|
||||
|
||||
public static ServiceOrder InsertServiceOrderToDatabaseAndReturn(this TwoFromTheCasketDbContext dbContext, string orderId, string serviceId, string masterId, int timeOfWorking = 1)
|
||||
{
|
||||
var serviceOrder = new ServiceOrder()
|
||||
{
|
||||
OrderId = orderId,
|
||||
ServiceId = serviceId,
|
||||
MasterId = masterId,
|
||||
TimeOfWorking = timeOfWorking
|
||||
};
|
||||
dbContext.ServiceOrders.Add(serviceOrder);
|
||||
dbContext.SaveChanges();
|
||||
return serviceOrder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using TwoFromTheCasketContratcs.ViewModels;
|
||||
using TwoFromTheCasketContratcs.Enums;
|
||||
using TwoFromTheCasketTest.Infrastructure;
|
||||
using TwoFromTheCasketDatabase.Implementation;
|
||||
using TwoFromTheCasketContratcs.DataModels;
|
||||
using System.Net;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace TwoFromTheCasketTest.WebApiControllersTests;
|
||||
|
||||
@@ -13,43 +16,84 @@ internal class ReportControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
TwoFromTheCasketDbContext.RemoveServiceHistoriesFromDatabase();
|
||||
TwoFromTheCasketDbContext.RemoveServicesFromDatabase();
|
||||
TwoFromTheCasketDbContext.RemoveServiceOrdersFromDatabase();
|
||||
TwoFromTheCasketDbContext.RemoveSalariesFromDatabase();
|
||||
TwoFromTheCasketDbContext.RemoveOrdersFromDatabase();
|
||||
TwoFromTheCasketDbContext.RemoveMastersFromDatabase();
|
||||
TwoFromTheCasketDbContext.RemovePostsFromDatabase();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task GetMasters_WhenHaveRecords_ShouldSuccess_Test()
|
||||
public async Task GetServices_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var post = TwoFromTheCasketDbContext.InsertPostToDatabaseAndReturn();
|
||||
var master1 = TwoFromTheCasketDbContext.InsertMasterToDatabaseAndReturn(fio: "Иванов Иван Иванович", postId: post.PostId);
|
||||
var master2 = TwoFromTheCasketDbContext.InsertMasterToDatabaseAndReturn(fio: "Петров Петр Петрович", postId: post.PostId);
|
||||
var master3 = TwoFromTheCasketDbContext.InsertMasterToDatabaseAndReturn(fio: "Сидоров Сидор Сидорович", postId: post.PostId);
|
||||
|
||||
// Создаем сервисы с уникальными именами
|
||||
var service1 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(id: Guid.NewGuid().ToString(), serviceName: "Service 1", masterId: master1.Id);
|
||||
var service2 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(id: Guid.NewGuid().ToString(), serviceName: "Service 2", masterId: master2.Id);
|
||||
var service3 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(id: Guid.NewGuid().ToString(), serviceName: "Service 3", masterId: master3.Id);
|
||||
|
||||
// Создаем историю сервисов
|
||||
TwoFromTheCasketDbContext.InsertServiceHistoryToDatabaseAndReturn(serviceId: service1.Id);
|
||||
TwoFromTheCasketDbContext.InsertServiceHistoryToDatabaseAndReturn(serviceId: service2.Id);
|
||||
TwoFromTheCasketDbContext.InsertServiceHistoryToDatabaseAndReturn(serviceId: service3.Id);
|
||||
var service1 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
serviceName: "Покраска стен",
|
||||
masterId: master1.Id,
|
||||
serviceType: ServiceType.Painting,
|
||||
price: 800.0);
|
||||
var service2 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
serviceName: "Штукатурка",
|
||||
masterId: master2.Id,
|
||||
serviceType: ServiceType.Plastering,
|
||||
price: 1500.0);
|
||||
|
||||
|
||||
TwoFromTheCasketDbContext.ChangeTracker.Clear();
|
||||
|
||||
|
||||
var serviceDataModel1 = new ServiceDataModel(service1.Id, service1.ServiceName, service1.ServiceType, service1.MasterId, 900.0, service1.IsDeleted);
|
||||
var serviceStorageContract = new ServiceStorageContract(TwoFromTheCasketDbContext);
|
||||
serviceStorageContract.UpdElement(serviceDataModel1);
|
||||
|
||||
TwoFromTheCasketDbContext.ChangeTracker.Clear();
|
||||
|
||||
|
||||
var serviceDataModel2 = new ServiceDataModel(service1.Id, service1.ServiceName, service1.ServiceType, service1.MasterId, 1000.0, service1.IsDeleted);
|
||||
serviceStorageContract.UpdElement(serviceDataModel2);
|
||||
|
||||
|
||||
TwoFromTheCasketDbContext.ChangeTracker.Clear();
|
||||
|
||||
var startDate = DateTime.SpecifyKind(DateTime.UtcNow.AddDays(-30), DateTimeKind.Utc);
|
||||
var endDate = DateTime.SpecifyKind(DateTime.UtcNow.AddDays(1), DateTimeKind.Utc);
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/Report/GetMasters");
|
||||
var response = await HttpClient.GetAsync($"/api/Report/GetServices?fromDate={startDate:yyyy-MM-dd}&toDate={endDate:yyyy-MM-dd}");
|
||||
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<ServiceHistoryViewModel>>(response);
|
||||
var data = await GetModelFromResponseAsync<List<ServiceWithHistoryViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(3));
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
Assert.That(data.Any(s => s.ServiceName == "Покраска стен"), Is.True);
|
||||
Assert.That(data.Any(s => s.ServiceName == "Штукатурка"), Is.True);
|
||||
// Проверяем, что у услуги "Покраска стен" есть история изменений
|
||||
var paintingService = data.First(s => s.ServiceName == "Покраска стен");
|
||||
Assert.That(paintingService.History, Has.Count.GreaterThan(0));
|
||||
Assert.That(paintingService.Price, Is.EqualTo(1000.0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetServices_WhenDateIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/Report/GetServices?fromDate={DateTime.UtcNow.AddDays(1):yyyy-MM-dd}&toDate={DateTime.UtcNow.AddDays(-1):yyyy-MM-dd}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetOrders_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
@@ -118,11 +162,23 @@ internal class ReportControllerTests : BaseWebApiControllerTest
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<MasterSalaryByPeriodViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
Assert.That(data, Has.Count.EqualTo(3));
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data.First(x => x.MasterFIO == master1.FIO).TotalSalary, Is.EqualTo(1000));
|
||||
Assert.That(data.First(x => x.MasterFIO == master2.FIO).TotalSalary, Is.EqualTo(800));
|
||||
|
||||
Assert.That(data.Any(x => x.MasterFIO == master1.FIO), Is.True);
|
||||
Assert.That(data.Any(x => x.MasterFIO == master2.FIO), Is.True);
|
||||
|
||||
|
||||
var master1Salaries = data.Where(x => x.MasterFIO == master1.FIO).ToList();
|
||||
var master2Salaries = data.Where(x => x.MasterFIO == master2.FIO).ToList();
|
||||
|
||||
Assert.That(master1Salaries.Count, Is.EqualTo(1));
|
||||
Assert.That(master2Salaries.Count, Is.EqualTo(2));
|
||||
|
||||
Assert.That(master1Salaries.First().TotalSalary, Is.EqualTo(1000));
|
||||
Assert.That(master2Salaries.Any(x => x.TotalSalary == 500), Is.True);
|
||||
Assert.That(master2Salaries.Any(x => x.TotalSalary == 300), Is.True);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -136,16 +192,57 @@ internal class ReportControllerTests : BaseWebApiControllerTest
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task LoadMasters_WhenHaveRecords_ShouldSuccess_Test()
|
||||
public async Task LoadServices_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
// Arrange
|
||||
var post = TwoFromTheCasketDbContext.InsertPostToDatabaseAndReturn();
|
||||
var master1 = TwoFromTheCasketDbContext.InsertMasterToDatabaseAndReturn(fio: "Иванов Иван Иванович", postId: post.PostId);
|
||||
var master2 = TwoFromTheCasketDbContext.InsertMasterToDatabaseAndReturn(fio: "Петров Петр Петрович", postId: post.PostId);
|
||||
|
||||
// Создаем сервис с начальной ценой
|
||||
var service1 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
serviceName: "Покраска стен",
|
||||
masterId: master1.Id,
|
||||
serviceType: ServiceType.Painting,
|
||||
price: 800.0);
|
||||
var service2 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
serviceName: "Штукатурка",
|
||||
masterId: master2.Id,
|
||||
serviceType: ServiceType.Plastering,
|
||||
price: 1500.0);
|
||||
|
||||
|
||||
TwoFromTheCasketDbContext.ChangeTracker.Clear();
|
||||
|
||||
|
||||
var serviceDataModel1 = new ServiceDataModel(service1.Id, service1.ServiceName, service1.ServiceType, service1.MasterId, 900.0, service1.IsDeleted);
|
||||
var serviceStorageContract = new ServiceStorageContract(TwoFromTheCasketDbContext);
|
||||
serviceStorageContract.UpdElement(serviceDataModel1);
|
||||
|
||||
|
||||
TwoFromTheCasketDbContext.ChangeTracker.Clear();
|
||||
|
||||
|
||||
|
||||
var startDate = DateTime.SpecifyKind(DateTime.UtcNow.AddDays(-30), DateTimeKind.Utc);
|
||||
var endDate = DateTime.SpecifyKind(DateTime.UtcNow.AddDays(1), DateTimeKind.Utc);
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/Report/LoadMasters?fromDate={DateTime.UtcNow.AddDays(-1):yyyy-MM-dd}&toDate={DateTime.UtcNow.AddDays(1):yyyy-MM-dd}");
|
||||
var response = await HttpClient.GetAsync($"/api/Report/LoadServices?fromDate={startDate:yyyy-MM-dd}&toDate={endDate:yyyy-MM-dd}");
|
||||
|
||||
//Assert
|
||||
await AssertStreamAsync(response, "masters.docx");
|
||||
await AssertStreamAsync(response, "services_with_history.docx");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task LoadServices_WhenDateIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/Report/LoadServices?fromDate={DateTime.UtcNow.AddDays(1):yyyy-MM-dd}&toDate={DateTime.UtcNow.AddDays(-1):yyyy-MM-dd}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -156,8 +253,69 @@ internal class ReportControllerTests : BaseWebApiControllerTest
|
||||
var today = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc);
|
||||
var tomorrow = DateTime.SpecifyKind(DateTime.UtcNow.AddDays(1), DateTimeKind.Utc);
|
||||
|
||||
TwoFromTheCasketDbContext.InsertOrderToDatabaseAndReturn(id: Guid.NewGuid().ToString(), date: yesterday);
|
||||
TwoFromTheCasketDbContext.InsertOrderToDatabaseAndReturn(id: Guid.NewGuid().ToString(), date: today);
|
||||
|
||||
var post1 = TwoFromTheCasketDbContext.InsertPostToDatabaseAndReturn();
|
||||
var post2 = TwoFromTheCasketDbContext.InsertPostToDatabaseAndReturn();
|
||||
var master1 = TwoFromTheCasketDbContext.InsertMasterToDatabaseAndReturn(fio: "Иванов Иван Иванович", postId: post1.PostId);
|
||||
var master2 = TwoFromTheCasketDbContext.InsertMasterToDatabaseAndReturn(fio: "Петров Петр Петрович", postId: post2.PostId);
|
||||
|
||||
|
||||
var service1 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
serviceName: "Покраска стен",
|
||||
masterId: master1.Id,
|
||||
serviceType: ServiceType.Painting,
|
||||
price: 800.0);
|
||||
var service2 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
serviceName: "Штукатурка",
|
||||
masterId: master2.Id,
|
||||
serviceType: ServiceType.Plastering,
|
||||
price: 1500.0);
|
||||
var service3 = TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
serviceName: "Укладка плитки",
|
||||
masterId: master1.Id,
|
||||
serviceType: ServiceType.Carpentry,
|
||||
price: 2000.0);
|
||||
|
||||
|
||||
var order1 = TwoFromTheCasketDbContext.InsertOrderToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
date: yesterday,
|
||||
status: StatusType.InProcess,
|
||||
roomType: RoomType.Residential);
|
||||
var order2 = TwoFromTheCasketDbContext.InsertOrderToDatabaseAndReturn(
|
||||
id: Guid.NewGuid().ToString(),
|
||||
date: today,
|
||||
status: StatusType.InProcess,
|
||||
roomType: RoomType.Industrial);
|
||||
|
||||
|
||||
TwoFromTheCasketDbContext.InsertServiceOrderToDatabaseAndReturn(
|
||||
orderId: order1.Id,
|
||||
serviceId: service1.Id,
|
||||
masterId: master1.Id,
|
||||
timeOfWorking: 4);
|
||||
|
||||
TwoFromTheCasketDbContext.InsertServiceOrderToDatabaseAndReturn(
|
||||
orderId: order1.Id,
|
||||
serviceId: service2.Id,
|
||||
masterId: master2.Id,
|
||||
timeOfWorking: 6);
|
||||
|
||||
TwoFromTheCasketDbContext.InsertServiceOrderToDatabaseAndReturn(
|
||||
orderId: order2.Id,
|
||||
serviceId: service3.Id,
|
||||
masterId: master1.Id,
|
||||
timeOfWorking: 8);
|
||||
|
||||
TwoFromTheCasketDbContext.InsertServiceOrderToDatabaseAndReturn(
|
||||
orderId: order2.Id,
|
||||
serviceId: service1.Id,
|
||||
masterId: master1.Id,
|
||||
timeOfWorking: 3);
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/Report/LoadOrders?fromDate={yesterday:yyyy-MM-dd}&toDate={tomorrow:yyyy-MM-dd}");
|
||||
//Assert
|
||||
@@ -206,6 +364,9 @@ internal class ReportControllerTests : BaseWebApiControllerTest
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static async Task AssertStreamAsync(HttpResponseMessage response, string fileNameForSave = "")
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
@@ -224,7 +385,23 @@ internal class ReportControllerTests : BaseWebApiControllerTest
|
||||
var path = Path.Combine(Directory.GetCurrentDirectory(), fileName);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
try
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
||||
await Task.Delay(100);
|
||||
try
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
stream.Position = 0;
|
||||
using var fileStream = new FileStream(path, FileMode.OpenOrCreate);
|
||||
|
||||
@@ -25,6 +25,7 @@ public class ReportAdapter : IReportAdapter
|
||||
cfg.CreateMap<ServiceHistoryDataModel, ServiceHistoryViewModel>();
|
||||
cfg.CreateMap<OrderDataModel, OrderViewModel>();
|
||||
cfg.CreateMap<MasterSalaryByPeriodDataModel, MasterSalaryByPeriodViewModel>();
|
||||
cfg.CreateMap<ServiceWithHistoryDataModel, ServiceWithHistoryViewModel>();
|
||||
});
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
@@ -57,30 +58,6 @@ public class ReportAdapter : IReportAdapter
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> CreateDocumentMastersWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stream = await _reportContract.CreateDocumentServicesWithHistoryAsync(dateStart, dateFinish, ct);
|
||||
return SendStream(stream, "service_history.docx");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception");
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
@@ -139,30 +116,6 @@ public class ReportAdapter : IReportAdapter
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> GetDataMastersWithHistoryAsync(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var histories = await _reportContract.GetDataServiceHistoryAsync(ct);
|
||||
return ReportOperationResponse.OK(histories.Select(x => _mapper.Map<ServiceHistoryViewModel>(x)).ToList());
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception");
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
@@ -192,6 +145,65 @@ public class ReportAdapter : IReportAdapter
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> GetDataServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _reportContract.GetDataServicesWithHistoryAsync(dateStart, dateFinish, ct);
|
||||
var viewModels = data.Select(x => _mapper.Map<ServiceWithHistoryViewModel>(x)).ToList();
|
||||
return ReportOperationResponse.OK(viewModels);
|
||||
}
|
||||
catch (IncorrectDatesException ex)
|
||||
{
|
||||
_logger.LogError(ex, "IncorrectDatesException in GetDataServicesWithHistoryAsync");
|
||||
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException in GetDataServicesWithHistoryAsync: {message}", ex.Message);
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException in GetDataServicesWithHistoryAsync: {message}", ex.Message);
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception in GetDataServicesWithHistoryAsync: {message}", ex.Message);
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> CreateDocumentServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stream = await _reportContract.CreateDocumentServicesWithHistoryAsync(dateStart, dateFinish, ct);
|
||||
return SendStream(stream, "services_with_history.docx");
|
||||
}
|
||||
catch (IncorrectDatesException ex)
|
||||
{
|
||||
_logger.LogError(ex, "IncorrectDatesException in CreateDocumentServicesWithHistoryAsync");
|
||||
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException in CreateDocumentServicesWithHistoryAsync: {message}", ex.Message);
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException in CreateDocumentServicesWithHistoryAsync: {message}", ex.Message);
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception in CreateDocumentServicesWithHistoryAsync: {message}", ex.Message);
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static ReportOperationResponse SendStream(Stream stream, string fileName)
|
||||
{
|
||||
stream.Position = 0;
|
||||
|
||||
@@ -13,9 +13,11 @@ public class ReportController(IReportAdapter adapter) : ControllerBase
|
||||
|
||||
[HttpGet]
|
||||
[Consumes("application/json")]
|
||||
public async Task<IActionResult> GetMasters(CancellationToken ct)
|
||||
public async Task<IActionResult> GetServices(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
|
||||
{
|
||||
return (await _adapter.GetDataMastersWithHistoryAsync(ct)).GetResponse(Request, Response);
|
||||
var utcFromDate = DateTime.SpecifyKind(fromDate, DateTimeKind.Utc);
|
||||
var utcToDate = DateTime.SpecifyKind(toDate, DateTimeKind.Utc);
|
||||
return (await _adapter.GetDataServicesWithHistoryAsync(utcFromDate, utcToDate, cancellationToken)).GetResponse(Request, Response);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -38,11 +40,11 @@ public class ReportController(IReportAdapter adapter) : ControllerBase
|
||||
|
||||
[HttpGet]
|
||||
[Consumes("application/octet-stream")]
|
||||
public async Task<IActionResult> LoadMasters(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
|
||||
public async Task<IActionResult> LoadServices(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
|
||||
{
|
||||
var utcFromDate = DateTime.SpecifyKind(fromDate, DateTimeKind.Utc);
|
||||
var utcToDate = DateTime.SpecifyKind(toDate, DateTimeKind.Utc);
|
||||
return (await _adapter.CreateDocumentMastersWithHistoryAsync(utcFromDate, utcToDate, cancellationToken)).GetResponse(Request, Response);
|
||||
return (await _adapter.CreateDocumentServicesWithHistoryAsync(utcFromDate, utcToDate, cancellationToken)).GetResponse(Request, Response);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
||||
Reference in New Issue
Block a user