using AutoMapper;
using Kean.Domain;
using Kean.Domain.Order.Models;
using Kean.Infrastructure.Database;
using Kean.Infrastructure.Database.Repository.Default;
using Kean.Infrastructure.Database.Repository.Default.Entities;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Kean.Infrastructure.Repository
{
///
/// 订单仓库
///
public class OrderRepository :
Domain.Order.Repositories.IOrderRepository
{
private readonly IMapper _mapper; // 模型映射
private readonly IDefaultDb _database; // 默认数据库
///
/// 构造函数
///
public OrderRepository(
IMapper mapper,
IDefaultDb database)
{
_mapper = mapper;
_database = database;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.GetType 方法
*/
public async Task GetType(int id)
{
return _mapper.Map(await _database.From()
.Where(t => t.TYPE_FLAG == true && t.TYPE_ID == id)
.Single());
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsTypeCodeExist 方法
*/
public async Task IsTypeCodeExist(string code, int? igrone)
{
var schema = _database.From().Where(t => t.TYPE_FLAG == true && t.TYPE_CODE == code);
if (igrone.HasValue)
{
schema = schema.Where(t => t.TYPE_ID != igrone.Value);
}
return (await schema.Single(t => new { Count = Function.Count(t.TYPE_ID) })).Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsTypeNameExist 方法
*/
public async Task IsTypeNameExist(string name, int? igrone)
{
var schema = _database.From().Where(t => t.TYPE_FLAG == true && t.TYPE_NAME == name);
if (igrone.HasValue)
{
schema = schema.Where(t => t.TYPE_ID != igrone.Value);
}
return (await schema.Single(t => new { Count = Function.Count(t.TYPE_ID) })).Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsTypeUsing 方法
*/
public async Task IsTypeUsing(int id)
{
return (await _database.From()
.Where(p => p.PLAN_TYPE == id)
.Single(p => new { Count = Function.Count(p.PLAN_ID) }))
.Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.CreateType 方法
*/
public async Task CreateType(Domain.Order.Models.Type type)
{
var entity = _mapper.Map(type);
entity.TYPE_FLAG = true;
entity.UPDATE_TIME = entity.CREATE_TIME = DateTime.Now;
var id = await _database.From().Add(entity);
return Convert.ToInt32(id);
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.ModifyType 方法
*/
public Task ModifyType(Domain.Order.Models.Type type)
{
var entity = _mapper.Map(type);
entity.TYPE_FLAG = true;
entity.UPDATE_TIME = DateTime.Now;
return _database.From().Update(entity, nameof(T_PLAN_TYPE.CREATE_TIME));
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.DeleteType 方法
*/
public async Task DeleteType(int id)
{
await _database.From()
.Where(t => t.TYPE_ID == id)
.Update(new
{
TYPE_FLAG = false,
UPDATE_TIME = DateTime.Now
});
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsFlowExist 方法
*/
public async Task IsFlowExist(int id)
{
return (await _database.From()
.Where(f => f.FLOW_FLAG == true && f.FLOW_ID == id)
.Single(f => new { Count = Function.Count(f.FLOW_ID) })).Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsFlowNameExist 方法
*/
public async Task IsFlowNameExist(string name, int? igrone)
{
var schema = _database.From().Where(f => f.FLOW_FLAG == true && f.FLOW_NAME == name);
if (igrone.HasValue)
{
schema = schema.Where(f => f.FLOW_ID != igrone.Value);
}
return (await schema.Single(f => new { Count = Function.Count(f.FLOW_ID) })).Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsFlowUsing 方法
*/
public async Task IsFlowUsing(int id)
{
return (await _database.From()
.Where(p => p.PLAN_FLOW == id)
.Single(p => new { Count = Function.Count(p.PLAN_ID) }))
.Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.CreateFlow 方法
*/
public async Task CreateFlow(Flow flow)
{
var timestamp = DateTime.Now;
var planFlow = _mapper.Map(flow);
planFlow.FLOW_FLAG = true;
planFlow.UPDATE_TIME = planFlow.CREATE_TIME = timestamp;
var id = Convert.ToInt32(await _database.From().Add(planFlow));
if (flow.Nodes?.Any() == true)
{
var nodeId = new Dictionary();
foreach (var item in flow.Nodes)
{
var planFlowNode = _mapper.Map(item);
planFlowNode.FLOW_ID = id;
planFlowNode.UPDATE_TIME = planFlowNode.CREATE_TIME = timestamp;
nodeId.Add(item.Id, item.Id = Convert.ToInt32(await _database.From().Add(planFlowNode)));
}
foreach (var item in flow.Paths)
{
item.Source = nodeId[item.Source];
item.Target = nodeId[item.Target];
var planFlowPath = _mapper.Map(item); ;
planFlowPath.FLOW_ID = id;
planFlowPath.UPDATE_TIME = planFlowPath.CREATE_TIME = timestamp;
item.Id = Convert.ToInt32(await _database.From().Add(planFlowPath));
}
}
return id;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.ModifyFlow 方法
*/
public async Task ModifyFlow(Flow flow)
{
var timestamp = DateTime.Now;
var planFlow = _mapper.Map(flow);
planFlow.FLOW_FLAG = true;
planFlow.UPDATE_TIME = timestamp;
await _database.From().Update(planFlow, nameof(T_PLAN_FLOW.CREATE_TIME));
if (flow.Nodes != null || flow.Paths != null)
{
await _database.From()
.Where(n => n.FLOW_ID == flow.Id)
.Delete();
await _database.From()
.Where(p => p.FLOW_ID == flow.Id)
.Delete();
if (flow.Nodes.Any())
{
var nodeId = new Dictionary();
foreach (var item in flow.Nodes)
{
var planFlowNode = _mapper.Map(item);
planFlowNode.FLOW_ID = flow.Id;
planFlowNode.UPDATE_TIME = planFlowNode.CREATE_TIME = timestamp;
nodeId.Add(item.Id, item.Id = Convert.ToInt32(await _database.From().Add(planFlowNode)));
}
foreach (var item in flow.Paths)
{
item.Source = nodeId[item.Source];
item.Target = nodeId[item.Target];
var planFlowPath = _mapper.Map(item); ;
planFlowPath.FLOW_ID = flow.Id;
planFlowPath.UPDATE_TIME = planFlowPath.CREATE_TIME = timestamp;
item.Id = Convert.ToInt32(await _database.From().Add(planFlowPath));
}
}
}
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.DeleteFlow 方法
*/
public async Task DeleteFlow(int id)
{
await _database.From()
.Where(f => f.FLOW_ID == id)
.Update(new
{
FLOW_FLAG = false,
UPDATE_TIME = DateTime.Now
});
await _database.From()
.Where(n => n.FLOW_ID == id)
.Delete();
await _database.From()
.Where(p => p.FLOW_ID == id)
.Delete();
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.GetNode 方法
*/
public async Task GetNode(int flow, string type)
{
return _mapper.Map(await _database.From()
.Where(n => n.FLOW_ID == flow && n.NODE_TYPE == type)
.Single());
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsSerialExist 方法
*/
public async Task IsSerialExist(int id)
{
return (await _database.From()
.Where(s => s.SERIAL_ID == id)
.Single(s => new { Count = Function.Count(s.SERIAL_ID) }))
.Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.GetSerialValue 方法
*/
public async Task GetSerialValue(int id, DateTime timestamp, int timeout)
{
int? result = null;
var guid = Guid.NewGuid().ToString("N");
var stopwatch = new Stopwatch();
stopwatch.Start();
while(!result.HasValue)
{
if (stopwatch.ElapsedMilliseconds >= timeout)
{
stopwatch.Stop();
break;
}
else
{
var serial = await _database.From()
.Where(s => s.SERIAL_ID == id)
.Single();
var cycle = serial.SERIAL_CYCLE;
if (cycle == string.Empty)
{
serial.SERIAL_VALUE++;
}
else
{
cycle = timestamp.ToString("yyyyMMddHHmmss"[..cycle.Length]);
if (cycle == serial.SERIAL_CYCLE)
{
serial.SERIAL_VALUE++;
}
else
{
serial.SERIAL_VALUE = 1;
}
}
if(await _database.From()
.Where(s => s.SERIAL_ID == id && s.SERIAL_VERSION == serial.SERIAL_VERSION)
.Update(new
{
SERIAL_CYCLE = cycle,
SERIAL_VALUE = serial.SERIAL_VALUE,
SERIAL_VERSION = guid,
UPDATE_TIME = DateTime.Now
}) > 0)
{
result = serial.SERIAL_VALUE;
stopwatch.Stop();
break;
}
}
}
return result;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.CreateSerial 方法
*/
public async Task CreateSerial(int id, string cycle)
{
var timestamp = DateTime.Now;
await _database.From().Add(new()
{
SERIAL_ID = id,
SERIAL_CYCLE = cycle,
SERIAL_VALUE = 1,
SERIAL_VERSION = Guid.NewGuid().ToString("N"),
CREATE_TIME= timestamp,
UPDATE_TIME= timestamp
});
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsOrderExist 方法
*/
public async Task IsOrderExist(int id)
{
return (await _database.From()
.Where(p => p.PLAN_ID == id)
.Single(p => new { Count = Function.Count(p.PLAN_ID) }))
.Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsOrderExist 方法
*/
public async Task IsOrderExist(string no)
{
return (await _database.From()
.Where(p => p.PLAN_CODE == no)
.Single(p => new { Count = Function.Count(p.PLAN_ID) }))
.Count > 0;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.CreateOrder 方法
*/
public async Task CreateOrder(Domain.Order.Models.Order order)
{
var timestamp = DateTime.Now;
var planMain = _mapper.Map(order);
planMain.CREATE_TIME = timestamp;
planMain.UPDATE_TIME = timestamp;
await _database.From().Add(planMain);
foreach (var item in order.Lines)
{
var planList = _mapper.Map(item);
planList.PLAN_ID = planMain.PLAN_ID;
planList.CREATE_TIME = timestamp;
planList.UPDATE_TIME = timestamp;
item.Id = Convert.ToInt32(await _database.From().Add(planList));
}
return planMain.PLAN_ID;
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.ModifyOrder 方法
*/
public async Task ModifyOrder(int id, IEnumerable lines)
{
var timestamp = DateTime.Now;
var planLists = (await _database.From()
.Where(p => p.PLAN_ID == id)
.Select())
.ToDictionary(e => e.PLAN_LIST_ID, e => e);
foreach (var item in lines)
{
if (item.Id == 0)
{
var planList = _mapper.Map(item);
planList.PLAN_ID = id;
planList.CREATE_TIME = timestamp;
planList.UPDATE_TIME = timestamp;
item.Id = Convert.ToInt32(await _database.From().Add(planList));
}
else
{
if (!planLists.ContainsKey(item.Id))
{
throw new RepositoryException("订单行不存在", new(nameof(item.Id), item.Id));
}
var planList = planLists[item.Id];
if (planList.ORDERED_QUANTITY > 0 || planList.FINISHED_QUANTITY > 0)
{
throw new RepositoryException("已执行的订单行不允许修改", new(nameof(item.Id), item.Id));
}
planLists.Remove(item.Id);
planList = _mapper.Map(item);
planList.PLAN_ID = id;
planList.UPDATE_TIME = timestamp;
await _database.From().Update(planList, nameof(T_PLAN_LIST.CREATE_TIME));
}
}
foreach (var item in planLists.Values)
{
if (item.ORDERED_QUANTITY > 0 || item.FINISHED_QUANTITY > 0)
{
throw new RepositoryException("已执行的订单行不允许删除", new(nameof(OrderLine.Id), item.PLAN_LIST_ID));
}
await _database.From().Delete(item);
}
}
/*
* 实现 Kean.Domain.Order.Repositories.IOrderRepository.DeleteOrder 方法
*/
public async Task DeleteOrder(int id)
{
await _database.From().Where(p => p.PLAN_ID == id).Delete();
await _database.From().Where(p => p.PLAN_ID == id).Delete();
}
}
}