From 26229ef1c27ac936ebf95756babdfd844c40931d Mon Sep 17 00:00:00 2001 From: Fenrikur <3359222+Fenrikur@users.noreply.github.com> Date: Sun, 15 Sep 2024 18:49:15 +0200 Subject: [PATCH 1/7] fix(artshow): reference to deprecated functionality --- .../ArtShow/AgentClosingResultService.cs | 4 +--- .../ArtShow/ItemActivityService.cs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs b/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs index 8412ffd9..474aea3b 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs @@ -49,9 +49,7 @@ public async Task ImportAgentClosingResultLogAsync(TextReader logR csv.Context.Configuration.Delimiter = ","; csv.Context.Configuration.HasHeaderRecord = false; - var csvRecords = await csv.GetRecordsAsync().ToListAsync(); - - foreach (var csvRecord in csvRecords) + await foreach (var csvRecord in csv.GetRecordsAsync()) { var existingRecord = await _appDbContext.AgentClosingResults.AsNoTracking().FirstOrDefaultAsync(a => a.ImportHash == csvRecord.Hash.Value); if (existingRecord != null) diff --git a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs index ae930637..819bd69a 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs @@ -43,10 +43,8 @@ public async Task ImportActivityLogAsync(TextReader logReader) csv.Context.RegisterClassMap(); csv.Context.Configuration.Delimiter = ","; csv.Context.Configuration.HasHeaderRecord = false; - - var csvRecords = await csv.GetRecordsAsync().ToListAsync(); - foreach (var csvRecord in csvRecords) + await foreach (var csvRecord in csv.GetRecordsAsync()) { var existingRecord = await _appDbContext.ItemActivitys.AsNoTracking().FirstOrDefaultAsync(a => a.ImportHash == csvRecord.Hash.Value); if (existingRecord != null) From 97fc341b35373eafbdc5f1f7593b7289d680254f Mon Sep 17 00:00:00 2001 From: Fenrikur <3359222+Fenrikur@users.noreply.github.com> Date: Sun, 15 Sep 2024 21:50:20 +0200 Subject: [PATCH 2/7] feat(artshow): add FinalBidAmount field for won items --- .../ArtShow/ItemActivityRecord.cs | 1 + ..._AddItemActivityFinalBidAmount.Designer.cs | 1462 +++++++++++++++++ ...915170539_AddItemActivityFinalBidAmount.cs | 28 + .../Migrations/AppDbContextModelSnapshot.cs | 3 + .../ArtShow/ItemActivityNotificationResult.cs | 1 + .../ArtShow/AgentClosingResultService.cs | 4 +- .../ArtShow/ItemActivityService.cs | 38 +- .../ArtShow/LogImportRow.cs | 3 +- .../ArtShow/LogImportRowClassMap.cs | 3 +- .../Controllers/ArtShowController.cs | 4 +- 10 files changed, 1534 insertions(+), 13 deletions(-) create mode 100644 src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/20240915170539_AddItemActivityFinalBidAmount.Designer.cs create mode 100644 src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/20240915170539_AddItemActivityFinalBidAmount.cs diff --git a/src/Eurofurence.App.Domain.Model/ArtShow/ItemActivityRecord.cs b/src/Eurofurence.App.Domain.Model/ArtShow/ItemActivityRecord.cs index e1d4e480..f583efd6 100644 --- a/src/Eurofurence.App.Domain.Model/ArtShow/ItemActivityRecord.cs +++ b/src/Eurofurence.App.Domain.Model/ArtShow/ItemActivityRecord.cs @@ -16,6 +16,7 @@ public enum StatusEnum public string ArtistName { get; set; } public string ArtPieceTitle { get; set; } public StatusEnum Status { get; set; } + public int? FinalBidAmount { get; set; } public DateTime ImportDateTimeUtc { get; set; } public DateTime? NotificationDateTimeUtc { get; set; } diff --git a/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/20240915170539_AddItemActivityFinalBidAmount.Designer.cs b/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/20240915170539_AddItemActivityFinalBidAmount.Designer.cs new file mode 100644 index 00000000..55b8f40f --- /dev/null +++ b/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/20240915170539_AddItemActivityFinalBidAmount.Designer.cs @@ -0,0 +1,1462 @@ +// +using System; +using Eurofurence.App.Infrastructure.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Eurofurence.App.Infrastructure.EntityFramework.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20240915170539_AddItemActivityFinalBidAmount")] + partial class AddItemActivityFinalBidAmount + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Announcements.AnnouncementRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Area") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Author") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ExternalReference") + .HasColumnType("longtext"); + + b.Property("ImageId") + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ValidFromDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("ValidUntilDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("Announcements"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtShow.AgentClosingResultRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AgentBadgeNo") + .HasColumnType("int"); + + b.Property("AgentName") + .HasColumnType("longtext"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("ExhibitsSold") + .HasColumnType("int"); + + b.Property("ExhibitsToAuction") + .HasColumnType("int"); + + b.Property("ExhibitsUnsold") + .HasColumnType("int"); + + b.Property("ImportDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("ImportHash") + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("NotificationDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("OwnerUid") + .HasColumnType("longtext"); + + b.Property("PrivateMessageId") + .HasColumnType("char(36)"); + + b.Property("TotalCashAmount") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.ToTable("AgentClosingResults"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtShow.ItemActivityRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ASIDNO") + .HasColumnType("int"); + + b.Property("ArtPieceTitle") + .HasColumnType("longtext"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("FinalBidAmount") + .HasColumnType("int"); + + b.Property("ImportDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("ImportHash") + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("NotificationDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("OwnerUid") + .HasColumnType("longtext"); + + b.Property("PrivateMessageId") + .HasColumnType("char(36)"); + + b.Property("Status") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ItemActivitys"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.ArtistAlleyUserPenaltyRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("IdentityId") + .HasColumnType("longtext") + .HasColumnName("IdentityId"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("int") + .HasColumnName("Status"); + + b.HasKey("Id"); + + b.ToTable("ArtistAlleyUserPenalties"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.ArtistAlleyUserPenaltyRecord+StateChangeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChangedBy") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ChangedBy"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("PenaltyStatus") + .HasColumnType("int") + .HasColumnName("PenaltyStatus"); + + b.Property("Reason") + .HasColumnType("longtext") + .HasColumnName("Reason"); + + b.Property("UserPenaltyRecordId") + .HasColumnType("char(36)") + .HasColumnName("UserPenaltyRecordId"); + + b.HasKey("Id"); + + b.HasIndex("UserPenaltyRecordId"); + + b.ToTable("ArtistAlleyUserPenaltyChangeRecord"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.TableRegistrationRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("DisplayName") + .HasColumnType("longtext"); + + b.Property("ImageId") + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Location") + .HasColumnType("longtext"); + + b.Property("OwnerUid") + .HasColumnType("longtext"); + + b.Property("OwnerUsername") + .HasColumnType("longtext"); + + b.Property("ShortDescription") + .HasColumnType("longtext"); + + b.Property("State") + .HasColumnType("int"); + + b.Property("TelegramHandle") + .HasColumnType("longtext"); + + b.Property("WebsiteUrl") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("TableRegistrations"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.TableRegistrationRecord+StateChangeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChangedByUid") + .HasColumnType("longtext"); + + b.Property("ChangedDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("NewState") + .HasColumnType("int"); + + b.Property("OldState") + .HasColumnType("int"); + + b.Property("TableRegistrationRecordId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TableRegistrationRecordId"); + + b.ToTable("StateChangeRecord"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.CollectionGame.CollectionEntryRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EventDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("FursuitParticipationId") + .HasColumnType("char(36)"); + + b.Property("FursuitParticipationRecordId") + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("PlayerParticipationId") + .HasColumnType("longtext"); + + b.Property("PlayerParticipationRecordId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("FursuitParticipationRecordId"); + + b.HasIndex("PlayerParticipationRecordId"); + + b.ToTable("CollectionEntries"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Communication.PrivateMessageRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AuthorName") + .HasColumnType("longtext"); + + b.Property("CreatedDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("ReadDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("ReceivedDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("RecipientIdentityId") + .HasColumnType("longtext"); + + b.Property("RecipientRegSysId") + .HasColumnType("longtext"); + + b.Property("SenderUid") + .HasColumnType("longtext"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PrivateMessages"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Dealers.DealerRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AboutTheArtText") + .HasColumnType("longtext"); + + b.Property("AboutTheArtistText") + .HasColumnType("longtext"); + + b.Property("ArtPreviewCaption") + .HasColumnType("longtext"); + + b.Property("ArtPreviewImageId") + .HasColumnType("char(36)"); + + b.Property("ArtistImageId") + .HasColumnType("char(36)"); + + b.Property("ArtistThumbnailImageId") + .HasColumnType("char(36)"); + + b.Property("AttendeeNickname") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AttendsOnFriday") + .HasColumnType("tinyint(1)"); + + b.Property("AttendsOnSaturday") + .HasColumnType("tinyint(1)"); + + b.Property("AttendsOnThursday") + .HasColumnType("tinyint(1)"); + + b.Property("BlueskyHandle") + .HasColumnType("longtext"); + + b.Property("Categories") + .HasColumnType("longtext"); + + b.Property("DiscordHandle") + .HasColumnType("longtext"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsAfterDark") + .HasColumnType("tinyint(1)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("Keywords") + .HasColumnType("json"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("MastodonHandle") + .HasColumnType("longtext"); + + b.Property("Merchandise") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RegistrationNumber") + .HasColumnType("int"); + + b.Property("ShortDescription") + .HasColumnType("longtext"); + + b.Property("TelegramHandle") + .HasColumnType("longtext"); + + b.Property("TwitterHandle") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtPreviewImageId"); + + b.HasIndex("ArtistImageId"); + + b.HasIndex("ArtistThumbnailImageId"); + + b.ToTable("Dealers"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventConferenceDayRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EventConferenceDays"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventConferenceRoomRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("ShortName") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EventConferenceRooms"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventConferenceTrackRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EventConferenceTracks"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventFeedbackRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EventId") + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("Rating") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EventId"); + + b.ToTable("EventFeedbacks"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Abstract") + .HasColumnType("longtext"); + + b.Property("BannerImageId") + .HasColumnType("char(36)"); + + b.Property("ConferenceDayId") + .HasColumnType("char(36)"); + + b.Property("ConferenceRoomId") + .HasColumnType("char(36)"); + + b.Property("ConferenceTrackId") + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Duration") + .HasColumnType("time(6)"); + + b.Property("EndDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("IsAcceptingFeedback") + .HasColumnType("tinyint(1)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("IsDeviatingFromConBook") + .HasColumnType("tinyint(1)"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("PanelHosts") + .HasColumnType("longtext"); + + b.Property("PosterImageId") + .HasColumnType("char(36)"); + + b.Property("Slug") + .HasColumnType("longtext"); + + b.Property("SourceEventId") + .HasColumnType("int"); + + b.Property("StartDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("SubTitle") + .HasColumnType("longtext"); + + b.Property("Tags") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("BannerImageId"); + + b.HasIndex("ConferenceDayId"); + + b.HasIndex("ConferenceRoomId"); + + b.HasIndex("ConferenceTrackId"); + + b.HasIndex("PosterImageId"); + + b.ToTable("Events"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fragments.LinkFragment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DealerRecordId") + .HasColumnType("char(36)"); + + b.Property("FragmentType") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("KnowledgeEntryRecordId") + .HasColumnType("char(36)"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("MapEntryRecordId") + .HasColumnType("char(36)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Target") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("DealerRecordId"); + + b.HasIndex("KnowledgeEntryRecordId"); + + b.HasIndex("MapEntryRecordId"); + + b.ToTable("LinkFragments"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fursuits.CollectingGame.FursuitParticipationRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CollectionCount") + .HasColumnType("int"); + + b.Property("FursuitBadgeId") + .HasColumnType("char(36)"); + + b.Property("IsBanned") + .HasColumnType("tinyint(1)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("LastCollectionDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("OwnerUid") + .HasColumnType("longtext"); + + b.Property("TokenRegistrationDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("TokenValue") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("FursuitParticipations"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fursuits.CollectingGame.PlayerParticipationRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CollectionCount") + .HasColumnType("int"); + + b.Property("IsBanned") + .HasColumnType("tinyint(1)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("Karma") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("LastCollectionDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("PlayerUid") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlayerParticipations"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fursuits.CollectingGame.TokenRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("IsLinked") + .HasColumnType("tinyint(1)"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("LinkDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("LinkedFursuitParticipantUid") + .HasColumnType("char(36)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fursuits.FursuitBadgeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CollectionCode") + .HasColumnType("longtext"); + + b.Property("ExternalReference") + .HasColumnType("longtext"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ImageId") + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("IsPublic") + .HasColumnType("tinyint(1)"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OwnerUid") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Species") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("WornBy") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("FursuitBadges"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Images.ImageRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContentHashSha1") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("InternalFileName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("InternalReference") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("IsRestricted") + .HasColumnType("tinyint(1)"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("MimeType") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SizeInBytes") + .HasColumnType("bigint"); + + b.Property("Url") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Knowledge.KnowledgeEntryRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("KnowledgeGroupId") + .HasColumnType("char(36)"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Text") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("KnowledgeGroupId"); + + b.ToTable("KnowledgeEntries"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Knowledge.KnowledgeGroupRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FontAwesomeIconName") + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("ShowInHamburgerMenu") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("KnowledgeGroups"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.LostAndFound.LostAndFoundRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("ExternalId") + .HasColumnType("int"); + + b.Property("FoundDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("ImageUrl") + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("LostDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("ReturnDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("LostAndFounds"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Maps.MapEntryRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("MapId") + .HasColumnType("char(36)"); + + b.Property("TapRadius") + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("int"); + + b.Property("Y") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MapId"); + + b.ToTable("MapEntries"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Maps.MapRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ImageId") + .HasColumnType("char(36)"); + + b.Property("IsBrowseable") + .HasColumnType("tinyint(1)"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Order") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.PushNotifications.DeviceIdentityRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DeviceToken") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DeviceType") + .HasColumnType("int"); + + b.Property("IdentityId") + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("DeviceIdentities"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.PushNotifications.RegistrationIdentityRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("IdentityId") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("RegSysId") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("RegistrationIdentities"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Sync.EntityStorageInfoRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DeltaStartDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("EntityType") + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("EntityStorageInfos"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Telegram.UserRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Acl") + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("int"); + + b.Property("LastChangeDateTimeUtc") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("ImageRecordKnowledgeEntryRecord", b => + { + b.Property("ImagesId") + .HasColumnType("char(36)"); + + b.Property("KnowledgeEntriesId") + .HasColumnType("char(36)"); + + b.HasKey("ImagesId", "KnowledgeEntriesId"); + + b.HasIndex("KnowledgeEntriesId"); + + b.ToTable("ImageRecordKnowledgeEntryRecord"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Announcements.AnnouncementRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "Image") + .WithMany("Announcements") + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.ArtistAlleyUserPenaltyRecord+StateChangeRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.ArtistsAlley.ArtistAlleyUserPenaltyRecord", "UserPenaltyRecord") + .WithMany("AuditLog") + .HasForeignKey("UserPenaltyRecordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("UserPenaltyRecord"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.TableRegistrationRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "Image") + .WithMany("TableRegistrations") + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.TableRegistrationRecord+StateChangeRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.ArtistsAlley.TableRegistrationRecord", null) + .WithMany("StateChangeLog") + .HasForeignKey("TableRegistrationRecordId"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.CollectionGame.CollectionEntryRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Fursuits.CollectingGame.FursuitParticipationRecord", null) + .WithMany("CollectionEntries") + .HasForeignKey("FursuitParticipationRecordId"); + + b.HasOne("Eurofurence.App.Domain.Model.Fursuits.CollectingGame.PlayerParticipationRecord", null) + .WithMany("CollectionEntries") + .HasForeignKey("PlayerParticipationRecordId"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Dealers.DealerRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "ArtPreviewImage") + .WithMany("DealerArtPreviews") + .HasForeignKey("ArtPreviewImageId"); + + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "ArtistImage") + .WithMany("DealerArtists") + .HasForeignKey("ArtistImageId"); + + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "ArtistThumbnailImage") + .WithMany("DealerArtistThumbnails") + .HasForeignKey("ArtistThumbnailImageId"); + + b.Navigation("ArtPreviewImage"); + + b.Navigation("ArtistImage"); + + b.Navigation("ArtistThumbnailImage"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventFeedbackRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Events.EventRecord", "Event") + .WithMany() + .HasForeignKey("EventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Event"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "BannerImage") + .WithMany("EventBanners") + .HasForeignKey("BannerImageId"); + + b.HasOne("Eurofurence.App.Domain.Model.Events.EventConferenceDayRecord", "ConferenceDay") + .WithMany("Events") + .HasForeignKey("ConferenceDayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Eurofurence.App.Domain.Model.Events.EventConferenceRoomRecord", "ConferenceRoom") + .WithMany("Events") + .HasForeignKey("ConferenceRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Eurofurence.App.Domain.Model.Events.EventConferenceTrackRecord", "ConferenceTrack") + .WithMany("Events") + .HasForeignKey("ConferenceTrackId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "PosterImage") + .WithMany("EventPosters") + .HasForeignKey("PosterImageId"); + + b.Navigation("BannerImage"); + + b.Navigation("ConferenceDay"); + + b.Navigation("ConferenceRoom"); + + b.Navigation("ConferenceTrack"); + + b.Navigation("PosterImage"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fragments.LinkFragment", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Dealers.DealerRecord", null) + .WithMany("Links") + .HasForeignKey("DealerRecordId"); + + b.HasOne("Eurofurence.App.Domain.Model.Knowledge.KnowledgeEntryRecord", null) + .WithMany("Links") + .HasForeignKey("KnowledgeEntryRecordId"); + + b.HasOne("Eurofurence.App.Domain.Model.Maps.MapEntryRecord", null) + .WithMany("Links") + .HasForeignKey("MapEntryRecordId"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fursuits.FursuitBadgeRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "Image") + .WithMany("FursuitBadges") + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Knowledge.KnowledgeEntryRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Knowledge.KnowledgeGroupRecord", "KnowledgeGroup") + .WithMany("KnowledgeEntries") + .HasForeignKey("KnowledgeGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("KnowledgeGroup"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Maps.MapEntryRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Maps.MapRecord", "Map") + .WithMany("Entries") + .HasForeignKey("MapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Map"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Maps.MapRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", "Image") + .WithMany("Maps") + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("ImageRecordKnowledgeEntryRecord", b => + { + b.HasOne("Eurofurence.App.Domain.Model.Images.ImageRecord", null) + .WithMany() + .HasForeignKey("ImagesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Eurofurence.App.Domain.Model.Knowledge.KnowledgeEntryRecord", null) + .WithMany() + .HasForeignKey("KnowledgeEntriesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.ArtistAlleyUserPenaltyRecord", b => + { + b.Navigation("AuditLog"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.ArtistsAlley.TableRegistrationRecord", b => + { + b.Navigation("StateChangeLog"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Dealers.DealerRecord", b => + { + b.Navigation("Links"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventConferenceDayRecord", b => + { + b.Navigation("Events"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventConferenceRoomRecord", b => + { + b.Navigation("Events"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Events.EventConferenceTrackRecord", b => + { + b.Navigation("Events"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fursuits.CollectingGame.FursuitParticipationRecord", b => + { + b.Navigation("CollectionEntries"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Fursuits.CollectingGame.PlayerParticipationRecord", b => + { + b.Navigation("CollectionEntries"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Images.ImageRecord", b => + { + b.Navigation("Announcements"); + + b.Navigation("DealerArtPreviews"); + + b.Navigation("DealerArtistThumbnails"); + + b.Navigation("DealerArtists"); + + b.Navigation("EventBanners"); + + b.Navigation("EventPosters"); + + b.Navigation("FursuitBadges"); + + b.Navigation("Maps"); + + b.Navigation("TableRegistrations"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Knowledge.KnowledgeEntryRecord", b => + { + b.Navigation("Links"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Knowledge.KnowledgeGroupRecord", b => + { + b.Navigation("KnowledgeEntries"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Maps.MapEntryRecord", b => + { + b.Navigation("Links"); + }); + + modelBuilder.Entity("Eurofurence.App.Domain.Model.Maps.MapRecord", b => + { + b.Navigation("Entries"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/20240915170539_AddItemActivityFinalBidAmount.cs b/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/20240915170539_AddItemActivityFinalBidAmount.cs new file mode 100644 index 00000000..78d2fd1c --- /dev/null +++ b/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/20240915170539_AddItemActivityFinalBidAmount.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Eurofurence.App.Infrastructure.EntityFramework.Migrations +{ + /// + public partial class AddItemActivityFinalBidAmount : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "FinalBidAmount", + table: "ItemActivitys", + type: "int", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "FinalBidAmount", + table: "ItemActivitys"); + } + } +} diff --git a/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/AppDbContextModelSnapshot.cs b/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/AppDbContextModelSnapshot.cs index b381a8cf..a35c3396 100644 --- a/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/AppDbContextModelSnapshot.cs +++ b/src/Eurofurence.App.Infrastructure.EntityFramework/Migrations/AppDbContextModelSnapshot.cs @@ -137,6 +137,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("ArtistName") .HasColumnType("longtext"); + b.Property("FinalBidAmount") + .HasColumnType("int"); + b.Property("ImportDateTimeUtc") .HasColumnType("datetime(6)"); diff --git a/src/Eurofurence.App.Server.Services/Abstractions/ArtShow/ItemActivityNotificationResult.cs b/src/Eurofurence.App.Server.Services/Abstractions/ArtShow/ItemActivityNotificationResult.cs index 24e38438..6b2e7c76 100644 --- a/src/Eurofurence.App.Server.Services/Abstractions/ArtShow/ItemActivityNotificationResult.cs +++ b/src/Eurofurence.App.Server.Services/Abstractions/ArtShow/ItemActivityNotificationResult.cs @@ -7,5 +7,6 @@ public class ItemActivityNotificationResult public string RecipientUid { get; set; } public IList IdsSold { get; set; } public IList IdsToAuction { get; set; } + public int GrandTotal { get; set; } } } \ No newline at end of file diff --git a/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs b/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs index 474aea3b..fc0f7215 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -118,7 +118,7 @@ private async Task SendAgentClosingResultNotificationAsync(AgentClosingResultRec .AppendLine($"Dear {result.AgentName},\n\nWe'd like to inform you about the Art Show results for artist {result.ArtistName}.\n") .AppendLine($"Of {result.ExhibitsTotal} total exhibits:\n\n- {result.ExhibitsUnsold} remain unsold \n- {result.ExhibitsSold} were sold (before/during closing) \n- {result.ExhibitsToAuction} are going to the art auction \n") .AppendLine($"Your expected payout as of now is {result.TotalCashAmount} € (charity percentages, where applicable, already deducted).\n\nIf any exhibits are heading to the auction, the actual payout amount may still increase.\n") - .AppendLine($"Please pick up any unsold exhibits ({result.ExhibitsUnsold}) in the Art Show during Sales & Unsold Art Pickup times and collect your payout during Artists' Payout times.\n\nThank you!"); + .AppendLine($"Please pick up any unsold exhibits ({result.ExhibitsUnsold}) in the Art Show during Sales & Unsold Art Pickup times and collect your payout during Artists' Payout times.\n\nThank you!\n\n(Disclaimer: expected payout is purely informative and not guaranteed to be accurate, please double check with the posted listings or contact the Art Show team in case of irregularities.)"); var request = new SendPrivateMessageByRegSysRequest() { diff --git a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs index 819bd69a..399c6bc0 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -60,8 +60,9 @@ public async Task ImportActivityLogAsync(TextReader logReader) ASIDNO = csvRecord.ASIDNO, ArtistName = csvRecord.ArtistName, ArtPieceTitle = csvRecord.ArtPieceTitle, - Status = (ItemActivityRecord.StatusEnum) Enum.Parse(typeof(ItemActivityRecord.StatusEnum), + Status = (ItemActivityRecord.StatusEnum)Enum.Parse(typeof(ItemActivityRecord.StatusEnum), csvRecord.Status, true), + FinalBidAmount = csvRecord.FinalBidAmount, ImportDateTimeUtc = DateTime.UtcNow, ImportHash = csvRecord.Hash.Value }; @@ -131,9 +132,17 @@ private async Task SendItemsToAuctionNotificationAsync(string recipientUid, ILis $"{items.Count} item(s) on which you have been the last bidder will be part of the auction.\n"); foreach (var item in items) - message.AppendLine($"- {item.ASIDNO}: \"{item.ArtPieceTitle}\" by \"{item.ArtistName}\""); + { + if (item.FinalBidAmount is { } finalBidAmount && finalBidAmount > 0) + { + message.AppendLine($"- {item.ASIDNO}: \"{item.ArtPieceTitle}\" by \"{item.ArtistName}\" with final bid before auction {item.FinalBidAmount} €"); + } + else { + message.AppendLine($"- {item.ASIDNO}: \"{item.ArtPieceTitle}\" by \"{item.ArtistName}\""); + } + } - message.AppendLine("\nIf you wish to defend your current bids against other potential higher bids, please attend the auction.\n\nThank you!"); + message.AppendLine("\nIf you wish to defend your current bids against other potential higher bids, please attend the auction.\n\nThank you!\n\n(Disclaimer: final bid amounts not guaranteed to be accurate, please double check with the posted listings or contact the Art Show team in case of irregularities.)"); var request = new SendPrivateMessageByRegSysRequest() { @@ -166,10 +175,24 @@ private async Task SendItemsSoldNotificationAsync(string recipientUid, IList 0) + { + message.AppendLine($"- {item.ASIDNO}: \"{item.ArtPieceTitle}\" by \"{item.ArtistName}\" for a final bid of {finalBidAmount} €"); + totalDues += finalBidAmount; + } + else + { + message.AppendLine($"- {item.ASIDNO}: \"{item.ArtPieceTitle}\" by \"{item.ArtistName}\""); + } + } + + if (totalDues > 0) + message.AppendLine($"\nYour grand total is: {totalDues} €"); - message.AppendLine("\nPlease pick them up at the Art Show during sales hours (these are announced in the event schedule and can be found both in your con book or the mobile app).\n\nThank you!"); + message.AppendLine("\nPlease make sure you have sufficient cash with you and pay your items at the Security Desk in the foyer before proceeding to pick them up at the Art Show during Sales 6 Pickup. The times for Sales & Pickup are announced in the event schedule and can be found in your conbook, the schedule on our website or right here in the mobile app.\n\nThank you!\n\n(Disclaimer: grand total only includes items with final bid in listing above, won items and final bid amounts are purely informative and not guaranteed to be accurate, please double check with the posted listings or contact the Art Show team in case of irregularities.)"); var request = new SendPrivateMessageByRegSysRequest() { @@ -203,7 +226,8 @@ public IList SimulateNotificationRun() { RecipientUid = bundle.RecipientUid, IdsSold = bundle.ItemsSold.Select(a => a.ASIDNO).ToList(), - IdsToAuction = bundle.ItemsToAuction.Select(a => a.ASIDNO).ToList() + IdsToAuction = bundle.ItemsToAuction.Select(a => a.ASIDNO).ToList(), + GrandTotal = bundle.ItemsSold.Sum(i => (i.FinalBidAmount is { } finalBidAmount && finalBidAmount > 0) ? finalBidAmount : 0), }) .ToList(); } diff --git a/src/Eurofurence.App.Server.Services/ArtShow/LogImportRow.cs b/src/Eurofurence.App.Server.Services/ArtShow/LogImportRow.cs index d6716217..07efbc86 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/LogImportRow.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/LogImportRow.cs @@ -10,8 +10,9 @@ class LogImportRow public string ArtistName { get; set; } public string ArtPieceTitle { get; set; } public string Status { get; set; } + public int? FinalBidAmount { get; set; } public Lazy Hash => new Lazy( - () => Hashing.ComputeHashSha1(RegNo, ASIDNO, ArtistName, ArtPieceTitle, Status)); + () => Hashing.ComputeHashSha1(RegNo, ASIDNO, ArtistName, ArtPieceTitle, Status, FinalBidAmount ?? -1)); } } \ No newline at end of file diff --git a/src/Eurofurence.App.Server.Services/ArtShow/LogImportRowClassMap.cs b/src/Eurofurence.App.Server.Services/ArtShow/LogImportRowClassMap.cs index 2c18c9ee..d2fb19f1 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/LogImportRowClassMap.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/LogImportRowClassMap.cs @@ -1,4 +1,4 @@ -using CsvHelper.Configuration; +using CsvHelper.Configuration; namespace Eurofurence.App.Server.Services.ArtShow { @@ -11,6 +11,7 @@ public LogImportRowClassMap() Map(m => m.ArtistName).Index(2); Map(m => m.ArtPieceTitle).Index(3); Map(m => m.Status).Index(4); + Map(m => m.FinalBidAmount).Index(5); } } } \ No newline at end of file diff --git a/src/Eurofurence.App.Server.Web/Controllers/ArtShowController.cs b/src/Eurofurence.App.Server.Web/Controllers/ArtShowController.cs index 0bca2d53..18862a41 100644 --- a/src/Eurofurence.App.Server.Web/Controllers/ArtShowController.cs +++ b/src/Eurofurence.App.Server.Web/Controllers/ArtShowController.cs @@ -26,7 +26,7 @@ public ArtShowController( /// Import Art Show results for bidders (CSV) /// /// - /// Imports the Art Show result CSV for bidders (`RegNo, ASIDNO, ArtistName, ArtPieceTitle, Status ["Sold", Auction"]`).

+ /// Imports the Art Show result CSV for bidders (`RegNo,ASIDNO,ArtistName,ArtPieceTitle,Status,FinalBidAmount`), where `Status` may only be one of `Auction` or `Sold`.

/// There's a row-hash built from the mentioned import fields. If a row with the same hash is already present, it will be skipped. /// (Importing the same data multiple times does not lead to duplicates.) ///
@@ -96,7 +96,7 @@ public async Task DeleteUnprocessedItemActivitiesImportRowsAsync() /// Import Art Show results for agents (CSV) /// /// - /// Imports the Art Show result CSV for agents (`AgentBadgeNo, AgentName, ArtistName, TotalCashAmount, ExhibitsSold, ExhibitsUnsold, ExhibitsToAuction`).

+ /// Imports the Art Show result CSV for agents (`AgentBadgeNo,AgentName,ArtistName,TotalCashAmount,ExhibitsSold,ExhibitsUnsold,ExhibitsToAuction`).

/// There's a row-hash built from the mentioned import fields. If a row with the same hash is already present, it will be skipped. /// (Importing the same data multiple times does not lead to duplicates.) ///
From 94fcf330312df73fa9a91ac50892d5dc4c4c406b Mon Sep 17 00:00:00 2001 From: Fenrikur <3359222+Fenrikur@users.noreply.github.com> Date: Sun, 15 Sep 2024 21:51:38 +0200 Subject: [PATCH 3/7] fix(artshow): concurrency and localization issues --- .../ArtShow/AgentClosingResultService.cs | 16 +++++++--------- .../ArtShow/ItemActivityService.cs | 15 ++++++--------- .../ArtShow/LogImportRowClassMap.cs | 2 +- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs b/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs index fc0f7215..93e5cbdf 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -43,11 +43,10 @@ public async Task ImportAgentClosingResultLogAsync(TextReader logR { await _semaphore.WaitAsync(); - var csv = new CsvReader(logReader, CultureInfo.CurrentCulture); + var csv = new CsvReader(logReader, CultureInfo.InvariantCulture); csv.Context.RegisterClassMap(); csv.Context.Configuration.Delimiter = ","; - csv.Context.Configuration.HasHeaderRecord = false; await foreach (var csvRecord in csv.GetRecordsAsync()) { @@ -87,8 +86,8 @@ public async Task ImportAgentClosingResultLogAsync(TextReader logR return importResult; } - private IQueryable GetUnprocessedImportRows() - => _appDbContext.AgentClosingResults.Where(a => a.NotificationDateTimeUtc == null); + private IList GetUnprocessedImportRows() + => _appDbContext.AgentClosingResults.Where(a => a.NotificationDateTimeUtc == null).ToList(); public async Task ExecuteNotificationRunAsync() @@ -99,9 +98,8 @@ public async Task ExecuteNotificationRunAsync() var newNotifications = GetUnprocessedImportRows(); - var tasks = newNotifications.AsEnumerable().Select(SendAgentClosingResultNotificationAsync); - - await Task.WhenAll(tasks); + foreach (var newNotification in newNotifications) + await SendAgentClosingResultNotificationAsync(newNotification); } finally { @@ -135,7 +133,7 @@ private async Task SendAgentClosingResultNotificationAsync(AgentClosingResultRec result.PrivateMessageId = privateMessageId; result.NotificationDateTimeUtc = DateTime.UtcNow; - _appDbContext.AgentClosingResults.Update(result); + _appDbContext.Update(result); await _appDbContext.SaveChangesAsync(); } diff --git a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs index 399c6bc0..f88d440c 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -26,7 +26,7 @@ public class ItemActivityService : IItemActivityService public ItemActivityService( AppDbContext appDbContext, - ConventionSettings conventionSettings, + ConventionSettings conventionSettings, IPrivateMessageService privateMessageService ) { @@ -38,12 +38,11 @@ IPrivateMessageService privateMessageService public async Task ImportActivityLogAsync(TextReader logReader) { var importResult = new ImportResult(); - var csv = new CsvReader(logReader, CultureInfo.CurrentCulture); + var csv = new CsvReader(logReader, CultureInfo.InvariantCulture); csv.Context.RegisterClassMap(); csv.Context.Configuration.Delimiter = ","; - csv.Context.Configuration.HasHeaderRecord = false; - + await foreach (var csvRecord in csv.GetRecordsAsync()) { var existingRecord = await _appDbContext.ItemActivitys.AsNoTracking().FirstOrDefaultAsync(a => a.ImportHash == csvRecord.Hash.Value); @@ -109,13 +108,11 @@ public async Task ExecuteNotificationRunAsync() var notificationBundles = BuildNotificationBundles(); - var tasks = notificationBundles.Select(async bundle => + foreach (var bundle in notificationBundles) { if (bundle.ItemsSold?.Count > 0) await SendItemsSoldNotificationAsync(bundle.RecipientUid, bundle.ItemsSold); if (bundle.ItemsToAuction?.Count > 0) await SendItemsToAuctionNotificationAsync(bundle.RecipientUid, bundle.ItemsToAuction); - }); - - await Task.WhenAll(tasks); + } } finally { diff --git a/src/Eurofurence.App.Server.Services/ArtShow/LogImportRowClassMap.cs b/src/Eurofurence.App.Server.Services/ArtShow/LogImportRowClassMap.cs index d2fb19f1..ec97e777 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/LogImportRowClassMap.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/LogImportRowClassMap.cs @@ -1,4 +1,4 @@ -using CsvHelper.Configuration; +using CsvHelper.Configuration; namespace Eurofurence.App.Server.Services.ArtShow { From 290b8fa1c8786fb2623cf1e9e12a958ce52349eb Mon Sep 17 00:00:00 2001 From: Fenrikur <3359222+Fenrikur@users.noreply.github.com> Date: Sun, 15 Sep 2024 21:54:47 +0200 Subject: [PATCH 4/7] chore(artshow): add clarification on grand total --- .../ArtShow/ItemActivityService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs index f88d440c..3cac527d 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs @@ -187,9 +187,9 @@ private async Task SendItemsSoldNotificationAsync(string recipientUid, IList 0) - message.AppendLine($"\nYour grand total is: {totalDues} €"); + message.AppendLine($"\nYour expected grand total is: {totalDues} €"); - message.AppendLine("\nPlease make sure you have sufficient cash with you and pay your items at the Security Desk in the foyer before proceeding to pick them up at the Art Show during Sales 6 Pickup. The times for Sales & Pickup are announced in the event schedule and can be found in your conbook, the schedule on our website or right here in the mobile app.\n\nThank you!\n\n(Disclaimer: grand total only includes items with final bid in listing above, won items and final bid amounts are purely informative and not guaranteed to be accurate, please double check with the posted listings or contact the Art Show team in case of irregularities.)"); + message.AppendLine("\nPlease make sure you have sufficient cash with you and pay your items at the Security Desk in the foyer before proceeding to pick them up at the Art Show during Sales 6 Pickup. The times for Sales & Pickup are announced in the event schedule and can be found in your conbook, the schedule on our website or right here in the mobile app.\n\nThank you!\n\n(Disclaimer: expected grand total only includes items with final bid in listing above, won items and final bid amounts are purely informative and not guaranteed to be accurate, please double check with the posted listings or contact the Art Show team in case of irregularities.)"); var request = new SendPrivateMessageByRegSysRequest() { From 6c987d5d0df64f01bf0a4dc036dd71b66f741518 Mon Sep 17 00:00:00 2001 From: Fenrikur <3359222+Fenrikur@users.noreply.github.com> Date: Sun, 15 Sep 2024 22:03:32 +0200 Subject: [PATCH 5/7] fix(artshow): limit decimals for TotalCashAmount to two --- .../ArtShow/AgentClosingResultService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs b/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs index 93e5cbdf..ab2f53fc 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/AgentClosingResultService.cs @@ -115,7 +115,7 @@ private async Task SendAgentClosingResultNotificationAsync(AgentClosingResultRec message .AppendLine($"Dear {result.AgentName},\n\nWe'd like to inform you about the Art Show results for artist {result.ArtistName}.\n") .AppendLine($"Of {result.ExhibitsTotal} total exhibits:\n\n- {result.ExhibitsUnsold} remain unsold \n- {result.ExhibitsSold} were sold (before/during closing) \n- {result.ExhibitsToAuction} are going to the art auction \n") - .AppendLine($"Your expected payout as of now is {result.TotalCashAmount} € (charity percentages, where applicable, already deducted).\n\nIf any exhibits are heading to the auction, the actual payout amount may still increase.\n") + .AppendLine($"Your expected payout as of now is {result.TotalCashAmount:.00} € (charity percentages, where applicable, already deducted).\n\nIf any exhibits are heading to the auction, the actual payout amount may still increase.\n") .AppendLine($"Please pick up any unsold exhibits ({result.ExhibitsUnsold}) in the Art Show during Sales & Unsold Art Pickup times and collect your payout during Artists' Payout times.\n\nThank you!\n\n(Disclaimer: expected payout is purely informative and not guaranteed to be accurate, please double check with the posted listings or contact the Art Show team in case of irregularities.)"); var request = new SendPrivateMessageByRegSysRequest() From 176ba6156fb1c9573ab479d827ba60697b038779 Mon Sep 17 00:00:00 2001 From: Fenrikur <3359222+Fenrikur@users.noreply.github.com> Date: Sun, 15 Sep 2024 22:51:48 +0200 Subject: [PATCH 6/7] chore(static): update minimum OS versions for app --- src/Eurofurence.App.Server.Web/wwwroot/index.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Eurofurence.App.Server.Web/wwwroot/index.html b/src/Eurofurence.App.Server.Web/wwwroot/index.html index dfdd6237..06ef7ad4 100644 --- a/src/Eurofurence.App.Server.Web/wwwroot/index.html +++ b/src/Eurofurence.App.Server.Web/wwwroot/index.html @@ -62,7 +62,7 @@

Looking for the Eurofurence Mobile App?

QR Code for Android Phone Version

Android Phone

-
OS Version 5.0+
+
OS Version 6.0 or later
Google Play Button @@ -72,7 +72,8 @@
OS Version 5.0+
QR Code for iOS Version

iPhone/iPad

-
OS Version 15+
+
OS Version 13.4 or later
+ Date: Mon, 16 Sep 2024 11:07:53 +0200 Subject: [PATCH 7/7] chore(artshow): typo in message text --- .../ArtShow/ItemActivityService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs index 3cac527d..49488ac0 100644 --- a/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs +++ b/src/Eurofurence.App.Server.Services/ArtShow/ItemActivityService.cs @@ -189,7 +189,7 @@ private async Task SendItemsSoldNotificationAsync(string recipientUid, IList 0) message.AppendLine($"\nYour expected grand total is: {totalDues} €"); - message.AppendLine("\nPlease make sure you have sufficient cash with you and pay your items at the Security Desk in the foyer before proceeding to pick them up at the Art Show during Sales 6 Pickup. The times for Sales & Pickup are announced in the event schedule and can be found in your conbook, the schedule on our website or right here in the mobile app.\n\nThank you!\n\n(Disclaimer: expected grand total only includes items with final bid in listing above, won items and final bid amounts are purely informative and not guaranteed to be accurate, please double check with the posted listings or contact the Art Show team in case of irregularities.)"); + message.AppendLine("\nPlease make sure you have sufficient cash with you and pay your items at the Security Desk in the foyer before proceeding to pick them up at the Art Show during Sales & Pickup. The times for Sales & Pickup are announced in the event schedule and can be found in your conbook, the schedule on our website or right here in the mobile app.\n\nThank you!\n\n(Disclaimer: expected grand total only includes items with final bid in listing above, won items and final bid amounts are purely informative and not guaranteed to be accurate, please double check with the posted listings or contact the Art Show team in case of irregularities.)"); var request = new SendPrivateMessageByRegSysRequest() {