feat: Implement a comprehensive custom fields system with backend management and frontend rendering capabilities.

This commit is contained in:
2025-11-29 17:53:34 +01:00
parent 71071f42dc
commit 5a8740269b
19 changed files with 4881 additions and 38 deletions

View File

@@ -0,0 +1,153 @@
using Apollinare.API.Services;
using Apollinare.Domain.Entities;
using Apollinare.Domain.Enums;
using Microsoft.AspNetCore.Mvc;
namespace Apollinare.API.Controllers;
[ApiController]
[Route("api/custom-fields")]
public class CustomFieldDefinitionsController : ControllerBase
{
private readonly CustomFieldService _service;
private readonly ILogger<CustomFieldDefinitionsController> _logger;
public CustomFieldDefinitionsController(CustomFieldService service, ILogger<CustomFieldDefinitionsController> logger)
{
_service = service;
_logger = logger;
}
[HttpGet]
public async Task<ActionResult<List<CustomFieldDefinitionDto>>> GetAll()
{
var defs = await _service.GetAllDefinitionsAsync();
return Ok(defs.Select(ToDto).ToList());
}
[HttpGet("entity/{entityName}")]
public async Task<ActionResult<List<CustomFieldDefinitionDto>>> GetByEntity(string entityName)
{
var defs = await _service.GetDefinitionsByEntityAsync(entityName);
return Ok(defs.Select(ToDto).ToList());
}
[HttpGet("{id:int}")]
public async Task<ActionResult<CustomFieldDefinitionDto>> Get(int id)
{
var def = await _service.GetDefinitionAsync(id);
if (def == null) return NotFound();
return Ok(ToDto(def));
}
[HttpPost]
public async Task<ActionResult<CustomFieldDefinitionDto>> Create(CustomFieldDefinitionDto dto)
{
try
{
var entity = new CustomFieldDefinition
{
EntityName = dto.EntityName,
FieldName = dto.FieldName,
Label = dto.Label,
Type = dto.Type,
IsRequired = dto.IsRequired,
DefaultValue = dto.DefaultValue,
OptionsJson = dto.OptionsJson,
SortOrder = dto.SortOrder,
Description = dto.Description,
IsActive = dto.IsActive,
ValidationRegex = dto.ValidationRegex,
Placeholder = dto.Placeholder
};
var created = await _service.CreateDefinitionAsync(entity);
return CreatedAtAction(nameof(Get), new { id = created.Id }, ToDto(created));
}
catch (ArgumentException ex)
{
return BadRequest(new { error = ex.Message });
}
}
[HttpPut("{id:int}")]
public async Task<ActionResult<CustomFieldDefinitionDto>> Update(int id, CustomFieldDefinitionDto dto)
{
try
{
var entity = new CustomFieldDefinition
{
EntityName = dto.EntityName,
FieldName = dto.FieldName,
Label = dto.Label,
Type = dto.Type,
IsRequired = dto.IsRequired,
DefaultValue = dto.DefaultValue,
OptionsJson = dto.OptionsJson,
SortOrder = dto.SortOrder,
Description = dto.Description,
IsActive = dto.IsActive,
ValidationRegex = dto.ValidationRegex,
Placeholder = dto.Placeholder
};
var updated = await _service.UpdateDefinitionAsync(id, entity);
return Ok(ToDto(updated));
}
catch (KeyNotFoundException)
{
return NotFound();
}
}
[HttpDelete("{id:int}")]
public async Task<ActionResult> Delete(int id)
{
try
{
await _service.DeleteDefinitionAsync(id);
return NoContent();
}
catch (KeyNotFoundException)
{
return NotFound();
}
}
private static CustomFieldDefinitionDto ToDto(CustomFieldDefinition entity)
{
return new CustomFieldDefinitionDto
{
Id = entity.Id,
EntityName = entity.EntityName,
FieldName = entity.FieldName,
Label = entity.Label,
Type = entity.Type,
IsRequired = entity.IsRequired,
DefaultValue = entity.DefaultValue,
OptionsJson = entity.OptionsJson,
SortOrder = entity.SortOrder,
Description = entity.Description,
IsActive = entity.IsActive,
ValidationRegex = entity.ValidationRegex,
Placeholder = entity.Placeholder
};
}
}
public class CustomFieldDefinitionDto
{
public int Id { get; set; }
public required string EntityName { get; set; }
public required string FieldName { get; set; }
public required string Label { get; set; }
public CustomFieldType Type { get; set; }
public bool IsRequired { get; set; }
public string? DefaultValue { get; set; }
public string? OptionsJson { get; set; }
public int SortOrder { get; set; }
public string? Description { get; set; }
public bool IsActive { get; set; }
public string? ValidationRegex { get; set; }
public string? Placeholder { get; set; }
}

View File

@@ -1,5 +1,6 @@
using Apollinare.API.Hubs;
using Apollinare.API.Services;
// Trigger rebuild
using Apollinare.API.Services.Reports;
using Apollinare.API.Modules.Warehouse.Services;
using Apollinare.Infrastructure.Data;
@@ -20,6 +21,7 @@ builder.Services.AddScoped<DemoDataService>();
builder.Services.AddScoped<ReportGeneratorService>();
builder.Services.AddScoped<ModuleService>();
builder.Services.AddScoped<AutoCodeService>();
builder.Services.AddScoped<CustomFieldService>();
builder.Services.AddSingleton<DataNotificationService>();
// Warehouse Module Services

View File

@@ -0,0 +1,91 @@
using Apollinare.Domain.Entities;
using Apollinare.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
namespace Apollinare.API.Services;
public class CustomFieldService
{
private readonly AppollinareDbContext _context;
private readonly ILogger<CustomFieldService> _logger;
public CustomFieldService(AppollinareDbContext context, ILogger<CustomFieldService> logger)
{
_context = context;
_logger = logger;
}
public async Task<List<CustomFieldDefinition>> GetAllDefinitionsAsync()
{
return await _context.CustomFieldDefinitions
.OrderBy(x => x.EntityName)
.ThenBy(x => x.SortOrder)
.ToListAsync();
}
public async Task<List<CustomFieldDefinition>> GetDefinitionsByEntityAsync(string entityName)
{
return await _context.CustomFieldDefinitions
.Where(x => x.EntityName == entityName && x.IsActive)
.OrderBy(x => x.SortOrder)
.ToListAsync();
}
public async Task<CustomFieldDefinition?> GetDefinitionAsync(int id)
{
return await _context.CustomFieldDefinitions.FindAsync(id);
}
public async Task<CustomFieldDefinition> CreateDefinitionAsync(CustomFieldDefinition definition)
{
// Check for duplicate field name in the same entity
var exists = await _context.CustomFieldDefinitions
.AnyAsync(x => x.EntityName == definition.EntityName && x.FieldName == definition.FieldName);
if (exists)
{
throw new ArgumentException($"Field '{definition.FieldName}' already exists for entity '{definition.EntityName}'");
}
definition.CreatedAt = DateTime.UtcNow;
_context.CustomFieldDefinitions.Add(definition);
await _context.SaveChangesAsync();
return definition;
}
public async Task<CustomFieldDefinition> UpdateDefinitionAsync(int id, CustomFieldDefinition updatedDef)
{
var existing = await _context.CustomFieldDefinitions.FindAsync(id);
if (existing == null)
{
throw new KeyNotFoundException($"CustomFieldDefinition with ID {id} not found");
}
existing.Label = updatedDef.Label;
existing.Type = updatedDef.Type;
existing.IsRequired = updatedDef.IsRequired;
existing.DefaultValue = updatedDef.DefaultValue;
existing.OptionsJson = updatedDef.OptionsJson;
existing.SortOrder = updatedDef.SortOrder;
existing.Description = updatedDef.Description;
existing.IsActive = updatedDef.IsActive;
existing.ValidationRegex = updatedDef.ValidationRegex;
existing.Placeholder = updatedDef.Placeholder;
existing.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
return existing;
}
public async Task DeleteDefinitionAsync(int id)
{
var existing = await _context.CustomFieldDefinitions.FindAsync(id);
if (existing == null)
{
throw new KeyNotFoundException($"CustomFieldDefinition with ID {id} not found");
}
_context.CustomFieldDefinitions.Remove(existing);
await _context.SaveChangesAsync();
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -7,4 +7,9 @@ public abstract class BaseEntity
public string? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public string? UpdatedBy { get; set; }
/// <summary>
/// Stores custom field values as JSON: {"birthday": "2023-01-01", "vip_status": "gold"}
/// </summary>
public string? CustomFieldsJson { get; set; }
}

View File

@@ -0,0 +1,19 @@
using Apollinare.Domain.Enums;
namespace Apollinare.Domain.Entities;
public class CustomFieldDefinition : BaseEntity
{
public required string EntityName { get; set; } // e.g. "Cliente", "WarehouseArticle"
public required string FieldName { get; set; } // Internal name, e.g. "birthday"
public required string Label { get; set; } // Display name, e.g. "Birthday"
public CustomFieldType Type { get; set; }
public bool IsRequired { get; set; }
public string? DefaultValue { get; set; }
public string? OptionsJson { get; set; } // For Select/MultiSelect: ["Option A", "Option B"]
public int SortOrder { get; set; }
public string? Description { get; set; }
public bool IsActive { get; set; } = true;
public string? ValidationRegex { get; set; }
public string? Placeholder { get; set; }
}

View File

@@ -0,0 +1,15 @@
namespace Apollinare.Domain.Enums;
public enum CustomFieldType
{
Text = 0,
Number = 1,
Date = 2,
Boolean = 3,
Select = 4,
MultiSelect = 5,
TextArea = 6,
Color = 7,
Url = 8,
Email = 9
}

View File

@@ -44,6 +44,9 @@ public class AppollinareDbContext : DbContext
// Auto Code system
public DbSet<AutoCode> AutoCodes => Set<AutoCode>();
// Custom Fields system
public DbSet<CustomFieldDefinition> CustomFieldDefinitions => Set<CustomFieldDefinition>();
// Warehouse module entities
public DbSet<WarehouseLocation> WarehouseLocations => Set<WarehouseLocation>();
public DbSet<WarehouseArticle> WarehouseArticles => Set<WarehouseArticle>();
@@ -284,6 +287,13 @@ public class AppollinareDbContext : DbContext
entity.HasIndex(e => e.ModuleCode);
});
// CustomFieldDefinition
modelBuilder.Entity<CustomFieldDefinition>(entity =>
{
entity.HasIndex(e => new { e.EntityName, e.FieldName }).IsUnique();
entity.HasIndex(e => e.EntityName);
});
// ===============================================
// WAREHOUSE MODULE ENTITIES
// ===============================================

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,472 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Apollinare.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class AddCustomFieldsSystem : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "WarehouseLocations",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "WarehouseArticles",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "WarehouseArticleCategories",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "VirtualDatasets",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "Utenti",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "TipiRisorsa",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "TipiPasto",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "TipiOspite",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "TipiMateriale",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "TipiEvento",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "StockValuations",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "StockValuationLayers",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "StockMovements",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "StockMovementLines",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "StockLevels",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "Risorse",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "ReportTemplates",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "ReportImages",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "ReportFonts",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "MovementReasons",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "ModuleSubscriptions",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "Location",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "InventoryCounts",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "InventoryCountLines",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "EventiDettaglioRisorse",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "EventiDettaglioPrelievo",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "EventiDettaglioOspiti",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "EventiDegustazioni",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "EventiAltriCosti",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "EventiAllegati",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "EventiAcconti",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "Eventi",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "Configurazioni",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "CodiciCategoria",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "Clienti",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "AutoCodes",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "Articoli",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "ArticleSerials",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "ArticleBatches",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "ArticleBarcodes",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CustomFieldsJson",
table: "AppModules",
type: "TEXT",
nullable: true);
migrationBuilder.CreateTable(
name: "CustomFieldDefinitions",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
EntityName = table.Column<string>(type: "TEXT", nullable: false),
FieldName = table.Column<string>(type: "TEXT", nullable: false),
Label = table.Column<string>(type: "TEXT", nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false),
IsRequired = table.Column<bool>(type: "INTEGER", nullable: false),
DefaultValue = table.Column<string>(type: "TEXT", nullable: true),
OptionsJson = table.Column<string>(type: "TEXT", nullable: true),
SortOrder = table.Column<int>(type: "INTEGER", nullable: false),
Description = table.Column<string>(type: "TEXT", nullable: true),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
ValidationRegex = table.Column<string>(type: "TEXT", nullable: true),
Placeholder = table.Column<string>(type: "TEXT", nullable: true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
CreatedBy = table.Column<string>(type: "TEXT", nullable: true),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
UpdatedBy = table.Column<string>(type: "TEXT", nullable: true),
CustomFieldsJson = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_CustomFieldDefinitions", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_CustomFieldDefinitions_EntityName",
table: "CustomFieldDefinitions",
column: "EntityName");
migrationBuilder.CreateIndex(
name: "IX_CustomFieldDefinitions_EntityName_FieldName",
table: "CustomFieldDefinitions",
columns: new[] { "EntityName", "FieldName" },
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "CustomFieldDefinitions");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "WarehouseLocations");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "WarehouseArticles");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "WarehouseArticleCategories");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "VirtualDatasets");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "Utenti");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "TipiRisorsa");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "TipiPasto");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "TipiOspite");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "TipiMateriale");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "TipiEvento");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "StockValuations");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "StockValuationLayers");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "StockMovements");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "StockMovementLines");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "StockLevels");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "Risorse");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "ReportTemplates");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "ReportImages");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "ReportFonts");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "MovementReasons");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "ModuleSubscriptions");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "Location");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "InventoryCounts");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "InventoryCountLines");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "EventiDettaglioRisorse");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "EventiDettaglioPrelievo");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "EventiDettaglioOspiti");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "EventiDegustazioni");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "EventiAltriCosti");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "EventiAllegati");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "EventiAcconti");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "Eventi");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "Configurazioni");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "CodiciCategoria");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "Clienti");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "AutoCodes");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "Articoli");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "ArticleSerials");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "ArticleBatches");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "ArticleBarcodes");
migrationBuilder.DropColumn(
name: "CustomFieldsJson",
table: "AppModules");
}
}
}

View File

@@ -37,6 +37,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Dependencies")
.HasColumnType("TEXT");
@@ -107,6 +110,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("TEXT");
@@ -168,6 +174,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
@@ -263,6 +272,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasColumnType("TEXT");
@@ -331,6 +343,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("TEXT");
@@ -362,6 +377,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.HasColumnType("TEXT");
@@ -382,6 +400,76 @@ namespace Apollinare.Infrastructure.Migrations
b.ToTable("Configurazioni");
});
modelBuilder.Entity("Apollinare.Domain.Entities.CustomFieldDefinition", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime?>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("DefaultValue")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
b.Property<string>("EntityName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("FieldName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsActive")
.HasColumnType("INTEGER");
b.Property<bool>("IsRequired")
.HasColumnType("INTEGER");
b.Property<string>("Label")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OptionsJson")
.HasColumnType("TEXT");
b.Property<string>("Placeholder")
.HasColumnType("TEXT");
b.Property<int>("SortOrder")
.HasColumnType("INTEGER");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("TEXT");
b.Property<string>("UpdatedBy")
.HasColumnType("TEXT");
b.Property<string>("ValidationRegex")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("EntityName");
b.HasIndex("EntityName", "FieldName")
.IsUnique();
b.ToTable("CustomFieldDefinitions");
});
modelBuilder.Entity("Apollinare.Domain.Entities.Evento", b =>
{
b.Property<int>("Id")
@@ -409,6 +497,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<DateTime>("DataEvento")
.HasColumnType("TEXT");
@@ -504,6 +595,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<DateTime?>("DataPagamento")
.HasColumnType("TEXT");
@@ -553,6 +647,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<int>("EventoId")
.HasColumnType("INTEGER");
@@ -600,6 +697,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("TEXT");
@@ -644,6 +744,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<DateTime>("DataDegustazione")
.HasColumnType("TEXT");
@@ -699,6 +802,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<int>("EventoId")
.HasColumnType("INTEGER");
@@ -747,6 +853,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<int>("EventoId")
.HasColumnType("INTEGER");
@@ -792,6 +901,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<int>("EventoId")
.HasColumnType("INTEGER");
@@ -849,6 +961,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<decimal?>("DistanzaKm")
.HasColumnType("TEXT");
@@ -902,6 +1017,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<DateTime?>("EndDate")
.HasColumnType("TEXT");
@@ -956,6 +1074,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<long>("FileSize")
.HasColumnType("INTEGER");
@@ -1011,6 +1132,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<long>("FileSize")
.HasColumnType("INTEGER");
@@ -1064,6 +1188,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.HasColumnType("TEXT");
@@ -1122,6 +1249,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasColumnType("TEXT");
@@ -1170,6 +1300,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("TEXT");
@@ -1209,6 +1342,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("TEXT");
@@ -1243,6 +1379,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("TEXT");
@@ -1277,6 +1416,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("TEXT");
@@ -1311,6 +1453,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("TEXT");
@@ -1344,6 +1489,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasColumnType("TEXT");
@@ -1397,6 +1545,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Descrizione")
.HasColumnType("TEXT");
@@ -1447,6 +1598,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
@@ -1505,6 +1659,9 @@ namespace Apollinare.Infrastructure.Migrations
.HasPrecision(18, 4)
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<DateTime?>("ExpiryDate")
.HasColumnType("TEXT");
@@ -1583,6 +1740,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<int?>("CurrentWarehouseId")
.HasColumnType("INTEGER");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<int?>("CustomerId")
.HasColumnType("INTEGER");
@@ -1666,6 +1826,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
@@ -1751,6 +1914,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<int>("InventoryCountId")
.HasColumnType("INTEGER");
@@ -1814,6 +1980,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
@@ -1881,6 +2050,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<DateTime?>("LastInventoryDate")
.HasColumnType("TEXT");
@@ -1951,6 +2123,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<int?>("CustomerId")
.HasColumnType("INTEGER");
@@ -2038,6 +2213,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("DestinationLocationCode")
.HasColumnType("TEXT");
@@ -2116,6 +2294,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<decimal>("InboundQuantity")
.HasPrecision(18, 4)
.HasColumnType("TEXT");
@@ -2202,6 +2383,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<bool>("IsExhausted")
.HasColumnType("INTEGER");
@@ -2276,6 +2460,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<decimal?>("Depth")
.HasColumnType("TEXT");
@@ -2417,6 +2604,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<int?>("DefaultValuationMethod")
.HasColumnType("INTEGER");
@@ -2494,6 +2684,9 @@ namespace Apollinare.Infrastructure.Migrations
b.Property<string>("CreatedBy")
.HasColumnType("TEXT");
b.Property<string>("CustomFieldsJson")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");