diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index bb7c2cb..4c9de96 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -20,6 +20,7 @@ import ReportEditorPage from "./pages/ReportEditorPage"; import ModulesAdminPage from "./pages/ModulesAdminPage"; import ModulePurchasePage from "./pages/ModulePurchasePage"; import AutoCodesAdminPage from "./pages/AutoCodesAdminPage"; +import CustomFieldsAdminPage from "./pages/CustomFieldsAdminPage"; import WarehouseRoutes from "./modules/warehouse/routes"; import { ModuleGuard } from "./components/ModuleGuard"; import { useRealTimeUpdates } from "./hooks/useRealTimeUpdates"; @@ -101,6 +102,10 @@ function App() { path="admin/auto-codes" element={} /> + } + /> {/* Warehouse Module */} void; + readOnly?: boolean; +} + +export const CustomFieldsRenderer: React.FC = ({ entityName, values, onChange, readOnly = false }) => { + const [definitions, setDefinitions] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const loadDefinitions = async () => { + try { + const defs = await customFieldService.getByEntity(entityName); + setDefinitions(defs); + } catch (error) { + console.error("Failed to load custom fields", error); + } finally { + setLoading(false); + } + }; + loadDefinitions(); + }, [entityName]); + + if (loading) return null; + if (definitions.length === 0) return null; + + return ( + + + Campi Personalizzati + + + {definitions.map(def => ( + + onChange(def.fieldName, val)} + readOnly={readOnly} + /> + + ))} + + + ); +}; + +const FieldRenderer: React.FC<{ + definition: CustomFieldDefinition; + value: any; + onChange: (value: any) => void; + readOnly: boolean; +}> = ({ definition, value, onChange, readOnly }) => { + + const handleChange = (e: React.ChangeEvent) => { + onChange(e.target.value); + }; + + switch (definition.type) { + case CustomFieldType.Text: + case CustomFieldType.Email: + case CustomFieldType.Url: + return ( + + ); + + case CustomFieldType.Number: + return ( + + ); + + case CustomFieldType.TextArea: + return ( + + ); + + case CustomFieldType.Boolean: + return ( + onChange(e.target.checked)} + disabled={readOnly} + /> + } + label={definition.label} + /> + ); + + case CustomFieldType.Date: + return ( + onChange(newValue ? newValue.toISOString() : null)} + disabled={readOnly} + slotProps={{ textField: { fullWidth: true, required: definition.isRequired, helperText: definition.description, size: 'small' } }} + /> + ); + + case CustomFieldType.Select: + let options: string[] = []; + try { + options = definition.optionsJson ? JSON.parse(definition.optionsJson) : []; + } catch (e) { + console.error("Invalid options JSON", e); + } + return ( + + {options.map((opt) => ( + + {opt} + + ))} + + ); + + case CustomFieldType.Color: + return ( + + ); + + default: + return null; + } +}; diff --git a/frontend/src/pages/ClientiPage.tsx b/frontend/src/pages/ClientiPage.tsx index 0f9e92f..19a26de 100644 --- a/frontend/src/pages/ClientiPage.tsx +++ b/frontend/src/pages/ClientiPage.tsx @@ -11,7 +11,7 @@ import { DialogContent, DialogActions, TextField, - Grid, + } from "@mui/material"; import { DataGrid, GridColDef } from "@mui/x-data-grid"; import { @@ -21,12 +21,15 @@ import { } from "@mui/icons-material"; import { clientiService } from "../services/lookupService"; import { Cliente } from "../types"; +import { CustomFieldsRenderer } from "../components/customFields/CustomFieldsRenderer"; +import { CustomFieldValues } from "../types/customFields"; export default function ClientiPage() { const queryClient = useQueryClient(); const [openDialog, setOpenDialog] = useState(false); const [editingId, setEditingId] = useState(null); const [formData, setFormData] = useState>({ attivo: true }); + const [customFields, setCustomFields] = useState({}); const { data: clienti = [], isLoading } = useQuery({ queryKey: ["clienti"], @@ -59,22 +62,33 @@ export default function ClientiPage() { setOpenDialog(false); setEditingId(null); setFormData({ attivo: true }); + setCustomFields({}); }; const handleEdit = (cliente: Cliente) => { setFormData(cliente); setEditingId(cliente.id); + try { + setCustomFields(cliente.customFieldsJson ? JSON.parse(cliente.customFieldsJson) : {}); + } catch (e) { + setCustomFields({}); + } setOpenDialog(true); }; const handleSubmit = () => { + const dataWithCustomFields = { + ...formData, + customFieldsJson: JSON.stringify(customFields) + }; + if (editingId) { // In modifica, non inviamo il codice (non modificabile) - const { codice: _codice, ...updateData } = formData; + const { codice: _codice, ...updateData } = dataWithCustomFields; updateMutation.mutate({ id: editingId, data: updateData }); } else { // In creazione, non inviamo il codice (generato automaticamente) - const { codice: _codice, ...createData } = formData; + const { codice: _codice, ...createData } = dataWithCustomFields; createMutation.mutate(createData); } }; @@ -162,8 +176,8 @@ export default function ClientiPage() { {editingId ? "Modifica Cliente" : "Nuovo Cliente"} - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + setCustomFields(prev => ({ ...prev, [field]: value }))} + /> + + diff --git a/frontend/src/pages/CustomFieldsAdminPage.tsx b/frontend/src/pages/CustomFieldsAdminPage.tsx new file mode 100644 index 0000000..84f3061 --- /dev/null +++ b/frontend/src/pages/CustomFieldsAdminPage.tsx @@ -0,0 +1,302 @@ + +import React, { useState, useEffect } from 'react'; +import { + Box, + Button, + Card, + CardContent, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + FormControl, + + InputLabel, + MenuItem, + Select, + TextField, + Typography, + FormControlLabel, + Checkbox, + Snackbar, + Alert +} from '@mui/material'; +import { DataGrid, GridColDef, GridActionsCellItem } from '@mui/x-data-grid'; +import { Add as AddIcon, Edit as EditIcon, Delete as DeleteIcon } from '@mui/icons-material'; +import { CustomFieldDefinition, CustomFieldType } from '../types/customFields'; +import { customFieldService } from '../services/customFieldService'; + +const ENTITIES = [ + { value: 'Cliente', label: 'Clienti' }, + { value: 'Articolo', label: 'Articoli (Catering)' }, + { value: 'Evento', label: 'Eventi' }, + { value: 'WarehouseArticle', label: 'Articoli Magazzino' }, + { value: 'WarehouseLocation', label: 'Magazzini' }, + { value: 'Risorsa', label: 'Risorse (Staff)' } +]; + +const FIELD_TYPES = [ + { value: CustomFieldType.Text, label: 'Testo' }, + { value: CustomFieldType.Number, label: 'Numero' }, + { value: CustomFieldType.Date, label: 'Data' }, + { value: CustomFieldType.Boolean, label: 'Booleano (Sì/No)' }, + { value: CustomFieldType.Select, label: 'Lista a discesa' }, + { value: CustomFieldType.TextArea, label: 'Area di testo' }, + { value: CustomFieldType.Color, label: 'Colore' }, + { value: CustomFieldType.Url, label: 'URL' }, + { value: CustomFieldType.Email, label: 'Email' } +]; + +const CustomFieldsAdminPage: React.FC = () => { + const [selectedEntity, setSelectedEntity] = useState(ENTITIES[0].value); + const [fields, setFields] = useState([]); + const [loading, setLoading] = useState(false); + const [dialogOpen, setDialogOpen] = useState(false); + const [currentField, setCurrentField] = useState>({}); + const [snackbar, setSnackbar] = useState<{ open: boolean, message: string, severity: 'success' | 'error' }>({ + open: false, + message: '', + severity: 'success' + }); + + const showSnackbar = (message: string, severity: 'success' | 'error') => { + setSnackbar({ open: true, message, severity }); + }; + + const handleCloseSnackbar = () => setSnackbar({ ...snackbar, open: false }); + + const loadFields = async () => { + setLoading(true); + try { + const data = await customFieldService.getByEntity(selectedEntity); + setFields(data); + } catch (error) { + showSnackbar('Errore nel caricamento dei campi', 'error'); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + loadFields(); + }, [selectedEntity]); + + const handleSave = async () => { + try { + if (currentField.id) { + await customFieldService.update(currentField.id, currentField as CustomFieldDefinition); + showSnackbar('Campo aggiornato con successo', 'success'); + } else { + await customFieldService.create({ + ...currentField, + entityName: selectedEntity, + isActive: true, + sortOrder: fields.length + 1 + } as CustomFieldDefinition); + showSnackbar('Campo creato con successo', 'success'); + } + setDialogOpen(false); + loadFields(); + } catch (error) { + showSnackbar('Errore nel salvataggio', 'error'); + } + }; + + const handleDelete = async (id: number) => { + if (window.confirm('Sei sicuro di voler eliminare questo campo?')) { + try { + await customFieldService.delete(id); + showSnackbar('Campo eliminato', 'success'); + loadFields(); + } catch (error) { + showSnackbar('Errore durante l\'eliminazione', 'error'); + } + } + }; + + const columns: GridColDef[] = [ + { field: 'label', headerName: 'Etichetta', flex: 1 }, + { field: 'fieldName', headerName: 'Nome Interno', flex: 1 }, + { + field: 'type', + headerName: 'Tipo', + width: 150, + valueFormatter: (params) => FIELD_TYPES.find(t => t.value === params.value)?.label + }, + { + field: 'isRequired', + headerName: 'Obbligatorio', + width: 120, + type: 'boolean' + }, + { + field: 'sortOrder', + headerName: 'Ordine', + width: 100, + type: 'number', + editable: true + }, + { + field: 'actions', + type: 'actions', + headerName: 'Azioni', + width: 100, + getActions: (params) => [ + } + label="Modifica" + onClick={() => { + setCurrentField(params.row); + setDialogOpen(true); + }} + />, + } + label="Elimina" + onClick={() => handleDelete(params.row.id)} + />, + ], + }, + ]; + + return ( + + + Gestione Campi Personalizzati + + + + + + + + Entità + + + + + + + + + + +
+ +
+ + setDialogOpen(false)} maxWidth="sm" fullWidth> + {currentField.id ? 'Modifica Campo' : 'Nuovo Campo'} + + + setCurrentField({ ...currentField, label: e.target.value })} + required + /> + setCurrentField({ ...currentField, fieldName: e.target.value })} + required + helperText="Deve essere univoco per l'entità. Usa solo lettere minuscole e underscore." + disabled={!!currentField.id} + /> + + Tipo + + + + {currentField.type === CustomFieldType.Select && ( + setCurrentField({ ...currentField, optionsJson: e.target.value })} + placeholder='["Opzione 1", "Opzione 2"]' + helperText="Inserisci un array JSON valido di stringhe" + /> + )} + + setCurrentField({ ...currentField, description: e.target.value })} + /> + + setCurrentField({ ...currentField, isRequired: e.target.checked })} + /> + } + label="Obbligatorio" + /> + + setCurrentField({ ...currentField, sortOrder: parseInt(e.target.value) })} + /> + + + + + + + + + + + {snackbar.message} + + +
+ ); +}; + +export default CustomFieldsAdminPage; + diff --git a/frontend/src/services/customFieldService.ts b/frontend/src/services/customFieldService.ts new file mode 100644 index 0000000..3170c3b --- /dev/null +++ b/frontend/src/services/customFieldService.ts @@ -0,0 +1,24 @@ +import api from './api'; +import { CustomFieldDefinition } from '../types/customFields'; + +export const customFieldService = { + getAll: async () => { + const response = await api.get('/custom-fields'); + return response.data; + }, + getByEntity: async (entityName: string) => { + const response = await api.get(`/custom-fields/entity/${entityName}`); + return response.data; + }, + create: async (definition: Omit) => { + const response = await api.post('/custom-fields', definition); + return response.data; + }, + update: async (id: number, definition: CustomFieldDefinition) => { + const response = await api.put(`/custom-fields/${id}`, definition); + return response.data; + }, + delete: async (id: number) => { + await api.delete(`/custom-fields/${id}`); + } +}; diff --git a/frontend/src/types/customFields.ts b/frontend/src/types/customFields.ts new file mode 100644 index 0000000..435dee5 --- /dev/null +++ b/frontend/src/types/customFields.ts @@ -0,0 +1,32 @@ +export enum CustomFieldType { + Text = 0, + Number = 1, + Date = 2, + Boolean = 3, + Select = 4, + MultiSelect = 5, + TextArea = 6, + Color = 7, + Url = 8, + Email = 9 +} + +export interface CustomFieldDefinition { + id: number; + entityName: string; + fieldName: string; + label: string; + type: CustomFieldType; + isRequired: boolean; + defaultValue?: string; + optionsJson?: string; + sortOrder: number; + description?: string; + isActive: boolean; + validationRegex?: string; + placeholder?: string; +} + +export interface CustomFieldValues { + [key: string]: any; +} diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 939c149..c37e6ae 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -10,6 +10,7 @@ export interface BaseEntity { createdBy?: string; updatedAt?: string; updatedBy?: string; + customFieldsJson?: string; } export interface Cliente extends BaseEntity { diff --git a/src/Apollinare.API/Controllers/CustomFieldDefinitionsController.cs b/src/Apollinare.API/Controllers/CustomFieldDefinitionsController.cs new file mode 100644 index 0000000..fbc9420 --- /dev/null +++ b/src/Apollinare.API/Controllers/CustomFieldDefinitionsController.cs @@ -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 _logger; + + public CustomFieldDefinitionsController(CustomFieldService service, ILogger logger) + { + _service = service; + _logger = logger; + } + + [HttpGet] + public async Task>> GetAll() + { + var defs = await _service.GetAllDefinitionsAsync(); + return Ok(defs.Select(ToDto).ToList()); + } + + [HttpGet("entity/{entityName}")] + public async Task>> GetByEntity(string entityName) + { + var defs = await _service.GetDefinitionsByEntityAsync(entityName); + return Ok(defs.Select(ToDto).ToList()); + } + + [HttpGet("{id:int}")] + public async Task> Get(int id) + { + var def = await _service.GetDefinitionAsync(id); + if (def == null) return NotFound(); + return Ok(ToDto(def)); + } + + [HttpPost] + public async Task> 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> 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 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; } +} diff --git a/src/Apollinare.API/Program.cs b/src/Apollinare.API/Program.cs index c6478dd..7fa626d 100644 --- a/src/Apollinare.API/Program.cs +++ b/src/Apollinare.API/Program.cs @@ -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(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddSingleton(); // Warehouse Module Services diff --git a/src/Apollinare.API/Services/CustomFieldService.cs b/src/Apollinare.API/Services/CustomFieldService.cs new file mode 100644 index 0000000..da4767b --- /dev/null +++ b/src/Apollinare.API/Services/CustomFieldService.cs @@ -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 _logger; + + public CustomFieldService(AppollinareDbContext context, ILogger logger) + { + _context = context; + _logger = logger; + } + + public async Task> GetAllDefinitionsAsync() + { + return await _context.CustomFieldDefinitions + .OrderBy(x => x.EntityName) + .ThenBy(x => x.SortOrder) + .ToListAsync(); + } + + public async Task> GetDefinitionsByEntityAsync(string entityName) + { + return await _context.CustomFieldDefinitions + .Where(x => x.EntityName == entityName && x.IsActive) + .OrderBy(x => x.SortOrder) + .ToListAsync(); + } + + public async Task GetDefinitionAsync(int id) + { + return await _context.CustomFieldDefinitions.FindAsync(id); + } + + public async Task 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 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(); + } +} diff --git a/src/Apollinare.API/apollinare.db-shm b/src/Apollinare.API/apollinare.db-shm index fc0c255..99ddfc3 100644 Binary files a/src/Apollinare.API/apollinare.db-shm and b/src/Apollinare.API/apollinare.db-shm differ diff --git a/src/Apollinare.API/apollinare.db-wal b/src/Apollinare.API/apollinare.db-wal index 7a1b575..856b57f 100644 Binary files a/src/Apollinare.API/apollinare.db-wal and b/src/Apollinare.API/apollinare.db-wal differ diff --git a/src/Apollinare.Domain/Entities/BaseEntity.cs b/src/Apollinare.Domain/Entities/BaseEntity.cs index 3e78ada..00a917c 100644 --- a/src/Apollinare.Domain/Entities/BaseEntity.cs +++ b/src/Apollinare.Domain/Entities/BaseEntity.cs @@ -7,4 +7,9 @@ public abstract class BaseEntity public string? CreatedBy { get; set; } public DateTime? UpdatedAt { get; set; } public string? UpdatedBy { get; set; } + + /// + /// Stores custom field values as JSON: {"birthday": "2023-01-01", "vip_status": "gold"} + /// + public string? CustomFieldsJson { get; set; } } diff --git a/src/Apollinare.Domain/Entities/CustomFieldDefinition.cs b/src/Apollinare.Domain/Entities/CustomFieldDefinition.cs new file mode 100644 index 0000000..e2aa4e9 --- /dev/null +++ b/src/Apollinare.Domain/Entities/CustomFieldDefinition.cs @@ -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; } +} diff --git a/src/Apollinare.Domain/Enums/CustomFieldType.cs b/src/Apollinare.Domain/Enums/CustomFieldType.cs new file mode 100644 index 0000000..7db8ea7 --- /dev/null +++ b/src/Apollinare.Domain/Enums/CustomFieldType.cs @@ -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 +} diff --git a/src/Apollinare.Infrastructure/Data/AppollinareDbContext.cs b/src/Apollinare.Infrastructure/Data/AppollinareDbContext.cs index 0c49e4c..c11d2a9 100644 --- a/src/Apollinare.Infrastructure/Data/AppollinareDbContext.cs +++ b/src/Apollinare.Infrastructure/Data/AppollinareDbContext.cs @@ -44,6 +44,9 @@ public class AppollinareDbContext : DbContext // Auto Code system public DbSet AutoCodes => Set(); + // Custom Fields system + public DbSet CustomFieldDefinitions => Set(); + // Warehouse module entities public DbSet WarehouseLocations => Set(); public DbSet WarehouseArticles => Set(); @@ -284,6 +287,13 @@ public class AppollinareDbContext : DbContext entity.HasIndex(e => e.ModuleCode); }); + // CustomFieldDefinition + modelBuilder.Entity(entity => + { + entity.HasIndex(e => new { e.EntityName, e.FieldName }).IsUnique(); + entity.HasIndex(e => e.EntityName); + }); + // =============================================== // WAREHOUSE MODULE ENTITIES // =============================================== diff --git a/src/Apollinare.Infrastructure/Migrations/20251129161359_AddCustomFieldsSystem.Designer.cs b/src/Apollinare.Infrastructure/Migrations/20251129161359_AddCustomFieldsSystem.Designer.cs new file mode 100644 index 0000000..6fc86ed --- /dev/null +++ b/src/Apollinare.Infrastructure/Migrations/20251129161359_AddCustomFieldsSystem.Designer.cs @@ -0,0 +1,3303 @@ +// +using System; +using Apollinare.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Apollinare.Infrastructure.Migrations +{ + [DbContext(typeof(AppollinareDbContext))] + [Migration("20251129161359_AddCustomFieldsSystem")] + partial class AddCustomFieldsSystem + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.0"); + + modelBuilder.Entity("Apollinare.Domain.Entities.AppModule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasePrice") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Dependencies") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Icon") + .HasColumnType("TEXT"); + + b.Property("IsAvailable") + .HasColumnType("INTEGER"); + + b.Property("IsCore") + .HasColumnType("INTEGER"); + + b.Property("MonthlyMultiplier") + .HasPrecision(5, 2) + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RoutePath") + .HasColumnType("TEXT"); + + b.Property("SortOrder") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Code") + .IsUnique(); + + b.HasIndex("SortOrder"); + + b.ToTable("AppModules"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Articolo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("CategoriaId") + .HasColumnType("INTEGER"); + + b.Property("Codice") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CodiceAlternativo") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Immagine") + .HasColumnType("BLOB"); + + b.Property("MimeType") + .HasColumnType("TEXT"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("QtaDisponibile") + .HasColumnType("TEXT"); + + b.Property("QtaStdA") + .HasColumnType("TEXT"); + + b.Property("QtaStdB") + .HasColumnType("TEXT"); + + b.Property("QtaStdS") + .HasColumnType("TEXT"); + + b.Property("TipoMaterialeId") + .HasColumnType("INTEGER"); + + b.Property("UnitaMisura") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CategoriaId"); + + b.HasIndex("Codice") + .IsUnique(); + + b.HasIndex("TipoMaterialeId"); + + b.ToTable("Articoli"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.AutoCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("EntityCode") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("EntityName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsReadOnly") + .HasColumnType("INTEGER"); + + b.Property("LastResetMonth") + .HasColumnType("INTEGER"); + + b.Property("LastResetYear") + .HasColumnType("INTEGER"); + + b.Property("LastSequence") + .HasColumnType("INTEGER"); + + b.Property("ModuleCode") + .HasColumnType("TEXT"); + + b.Property("Pattern") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Prefix") + .HasColumnType("TEXT"); + + b.Property("ResetSequenceMonthly") + .HasColumnType("INTEGER"); + + b.Property("ResetSequenceYearly") + .HasColumnType("INTEGER"); + + b.Property("SortOrder") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EntityCode") + .IsUnique(); + + b.HasIndex("ModuleCode"); + + b.ToTable("AutoCodes"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Cliente", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Cap") + .HasColumnType("TEXT"); + + b.Property("Citta") + .HasColumnType("TEXT"); + + b.Property("Codice") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CodiceAlternativo") + .HasColumnType("TEXT"); + + b.Property("CodiceDestinatario") + .HasColumnType("TEXT"); + + b.Property("CodiceFiscale") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("Indirizzo") + .HasColumnType("TEXT"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("PartitaIva") + .HasColumnType("TEXT"); + + b.Property("Pec") + .HasColumnType("TEXT"); + + b.Property("Provincia") + .HasColumnType("TEXT"); + + b.Property("RagioneSociale") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Telefono") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PartitaIva"); + + b.HasIndex("RagioneSociale"); + + b.ToTable("Clienti"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.CodiceCategoria", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Codice") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CoeffA") + .HasColumnType("TEXT"); + + b.Property("CoeffB") + .HasColumnType("TEXT"); + + b.Property("CoeffS") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("CodiciCategoria"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Configurazione", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Chiave") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("Valore") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Chiave") + .IsUnique(); + + b.ToTable("Configurazioni"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.CustomFieldDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("DefaultValue") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("EntityName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsRequired") + .HasColumnType("INTEGER"); + + b.Property("Label") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OptionsJson") + .HasColumnType("TEXT"); + + b.Property("Placeholder") + .HasColumnType("TEXT"); + + b.Property("SortOrder") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClienteId") + .HasColumnType("INTEGER"); + + b.Property("Codice") + .HasColumnType("TEXT"); + + b.Property("Confermato") + .HasColumnType("INTEGER"); + + b.Property("CostoPersona") + .HasColumnType("TEXT"); + + b.Property("CostoTotale") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("DataEvento") + .HasColumnType("TEXT"); + + b.Property("DataScadenzaPreventivo") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .HasColumnType("TEXT"); + + b.Property("LocationId") + .HasColumnType("INTEGER"); + + b.Property("NoteAllestimento") + .HasColumnType("TEXT"); + + b.Property("NoteCliente") + .HasColumnType("TEXT"); + + b.Property("NoteCucina") + .HasColumnType("TEXT"); + + b.Property("NoteInterne") + .HasColumnType("TEXT"); + + b.Property("NumeroOspiti") + .HasColumnType("INTEGER"); + + b.Property("NumeroOspitiAdulti") + .HasColumnType("INTEGER"); + + b.Property("NumeroOspitiBambini") + .HasColumnType("INTEGER"); + + b.Property("NumeroOspitiBuffet") + .HasColumnType("INTEGER"); + + b.Property("NumeroOspitiSeduti") + .HasColumnType("INTEGER"); + + b.Property("OraFine") + .HasColumnType("TEXT"); + + b.Property("OraInizio") + .HasColumnType("TEXT"); + + b.Property("Saldo") + .HasColumnType("TEXT"); + + b.Property("Stato") + .HasColumnType("INTEGER"); + + b.Property("TipoEventoId") + .HasColumnType("INTEGER"); + + b.Property("TotaleAcconti") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ClienteId"); + + b.HasIndex("Codice"); + + b.HasIndex("DataEvento"); + + b.HasIndex("LocationId"); + + b.HasIndex("Stato"); + + b.HasIndex("TipoEventoId"); + + b.ToTable("Eventi"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoAcconto", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AConferma") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("DataPagamento") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .HasColumnType("TEXT"); + + b.Property("EventoId") + .HasColumnType("INTEGER"); + + b.Property("Importo") + .HasColumnType("TEXT"); + + b.Property("MetodoPagamento") + .HasColumnType("TEXT"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("Ordine") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventoId"); + + b.ToTable("EventiAcconti"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoAllegato", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Contenuto") + .HasColumnType("BLOB"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("EventoId") + .HasColumnType("INTEGER"); + + b.Property("MimeType") + .HasColumnType("TEXT"); + + b.Property("NomeFile") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventoId"); + + b.ToTable("EventiAllegati"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoAltroCosto", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AliquotaIva") + .HasColumnType("TEXT"); + + b.Property("ApplicaIva") + .HasColumnType("INTEGER"); + + b.Property("CostoUnitario") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("EventoId") + .HasColumnType("INTEGER"); + + b.Property("Ordine") + .HasColumnType("INTEGER"); + + b.Property("Quantita") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventoId"); + + b.ToTable("EventiAltriCosti"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoDegustazione", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Completata") + .HasColumnType("INTEGER"); + + b.Property("CostoDegustazione") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("DataDegustazione") + .HasColumnType("TEXT"); + + b.Property("Detraibile") + .HasColumnType("INTEGER"); + + b.Property("EventoId") + .HasColumnType("INTEGER"); + + b.Property("Luogo") + .HasColumnType("TEXT"); + + b.Property("Menu") + .HasColumnType("TEXT"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("NumeroPaganti") + .HasColumnType("INTEGER"); + + b.Property("NumeroPersone") + .HasColumnType("INTEGER"); + + b.Property("Ora") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventoId"); + + b.ToTable("EventiDegustazioni"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoDettaglioOspiti", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CostoUnitario") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("EventoId") + .HasColumnType("INTEGER"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("Numero") + .HasColumnType("INTEGER"); + + b.Property("Ordine") + .HasColumnType("INTEGER"); + + b.Property("Sconto") + .HasColumnType("TEXT"); + + b.Property("TipoOspiteId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventoId"); + + b.HasIndex("TipoOspiteId"); + + b.ToTable("EventiDettaglioOspiti"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoDettaglioPrelievo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticoloId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("EventoId") + .HasColumnType("INTEGER"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("QtaCalcolata") + .HasColumnType("TEXT"); + + b.Property("QtaEffettiva") + .HasColumnType("TEXT"); + + b.Property("QtaRichiesta") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArticoloId"); + + b.HasIndex("EventoId"); + + b.ToTable("EventiDettaglioPrelievo"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoDettaglioRisorsa", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Costo") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("EventoId") + .HasColumnType("INTEGER"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("OraFine") + .HasColumnType("TEXT"); + + b.Property("OraInizio") + .HasColumnType("TEXT"); + + b.Property("OreLavoro") + .HasColumnType("TEXT"); + + b.Property("RisorsaId") + .HasColumnType("INTEGER"); + + b.Property("Ruolo") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventoId"); + + b.HasIndex("RisorsaId"); + + b.ToTable("EventiDettaglioRisorse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Cap") + .HasColumnType("TEXT"); + + b.Property("Citta") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("DistanzaKm") + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("Indirizzo") + .HasColumnType("TEXT"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("Provincia") + .HasColumnType("TEXT"); + + b.Property("Referente") + .HasColumnType("TEXT"); + + b.Property("Telefono") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Nome"); + + b.ToTable("Location"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.ModuleSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AutoRenew") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("IsEnabled") + .HasColumnType("INTEGER"); + + b.Property("LastRenewalDate") + .HasColumnType("TEXT"); + + b.Property("ModuleId") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("PaidPrice") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("SubscriptionType") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ModuleId") + .IsUnique(); + + b.ToTable("ModuleSubscriptions"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.ReportFont", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("FileSize") + .HasColumnType("INTEGER"); + + b.Property("FontData") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("FontFamily") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FontStyle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MimeType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("FontFamily"); + + b.ToTable("ReportFonts"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.ReportImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Categoria") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("FileSize") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("MimeType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Categoria"); + + b.ToTable("ReportImages"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.ReportTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Categoria") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .HasColumnType("TEXT"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Orientation") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PageSize") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TemplateJson") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Thumbnail") + .HasColumnType("BLOB"); + + b.Property("ThumbnailMimeType") + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Categoria"); + + b.HasIndex("Nome"); + + b.ToTable("ReportTemplates"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Risorsa", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Cognome") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Note") + .HasColumnType("TEXT"); + + b.Property("Telefono") + .HasColumnType("TEXT"); + + b.Property("TipoRisorsaId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("TipoRisorsaId"); + + b.ToTable("Risorse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoEvento", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Codice") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TipoPastoId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("TipoPastoId"); + + b.ToTable("TipiEvento"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoMateriale", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Codice") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("TipiMateriale"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoOspite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Codice") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("TipiOspite"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoPasto", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Codice") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("TipiPasto"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoRisorsa", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Codice") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("TipiRisorsa"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Utente", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Cognome") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("Nome") + .HasColumnType("TEXT"); + + b.Property("Ruolo") + .HasColumnType("TEXT"); + + b.Property("SolaLettura") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("Utenti"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.VirtualDataset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attivo") + .HasColumnType("INTEGER"); + + b.Property("Categoria") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ConfigurationJson") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Descrizione") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Categoria"); + + b.HasIndex("Nome") + .IsUnique(); + + b.ToTable("VirtualDatasets"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.ArticleBarcode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticleId") + .HasColumnType("INTEGER"); + + b.Property("Barcode") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsPrimary") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArticleId"); + + b.HasIndex("Barcode") + .IsUnique(); + + b.ToTable("ArticleBarcodes", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.ArticleBatch", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticleId") + .HasColumnType("INTEGER"); + + b.Property("BatchNumber") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Certifications") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CurrentQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("ExpiryDate") + .HasColumnType("TEXT"); + + b.Property("InitialQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("LastQualityCheckDate") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("ProductionDate") + .HasColumnType("TEXT"); + + b.Property("QualityStatus") + .HasColumnType("INTEGER"); + + b.Property("ReservedQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("SupplierBatch") + .HasColumnType("TEXT"); + + b.Property("SupplierId") + .HasColumnType("INTEGER"); + + b.Property("UnitCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ExpiryDate"); + + b.HasIndex("Status"); + + b.HasIndex("ArticleId", "BatchNumber") + .IsUnique(); + + b.ToTable("ArticleBatches", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.ArticleSerial", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticleId") + .HasColumnType("INTEGER"); + + b.Property("Attributes") + .HasColumnType("TEXT"); + + b.Property("BatchId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CurrentWarehouseId") + .HasColumnType("INTEGER"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("CustomerId") + .HasColumnType("INTEGER"); + + b.Property("ManufacturerSerial") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("ProductionDate") + .HasColumnType("TEXT"); + + b.Property("SalesReference") + .HasColumnType("TEXT"); + + b.Property("SerialNumber") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SoldDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("SupplierId") + .HasColumnType("INTEGER"); + + b.Property("UnitCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("WarrantyExpiryDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BatchId"); + + b.HasIndex("CurrentWarehouseId"); + + b.HasIndex("Status"); + + b.HasIndex("ArticleId", "SerialNumber") + .IsUnique(); + + b.ToTable("ArticleSerials", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.InventoryCount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AdjustmentMovementId") + .HasColumnType("INTEGER"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ConfirmedBy") + .HasColumnType("TEXT"); + + b.Property("ConfirmedDate") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("InventoryDate") + .HasColumnType("TEXT"); + + b.Property("NegativeDifferenceValue") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("PositiveDifferenceValue") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("WarehouseId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("AdjustmentMovementId"); + + b.HasIndex("CategoryId"); + + b.HasIndex("Code") + .IsUnique(); + + b.HasIndex("InventoryDate"); + + b.HasIndex("Status"); + + b.HasIndex("WarehouseId"); + + b.ToTable("InventoryCounts", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.InventoryCountLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticleId") + .HasColumnType("INTEGER"); + + b.Property("BatchId") + .HasColumnType("INTEGER"); + + b.Property("CountedAt") + .HasColumnType("TEXT"); + + b.Property("CountedBy") + .HasColumnType("TEXT"); + + b.Property("CountedQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("InventoryCountId") + .HasColumnType("INTEGER"); + + b.Property("LocationCode") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("SecondCountBy") + .HasColumnType("TEXT"); + + b.Property("SecondCountQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("TheoreticalQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UnitCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("WarehouseId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArticleId"); + + b.HasIndex("BatchId"); + + b.HasIndex("WarehouseId"); + + b.HasIndex("InventoryCountId", "ArticleId", "WarehouseId", "BatchId") + .IsUnique(); + + b.ToTable("InventoryCountLines", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.MovementReason", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsSystem") + .HasColumnType("INTEGER"); + + b.Property("MovementType") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("RequiresExternalReference") + .HasColumnType("INTEGER"); + + b.Property("RequiresValuation") + .HasColumnType("INTEGER"); + + b.Property("SortOrder") + .HasColumnType("INTEGER"); + + b.Property("StockSign") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("UpdatesAverageCost") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Code") + .IsUnique(); + + b.HasIndex("IsActive"); + + b.HasIndex("MovementType"); + + b.ToTable("MovementReasons", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticleId") + .HasColumnType("INTEGER"); + + b.Property("BatchId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("LastInventoryDate") + .HasColumnType("TEXT"); + + b.Property("LastMovementDate") + .HasColumnType("TEXT"); + + b.Property("LocationCode") + .HasColumnType("TEXT"); + + b.Property("OnOrderQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("Quantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("ReservedQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("StockValue") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UnitCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("WarehouseId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BatchId"); + + b.HasIndex("LocationCode"); + + b.HasIndex("WarehouseId"); + + b.HasIndex("ArticleId", "WarehouseId", "BatchId") + .IsUnique(); + + b.ToTable("StockLevels", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockMovement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConfirmedBy") + .HasColumnType("TEXT"); + + b.Property("ConfirmedDate") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("CustomerId") + .HasColumnType("INTEGER"); + + b.Property("DestinationWarehouseId") + .HasColumnType("INTEGER"); + + b.Property("DocumentNumber") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExternalDocumentType") + .HasColumnType("INTEGER"); + + b.Property("ExternalReference") + .HasColumnType("TEXT"); + + b.Property("MovementDate") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("ReasonId") + .HasColumnType("INTEGER"); + + b.Property("SourceWarehouseId") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("SupplierId") + .HasColumnType("INTEGER"); + + b.Property("TotalValue") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DestinationWarehouseId"); + + b.HasIndex("DocumentNumber") + .IsUnique(); + + b.HasIndex("ExternalReference"); + + b.HasIndex("MovementDate"); + + b.HasIndex("ReasonId"); + + b.HasIndex("SourceWarehouseId"); + + b.HasIndex("Status"); + + b.HasIndex("Type"); + + b.ToTable("StockMovements", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockMovementLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticleId") + .HasColumnType("INTEGER"); + + b.Property("BatchId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("DestinationLocationCode") + .HasColumnType("TEXT"); + + b.Property("ExternalLineReference") + .HasColumnType("TEXT"); + + b.Property("LineNumber") + .HasColumnType("INTEGER"); + + b.Property("LineValue") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("MovementId") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("Quantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("SerialId") + .HasColumnType("INTEGER"); + + b.Property("SourceLocationCode") + .HasColumnType("TEXT"); + + b.Property("UnitCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UnitOfMeasure") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArticleId"); + + b.HasIndex("BatchId"); + + b.HasIndex("SerialId"); + + b.HasIndex("MovementId", "LineNumber") + .IsUnique(); + + b.ToTable("StockMovementLines", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockValuation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticleId") + .HasColumnType("INTEGER"); + + b.Property("ClosedBy") + .HasColumnType("TEXT"); + + b.Property("ClosedDate") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("InboundQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("InboundValue") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("IsClosed") + .HasColumnType("INTEGER"); + + b.Property("Method") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("OutboundQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("OutboundValue") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("Period") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("TotalValue") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UnitCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("ValuationDate") + .HasColumnType("TEXT"); + + b.Property("WarehouseId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArticleId"); + + b.HasIndex("IsClosed"); + + b.HasIndex("ValuationDate"); + + b.HasIndex("WarehouseId"); + + b.HasIndex("Period", "ArticleId", "WarehouseId") + .IsUnique(); + + b.ToTable("StockValuations", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockValuationLayer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArticleId") + .HasColumnType("INTEGER"); + + b.Property("BatchId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("IsExhausted") + .HasColumnType("INTEGER"); + + b.Property("LayerDate") + .HasColumnType("TEXT"); + + b.Property("OriginalQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("RemainingQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("SourceMovementId") + .HasColumnType("INTEGER"); + + b.Property("UnitCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("WarehouseId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BatchId"); + + b.HasIndex("IsExhausted"); + + b.HasIndex("SourceMovementId"); + + b.HasIndex("WarehouseId"); + + b.HasIndex("ArticleId", "WarehouseId", "LayerDate"); + + b.ToTable("StockValuationLayers", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AlternativeCode") + .HasColumnType("TEXT"); + + b.Property("Barcode") + .HasColumnType("TEXT"); + + b.Property("BaseSellingPrice") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Depth") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpiryWarningDays") + .HasColumnType("INTEGER"); + + b.Property("HasExpiry") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("TEXT"); + + b.Property("Image") + .HasColumnType("BLOB"); + + b.Property("ImageMimeType") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsBatchManaged") + .HasColumnType("INTEGER"); + + b.Property("IsSerialManaged") + .HasColumnType("INTEGER"); + + b.Property("LastPurchaseCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("LeadTimeDays") + .HasColumnType("INTEGER"); + + b.Property("ManufacturerCode") + .HasColumnType("TEXT"); + + b.Property("MaximumStock") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("MinimumStock") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("ReorderPoint") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("ReorderQuantity") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("SecondaryUnitOfMeasure") + .HasColumnType("TEXT"); + + b.Property("ShortDescription") + .HasColumnType("TEXT"); + + b.Property("StandardCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("StockManagement") + .HasColumnType("INTEGER"); + + b.Property("UnitConversionFactor") + .HasPrecision(18, 6) + .HasColumnType("TEXT"); + + b.Property("UnitOfMeasure") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("ValuationMethod") + .HasColumnType("INTEGER"); + + b.Property("Volume") + .HasPrecision(18, 6) + .HasColumnType("TEXT"); + + b.Property("Weight") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("WeightedAverageCost") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("Width") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Barcode"); + + b.HasIndex("CategoryId"); + + b.HasIndex("Code") + .IsUnique(); + + b.HasIndex("IsActive"); + + b.ToTable("WarehouseArticles", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.WarehouseArticleCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AlternativeCode") + .HasColumnType("TEXT"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("DefaultValuationMethod") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("FullPath") + .HasColumnType("TEXT"); + + b.Property("Icon") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("ParentCategoryId") + .HasColumnType("INTEGER"); + + b.Property("SortOrder") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Code") + .IsUnique(); + + b.HasIndex("FullPath"); + + b.HasIndex("ParentCategoryId"); + + b.ToTable("WarehouseArticleCategories", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Address") + .HasColumnType("TEXT"); + + b.Property("AlternativeCode") + .HasColumnType("TEXT"); + + b.Property("City") + .HasColumnType("TEXT"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Country") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDefault") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("PostalCode") + .HasColumnType("TEXT"); + + b.Property("Province") + .HasColumnType("TEXT"); + + b.Property("SortOrder") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Code") + .IsUnique(); + + b.HasIndex("IsActive"); + + b.HasIndex("IsDefault"); + + b.ToTable("WarehouseLocations", (string)null); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Articolo", b => + { + b.HasOne("Apollinare.Domain.Entities.CodiceCategoria", "Categoria") + .WithMany("Articoli") + .HasForeignKey("CategoriaId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.TipoMateriale", "TipoMateriale") + .WithMany("Articoli") + .HasForeignKey("TipoMaterialeId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Categoria"); + + b.Navigation("TipoMateriale"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Evento", b => + { + b.HasOne("Apollinare.Domain.Entities.Cliente", "Cliente") + .WithMany("Eventi") + .HasForeignKey("ClienteId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Location", "Location") + .WithMany("Eventi") + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.TipoEvento", "TipoEvento") + .WithMany("Eventi") + .HasForeignKey("TipoEventoId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Cliente"); + + b.Navigation("Location"); + + b.Navigation("TipoEvento"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoAcconto", b => + { + b.HasOne("Apollinare.Domain.Entities.Evento", "Evento") + .WithMany("Acconti") + .HasForeignKey("EventoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evento"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoAllegato", b => + { + b.HasOne("Apollinare.Domain.Entities.Evento", "Evento") + .WithMany("Allegati") + .HasForeignKey("EventoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evento"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoAltroCosto", b => + { + b.HasOne("Apollinare.Domain.Entities.Evento", "Evento") + .WithMany("AltriCosti") + .HasForeignKey("EventoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evento"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoDegustazione", b => + { + b.HasOne("Apollinare.Domain.Entities.Evento", "Evento") + .WithMany("Degustazioni") + .HasForeignKey("EventoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evento"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoDettaglioOspiti", b => + { + b.HasOne("Apollinare.Domain.Entities.Evento", "Evento") + .WithMany("DettagliOspiti") + .HasForeignKey("EventoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.TipoOspite", "TipoOspite") + .WithMany("DettagliOspiti") + .HasForeignKey("TipoOspiteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evento"); + + b.Navigation("TipoOspite"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoDettaglioPrelievo", b => + { + b.HasOne("Apollinare.Domain.Entities.Articolo", "Articolo") + .WithMany("DettagliPrelievo") + .HasForeignKey("ArticoloId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Evento", "Evento") + .WithMany("DettagliPrelievo") + .HasForeignKey("EventoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Articolo"); + + b.Navigation("Evento"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.EventoDettaglioRisorsa", b => + { + b.HasOne("Apollinare.Domain.Entities.Evento", "Evento") + .WithMany("DettagliRisorse") + .HasForeignKey("EventoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Risorsa", "Risorsa") + .WithMany("DettagliRisorse") + .HasForeignKey("RisorsaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evento"); + + b.Navigation("Risorsa"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.ModuleSubscription", b => + { + b.HasOne("Apollinare.Domain.Entities.AppModule", "Module") + .WithOne("Subscription") + .HasForeignKey("Apollinare.Domain.Entities.ModuleSubscription", "ModuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Module"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Risorsa", b => + { + b.HasOne("Apollinare.Domain.Entities.TipoRisorsa", "TipoRisorsa") + .WithMany("Risorse") + .HasForeignKey("TipoRisorsaId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("TipoRisorsa"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoEvento", b => + { + b.HasOne("Apollinare.Domain.Entities.TipoPasto", "TipoPasto") + .WithMany("TipiEvento") + .HasForeignKey("TipoPastoId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("TipoPasto"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.ArticleBarcode", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", "Article") + .WithMany("Barcodes") + .HasForeignKey("ArticleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Article"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.ArticleBatch", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", "Article") + .WithMany("Batches") + .HasForeignKey("ArticleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Article"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.ArticleSerial", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", "Article") + .WithMany("Serials") + .HasForeignKey("ArticleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.ArticleBatch", "Batch") + .WithMany("Serials") + .HasForeignKey("BatchId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", "CurrentWarehouse") + .WithMany() + .HasForeignKey("CurrentWarehouseId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Article"); + + b.Navigation("Batch"); + + b.Navigation("CurrentWarehouse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.InventoryCount", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.StockMovement", "AdjustmentMovement") + .WithMany() + .HasForeignKey("AdjustmentMovementId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticleCategory", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", "Warehouse") + .WithMany() + .HasForeignKey("WarehouseId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("AdjustmentMovement"); + + b.Navigation("Category"); + + b.Navigation("Warehouse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.InventoryCountLine", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", "Article") + .WithMany() + .HasForeignKey("ArticleId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.ArticleBatch", "Batch") + .WithMany() + .HasForeignKey("BatchId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.InventoryCount", "InventoryCount") + .WithMany("Lines") + .HasForeignKey("InventoryCountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", "Warehouse") + .WithMany() + .HasForeignKey("WarehouseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Article"); + + b.Navigation("Batch"); + + b.Navigation("InventoryCount"); + + b.Navigation("Warehouse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockLevel", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", "Article") + .WithMany("StockLevels") + .HasForeignKey("ArticleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.ArticleBatch", "Batch") + .WithMany("StockLevels") + .HasForeignKey("BatchId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", "Warehouse") + .WithMany("StockLevels") + .HasForeignKey("WarehouseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Article"); + + b.Navigation("Batch"); + + b.Navigation("Warehouse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockMovement", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", "DestinationWarehouse") + .WithMany("DestinationMovements") + .HasForeignKey("DestinationWarehouseId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.MovementReason", "Reason") + .WithMany("Movements") + .HasForeignKey("ReasonId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", "SourceWarehouse") + .WithMany("SourceMovements") + .HasForeignKey("SourceWarehouseId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("DestinationWarehouse"); + + b.Navigation("Reason"); + + b.Navigation("SourceWarehouse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockMovementLine", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", "Article") + .WithMany("MovementLines") + .HasForeignKey("ArticleId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.ArticleBatch", "Batch") + .WithMany("MovementLines") + .HasForeignKey("BatchId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.StockMovement", "Movement") + .WithMany("Lines") + .HasForeignKey("MovementId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.ArticleSerial", "Serial") + .WithMany("MovementLines") + .HasForeignKey("SerialId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Article"); + + b.Navigation("Batch"); + + b.Navigation("Movement"); + + b.Navigation("Serial"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockValuation", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", "Article") + .WithMany() + .HasForeignKey("ArticleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", "Warehouse") + .WithMany() + .HasForeignKey("WarehouseId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Article"); + + b.Navigation("Warehouse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockValuationLayer", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", "Article") + .WithMany() + .HasForeignKey("ArticleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.ArticleBatch", "Batch") + .WithMany() + .HasForeignKey("BatchId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.StockMovement", "SourceMovement") + .WithMany() + .HasForeignKey("SourceMovementId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", "Warehouse") + .WithMany() + .HasForeignKey("WarehouseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Article"); + + b.Navigation("Batch"); + + b.Navigation("SourceMovement"); + + b.Navigation("Warehouse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticleCategory", "Category") + .WithMany("Articles") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.WarehouseArticleCategory", b => + { + b.HasOne("Apollinare.Domain.Entities.Warehouse.WarehouseArticleCategory", "ParentCategory") + .WithMany("ChildCategories") + .HasForeignKey("ParentCategoryId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("ParentCategory"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.AppModule", b => + { + b.Navigation("Subscription"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Articolo", b => + { + b.Navigation("DettagliPrelievo"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Cliente", b => + { + b.Navigation("Eventi"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.CodiceCategoria", b => + { + b.Navigation("Articoli"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Evento", b => + { + b.Navigation("Acconti"); + + b.Navigation("Allegati"); + + b.Navigation("AltriCosti"); + + b.Navigation("Degustazioni"); + + b.Navigation("DettagliOspiti"); + + b.Navigation("DettagliPrelievo"); + + b.Navigation("DettagliRisorse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Location", b => + { + b.Navigation("Eventi"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Risorsa", b => + { + b.Navigation("DettagliRisorse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoEvento", b => + { + b.Navigation("Eventi"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoMateriale", b => + { + b.Navigation("Articoli"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoOspite", b => + { + b.Navigation("DettagliOspiti"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoPasto", b => + { + b.Navigation("TipiEvento"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.TipoRisorsa", b => + { + b.Navigation("Risorse"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.ArticleBatch", b => + { + b.Navigation("MovementLines"); + + b.Navigation("Serials"); + + b.Navigation("StockLevels"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.ArticleSerial", b => + { + b.Navigation("MovementLines"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.InventoryCount", b => + { + b.Navigation("Lines"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.MovementReason", b => + { + b.Navigation("Movements"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.StockMovement", b => + { + b.Navigation("Lines"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.WarehouseArticle", b => + { + b.Navigation("Barcodes"); + + b.Navigation("Batches"); + + b.Navigation("MovementLines"); + + b.Navigation("Serials"); + + b.Navigation("StockLevels"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.WarehouseArticleCategory", b => + { + b.Navigation("Articles"); + + b.Navigation("ChildCategories"); + }); + + modelBuilder.Entity("Apollinare.Domain.Entities.Warehouse.WarehouseLocation", b => + { + b.Navigation("DestinationMovements"); + + b.Navigation("SourceMovements"); + + b.Navigation("StockLevels"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Apollinare.Infrastructure/Migrations/20251129161359_AddCustomFieldsSystem.cs b/src/Apollinare.Infrastructure/Migrations/20251129161359_AddCustomFieldsSystem.cs new file mode 100644 index 0000000..3364516 --- /dev/null +++ b/src/Apollinare.Infrastructure/Migrations/20251129161359_AddCustomFieldsSystem.cs @@ -0,0 +1,472 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Apollinare.Infrastructure.Migrations +{ + /// + public partial class AddCustomFieldsSystem : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "WarehouseLocations", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "WarehouseArticles", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "WarehouseArticleCategories", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "VirtualDatasets", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "Utenti", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "TipiRisorsa", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "TipiPasto", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "TipiOspite", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "TipiMateriale", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "TipiEvento", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "StockValuations", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "StockValuationLayers", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "StockMovements", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "StockMovementLines", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "StockLevels", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "Risorse", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "ReportTemplates", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "ReportImages", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "ReportFonts", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "MovementReasons", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "ModuleSubscriptions", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "Location", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "InventoryCounts", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "InventoryCountLines", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "EventiDettaglioRisorse", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "EventiDettaglioPrelievo", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "EventiDettaglioOspiti", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "EventiDegustazioni", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "EventiAltriCosti", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "EventiAllegati", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "EventiAcconti", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "Eventi", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "Configurazioni", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "CodiciCategoria", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "Clienti", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "AutoCodes", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "Articoli", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "ArticleSerials", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "ArticleBatches", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "ArticleBarcodes", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CustomFieldsJson", + table: "AppModules", + type: "TEXT", + nullable: true); + + migrationBuilder.CreateTable( + name: "CustomFieldDefinitions", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + EntityName = table.Column(type: "TEXT", nullable: false), + FieldName = table.Column(type: "TEXT", nullable: false), + Label = table.Column(type: "TEXT", nullable: false), + Type = table.Column(type: "INTEGER", nullable: false), + IsRequired = table.Column(type: "INTEGER", nullable: false), + DefaultValue = table.Column(type: "TEXT", nullable: true), + OptionsJson = table.Column(type: "TEXT", nullable: true), + SortOrder = table.Column(type: "INTEGER", nullable: false), + Description = table.Column(type: "TEXT", nullable: true), + IsActive = table.Column(type: "INTEGER", nullable: false), + ValidationRegex = table.Column(type: "TEXT", nullable: true), + Placeholder = table.Column(type: "TEXT", nullable: true), + CreatedAt = table.Column(type: "TEXT", nullable: true), + CreatedBy = table.Column(type: "TEXT", nullable: true), + UpdatedAt = table.Column(type: "TEXT", nullable: true), + UpdatedBy = table.Column(type: "TEXT", nullable: true), + CustomFieldsJson = table.Column(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); + } + + /// + 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"); + } + } +} diff --git a/src/Apollinare.Infrastructure/Migrations/AppollinareDbContextModelSnapshot.cs b/src/Apollinare.Infrastructure/Migrations/AppollinareDbContextModelSnapshot.cs index 82e8df1..a4eac8c 100644 --- a/src/Apollinare.Infrastructure/Migrations/AppollinareDbContextModelSnapshot.cs +++ b/src/Apollinare.Infrastructure/Migrations/AppollinareDbContextModelSnapshot.cs @@ -37,6 +37,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Dependencies") .HasColumnType("TEXT"); @@ -107,6 +110,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .IsRequired() .HasColumnType("TEXT"); @@ -168,6 +174,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Description") .HasColumnType("TEXT"); @@ -263,6 +272,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Email") .HasColumnType("TEXT"); @@ -331,6 +343,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .IsRequired() .HasColumnType("TEXT"); @@ -362,6 +377,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .HasColumnType("TEXT"); @@ -382,6 +400,76 @@ namespace Apollinare.Infrastructure.Migrations b.ToTable("Configurazioni"); }); + modelBuilder.Entity("Apollinare.Domain.Entities.CustomFieldDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .HasColumnType("TEXT"); + + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + + b.Property("DefaultValue") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("EntityName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsRequired") + .HasColumnType("INTEGER"); + + b.Property("Label") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OptionsJson") + .HasColumnType("TEXT"); + + b.Property("Placeholder") + .HasColumnType("TEXT"); + + b.Property("SortOrder") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UpdatedBy") + .HasColumnType("TEXT"); + + b.Property("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("Id") @@ -409,6 +497,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("DataEvento") .HasColumnType("TEXT"); @@ -504,6 +595,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("DataPagamento") .HasColumnType("TEXT"); @@ -553,6 +647,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("EventoId") .HasColumnType("INTEGER"); @@ -600,6 +697,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .IsRequired() .HasColumnType("TEXT"); @@ -644,6 +744,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("DataDegustazione") .HasColumnType("TEXT"); @@ -699,6 +802,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("EventoId") .HasColumnType("INTEGER"); @@ -747,6 +853,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("EventoId") .HasColumnType("INTEGER"); @@ -792,6 +901,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("EventoId") .HasColumnType("INTEGER"); @@ -849,6 +961,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("DistanzaKm") .HasColumnType("TEXT"); @@ -902,6 +1017,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("EndDate") .HasColumnType("TEXT"); @@ -956,6 +1074,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("FileSize") .HasColumnType("INTEGER"); @@ -1011,6 +1132,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("FileSize") .HasColumnType("INTEGER"); @@ -1064,6 +1188,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .HasColumnType("TEXT"); @@ -1122,6 +1249,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Email") .HasColumnType("TEXT"); @@ -1170,6 +1300,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .IsRequired() .HasColumnType("TEXT"); @@ -1209,6 +1342,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .IsRequired() .HasColumnType("TEXT"); @@ -1243,6 +1379,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .IsRequired() .HasColumnType("TEXT"); @@ -1277,6 +1416,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .IsRequired() .HasColumnType("TEXT"); @@ -1311,6 +1453,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .IsRequired() .HasColumnType("TEXT"); @@ -1344,6 +1489,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Email") .HasColumnType("TEXT"); @@ -1397,6 +1545,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Descrizione") .HasColumnType("TEXT"); @@ -1447,6 +1598,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Description") .HasColumnType("TEXT"); @@ -1505,6 +1659,9 @@ namespace Apollinare.Infrastructure.Migrations .HasPrecision(18, 4) .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("ExpiryDate") .HasColumnType("TEXT"); @@ -1583,6 +1740,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CurrentWarehouseId") .HasColumnType("INTEGER"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("CustomerId") .HasColumnType("INTEGER"); @@ -1666,6 +1826,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Description") .IsRequired() .HasColumnType("TEXT"); @@ -1751,6 +1914,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("InventoryCountId") .HasColumnType("INTEGER"); @@ -1814,6 +1980,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Description") .IsRequired() .HasColumnType("TEXT"); @@ -1881,6 +2050,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("LastInventoryDate") .HasColumnType("TEXT"); @@ -1951,6 +2123,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("CustomerId") .HasColumnType("INTEGER"); @@ -2038,6 +2213,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("DestinationLocationCode") .HasColumnType("TEXT"); @@ -2116,6 +2294,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("InboundQuantity") .HasPrecision(18, 4) .HasColumnType("TEXT"); @@ -2202,6 +2383,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("IsExhausted") .HasColumnType("INTEGER"); @@ -2276,6 +2460,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Depth") .HasColumnType("TEXT"); @@ -2417,6 +2604,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("DefaultValuationMethod") .HasColumnType("INTEGER"); @@ -2494,6 +2684,9 @@ namespace Apollinare.Infrastructure.Migrations b.Property("CreatedBy") .HasColumnType("TEXT"); + b.Property("CustomFieldsJson") + .HasColumnType("TEXT"); + b.Property("Description") .HasColumnType("TEXT");