using System; using System.Collections.Generic; using System.Linq; using Luticate2.Utils.Dbo.Basic; using Luticate2.Utils.Dbo.Filter; using Luticate2.Utils.Dbo.OrderBy; using Luticate2.Utils.Dbo.Result; using Luticate2.Utils.Interfaces; namespace Luticate2.Utils.Business { public abstract class LuCrudBusiness : LuBusiness, ILuCrudInterface where TDataAccess : ILuCrudInterface where TDboCreate : class where TDboRead : class where TDboUpdate : class { protected readonly TDataAccess DataAccess; private readonly LuNotificationsBusiness _notificationsBusiness; protected virtual string EntityType { get; set; } protected virtual Func NotifyCreateFilter { get; set; } protected virtual Func NotifyUpdateFilter { get; set; } protected virtual Func NotifyDeleteFilter { get; set; } protected LuCrudBusiness(TDataAccess dataAccess, LuNotificationsBusiness notificationsBusiness) { DataAccess = dataAccess; _notificationsBusiness = notificationsBusiness; } protected virtual LuResult CheckAdd(TDboCreate obj) { return LuResult.Ok(obj); } protected virtual LuResult> CheckAdd(IEnumerable objs) { var list = new List(); foreach (var obj in objs) { var res = CheckAdd(obj); if (!res) { return res.To>(); } list.Add(res.Data); } return LuResult>.Ok(list); } protected virtual LuResult CheckEdit(TDboRead dbo, TDboUpdate update) { return LuResult.Ok(update); } protected LuResult GetAndCheckEdit(TId id, TDboUpdate update) { var res = GetSingleById(id); if (!res) { return res.To(); } return CheckEdit(res.Data, update); } public virtual LuResult Add(IEnumerable objs, Func, T> returnFunc) { var res = CheckAdd(objs); if (!res) { return res.To(); } return DataAccess.Add(res.Data, returnFunc); } public virtual LuResult Add(TDboCreate obj, Func returnFunc) { var res = CheckAdd(obj); if (!res) { return res.To(); } var newEntity = DataAccess.AddDbo(res.Data); if (newEntity) { _notificationsBusiness.NotifyCreate(EntityType, newEntity.Data, s => NotifyCreateFilter(s, newEntity.Data)); return LuResult.Ok(returnFunc(newEntity.Data)); } return newEntity.To(); } public virtual LuResult> AddId(IEnumerable objs) { return Add(objs, reads => reads.Select(read => (TId)((dynamic)read).Id)); } public virtual LuResult AddId(TDboCreate obj) { return Add(obj, read => (TId)((dynamic)read).Id); } public virtual LuResult> AddDbo(IEnumerable objs) { return Add(objs, reads => reads); } public virtual LuResult AddDbo(TDboCreate obj) { return Add(obj, read => read); } public virtual LuResult GetSingleById(TId id) { return DataAccess.GetSingleById(id); } public virtual LuResult> GetMultiple(LuOrderByDbo orderBy, LuFilterDbo filter, int page = 0, int perPage = int.MaxValue) { return DataAccess.GetMultiple(orderBy, filter, page, perPage); } public virtual LuResult> GetMultiple(LuOrderByDbo orderBy, int page = 0, int perPage = int.MaxValue) { return DataAccess.GetMultiple(orderBy, page, perPage); } public virtual LuResult EditSingleById(TId id, TDboUpdate update, Func returnFunc) { var originalEntity = GetSingleById(id); if (!originalEntity) { return originalEntity.To(); } var obj = CheckEdit(originalEntity.Data, update); if (!obj) { return obj.To(); } var editedEntity = DataAccess.EditSingleByIdDbo(id, obj.Data); if (editedEntity) { _notificationsBusiness.NotifyUpdate(EntityType, originalEntity.Data, editedEntity.Data, s => NotifyUpdateFilter(s, originalEntity.Data, editedEntity.Data)); return LuResult.Ok(returnFunc(editedEntity.Data)); } return editedEntity.To(); } public virtual LuResult EditSingleByIdId(TId id, TDboUpdate update) { return EditSingleById(id, update, read => (TId)((dynamic)read).Id); } public virtual LuResult EditSingleByIdDbo(TId id, TDboUpdate update) { return EditSingleById(id, update, read => read); } public virtual LuResult DeleteSingleById(TId id, Func returnFunc) { var originalEntity = GetSingleById(id); if (!originalEntity) { return originalEntity.To(); } var res = DataAccess.DeleteSingleById(id, returnFunc); if (res) { _notificationsBusiness.NotifyDelete(EntityType, originalEntity.Data, s => NotifyDeleteFilter(s, originalEntity.Data)); } return res; } public virtual LuResult DeleteSingleByIdId(TId id) { return DeleteSingleById(id, read => (TId)((dynamic)read).Id); } public virtual LuResult DeleteSingleByIdDbo(TId id) { return DeleteSingleById(id, read => read); } } }