Support primary extension
This commit is contained in:
parent
bff4b2675c
commit
fa882a1f4a
7
PhoneToolMX.Models/AllowNullAttribute.cs
Normal file
7
PhoneToolMX.Models/AllowNullAttribute.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace PhoneToolMX.Models
|
||||
{
|
||||
public class AllowNullAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -38,6 +38,20 @@ namespace PhoneToolMX.Data {
|
|||
var entry = await AddAsync(entity);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a DbSet with all required relationships
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">IOwnedModel</typeparam>
|
||||
/// <returns>DbSet<TEntity></returns>
|
||||
private IQueryable<TEntity> GetFullSet<TEntity>() where TEntity: class, IModel
|
||||
{
|
||||
var set = Set<TEntity>().AsQueryable();
|
||||
return typeof(TEntity).GetProperties()
|
||||
.Where(p => p.GetCustomAttributes(typeof(AlwaysIncludeAttribute), true)
|
||||
.Length != 0)
|
||||
.Aggregate(set, (current, prop) => current.Include(prop.Name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all entities of a certain model owned by the <see cref="User"/>.
|
||||
|
@ -48,14 +62,11 @@ namespace PhoneToolMX.Data {
|
|||
public ICollection<TEntity> GetOwned<TEntity>(User owner) where TEntity : class, IOwnedModel
|
||||
{
|
||||
if (owner == null) return null;
|
||||
var entity = Set<TEntity>().Where(x => x.Owners.Any(o => o.Id == owner.Id));
|
||||
var entity = GetFullSet<TEntity>().Where(x => x.Owners.Any(o => o.Id == owner.Id));
|
||||
// eager load all w/ AlwaysInclude
|
||||
entity = typeof(TEntity).GetProperties()
|
||||
.Where(p => p.GetCustomAttributes(typeof(AlwaysIncludeAttribute), true)
|
||||
.Length != 0)
|
||||
.Aggregate(entity, (current, prop) => current.Include(prop.Name));
|
||||
return entity.ToList();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a model entity by its Id
|
||||
|
@ -67,7 +78,7 @@ namespace PhoneToolMX.Data {
|
|||
/// </remarks>
|
||||
public TEntity GetEntityById<TEntity>(int? id) where TEntity : class, IModel
|
||||
{
|
||||
return id == null ? null : Set<TEntity>().FirstOrDefault(o => o.Id == id);
|
||||
return id == null ? null : GetFullSet<TEntity>().FirstOrDefault(o => o.Id == id);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -79,6 +90,7 @@ namespace PhoneToolMX.Data {
|
|||
ext.HasKey(x => x.Id);
|
||||
ext.Property(x => x.Id).UseIdentityColumn();
|
||||
ext.Property(x => x.ExtId).HasComputedColumnSql("\"Id\" + 1000", stored: true);
|
||||
// Randomly generates a 24-char password
|
||||
ext
|
||||
.Property(p => p.Password)
|
||||
.HasDefaultValueSql("encode(gen_random_bytes(18), 'base64')");
|
||||
|
@ -89,7 +101,7 @@ namespace PhoneToolMX.Data {
|
|||
.WithMany(x => x.Phones);
|
||||
phone.HasKey(p => p.Id);
|
||||
phone.Property(p => p.Id).UseIdentityColumn();
|
||||
// Randomly generates a 24-char password
|
||||
phone.HasOne(p => p.PrimaryExtension).WithMany();
|
||||
|
||||
// Wallpapers, ringtones, etc
|
||||
var cd = modelBuilder.Entity<CustomData>();
|
||||
|
|
361
PhoneToolMX.Models/Migrations/20231020205952_PrimaryExtension.Designer.cs
generated
Normal file
361
PhoneToolMX.Models/Migrations/20231020205952_PrimaryExtension.Designer.cs
generated
Normal file
|
@ -0,0 +1,361 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using System.Net.NetworkInformation;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using PhoneToolMX.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace PhoneToolMX.Models.Migrations
|
||||
{
|
||||
[DbContext(typeof(PTMXContext))]
|
||||
[Migration("20231020205952_PrimaryExtension")]
|
||||
partial class PrimaryExtension
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.23")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("ExtensionPhone", b =>
|
||||
{
|
||||
b.Property<int>("ExtensionsId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("PhonesId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("ExtensionsId", "PhonesId");
|
||||
|
||||
b.HasIndex("PhonesId");
|
||||
|
||||
b.ToTable("ExtensionPhone");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ExtensionUser", b =>
|
||||
{
|
||||
b.Property<int>("ExtensionsId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("OwnersId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("ExtensionsId", "OwnersId");
|
||||
|
||||
b.HasIndex("OwnersId");
|
||||
|
||||
b.ToTable("ExtensionUser");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.CustomData", b =>
|
||||
{
|
||||
b.Property<int?>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("Id"));
|
||||
|
||||
b.Property<byte[]>("Data")
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<int>("DataType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("FriendlyName")
|
||||
.HasMaxLength(16)
|
||||
.HasColumnType("character varying(16)");
|
||||
|
||||
b.Property<int?>("PhoneId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<long>("Size")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PhoneId");
|
||||
|
||||
b.ToTable("CustomData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Extension", b =>
|
||||
{
|
||||
b.Property<int?>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("Id"));
|
||||
|
||||
b.Property<string>("DirectoryName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("ExtId")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("integer")
|
||||
.HasComputedColumnSql("\"Id\" + 1000", true);
|
||||
|
||||
b.Property<int?>("HoldMusicId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Listed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("text")
|
||||
.HasDefaultValueSql("encode(gen_random_bytes(18), 'base64')");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("HoldMusicId");
|
||||
|
||||
b.ToTable("Extensions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Phone", b =>
|
||||
{
|
||||
b.Property<int?>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("Id"));
|
||||
|
||||
b.Property<int?>("BackgroundId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("FriendlyName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<PhysicalAddress>("MacAddress")
|
||||
.IsRequired()
|
||||
.HasColumnType("macaddr");
|
||||
|
||||
b.Property<int>("ModelId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int?>("PrimaryExtension")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BackgroundId");
|
||||
|
||||
b.HasIndex("ModelId");
|
||||
|
||||
b.ToTable("Phones");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.PhoneModel", b =>
|
||||
{
|
||||
b.Property<int?>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("Id"));
|
||||
|
||||
b.Property<long>("MaxExtensions")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("ModelName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PreVvxPolycom")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PhoneModels");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 0,
|
||||
MaxExtensions = 6L,
|
||||
ModelName = "Polycom VVX300/310",
|
||||
PreVvxPolycom = false
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Role", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Role");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.User", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneUser", b =>
|
||||
{
|
||||
b.Property<string>("OwnersId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("PhonesId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("OwnersId", "PhonesId");
|
||||
|
||||
b.HasIndex("PhonesId");
|
||||
|
||||
b.ToTable("PhoneUser");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ExtensionPhone", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.Extension", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ExtensionsId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.Phone", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("PhonesId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ExtensionUser", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.Extension", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ExtensionsId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnersId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.CustomData", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.Phone", null)
|
||||
.WithMany("Ringtones")
|
||||
.HasForeignKey("PhoneId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Extension", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.CustomData", "HoldMusic")
|
||||
.WithMany()
|
||||
.HasForeignKey("HoldMusicId");
|
||||
|
||||
b.Navigation("HoldMusic");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Phone", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.CustomData", "Background")
|
||||
.WithMany()
|
||||
.HasForeignKey("BackgroundId");
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.PhoneModel", "Model")
|
||||
.WithMany()
|
||||
.HasForeignKey("ModelId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Background");
|
||||
|
||||
b.Navigation("Model");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneUser", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnersId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.Phone", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("PhonesId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Phone", b =>
|
||||
{
|
||||
b.Navigation("Ringtones");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace PhoneToolMX.Models.Migrations
|
||||
{
|
||||
public partial class PrimaryExtension : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "PrimaryExtension",
|
||||
table: "Phones",
|
||||
type: "integer",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PrimaryExtension",
|
||||
table: "Phones");
|
||||
}
|
||||
}
|
||||
}
|
369
PhoneToolMX.Models/Migrations/20231020213049_PrimaryExtensionAsExtension.Designer.cs
generated
Normal file
369
PhoneToolMX.Models/Migrations/20231020213049_PrimaryExtensionAsExtension.Designer.cs
generated
Normal file
|
@ -0,0 +1,369 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using System.Net.NetworkInformation;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using PhoneToolMX.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace PhoneToolMX.Models.Migrations
|
||||
{
|
||||
[DbContext(typeof(PTMXContext))]
|
||||
[Migration("20231020213049_PrimaryExtensionAsExtension")]
|
||||
partial class PrimaryExtensionAsExtension
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.23")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("ExtensionPhone", b =>
|
||||
{
|
||||
b.Property<int>("ExtensionsId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("PhonesId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("ExtensionsId", "PhonesId");
|
||||
|
||||
b.HasIndex("PhonesId");
|
||||
|
||||
b.ToTable("ExtensionPhone");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ExtensionUser", b =>
|
||||
{
|
||||
b.Property<int>("ExtensionsId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("OwnersId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("ExtensionsId", "OwnersId");
|
||||
|
||||
b.HasIndex("OwnersId");
|
||||
|
||||
b.ToTable("ExtensionUser");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.CustomData", b =>
|
||||
{
|
||||
b.Property<int?>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("Id"));
|
||||
|
||||
b.Property<byte[]>("Data")
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<int>("DataType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("FriendlyName")
|
||||
.HasMaxLength(16)
|
||||
.HasColumnType("character varying(16)");
|
||||
|
||||
b.Property<int?>("PhoneId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<long>("Size")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PhoneId");
|
||||
|
||||
b.ToTable("CustomData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Extension", b =>
|
||||
{
|
||||
b.Property<int?>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("Id"));
|
||||
|
||||
b.Property<string>("DirectoryName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("ExtId")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("integer")
|
||||
.HasComputedColumnSql("\"Id\" + 1000", true);
|
||||
|
||||
b.Property<int?>("HoldMusicId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Listed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("text")
|
||||
.HasDefaultValueSql("encode(gen_random_bytes(18), 'base64')");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("HoldMusicId");
|
||||
|
||||
b.ToTable("Extensions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Phone", b =>
|
||||
{
|
||||
b.Property<int?>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("Id"));
|
||||
|
||||
b.Property<int?>("BackgroundId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("FriendlyName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<PhysicalAddress>("MacAddress")
|
||||
.IsRequired()
|
||||
.HasColumnType("macaddr");
|
||||
|
||||
b.Property<int>("ModelId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int?>("PrimaryExtensionId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BackgroundId");
|
||||
|
||||
b.HasIndex("ModelId");
|
||||
|
||||
b.HasIndex("PrimaryExtensionId");
|
||||
|
||||
b.ToTable("Phones");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.PhoneModel", b =>
|
||||
{
|
||||
b.Property<int?>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("Id"));
|
||||
|
||||
b.Property<long>("MaxExtensions")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("ModelName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PreVvxPolycom")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PhoneModels");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 0,
|
||||
MaxExtensions = 6L,
|
||||
ModelName = "Polycom VVX300/310",
|
||||
PreVvxPolycom = false
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Role", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Role");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.User", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneUser", b =>
|
||||
{
|
||||
b.Property<string>("OwnersId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("PhonesId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("OwnersId", "PhonesId");
|
||||
|
||||
b.HasIndex("PhonesId");
|
||||
|
||||
b.ToTable("PhoneUser");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ExtensionPhone", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.Extension", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ExtensionsId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.Phone", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("PhonesId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ExtensionUser", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.Extension", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ExtensionsId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnersId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.CustomData", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.Phone", null)
|
||||
.WithMany("Ringtones")
|
||||
.HasForeignKey("PhoneId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Extension", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.CustomData", "HoldMusic")
|
||||
.WithMany()
|
||||
.HasForeignKey("HoldMusicId");
|
||||
|
||||
b.Navigation("HoldMusic");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Phone", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.CustomData", "Background")
|
||||
.WithMany()
|
||||
.HasForeignKey("BackgroundId");
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.PhoneModel", "Model")
|
||||
.WithMany()
|
||||
.HasForeignKey("ModelId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.Extension", "PrimaryExtension")
|
||||
.WithMany()
|
||||
.HasForeignKey("PrimaryExtensionId");
|
||||
|
||||
b.Navigation("Background");
|
||||
|
||||
b.Navigation("Model");
|
||||
|
||||
b.Navigation("PrimaryExtension");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneUser", b =>
|
||||
{
|
||||
b.HasOne("PhoneToolMX.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnersId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.Phone", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("PhonesId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneToolMX.Models.Phone", b =>
|
||||
{
|
||||
b.Navigation("Ringtones");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace PhoneToolMX.Models.Migrations
|
||||
{
|
||||
public partial class PrimaryExtensionAsExtension : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "PrimaryExtension",
|
||||
table: "Phones",
|
||||
newName: "PrimaryExtensionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Phones_PrimaryExtensionId",
|
||||
table: "Phones",
|
||||
column: "PrimaryExtensionId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Phones_Extensions_PrimaryExtensionId",
|
||||
table: "Phones",
|
||||
column: "PrimaryExtensionId",
|
||||
principalTable: "Extensions",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Phones_Extensions_PrimaryExtensionId",
|
||||
table: "Phones");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Phones_PrimaryExtensionId",
|
||||
table: "Phones");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "PrimaryExtensionId",
|
||||
table: "Phones",
|
||||
newName: "PrimaryExtension");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -141,12 +141,17 @@ namespace PhoneToolMX.Models.Migrations
|
|||
b.Property<int>("ModelId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int?>("PrimaryExtensionId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BackgroundId");
|
||||
|
||||
b.HasIndex("ModelId");
|
||||
|
||||
b.HasIndex("PrimaryExtensionId");
|
||||
|
||||
b.ToTable("Phones");
|
||||
});
|
||||
|
||||
|
@ -326,9 +331,15 @@ namespace PhoneToolMX.Models.Migrations
|
|||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PhoneToolMX.Models.Extension", "PrimaryExtension")
|
||||
.WithMany()
|
||||
.HasForeignKey("PrimaryExtensionId");
|
||||
|
||||
b.Navigation("Background");
|
||||
|
||||
b.Navigation("Model");
|
||||
|
||||
b.Navigation("PrimaryExtension");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PhoneUser", b =>
|
||||
|
|
|
@ -12,6 +12,8 @@ namespace PhoneToolMX.Models
|
|||
foreach (var prop in GetType().GetProperties().Where(p => p.CanWrite)) {
|
||||
if (prop.GetValue(obj, null) is {} propVal) {
|
||||
prop.SetValue(this, propVal, null);
|
||||
} else if (prop.GetCustomAttributes(typeof(AllowNullAttribute)).FirstOrDefault() != null) {
|
||||
prop.SetValue(this, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ namespace PhoneToolMX.Models {
|
|||
|
||||
[AlwaysInclude]
|
||||
public ICollection<Extension> Extensions { get; set; }
|
||||
|
||||
public CustomData Background { get; set; }
|
||||
public ICollection<CustomData> Ringtones { get; set; }
|
||||
|
||||
public Extension PrimaryExtension { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
using PhoneToolMX.Data;
|
||||
using PhoneToolMX.Models;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
|
@ -25,18 +23,25 @@ namespace PhoneToolMX.Models.ViewModels
|
|||
|
||||
public ICollection<int?> Extensions { get; set; }
|
||||
|
||||
[AllowNull]
|
||||
public int? PrimaryExtension { get; set; }
|
||||
|
||||
public int MaxExtensions { get; set; }
|
||||
|
||||
public IOwnedModel ToEntity(PTMXContext ctx)
|
||||
{
|
||||
var exts = Extensions?.Select(x => ctx.Extensions.FirstOrDefault(e => e.Id == x)).ToList();
|
||||
return new Phone
|
||||
{
|
||||
Id = Id,
|
||||
MacAddress = PhysicalAddress.Parse(MacAddress),
|
||||
FriendlyName = FriendlyName,
|
||||
Model = ctx.PhoneModels.FirstOrDefault(p => p.Id == Model)!,
|
||||
Extensions = Extensions?.Select(x => ctx.Extensions.FirstOrDefault(e => e.Id == x)).ToList(),
|
||||
Extensions = exts,
|
||||
Owners = new List<User>(),
|
||||
PrimaryExtension = PrimaryExtension != null
|
||||
? exts?.FirstOrDefault(x => x.Id == PrimaryExtension)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -58,6 +63,7 @@ namespace PhoneToolMX.Models.ViewModels
|
|||
Model = phoneEnt.Model!.Id,
|
||||
Extensions = phoneEnt.Extensions?.Select(x => x.Id).ToList(),
|
||||
MaxExtensions = (int)phoneEnt.Model!.MaxExtensions,
|
||||
PrimaryExtension = phoneEnt.PrimaryExtension?.Id,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@ namespace PhoneToolMX.Controllers
|
|||
{
|
||||
var myExts = _context.GetOwned<Extension>(await CurrentUser());
|
||||
var phoneModels = _context.PhoneModels.ToList();
|
||||
var selectedExts = pvm?.Extensions == null ? null : myExts.Where(x => pvm.Extensions.Contains(x.Id)).ToList();
|
||||
ViewBag.MyExtensions = myExts;
|
||||
ViewBag.SelectedExtensions = pvm?.Extensions == null ? null : myExts.Where(x => pvm.Extensions.Contains(x.Id)).ToList();
|
||||
ViewBag.SelectedExtensions = selectedExts;
|
||||
ViewBag.PrimaryExtension = selectedExts?.FirstOrDefault(x => x.Id == (pvm.PrimaryExtension ?? -1));
|
||||
ViewBag.ModelNumbers = phoneModels;
|
||||
ViewBag.CurrentModel = pvm?.Model == null ? null : phoneModels.Where(m => m.Id == pvm.Model);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,14 @@
|
|||
<th>@Html.LabelFor(m => m.Extensions, "Extensions:")</th>
|
||||
<td>@Html.ListBoxFor(m => m.Extensions, new MultiSelectList(ViewBag.MyExtensions, "Id", "ListViewName", ViewBag.SelectedExtensions))
|
||||
</tr>
|
||||
<tr>
|
||||
<th>@Html.LabelFor(m => m.PrimaryExtension, "Primary Extension:")</th>
|
||||
<td>@if (ViewBag.SelectedExtensions == null || ((ICollection<Extension>)ViewBag.SelectedExtensions).Count == 0) {
|
||||
@Html.DropDownListFor(m => m.PrimaryExtension, new List<SelectListItem>(), "-- No Extensions Selected --", new { @disabled=true })
|
||||
} else {
|
||||
@Html.DropDownListFor(m => m.PrimaryExtension, new SelectList(ViewBag.SelectedExtensions, "Id", "ListViewName", ViewBag.PrimaryExtension), "None")
|
||||
}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" align="right">
|
||||
<input type="reset" value="Reset" />
|
||||
|
|
|
@ -54,6 +54,14 @@ namespace PolyProv.Controllers
|
|||
public IActionResult PhoneSettings(string addr)
|
||||
{
|
||||
var phone = GetByMacStr(addr);
|
||||
|
||||
// ReSharper disable once InvertIf
|
||||
if (phone?.PrimaryExtension is {} primary && phone.Extensions.FirstOrDefault() != primary) {
|
||||
// primary extension exists and is not first, reorder so it's first
|
||||
phone.Extensions.Remove(primary);
|
||||
phone.Extensions = phone.Extensions.Prepend(primary).ToList();
|
||||
}
|
||||
|
||||
return phone != null ? View("Phone", phone) : NotFound();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue