Push EFManager
continuous-integration/drone/push Build is failing Details

EFManagers
Louison PARANT 2 years ago
parent 360c84ed35
commit 931860ad0e

@ -1,4 +1,5 @@
using DTO; using DTO;
using EntityFrameworkLOL.DBContexts;
using EntityFrameworkLOL.Entities; using EntityFrameworkLOL.Entities;
using Model; using Model;
@ -27,12 +28,18 @@ namespace APILOL.Mapper
public static Champion ToModel(this ChampionEntity entity) public static Champion ToModel(this ChampionEntity entity)
{ {
return new Champion(entity.Name, entity.Class, entity.Icon, entity.Image.Base64, entity.Bio); var champion = new Champion(entity.Name, entity.Class, entity.Icon, "", entity.Bio);
if (entity.Skills != null) foreach (var s in entity.Skills) { champion.AddSkill(s.ToModel()); }
if (entity.Characteristics != null) foreach (var c in entity.Characteristics) { champion.AddCharacteristics(c.ToModel()); }
return champion;
} }
public static ChampionEntity ToEntity(this Champion item) public static ChampionEntity ToEntity(this Champion item, SQLiteContext context)
{ {
return new ChampionEntity ChampionEntity? championEntity = context.Champion.Find(item.Name);
if (championEntity == null)
{
championEntity = new()
{ {
Name = item.Name, Name = item.Name,
Bio = item.Bio, Bio = item.Bio,
@ -40,6 +47,10 @@ namespace APILOL.Mapper
Class = item.Class, Class = item.Class,
Image = new() { Base64 = item.Image.Base64 }, Image = new() { Base64 = item.Image.Base64 },
}; };
championEntity.Skills = item.Skills.Select(x => x.ToEntity(championEntity, context)).ToList();
championEntity.Characteristics = item.Characteristics.Select(x => x.ToEntity(championEntity, context)).ToList();
}
return championEntity;
} }
} }
} }

@ -0,0 +1,26 @@
using EntityFrameworkLOL.DBContexts;
using EntityFrameworkLOL.Entities;
namespace APILOL.Mapper
{
public static class CharacteristicsMapper
{
public static CharacteristicEntity ToEntity(this KeyValuePair<string, int> item, ChampionEntity champion, SQLiteContext context)
{
var characteristicEntity = context.Characteristic.Find(item.Key, champion.Name);
if (characteristicEntity == null)
{
return new()
{
Name = item.Key,
Value = item.Value,
};
}
return characteristicEntity;
}
public static Tuple<string, int> ToModel(this CharacteristicEntity entity)
=> new(entity.Name, entity.Value);
}
}

@ -1,4 +1,5 @@
using DTO; using DTO;
using EntityFrameworkLOL.DBContexts;
using EntityFrameworkLOL.Entities; using EntityFrameworkLOL.Entities;
using Model; using Model;
@ -27,15 +28,19 @@ namespace APILOL.Mapper
return new Rune(entity.Name, entity.Family, "", entity.Image.Base64, entity.Description); return new Rune(entity.Name, entity.Family, "", entity.Image.Base64, entity.Description);
} }
public static RuneEntity ToEntity(this Rune item) public static RuneEntity ToEntity(this Rune item, SQLiteContext context)
{ {
return new RuneEntity RuneEntity? runeEntity = context.Rune.Find(item.Name);
if (runeEntity == null)
{
return new()
{ {
Name = item.Name, Name = item.Name,
Description = item.Description, Description = item.Description,
Image = new() { Base64 = item.Image.Base64 }, Family = item.Family
Family = item.Family,
}; };
} }
return runeEntity;
}
} }
} }

@ -1,4 +1,5 @@
using DTO; using DTO;
using EntityFrameworkLOL.DBContexts;
using EntityFrameworkLOL.Entities; using EntityFrameworkLOL.Entities;
using Model; using Model;
@ -20,17 +21,36 @@ namespace APILOL.Mapper
return new RunePage(runePage.Name); return new RunePage(runePage.Name);
} }
public static RunePage ToModel(this RunePageEntity entity) public static RunePage ToModel(this RunePageEntity entity, SQLiteContext context)
{ {
return new RunePage(entity.Name); RunePage runePage = new(entity.Name);
if (entity.Runes != null)
{
foreach (var r in entity.Runes)
{
var rune = context.Rune.Find(r.Name);
//if (rune != null) runePage[r.category] = rune.ToModel();
};
}
return runePage;
} }
public static RunePageEntity ToEntity(this RunePage item) public static RunePageEntity ToEntity(this RunePage item, SQLiteContext context)
{ {
return new RunePageEntity RunePageEntity? runePageEntity = context.RunePage.Find(item.Name);
if (runePageEntity == null)
{
runePageEntity = new()
{ {
Name = item.Name, Name = item.Name,
}; };
runePageEntity.Runes = new List<RuneEntity>();
foreach (var r in item.Runes)
{
runePageEntity.Runes.Add(r.Value.ToEntity(context));
}
}
return runePageEntity;
} }
} }
} }

@ -0,0 +1,31 @@
using DTO;
using EntityFrameworkLOL.DBContexts;
using EntityFrameworkLOL.Entities;
using Model;
namespace APILOL.Mapper
{
public static class SkillMapper
{
public static SkillEntity ToEntity(this Skill item, ChampionEntity champion, SQLiteContext context)
{
var skillEntity = context.Skill.Find(item.Name);
if (skillEntity == null)
{
return new()
{
Name = item.Name,
Description = item.Description,
Type = item.Type,
Champions = new List<ChampionEntity>() { champion }
};
}
skillEntity!.Champions?.Add(champion);
return skillEntity;
}
public static Skill ToModel(this SkillEntity entity)
=> new(entity.Name, entity.Type, entity.Description);
}
}

@ -1,4 +1,5 @@
using DTO; using DTO;
using EntityFrameworkLOL.DBContexts;
using EntityFrameworkLOL.Entities; using EntityFrameworkLOL.Entities;
using Model; using Model;
@ -29,16 +30,16 @@ namespace APILOL.Mapper
return new Skin(entity.Name, entity.ChampionSkin.ToModel(), entity.Price, entity.Icon, entity.Description); return new Skin(entity.Name, entity.ChampionSkin.ToModel(), entity.Price, entity.Icon, entity.Description);
} }
public static SkinEntity ToEntity(this Skin item) public static SkinEntity ToEntity(this Skin item, SQLiteContext? context = null)
{ {
return new SkinEntity return new()
{ {
Name = item.Name, Name = item.Name,
ChampionSkin = context?.Champion.Find(item.Champion.Name) ?? item.Champion.ToEntity(context),
Description = item.Description, Description = item.Description,
Icon = item.Icon, Icon = item.Icon,
Price = item.Price, Image = null,
ChampionSkin = item.Champion.ToEntity(), Price = item.Price
Image = new() { Base64 = item.Image.Base64 },
}; };
} }
} }

@ -33,7 +33,7 @@ namespace EntityFrameworkLOL.Entities
public virtual ICollection<SkillEntity> Skills { get; set; } public virtual ICollection<SkillEntity> Skills { get; set; }
//public virtual ICollection<CharacteristicEntity> Characteristics { get; set; } public virtual ICollection<CharacteristicEntity> Characteristics { get; set; }
public virtual ICollection<RunePageEntity> RunePages { get; set; } public virtual ICollection<RunePageEntity> RunePages { get; set; }
} }

@ -2,6 +2,8 @@
using Shared; using Shared;
using System.Data.SqlTypes; using System.Data.SqlTypes;
using APILOL.Mapper; using APILOL.Mapper;
using Microsoft.EntityFrameworkCore;
using System.Xml.Linq;
namespace ManagersEF namespace ManagersEF
{ {
@ -16,18 +18,26 @@ namespace ManagersEF
public async Task<Champion?> AddItem(Champion? item) public async Task<Champion?> AddItem(Champion? item)
{ {
await parent.DbContext.Champion.AddAsync(item.ToEntity()); await parent.DbContext.Champion.AddAsync(item.ToEntity(parent.DbContext));
parent.DbContext.SaveChanges();
return item; return item;
} }
public async Task<bool> DeleteItem(Champion? item) public async Task<bool> DeleteItem(Champion? item)
{ {
parent.DbContext.Champion.Remove(item.ToEntity()); var toDelete = parent.DbContext.Champion.Find(item.Name);
if (toDelete != null)
{
parent.DbContext.Champion.Remove(toDelete);
parent.DbContext.SaveChanges();
return true; return true;
} }
return false;
}
public async Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
Console.WriteLine("GET");
return parent.DbContext.Champion.GetItemsWithFilterAndOrdering( return parent.DbContext.Champion.GetItemsWithFilterAndOrdering(
c => true, c => true,
index, count, index, count,
@ -36,6 +46,11 @@ namespace ManagersEF
public async Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.Champion.Include("Characteristics").GetItemsWithFilterAndOrdering(
c => c.Characteristics.Any(ch => ch.Name.Equals(charName)),
index, count,
orderingPropertyName, descending).Select(c => c.ToModel());
} }
public async Task<IEnumerable<Champion?>> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Champion?>> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
@ -57,8 +72,8 @@ namespace ManagersEF
public async Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.Champion.GetItemsWithFilterAndOrdering( return parent.DbContext.Champion.Include("runepages").GetItemsWithFilterAndOrdering(
c => c.RunePages.Any(rp => rp.Equals(runePage.ToEntity())), c => c.RunePages.Any(rp => rp.Equals(runePage.ToEntity(parent.DbContext))),
index, count, index, count,
orderingPropertyName, descending).Select(c => c.ToModel()); orderingPropertyName, descending).Select(c => c.ToModel());
@ -74,7 +89,7 @@ namespace ManagersEF
public async Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.Champion.GetItemsWithFilterAndOrdering( return parent.DbContext.Champion.Include("Skills").GetItemsWithFilterAndOrdering(
c => skill != null && c.Skills.Any(s => s.Name.Equals(skill)), c => skill != null && c.Skills.Any(s => s.Name.Equals(skill)),
index, count, index, count,
orderingPropertyName, descending).Select(c => c.ToModel()); orderingPropertyName, descending).Select(c => c.ToModel());
@ -104,7 +119,7 @@ namespace ManagersEF
public async Task<int> GetNbItemsByRunePage(RunePage? runePage) public async Task<int> GetNbItemsByRunePage(RunePage? runePage)
{ {
return parent.DbContext.Champion.Where(c => c.RunePages.Any(rp => rp.Equals(runePage.ToEntity()))).Count(); return parent.DbContext.Champion.Where(c => c.RunePages.Any(rp => rp.Equals(runePage.ToEntity(parent.DbContext)))).Count();
} }
@ -122,8 +137,9 @@ namespace ManagersEF
public async Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem) public async Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem)
{ {
parent.DbContext.Champion.Remove(oldItem.ToEntity()); var toUpdate = parent.DbContext.Champion.Find(oldItem.Name);
parent.DbContext.Champion.Add(newItem.ToEntity()); toUpdate = newItem.ToEntity(parent.DbContext);
parent.DbContext.SaveChanges();
return newItem; return newItem;
} }
} }

@ -1,8 +1,11 @@
using APILOL.Mapper; using APILOL.Mapper;
using EntityFrameworkLOL.Entities;
using ManagersEF; using ManagersEF;
using Microsoft.EntityFrameworkCore;
using Model; using Model;
using System.Data.SqlTypes; using System.Data.SqlTypes;
using System.Linq; using System.Linq;
using System.Xml.Linq;
namespace ManagersEF namespace ManagersEF
{ {
@ -17,30 +20,37 @@ namespace ManagersEF
public async Task<RunePage?> AddItem(RunePage? item) public async Task<RunePage?> AddItem(RunePage? item)
{ {
await parent.DbContext.RunePage.AddAsync(item.ToEntity()); await parent.DbContext.RunePage.AddAsync(item.ToEntity(parent.DbContext));
parent.DbContext.SaveChanges();
return item; return item;
} }
public async Task<bool> DeleteItem(RunePage? item) public async Task<bool> DeleteItem(RunePage? item)
{ {
parent.DbContext.RunePage.Remove(item.ToEntity()); var toDelete = parent.DbContext.RunePage.Find(item.Name);
if (toDelete != null)
{
parent.DbContext.RunePage.Remove(toDelete);
parent.DbContext.SaveChanges();
return true; return true;
} }
return false;
}
public async Task<IEnumerable<RunePage?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<RunePage?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.RunePage.GetItemsWithFilterAndOrdering( return parent.DbContext.RunePage.GetItemsWithFilterAndOrdering(
rp => true, rp => true,
index, count, index, count,
orderingPropertyName, descending).Select(rp => rp.ToModel()); orderingPropertyName, descending).Select(rp => rp.ToModel(parent.DbContext));
} }
public async Task<IEnumerable<RunePage?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<RunePage?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.RunePage.GetItemsWithFilterAndOrdering( return parent.DbContext.RunePage.Include("champions").GetItemsWithFilterAndOrdering(
rp => rp.Champions.Any(c => c.Name.Equals(champion.Name)), rp => rp.Champions.Any(c => c.Name.Equals(champion.Name)),
index, count, index, count,
orderingPropertyName, descending).Select(rp => rp.ToModel()); orderingPropertyName, descending).Select(rp => rp.ToModel(parent.DbContext));
} }
public async Task<IEnumerable<RunePage?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<RunePage?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
@ -48,15 +58,15 @@ namespace ManagersEF
return parent.DbContext.RunePage.GetItemsWithFilterAndOrdering( return parent.DbContext.RunePage.GetItemsWithFilterAndOrdering(
rp => rp.Name.Contains(substring), rp => rp.Name.Contains(substring),
index, count, index, count,
orderingPropertyName, descending).Select(rp => rp.ToModel()); orderingPropertyName, descending).Select(rp => rp.ToModel(parent.DbContext));
} }
public async Task<IEnumerable<RunePage?>> GetItemsByRune(Rune? rune, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<RunePage?>> GetItemsByRune(Rune? rune, int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.RunePage.GetItemsWithFilterAndOrdering( return parent.DbContext.RunePage.Include("entries").GetItemsWithFilterAndOrdering(
rp => rp.Runes.Any(r => r.Name.Equals(rune.Name)), rp => rp.entries.Any(r => r.RuneName.Equals(rune.Name)),
index, count, index, count,
orderingPropertyName, descending).Select(rp => rp.ToModel()); orderingPropertyName, descending).Select(rp => rp.ToModel(parent.DbContext));
} }
public async Task<int> GetNbItems() public async Task<int> GetNbItems()
@ -67,7 +77,7 @@ namespace ManagersEF
public async Task<int> GetNbItemsByChampion(Champion? champion) public async Task<int> GetNbItemsByChampion(Champion? champion)
{ {
return parent.DbContext.RunePage.Where(rp => rp.Champions.Any(c => c.Name.Equals(champion.Name))).Count(); return parent.DbContext.RunePage.Where(rp => rp.champions.Any(c => c.Name.Equals(champion.Name))).Count();
} }
@ -78,14 +88,27 @@ namespace ManagersEF
public async Task<int> GetNbItemsByRune(Model.Rune? rune) public async Task<int> GetNbItemsByRune(Model.Rune? rune)
{ {
return parent.DbContext.RunePage.Where(rp => rp.Runes.Any(r => r.Name.Equals(rune.Name))).Count(); return parent.DbContext.RunePage.Where(rp => rp.entries.Any(r => r.RuneName.Equals(rune.Name))).Count();
} }
public async Task<RunePage?> UpdateItem(RunePage? oldItem, RunePage? newItem) public async Task<RunePage?> UpdateItem(RunePage? oldItem, RunePage? newItem)
{ {
parent.DbContext.RunePage.Remove(oldItem.ToEntity()); var toUpdate = parent.DbContext.RunePage.Include("entries")
parent.DbContext.RunePage.Add(newItem.ToEntity()); .Where(x => x.Name.Equals(newItem.Name)).First();
try
{
toUpdate.entries = newItem.Runes.Select(r => new RunePageRuneEntity()
{
category = r.Key,
rune = r.Value.ToEntity(parent.DbContext),
}).ToList();
parent.DbContext.SaveChanges();
}
catch (DbUpdateException) { }
return newItem; return newItem;
} }
} }
} }

@ -1,6 +1,8 @@
using APILOL.Mapper; using APILOL.Mapper;
using Microsoft.EntityFrameworkCore;
using Model; using Model;
using Shared; using Shared;
using System.Xml.Linq;
namespace ManagersEF namespace ManagersEF
{ {
@ -14,15 +16,22 @@ namespace ManagersEF
=> this.parent = parent; => this.parent = parent;
public async Task<Rune?> AddItem(Rune? item) public async Task<Rune?> AddItem(Rune? item)
{ {
await parent.DbContext.Rune.AddAsync(item.ToEntity()); await parent.DbContext.Rune.AddAsync(item.ToEntity(parent.DbContext));
parent.DbContext.SaveChanges();
return item; return item;
} }
public async Task<bool> DeleteItem(Rune? item) public async Task<bool> DeleteItem(Rune? item)
{ {
parent.DbContext.Rune.Remove(item.ToEntity()); var toDelete = parent.DbContext.Rune.Find(item?.Name);
if (toDelete != null)
{
parent.DbContext.Rune.Remove(item?.ToEntity(parent.DbContext));
parent.DbContext.SaveChanges();
return true; return true;
} }
return false;
}
public async Task<IEnumerable<Rune?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Rune?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
@ -65,8 +74,10 @@ namespace ManagersEF
public async Task<Rune?> UpdateItem(Rune? oldItem, Rune? newItem) public async Task<Rune?> UpdateItem(Rune? oldItem, Rune? newItem)
{ {
parent.DbContext.Rune.Remove(oldItem.ToEntity()); var toUpdate = parent.DbContext.Rune.Find(oldItem.Name);
parent.DbContext.Rune.Add(newItem.ToEntity()); toUpdate.Description = newItem.Description;
toUpdate.Family = newItem.Family;
parent.DbContext.SaveChanges();
return newItem; return newItem;
} }
} }

@ -1,6 +1,8 @@
using APILOL.Mapper; using APILOL.Mapper;
using Microsoft.EntityFrameworkCore;
using Model; using Model;
using System.Data.SqlTypes; using System.Data.SqlTypes;
using System.Xml.Linq;
namespace ManagersEF namespace ManagersEF
{ {
@ -15,38 +17,45 @@ namespace ManagersEF
public async Task<Skin?> AddItem(Skin? item) public async Task<Skin?> AddItem(Skin? item)
{ {
await parent.DbContext.Skin.AddAsync(item.ToEntity()); await parent.DbContext.Skin.AddAsync(item.ToEntity(parent.DbContext));
parent.DbContext.SaveChanges();
return item; return item;
} }
public async Task<bool> DeleteItem(Skin? item) public async Task<bool> DeleteItem(Skin? item)
{ {
parent.DbContext.Skin.Remove(item.ToEntity()); var toDelete = parent.DbContext.Skin.Find(item.Name);
if (toDelete != null)
{
parent.DbContext.Skin.Remove(toDelete);
parent.DbContext.SaveChanges();
return true; return true;
} }
return false;
}
public async Task<IEnumerable<Skin?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Skin?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.Skin.GetItemsWithFilterAndOrdering( return parent.DbContext.Skin.Include("Champion").GetItemsWithFilterAndOrdering(
s => true, s => true,
index, count, index, count,
orderingPropertyName, descending).Select(s => s.ToModel()); orderingPropertyName, descending).Select(s => s?.ToModel());
} }
public async Task<IEnumerable<Skin?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Skin?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.Skin.GetItemsWithFilterAndOrdering( return parent.DbContext.Skin.Include("Champion").GetItemsWithFilterAndOrdering(
s => s.Champion.Name.Equals(champion.Name), s => s.ChampionSkin.Name.Equals(champion?.Name),
index, count, index, count,
orderingPropertyName, descending).Select(s => s.ToModel()); orderingPropertyName, descending).Select(s => s?.ToModel());
} }
public async Task<IEnumerable<Skin?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false) public async Task<IEnumerable<Skin?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{ {
return parent.DbContext.Skin.GetItemsWithFilterAndOrdering( return parent.DbContext.Skin.Include("Champion").GetItemsWithFilterAndOrdering(
s => s.Name.Contains(substring), s => s.Name.Contains(substring),
index, count, index, count,
orderingPropertyName, descending).Select(s => s.ToModel()); orderingPropertyName, descending).Select(s => s?.ToModel());
} }
public async Task<int> GetNbItems() public async Task<int> GetNbItems()
@ -56,9 +65,13 @@ namespace ManagersEF
public async Task<int> GetNbItemsByChampion(Champion? champion) public async Task<int> GetNbItemsByChampion(Champion? champion)
{ {
return parent.DbContext.Skin.Where(s => s.Champion.Name.Equals(champion.Name)) if (champion != null)
{
return parent.DbContext.Skin.Where(s => s.ChampionSkin.Name.Equals(champion.Name))
.Count(); .Count();
} }
return 0;
}
public async Task<int> GetNbItemsByName(string substring) public async Task<int> GetNbItemsByName(string substring)
{ {
@ -68,8 +81,8 @@ namespace ManagersEF
public async Task<Skin?> UpdateItem(Skin? oldItem, Skin? newItem) public async Task<Skin?> UpdateItem(Skin? oldItem, Skin? newItem)
{ {
parent.DbContext.Skin.Remove(oldItem.ToEntity()); var toUpdate = parent.DbContext.Skin.Find(oldItem.Name);
parent.DbContext.Skin.Add(newItem.ToEntity()); toUpdate.ChampionSkin = parent.DbContext.Champion.Find(newItem.Champion.Name);
return newItem; return newItem;
} }
} }

Loading…
Cancel
Save