fix(pickup): prevent null rowversion on settings and slots save
All checks were successful
Build and Deploy TenantApi / build-and-deploy (push) Successful in 43s
All checks were successful
Build and Deploy TenantApi / build-and-deploy (push) Successful in 43s
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -92,6 +93,7 @@ public sealed class StorePickupController(
|
||||
setting.AllowDaysAhead = Math.Clamp(request.BasicSettings.BookingDays, 1, 30);
|
||||
setting.MaxQuantityPerOrder = request.BasicSettings.MaxItemsPerOrder;
|
||||
setting.Mode = request.Mode is null ? setting.Mode : StoreApiHelpers.ToPickupMode(request.Mode);
|
||||
setting.RowVersion = CreateRowVersion();
|
||||
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
return ApiResponse<object>.Ok(null);
|
||||
@@ -110,6 +112,7 @@ public sealed class StorePickupController(
|
||||
|
||||
var setting = await EnsurePickupSettingAsync(tenantId, parsedStoreId, cancellationToken);
|
||||
setting.Mode = request.Mode is null ? setting.Mode : StoreApiHelpers.ToPickupMode(request.Mode);
|
||||
setting.RowVersion = CreateRowVersion();
|
||||
|
||||
var existingSlots = await dbContext.StorePickupSlots
|
||||
.Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId)
|
||||
@@ -137,7 +140,8 @@ public sealed class StorePickupController(
|
||||
Capacity = capacity,
|
||||
ReservedCount = Math.Clamp(slot.ReservedCount, 0, capacity),
|
||||
Weekdays = StoreApiHelpers.SerializeWeekdays(slot.DayOfWeeks),
|
||||
IsEnabled = slot.Enabled
|
||||
IsEnabled = slot.Enabled,
|
||||
RowVersion = CreateRowVersion()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -163,6 +167,7 @@ public sealed class StorePickupController(
|
||||
|
||||
var setting = await EnsurePickupSettingAsync(tenantId, parsedStoreId, cancellationToken);
|
||||
setting.Mode = request.Mode is null ? setting.Mode : StoreApiHelpers.ToPickupMode(request.Mode);
|
||||
setting.RowVersion = CreateRowVersion();
|
||||
|
||||
var normalizedRule = NormalizeFineRule(request.FineRule);
|
||||
setting.FineRuleJson = JsonSerializer.Serialize(normalizedRule, StoreApiHelpers.JsonOptions);
|
||||
@@ -218,7 +223,8 @@ public sealed class StorePickupController(
|
||||
{
|
||||
targetSetting = new StorePickupSetting
|
||||
{
|
||||
StoreId = targetStoreId
|
||||
StoreId = targetStoreId,
|
||||
RowVersion = CreateRowVersion()
|
||||
};
|
||||
await dbContext.StorePickupSettings.AddAsync(targetSetting, cancellationToken);
|
||||
}
|
||||
@@ -229,6 +235,7 @@ public sealed class StorePickupController(
|
||||
targetSetting.MaxQuantityPerOrder = sourceSetting?.MaxQuantityPerOrder ?? 20;
|
||||
targetSetting.Mode = sourceSetting?.Mode ?? StorePickupMode.Big;
|
||||
targetSetting.FineRuleJson = sourceSetting?.FineRuleJson;
|
||||
targetSetting.RowVersion = CreateRowVersion();
|
||||
}
|
||||
|
||||
var targetSlots = await dbContext.StorePickupSlots
|
||||
@@ -247,7 +254,8 @@ public sealed class StorePickupController(
|
||||
Capacity = slot.Capacity,
|
||||
ReservedCount = slot.ReservedCount,
|
||||
Weekdays = slot.Weekdays,
|
||||
IsEnabled = slot.IsEnabled
|
||||
IsEnabled = slot.IsEnabled,
|
||||
RowVersion = CreateRowVersion()
|
||||
}))
|
||||
.ToList();
|
||||
|
||||
@@ -275,12 +283,18 @@ public sealed class StorePickupController(
|
||||
|
||||
setting = new StorePickupSetting
|
||||
{
|
||||
StoreId = storeId
|
||||
StoreId = storeId,
|
||||
RowVersion = CreateRowVersion()
|
||||
};
|
||||
await dbContext.StorePickupSettings.AddAsync(setting, cancellationToken);
|
||||
return setting;
|
||||
}
|
||||
|
||||
private static byte[] CreateRowVersion()
|
||||
{
|
||||
return RandomNumberGenerator.GetBytes(16);
|
||||
}
|
||||
|
||||
private static PickupFineRuleDto ParseFineRule(string? raw)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(raw))
|
||||
|
||||
@@ -1093,7 +1093,9 @@ public sealed class TakeoutAppDbContext(
|
||||
builder.Property(x => x.Mode).HasConversion<int>();
|
||||
builder.Property(x => x.FineRuleJson).HasColumnType("text");
|
||||
builder.Property(x => x.RowVersion)
|
||||
.IsConcurrencyToken();
|
||||
.IsRequired()
|
||||
.IsConcurrencyToken()
|
||||
.ValueGeneratedNever();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId }).IsUnique();
|
||||
}
|
||||
|
||||
@@ -1106,7 +1108,9 @@ public sealed class TakeoutAppDbContext(
|
||||
builder.Property(x => x.Weekdays).HasMaxLength(32).IsRequired();
|
||||
builder.Property(x => x.CutoffMinutes).HasDefaultValue(30);
|
||||
builder.Property(x => x.RowVersion)
|
||||
.IsConcurrencyToken();
|
||||
.IsRequired()
|
||||
.IsConcurrencyToken()
|
||||
.ValueGeneratedNever();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.Name });
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +283,10 @@ public sealed class TakeoutTenantAppDbContext(
|
||||
builder.Property(x => x.AllowDaysAhead).HasDefaultValue(3);
|
||||
builder.Property(x => x.DefaultCutoffMinutes).HasDefaultValue(30);
|
||||
builder.Property(x => x.MaxQuantityPerOrder);
|
||||
builder.Property(x => x.RowVersion).IsRowVersion();
|
||||
builder.Property(x => x.RowVersion)
|
||||
.IsRequired()
|
||||
.IsConcurrencyToken()
|
||||
.ValueGeneratedNever();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId }).IsUnique();
|
||||
}
|
||||
|
||||
@@ -300,7 +303,10 @@ public sealed class TakeoutTenantAppDbContext(
|
||||
builder.Property(x => x.ReservedCount).HasDefaultValue(0);
|
||||
builder.Property(x => x.Weekdays).HasMaxLength(32).HasDefaultValue("1,2,3,4,5,6,7");
|
||||
builder.Property(x => x.IsEnabled).HasDefaultValue(true);
|
||||
builder.Property(x => x.RowVersion).IsRowVersion();
|
||||
builder.Property(x => x.RowVersion)
|
||||
.IsRequired()
|
||||
.IsConcurrencyToken()
|
||||
.ValueGeneratedNever();
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId, x.StartTime, x.EndTime }).IsUnique();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user