diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html
index a2d6718..acc956f 100644
--- a/Resources/ChangeLog.html
+++ b/Resources/ChangeLog.html
@@ -1,6 +1,6 @@
WebDoorCreator - Egalware
- Version: 0.9.2306.0111
+ Version: 0.9.2306.0112
Release note:
-
diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt
index ed8a5e6..1d6390d 100644
--- a/Resources/VersNum.txt
+++ b/Resources/VersNum.txt
@@ -1 +1 @@
-0.9.2306.0111
+0.9.2306.0112
diff --git a/Resources/manifest.xml b/Resources/manifest.xml
index d4fc8da..c2cee8d 100644
--- a/Resources/manifest.xml
+++ b/Resources/manifest.xml
@@ -1,6 +1,6 @@
-
- 0.9.2306.0111
+ 0.9.2306.0112
http://nexus.steamware.net/repository/SWS/WDC/stable/WDC.UI.zip
http://nexus.steamware.net/repository/SWS/WDC/stable/ChangeLog.html
false
diff --git a/WebDoorCreator.Data/Controllers/WebDoorCreatorController.cs b/WebDoorCreator.Data/Controllers/WebDoorCreatorController.cs
index 8fdd7da..bc41a98 100644
--- a/WebDoorCreator.Data/Controllers/WebDoorCreatorController.cs
+++ b/WebDoorCreator.Data/Controllers/WebDoorCreatorController.cs
@@ -195,6 +195,36 @@ namespace WebDoorCreator.Data.Controllers
return fatto;
}
+ ///
+ /// Getting door data by key
+ ///
+ ///
+ public DoorModel? DoorGetByKey(int doorId)
+ {
+ DoorModel? dbResult = new DoorModel();
+ // retrieving data from db
+ using (WDCDataContext localDbCtx = new WDCDataContext(_configuration))
+ {
+ try
+ {
+ // extracting entire set
+ dbResult = localDbCtx
+ .DbSetDoor
+ .Where(x => x.DoorId == doorId)
+ .Include(o => o.OrderNav)
+ .Include(t => t.TypeNav)
+ .OrderBy(x => x.DoorId)
+ .AsNoTracking()
+ .FirstOrDefault();
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Error in DoorGetByKey:{Environment.NewLine}{exc}");
+ }
+ }
+ return dbResult;
+ }
+
///
/// Adding a new door
///
@@ -823,6 +853,31 @@ namespace WebDoorCreator.Data.Controllers
return fatto;
}
+ public List OrderGetByCompStatus(int CompanyId, int StatusId)
+ {
+ List dbResult = new List();
+ using (var dbCtx = new WDCDataContext(_configuration))
+ {
+ try
+ {
+ var rawData = dbCtx
+ .DbSetOrders
+ .Where(x => x.CompanyId == CompanyId && x.Status == StatusId)
+ .AsNoTracking()
+ .ToList();
+ if (rawData != null)
+ {
+ dbResult = rawData;
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Error in OrderGetByCompStatus:{Environment.NewLine}{exc}");
+ }
+ }
+ return dbResult;
+ }
+
public OrderModel OrderGetByKey(int orderId)
{
OrderModel dbResult = new OrderModel();
@@ -848,31 +903,6 @@ namespace WebDoorCreator.Data.Controllers
return dbResult;
}
- public List OrderGetByCompStatus(int CompanyId, int StatusId)
- {
- List dbResult = new List();
- using (var dbCtx = new WDCDataContext(_configuration))
- {
- try
- {
- var rawData = dbCtx
- .DbSetOrders
- .Where(x => x.CompanyId == CompanyId && x.Status==StatusId)
- .AsNoTracking()
- .ToList();
- if (rawData != null)
- {
- dbResult = rawData;
- }
- }
- catch (Exception exc)
- {
- Log.Error($"Error in OrderGetByCompStatus:{Environment.NewLine}{exc}");
- }
- }
- return dbResult;
- }
-
///
/// Remove order
///
diff --git a/WebDoorCreator.Data/DbModels/DoorOpModel.cs b/WebDoorCreator.Data/DbModels/DoorOpModel.cs
index cede43b..271381f 100644
--- a/WebDoorCreator.Data/DbModels/DoorOpModel.cs
+++ b/WebDoorCreator.Data/DbModels/DoorOpModel.cs
@@ -156,9 +156,10 @@ namespace WebDoorCreator.Data.DbModels
///
/// Clone oggetto
///
- ///
+ ///
+ ///
///
- public DoorOpModel ObjClone(string userId, int doorId)
+ public DoorOpModel ObjClone(string userName, int doorId)
{
DoorOpModel answ = new DoorOpModel();
DateTime adesso = DateTime.Now;
@@ -168,8 +169,8 @@ namespace WebDoorCreator.Data.DbModels
{
DateIns = adesso,
DateMod = adesso,
- UserIdIns = userId,
- UserIdMod = userId,
+ UserIdIns = userName,
+ UserIdMod = userName,
ObjectId = ObjectId,
DoorId = DoorId,
JsoncConfigVal = JsoncConfigVal,
@@ -184,8 +185,8 @@ namespace WebDoorCreator.Data.DbModels
{
DateIns = adesso,
DateMod = adesso,
- UserIdIns = userId,
- UserIdMod = userId,
+ UserIdIns = userName,
+ UserIdMod = userName,
ObjectId = ObjectId,
DoorId = doorId,
JsoncConfigVal = JsoncConfigVal,
diff --git a/WebDoorCreator.Data/Services/WebDoorCreatorService.cs b/WebDoorCreator.Data/Services/WebDoorCreatorService.cs
index f11d5ae..8c3289a 100644
--- a/WebDoorCreator.Data/Services/WebDoorCreatorService.cs
+++ b/WebDoorCreator.Data/Services/WebDoorCreatorService.cs
@@ -963,6 +963,54 @@ namespace WebDoorCreator.Data.Services
return SteamCrypto.DecryptString(encData, Constants.passPhrase);
}
+ ///
+ /// Clone a copy of the door in the specified order
+ ///
+ /// Record id to edit or add
+ /// Destination order where door must be placed
+ /// userName for cloning
+ ///
+ public async Task DoorCloneToOrder(int doorId, int orderId, string userName)
+ {
+ var dbResult = false;
+ int newDoorId = 0;
+ var doorOps2Add = new List();
+ var CurrDoor = await DoorGetByKey(doorId);
+ var DoorOpsList = await DoorOpGetByDoorId(doorId);
+ if (DoorOpsList != null)
+ {
+ var doorOps2Clone = DoorOpsList?.Where(x => x.DoorId == doorId).ToList();
+
+ var door2Clone = CurrDoor;
+
+ if (door2Clone != null)
+ {
+ var doorToAdd = door2Clone.ObjClone(userName);
+ // imposto ordine per la porta...
+ doorToAdd.OrderId = orderId;
+ // salvo!
+ newDoorId = await DoorInsert(doorToAdd);
+ if (newDoorId != 0 && doorOps2Clone != null)
+ {
+ foreach (var item in doorOps2Clone)
+ {
+ var doorOp2Add = item.ObjClone(userName, newDoorId);
+ doorOps2Add.Add(doorOp2Add);
+ }
+ // salvo!
+ dbResult = await DoorOpInsert(newDoorId, doorOps2Add);
+ }
+ }
+ }
+
+ // await dbController.DoorModQty(NewQty, doorId, isAdd); svuoto cache
+ await DoorFlushCache(doorId);
+ await DoorOpFlushCache(doorId);
+ await OrderDetailFlushCache(orderId);
+ await OrdersFlushCache();
+ return dbResult;
+ }
+
///
/// CElimina record posta
///
@@ -998,6 +1046,47 @@ namespace WebDoorCreator.Data.Services
return answ;
}
+ ///
+ /// Doors key (DoorId)
+ ///
+ public async Task DoorGetByKey(int doorId)
+ {
+ string source = "DB";
+ DoorModel? dbResult = new DoorModel();
+ // cerco da cache
+ string currKey = $"{Constants.rKeyDoor}:Single:{doorId}";
+ Stopwatch stopWatch = new Stopwatch();
+ stopWatch.Start();
+ string? rawData = await redisDb.StringGetAsync(currKey);
+ if (!string.IsNullOrEmpty(rawData))
+ {
+ source = "REDIS";
+ var tempResult = JsonConvert.DeserializeObject(rawData);
+ if (tempResult == null)
+ {
+ dbResult = new DoorModel();
+ }
+ else
+ {
+ dbResult = tempResult;
+ }
+ }
+ else
+ {
+ dbResult = dbController.DoorGetByKey(doorId);
+ rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
+ await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
+ }
+ if (dbResult == null)
+ {
+ dbResult = new DoorModel();
+ }
+ stopWatch.Stop();
+ TimeSpan ts = stopWatch.Elapsed;
+ Log.Debug($"DoorGetByKey | {source} in: {ts.TotalMilliseconds} ms");
+ return dbResult;
+ }
+
///
/// Doors list by numRec
///
@@ -1094,24 +1183,6 @@ namespace WebDoorCreator.Data.Services
return dbResult;
}
-
- ///
- /// Clone a copy of the door in the specified order
- ///
- /// Record id to edit or add
- /// Destination order where door must be placed
- ///
- public async Task DoorCloneToOrder(int DoorId, int OrderId)
- {
- var dbResult = false;// await dbController.DoorModQty(NewQty, DoorId, isAdd);
- // svuoto cache
- await DoorFlushCache(DoorId);
- await DoorOpFlushCache(DoorId);
- await OrderDetailFlushCache(OrderId);
- await OrdersFlushCache();
- return dbResult;
- }
-
///
/// Adding or removing a single door
///
@@ -1243,7 +1314,7 @@ namespace WebDoorCreator.Data.Services
}
///
- /// Create DDF from DoorId
+ /// Create DDF from doorId
///
public async Task DoorOpGetDDF(int DoorId)
{
@@ -1804,6 +1875,22 @@ namespace WebDoorCreator.Data.Services
return dbResult;
}
+ ///
+ /// Clean REDIS order detail data in cache
+ ///
+ /// 0 = all
+ ///
+ public async Task OrderDetailFlushCache(int OrderId)
+ {
+ RedisValue pattern = new RedisValue($"{Constants.rKeyDoorsByOrder}:*");
+ if (OrderId > 0)
+ {
+ pattern = new RedisValue($"{Constants.rKeyDoorsByOrder}:{OrderId}");
+ }
+ bool answ = await ExecFlushRedisPattern(pattern);
+ return answ;
+ }
+
///
/// Order (content) cloning
///
@@ -1820,20 +1907,43 @@ namespace WebDoorCreator.Data.Services
return dbResult;
}
- ///
- /// Clean REDIS order detail data in cache
- ///
- /// 0 = all
- ///
- public async Task OrderDetailFlushCache(int OrderId)
+ public async Task
?> OrderGetByCompStatus(int CompanyId, int StatusId)
{
- RedisValue pattern = new RedisValue($"{Constants.rKeyDoorsByOrder}:*");
- if (OrderId > 0)
+ string source = "DB";
+
+ List? dbResult = new List();
+ // cerco da cache
+ string currKey = $"{Constants.rKeyOrderByComp}:{CompanyId}:{StatusId}"; ;
+ Stopwatch stopWatch = new Stopwatch();
+ stopWatch.Start();
+ string? rawData = await redisDb.StringGetAsync(currKey);
+ if (!string.IsNullOrEmpty(rawData))
{
- pattern = new RedisValue($"{Constants.rKeyDoorsByOrder}:{OrderId}");
+ source = "REDIS";
+ var tempResult = JsonConvert.DeserializeObject>(rawData);
+ if (tempResult == null)
+ {
+ dbResult = new List();
+ }
+ else
+ {
+ dbResult = tempResult;
+ }
}
- bool answ = await ExecFlushRedisPattern(pattern);
- return answ;
+ else
+ {
+ dbResult = dbController.OrderGetByCompStatus(CompanyId, StatusId);
+ rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
+ await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
+ }
+ if (dbResult == null)
+ {
+ dbResult = new List();
+ }
+ stopWatch.Stop();
+ TimeSpan ts = stopWatch.Elapsed;
+ Log.Debug($"OrderGetByCompStatus | {source} in: {ts.TotalMilliseconds} ms");
+ return dbResult;
}
public async Task OrderGetByKey(int orderId)
@@ -1875,46 +1985,6 @@ namespace WebDoorCreator.Data.Services
return dbResult;
}
-
- public async Task?> OrderGetByCompStatus(int CompanyId, int StatusId)
- {
- string source = "DB";
-
- List? dbResult = new List();
- // cerco da cache
- string currKey = $"{Constants.rKeyOrderByComp}:{CompanyId}:{StatusId}"; ;
- Stopwatch stopWatch = new Stopwatch();
- stopWatch.Start();
- string? rawData = await redisDb.StringGetAsync(currKey);
- if (!string.IsNullOrEmpty(rawData))
- {
- source = "REDIS";
- var tempResult = JsonConvert.DeserializeObject>(rawData);
- if (tempResult == null)
- {
- dbResult = new List();
- }
- else
- {
- dbResult = tempResult;
- }
- }
- else
- {
- dbResult = dbController.OrderGetByCompStatus(CompanyId, StatusId);
- rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
- await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
- }
- if (dbResult == null)
- {
- dbResult = new List();
- }
- stopWatch.Stop();
- TimeSpan ts = stopWatch.Elapsed;
- Log.Debug($"OrderGetByCompStatus | {source} in: {ts.TotalMilliseconds} ms");
- return dbResult;
- }
-
///
/// Remove order
///
@@ -1994,7 +2064,7 @@ namespace WebDoorCreator.Data.Services
{
var dbResult = await dbController.OrderUpdate(orderId, newStatus);
// elimino cache redis...
- //bool answ = await DoorFlushCache(currRec.DoorId);
+ //bool answ = await DoorFlushCache(currRec.doorId);
// elimino cache redis dati ordine...
bool answ = await FlushRedisCache();
return dbResult;
@@ -2307,18 +2377,20 @@ namespace WebDoorCreator.Data.Services
Log.Debug($"VocLemmaGetAll | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
- public async Task>?> VocLemmaTEMPGetAll()
+
+ public async Task VocLemmaInsert()
{
- string source = "DB";
- Dictionary>? dbResult = new Dictionary>();
- // cerco da cache
+ bool fatto = false;
+
+ List VocLemmas = new List();
+
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
- dbResult = dbController.VocLemmaTEMPGetAll();
+ fatto = await dbController.VocLemmaInsert();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
- Log.Debug($"VocLemmaGetAll | {source} in: {ts.TotalMilliseconds} ms");
- return dbResult;
+ Log.Debug($"VocLemmaInsert in: {ts.TotalMilliseconds} ms");
+ return fatto;
}
public async Task> VocLemmaInsertPrepare(string rootPath)
@@ -2367,21 +2439,18 @@ namespace WebDoorCreator.Data.Services
return VocLemmas;
}
-
-
- public async Task VocLemmaInsert()
+ public async Task>?> VocLemmaTEMPGetAll()
{
- bool fatto = false;
-
- List VocLemmas = new List();
-
+ string source = "DB";
+ Dictionary>? dbResult = new Dictionary>();
+ // cerco da cache
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
- fatto = await dbController.VocLemmaInsert();
+ dbResult = dbController.VocLemmaTEMPGetAll();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
- Log.Debug($"VocLemmaInsert in: {ts.TotalMilliseconds} ms");
- return fatto;
+ Log.Debug($"VocLemmaGetAll | {source} in: {ts.TotalMilliseconds} ms");
+ return dbResult;
}
#endregion Public Methods
diff --git a/WebDoorCreator.UI/Components/DoorMan/DoorModal.razor.cs b/WebDoorCreator.UI/Components/DoorMan/DoorModal.razor.cs
index 9081a05..06e9a92 100644
--- a/WebDoorCreator.UI/Components/DoorMan/DoorModal.razor.cs
+++ b/WebDoorCreator.UI/Components/DoorMan/DoorModal.razor.cs
@@ -9,17 +9,15 @@ namespace WebDoorCreator.UI.Components.DoorMan
{
public partial class DoorModal
{
- protected List doorOps2Add = new List();
+ #region Public Properties
public DoorModel CurrDoor { get; set; } = new DoorModel();
-
public DoorModel CurrDoorClone { get; set; } = new DoorModel();
[Parameter]
public int CurrDoorId { get; set; } = 0;
public List DoorsList { get; set; } = new List();
- public List OrdersCompList { get; set; } = new List();
[Parameter]
public EventCallback E_DoorClose { get; set; }
@@ -30,8 +28,22 @@ namespace WebDoorCreator.UI.Components.DoorMan
[Parameter]
public int OrderId { get; set; } = 0;
+ public List OrdersCompList { get; set; } = new List();
+
[Parameter]
- public string userId { get; set; } = "";
+ public string UserName { get; set; } = "";
+
+ #endregion Public Properties
+
+ #region Protected Fields
+
+ protected List doorOps2Add = new List();
+ protected bool SaveOnTemplate = false;
+
+ #endregion Protected Fields
+
+ #region Protected Properties
+
[Inject]
protected IConfiguration config { get; set; } = null!;
@@ -54,14 +66,12 @@ namespace WebDoorCreator.UI.Components.DoorMan
protected int newDoorId { get; set; } = 0;
+ protected int OrderIdTplSel { get; set; } = 0;
protected List ordListVal { get; set; } = new List();
[Inject]
protected QueueDataService QDataServ { get; set; } = null!;
- [Inject]
- protected WebDoorCreatorService WDService { get; set; } = null!;
-
protected int userCurrCompany
{
get => WDCUService.userCurrComp;
@@ -75,6 +85,13 @@ namespace WebDoorCreator.UI.Components.DoorMan
[Inject]
protected WDCUserService WDCUService { get; set; } = null!;
+ [Inject]
+ protected WebDoorCreatorService WDService { get; set; } = null!;
+
+ #endregion Protected Properties
+
+ #region Protected Methods
+
protected async Task addOrRemoveOneDoorNumber(bool isAdd)
{
//var door = new DoorModel();
@@ -128,6 +145,14 @@ namespace WebDoorCreator.UI.Components.DoorMan
///
protected async Task doClone()
{
+ var cloned = await WDService.DoorCloneToOrder(CurrDoor.DoorId, CurrDoor.OrderId, UserName);
+ if (cloned)
+ {
+ await doSave();
+ await closeModal();
+ }
+
+#if false
var DoorOpsList = await WDService.DoorOpGetByDoorId(CurrDoorId);
if (DoorOpsList != null)
{
@@ -158,51 +183,9 @@ namespace WebDoorCreator.UI.Components.DoorMan
}
}
}
+#endif
}
- ///
- /// Clona la porta selezionata con annesse door operations nel template selezionato...
- ///
- ///
- protected async Task doSaveTemplate()
- {
- if (!await JSRuntime.InvokeAsync("confirm", $"Are you sure? this operation will copy current door to selected template order?"))
- return;
-
- var DoorOpsList = await WDService.DoorOpGetByDoorId(CurrDoorId);
- if (DoorOpsList != null)
- {
- var doorOps2Clone = DoorOpsList?.Where(x => x.DoorId == CurrDoorId).ToList();
-
- var door2Clone = CurrDoor;
-
- if (door2Clone != null)
- {
- var doorToAdd = door2Clone.ObjClone(userId);
- // salvo!
- newDoorId = await WDService.DoorInsert(doorToAdd);
- if (newDoorId != 0 && doorOps2Clone != null)
- {
- foreach (var item in doorOps2Clone)
- {
- var doorOp2Add = item.ObjClone(userId, newDoorId);
- doorOps2Add.Add(doorOp2Add);
- }
-
- // salvo!
- var done = await WDService.DoorOpInsert(newDoorId, doorOps2Add);
- if (done)
- {
- await doSave();
- await closeModal();
- }
- }
- }
- }
- }
-
- protected bool SaveOnTemplate = false;
-
///
/// Effettua salvataggio record e generazione DDF
///
@@ -229,8 +212,8 @@ namespace WebDoorCreator.UI.Components.DoorMan
listOp = listOp.OrderBy(d => ordListVal.IndexOf(d.ObjectId)).ToList();
string currDdf = currDdfConv.GetSerialized(listOp);
- // FIXME TODO: si potrebbe eliminare in futuro che va su REDIS
- // versione corrente del DDF generato
+ // FIXME TODO: si potrebbe eliminare in futuro che va su REDIS versione corrente
+ // del DDF generato
int currVers = await QDataServ.SendCalcReq(newDoorId, currDdf);
if (currVers > 0)
@@ -241,6 +224,24 @@ namespace WebDoorCreator.UI.Components.DoorMan
}
}
+ ///
+ /// Clona la porta selezionata con annesse door operations nel template selezionato...
+ ///
+ ///
+ protected async Task doSaveTemplate()
+ {
+ if (!await JSRuntime.InvokeAsync("confirm", $"Are you sure? this operation will copy current door to selected template order?"))
+ return;
+
+ // prendo ord templ dest...
+ var cloned = await WDService.DoorCloneToOrder(CurrDoor.DoorId, OrderIdTplSel, UserName);
+ if (cloned)
+ {
+ await doSave();
+ await closeModal();
+ }
+ }
+
protected override async Task OnInitializedAsync()
{
await Task.Delay(1);
@@ -250,6 +251,7 @@ namespace WebDoorCreator.UI.Components.DoorMan
var footRows = config.GetSection("ConfDDF:Footer").Get>();
currDdfConv = new WebDoorCreator.Data.DDF.Converter(vers, remDoorOp, headRows, footRows);
}
+
protected override async Task OnParametersSetAsync()
{
await Task.Delay(1);
@@ -308,7 +310,6 @@ namespace WebDoorCreator.UI.Components.DoorMan
}
}
- protected int OrderIdTplSel { get; set; } = 0;
-
+ #endregion Protected Methods
}
}
\ No newline at end of file
diff --git a/WebDoorCreator.UI/Pages/OrdersHomePage.razor b/WebDoorCreator.UI/Pages/OrdersHomePage.razor
index b0ad169..fd87337 100644
--- a/WebDoorCreator.UI/Pages/OrdersHomePage.razor
+++ b/WebDoorCreator.UI/Pages/OrdersHomePage.razor
@@ -157,7 +157,7 @@
@if (currDoorModal != null && currDoorModal.DoorId != 0)
{
-
+
}
@if (newOrdReq)
{
diff --git a/WebDoorCreator.UI/Pages/SuperAdmin.razor.cs b/WebDoorCreator.UI/Pages/SuperAdmin.razor.cs
index e4d2e1a..f05db12 100644
--- a/WebDoorCreator.UI/Pages/SuperAdmin.razor.cs
+++ b/WebDoorCreator.UI/Pages/SuperAdmin.razor.cs
@@ -200,7 +200,7 @@ namespace WebDoorCreator.UI.Pages
// var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
// code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
- // var callbackUrl = $"/Account/ConfirmEmail?userId{user.Id}&code{code}&returnUrl=~/";
+ // var callbackUrl = $"/Account/ConfirmEmail?UserName{user.Id}&code{code}&returnUrl=~/";
// await _emailSender.SendEmailAsync(email, "Web Door Creator: Please confirm your email account",
// $"Click here to confirm the account linked with this email.");
diff --git a/WebDoorCreator.UI/WebDoorCreator.UI.csproj b/WebDoorCreator.UI/WebDoorCreator.UI.csproj
index 7344cbb..f0969ca 100644
--- a/WebDoorCreator.UI/WebDoorCreator.UI.csproj
+++ b/WebDoorCreator.UI/WebDoorCreator.UI.csproj
@@ -3,7 +3,7 @@
net6.0
enable
- 0.9.2306.0111
+ 0.9.2306.0112
enable
aspnet-WebDoorCreator.UI-dfe95fed-1398-4144-bd43-8b3a765d6608