270 lines
9.9 KiB
C#
270 lines
9.9 KiB
C#
using EgwCoreLib.Lux.Data.DbModel.Items;
|
|
using EgwCoreLib.Lux.Data.DbModel.Sales;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using static EgwCoreLib.Lux.Core.Enums;
|
|
|
|
namespace EgwCoreLib.Lux.Data.Repository.Sales
|
|
{
|
|
public class OfferRepository : BaseRepository, IOfferRepository
|
|
{
|
|
#region Public Constructors
|
|
|
|
public OfferRepository(IDbContextFactory<DataLayerContext> ctxFactory) : base(ctxFactory)
|
|
{
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Methods
|
|
|
|
public async Task<bool> AddAsync(OfferModel entity)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
await dbCtx.DbSetOffer.AddAsync(entity);
|
|
return await dbCtx.SaveChangesAsync() > 0;
|
|
}
|
|
|
|
public async Task<bool> CheckExpiredAsync()
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
DateTime adesso = DateTime.Now;
|
|
// recupero offerta...
|
|
var listExpired = await dbCtx
|
|
.DbSetOffer
|
|
.Where(x => x.ValidUntil < adesso && x.OffertState == OfferStates.Open)
|
|
.ToListAsync();
|
|
|
|
// se trovo le aggiorno come stato
|
|
if (listExpired != null)
|
|
{
|
|
foreach (var item in listExpired)
|
|
{
|
|
item.OffertState = OfferStates.Expired;
|
|
dbCtx.Entry(item).State = EntityState.Modified;
|
|
}
|
|
|
|
// salvo TUTTI i cambiamenti...
|
|
return await dbCtx.SaveChangesAsync() > 0;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue il cloning completo di un Offerta e di TUTTE le relative righe...
|
|
/// </summary>
|
|
/// <param name="rec2clone"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> CloneAsync(OfferModel rec2clone)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
|
|
// Wrap in transaction for atomicity (parent + children clone)
|
|
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
|
try
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
|
|
var currRec = await dbCtx.DbSetOffer
|
|
.Include(x => x.OfferRowNav)
|
|
.FirstOrDefaultAsync(x => x.OfferID == rec2clone.OfferID);
|
|
|
|
if (currRec == null)
|
|
return false;
|
|
|
|
DateTime adesso = DateTime.Now;
|
|
var lastRec = dbCtx
|
|
.DbSetOffer
|
|
.Where(x => x.RefYear == adesso.Year)
|
|
.OrderByDescending(x => x.RefNum)
|
|
.FirstOrDefault();
|
|
int newRefNum = lastRec != null ? lastRec.RefNum + 1 : 1;
|
|
|
|
// 2. Creo il nuovo parent
|
|
var newRec = new OfferModel()
|
|
{
|
|
ConsNote = rec2clone.ConsNote,
|
|
CustomerID = rec2clone.CustomerID,
|
|
DealerID = rec2clone.DealerID,
|
|
Description = rec2clone.Description,
|
|
DictPresel = rec2clone.DictPresel,
|
|
Discount = rec2clone.Discount,
|
|
DueDateProm = rec2clone.DueDateProm,
|
|
DueDateReq = rec2clone.DueDateReq,
|
|
Envir = rec2clone.Envir,
|
|
Inserted = adesso,
|
|
Modified = adesso,
|
|
OffertState = OfferStates.Open,
|
|
RefNum = newRefNum,
|
|
RefRev = 1,
|
|
RefYear = adesso.Year,
|
|
ValidUntil = currRec.ValidUntil
|
|
};
|
|
|
|
// 3. Clono i child
|
|
// sistemo child...
|
|
newRec.OfferRowNav = currRec.OfferRowNav
|
|
.Select(c => new OfferRowModel()
|
|
{
|
|
AwaitBom = c.AwaitBom,
|
|
AwaitPrice = c.AwaitPrice,
|
|
BomCost = c.BomCost,
|
|
BomOk = c.BomOk,
|
|
BomPrice = c.BomPrice,
|
|
Envir = c.Envir,
|
|
FileName = c.FileName,
|
|
FileResource = c.FileResource,
|
|
FileSize = c.FileSize,
|
|
Inserted = adesso,
|
|
ItemBOM = c.ItemBOM,
|
|
ItemJCD = c.ItemJCD,
|
|
ItemOk = c.ItemOk,
|
|
ItemSteps = c.ItemSteps,
|
|
ItemTags = c.ItemTags,
|
|
JobID = c.JobID,
|
|
Modified = c.Modified,
|
|
Note = c.Note,
|
|
ProdItemQty = c.ProdItemQty,
|
|
Qty = c.Qty,
|
|
RowNum = c.RowNum,
|
|
SellingItemID = c.SellingItemID,
|
|
SerStruct = c.SerStruct,
|
|
StepCost = c.StepCost,
|
|
StepFlowTime = c.StepFlowTime,
|
|
StepLeadTime = c.StepLeadTime,
|
|
StepPrice = c.StepPrice,
|
|
//OrderID = dbRec.OrderID,
|
|
OfferRowUID = c.OfferRowDtx
|
|
})
|
|
.ToList();
|
|
|
|
// 4. Aggiungo il nuovo parent (EF aggiunge anche i child)
|
|
dbCtx.DbSetOffer.Add(newRec);
|
|
|
|
// 5. Salvo tutto in transazione
|
|
await dbCtx.SaveChangesAsync();
|
|
await tx.CommitAsync();
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
await tx.RollbackAsync();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> DeleteAsync(OfferModel entity)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
dbCtx.DbSetOffer.Remove(entity);
|
|
return await dbCtx.SaveChangesAsync() > 0;
|
|
}
|
|
|
|
public async Task<List<OfferModel>> GetAllAsync()
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetOffer
|
|
.Include(c => c.CustomerNav)
|
|
.Include(d => d.DealerNav)
|
|
.Include(o => o.OfferRowNav)
|
|
.AsNoTracking()
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<List<ItemModel>> GetBomItemsAsync()
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetItem
|
|
.Where(x => x.ItemType == ItemClassType.Bom || x.ItemType == ItemClassType.BomAlt)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<OfferModel?> GetByIdAsync(int recId)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetOffer.FirstOrDefaultAsync(x => x.OfferID == recId);
|
|
}
|
|
|
|
public async Task<List<OfferModel>> GetFiltAsync(DateTime inizio, DateTime fine)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetOffer
|
|
.Where(x => x.Inserted >= inizio && x.Inserted <= fine)
|
|
.Include(c => c.CustomerNav)
|
|
.Include(d => d.DealerNav)
|
|
.Include(o => o.OfferRowNav)
|
|
.AsNoTracking()
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<List<ItemGroupModel>> GetItemGroupsAsync()
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetItemGroup.ToListAsync();
|
|
}
|
|
|
|
public async Task<List<OfferRowModel>> GetRowsAsync(int recId)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetOfferRow
|
|
.Where(x => x.OfferID == recId)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<bool> SaveRowsAsync(List<OfferRowModel> rows)
|
|
{
|
|
// Add validation for null or empty list
|
|
if (rows == null || rows.Count == 0) return false;
|
|
|
|
await using var dbCtx = await CreateContextAsync();
|
|
|
|
// Wrap in transaction for atomicity (batch update multiple rows)
|
|
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
|
try
|
|
{
|
|
foreach (var row in rows)
|
|
dbCtx.Entry(row).State = EntityState.Modified;
|
|
|
|
bool done = await dbCtx.SaveChangesAsync() > 0;
|
|
|
|
if (done)
|
|
await tx.CommitAsync();
|
|
|
|
return done;
|
|
}
|
|
catch
|
|
{
|
|
await tx.RollbackAsync();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> UpdateAsync(OfferModel entity)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
// Recuperiamo l'entità tracciata dal context
|
|
var trackedEntity = await dbCtx.DbSetOffer.FirstOrDefaultAsync(x => x.OfferID == entity.OfferID);
|
|
|
|
if (trackedEntity != null)
|
|
{
|
|
// verifico eventuale riapertura SE fosse expired ma la data è valida...
|
|
if (trackedEntity.OffertState == OfferStates.Expired && entity.ValidUntil > DateTime.Today)
|
|
{
|
|
entity.OffertState = OfferStates.Open;
|
|
}
|
|
// Aggiorna i valori dell'entità tracciata con quelli della nuova
|
|
dbCtx.Entry(trackedEntity).CurrentValues.SetValues(entity);
|
|
}
|
|
else
|
|
{
|
|
dbCtx.DbSetOffer.Update(entity);
|
|
}
|
|
return await dbCtx.SaveChangesAsync() > 0;
|
|
}
|
|
|
|
|
|
#endregion Public Methods
|
|
}
|
|
} |