908 lines
47 KiB
C#
908 lines
47 KiB
C#
using CRM.Core.BLL.Application.Order;
|
||
using CRM.Core.BLL.Base;
|
||
using CRM.Core.BLL.EventBus.Events;
|
||
using CRM.Core.BLL.Util;
|
||
using CRM.Core.Common.Layui;
|
||
using CRM.Core.DAL;
|
||
using CRM.Core.DTO;
|
||
using CRM.Core.Model;
|
||
using CRM.Core.Model.Entity;
|
||
using MySql.Data.MySqlClient;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.Linq;
|
||
using System.Linq.Expressions;
|
||
using System.Threading.Tasks;
|
||
using WX.CRM.Common;
|
||
|
||
namespace CRM.Core.BLL.Wx
|
||
{
|
||
public class WX_SzzyOrderRefund_BL : DbContextRepository<WX_SzzyOrderRefund>
|
||
{
|
||
|
||
public List<OrderRefundView> GetList(OrderRefundSelectDto info)
|
||
{
|
||
var where = PredicateExtensionses.True<WX_SzzyOrderRefund>();
|
||
if (info.orderId.HasValue)
|
||
where = where.And(p => p.orderid == info.orderId);
|
||
if (!string.IsNullOrEmpty(info.companyCode))
|
||
where = where.And(p => p.companycode == info.companyCode);
|
||
if (info.auditStatus.HasValue)
|
||
where = where.And(p => p.auditstatus == info.auditStatus);
|
||
if (info.sTime.HasValue)
|
||
where = where.And(p => p.refunddate >= info.sTime.Value);
|
||
if (info.eTime.HasValue)
|
||
{
|
||
var endtime = info.eTime.Value.AddDays(1);
|
||
where = where.And(p => p.refunddate < endtime);
|
||
}
|
||
if (info.isacturalrefund.HasValue)
|
||
{
|
||
where = where.And(p => p.isacturalrefund == info.isacturalrefund);
|
||
}
|
||
if (info.innamelist.HasValue)
|
||
{
|
||
where = where.And(p => p.innamelist == info.innamelist);
|
||
}
|
||
where = where.And(p => p.isdelete != 1);
|
||
//where = where.And(p => !(p.isdelete == 1 && p.auditstatus == 0));
|
||
if (info.price.HasValue)
|
||
{
|
||
where = where.And(p => p.refundprice == info.price);
|
||
}
|
||
if (!string.IsNullOrEmpty(info.channel))
|
||
{
|
||
var arr0 = info.channel.Split('|');
|
||
if (arr0.Length > 1)
|
||
{
|
||
var whereOr = PredicateExtensionses.False<WX_SzzyOrderRefund>();
|
||
foreach (var item in arr0)
|
||
{
|
||
var a = item.Split(',');
|
||
var min = Convert.ToInt32(a[0]);
|
||
var max = Convert.ToInt32(a[1]);
|
||
whereOr = whereOr.Or(m => m.channel >= min && m.channel <= max);
|
||
}
|
||
where = where.And(whereOr);
|
||
//where = where.And(m => m.channel >= 1100 && m.channel <= 1100 || m.channel >= 26600 && m.channel <= 26699);
|
||
}
|
||
else
|
||
{
|
||
var arr = info.channel.Split(',');
|
||
var min = Convert.ToInt32(arr[0]);
|
||
var max = Convert.ToInt32(arr[1]);
|
||
where = where.And(m => m.channel >= min && m.channel <= max);
|
||
}
|
||
}
|
||
var list = GetOrderRefundViews(where, info.resId, info.UMID, info.pager).ToList();
|
||
var companyList = new CACHE_BL().GetCompanyVirtual();
|
||
foreach (var item in list)
|
||
{
|
||
foreach (var company in companyList)
|
||
{
|
||
var channels = company.Channel.Split('|');
|
||
foreach (var subchannel in channels)
|
||
{
|
||
var subch = subchannel.Split(',');
|
||
var min = int.Parse(subch[0].ToString());
|
||
var max = int.Parse(subch[1].ToString());
|
||
|
||
if (item.channel != null && (item.channel.Value >= min && item.channel.Value <= max))
|
||
{
|
||
item.CompanyName = company.CompanyName;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return list;
|
||
|
||
}
|
||
public List<OrderRefundView> GetOrderRefundViews(Expression<Func<WX_SzzyOrderRefund, bool>> where, string resId, string UMID, Laypage pg)
|
||
{
|
||
using (var db = new zxdContext())
|
||
{
|
||
#region UMID转RESID
|
||
|
||
if (!string.IsNullOrEmpty(UMID) && string.IsNullOrEmpty(resId))
|
||
{
|
||
var MUIDMain = db.RES_CUSTOMER.FirstOrDefault(m => m.UMID == UMID.Trim());
|
||
if (MUIDMain != null)
|
||
{
|
||
resId = MUIDMain.RESID;
|
||
}
|
||
else
|
||
{
|
||
resId = "NULL_RESID";
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
var query = from a in db.WX_SzzyOrderRefund.Where(@where)
|
||
join b in db.WX_SZZYORDER on a.orderid equals b.ORDERID into t1
|
||
from b in t1.DefaultIfEmpty()
|
||
join c in db.Wx_SzzyOrderRefundContract on a.orderid equals c.OrderId into t2
|
||
from c in t2.DefaultIfEmpty()
|
||
join u in db.RES_CUSTOMER on b.RESID equals u.RESID into ucr
|
||
from uc in ucr.DefaultIfEmpty()
|
||
where string.IsNullOrEmpty(resId) ? 1 == 1 : b.RESID == resId
|
||
select new OrderRefundView
|
||
{
|
||
orderid = a.orderid,
|
||
deptcode = a.deptcode,
|
||
account = a.account,
|
||
att = a.att,
|
||
att2 = a.att2,
|
||
auditor = a.auditor,
|
||
auditorname = a.auditorname,
|
||
auditstatus = a.auditstatus,
|
||
audittime = a.audittime,
|
||
channel = a.channel,
|
||
companycode = a.companycode,
|
||
creator = a.creator,
|
||
creatorname = a.creatorname,
|
||
ctime = a.ctime,
|
||
id = a.id,
|
||
isacturalrefund = a.isacturalrefund,
|
||
isdelete = a.isdelete,
|
||
ismorepay = a.ismorepay,
|
||
isold = a.isold,
|
||
refunddate = a.refunddate,
|
||
refundprice = a.refundprice,
|
||
refundtype = a.refundtype,
|
||
refundtypename = a.refundtypename,
|
||
remark = a.remark,
|
||
username = a.username,
|
||
resid = b.RESID,
|
||
UMID = uc.UMID,
|
||
contracttime = c.ContractTime,
|
||
contractstatus = c.ContractStatus,
|
||
contractKey = c.ContractKey,
|
||
applytype = a.applytype,
|
||
customer_cancel_time = a.customer_cancel_time,
|
||
innamelist = a.innamelist,
|
||
retrace_refund_file = a.retrace_refund_file,
|
||
};
|
||
|
||
int skip = (pg.page - 1) * pg.limit;
|
||
pg.count = query.Count();
|
||
return query.OrderByDescending(x => x.ctime).Skip(skip).Take(pg.limit).ToList();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 退款审核
|
||
/// </summary>
|
||
/// <param name="orderRefund"></param>
|
||
public retMsg Audit(WX_SzzyOrderRefund model, WX_SZZYORDER uporder)
|
||
{
|
||
retMsg retMsg = new retMsg() { result = true, retcode = 200, retmsg = "succ" };
|
||
using (var client = RedisManager.GetClient())
|
||
{
|
||
string resid = "";
|
||
if (uporder != null)
|
||
{
|
||
resid = uporder.RESID;
|
||
}
|
||
else
|
||
{
|
||
var entry = new WX_SzzyOrderDeposit_BL().Get(m => m.id == model.orderid);
|
||
resid = entry.resid;
|
||
}
|
||
|
||
using (var datalock = client.AcquireLock("DataLock:" + resid, TimeSpan.FromSeconds(10)))
|
||
{
|
||
|
||
|
||
using (var db = new zxdContext())
|
||
{
|
||
using (var trans = db.Database.BeginTransaction())
|
||
{
|
||
try
|
||
{
|
||
//修改状态
|
||
var orderRefund = db.WX_SzzyOrderRefund.FirstOrDefault(m => m.id == model.id);
|
||
|
||
if (orderRefund.auditstatus == 1)
|
||
{
|
||
return new retMsg() { result = false, retcode = 500, retmsg = "已经确认了,不能重复确认!" };
|
||
}
|
||
orderRefund.refunddate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
|
||
//Update(orderRefund);
|
||
|
||
var deposit = db.WX_SzzyOrderDeposit.FirstOrDefault(m => m.id == orderRefund.orderid);
|
||
OrderAndPayInfoEvent eventInfo = new OrderAndPayInfoEvent() { depositList = new List<OrderAndPayInfo_Deposit>(), orderList = new List<OrderAndPayInfo_Order>(), payList = new List<OrderAndPayInfo_Pay>() };
|
||
if (uporder != null)///订单方式退款
|
||
{
|
||
retMsg ret1 = OrderRefund(db, model, uporder, eventInfo, model.isacturalrefund ?? 1);//第一步退订单
|
||
if (!ret1.result)
|
||
{
|
||
trans.Rollback();//有错误,直接回滚,返回错误
|
||
return ret1;
|
||
}
|
||
if (model.isacturalrefund == 1)
|
||
{
|
||
retMsg ret2 = StartRefund(db, model, uporder, eventInfo);//第二步开始退款(锁定金额,不能退款)
|
||
if (!ret2.result)
|
||
{
|
||
trans.Rollback();//有错误,直接回滚,返回错误
|
||
return ret2;
|
||
}
|
||
|
||
retMsg ret3 = EndRefund(db, model, uporder, eventInfo);// 3、完成退款 (解除金额锁定,进行退款)
|
||
if (!ret3.result)
|
||
{
|
||
trans.Rollback();//有错误,直接回滚,返回错误
|
||
return ret2;
|
||
}
|
||
|
||
}
|
||
|
||
var order = db.WX_SZZYORDER.FirstOrDefault(m => m.ORDERID == orderRefund.orderid);
|
||
//已退款,进行订单状态的修改
|
||
|
||
order.ORDERSTATUS = uporder.ORDERSTATUS;
|
||
order.ORDERSTATUSNAME = uporder.ORDERSTATUSNAME;
|
||
order.ORDERSTATUS = uporder.ORDERSTATUS;
|
||
order.ORDERSTATUSNAME = uporder.ORDERSTATUSNAME;
|
||
order.ISOPEN = uporder.ISOPEN;
|
||
order.BALANCEPAY = order.BALANCEPAY - orderRefund.refundprice;
|
||
//var lastpriceLJ = db.WX_SzzyOrderDeposit.Where(m => m.resid == order.RESID && m.isdelete == 0 && m.auditstatus == 1).Sum(m => m.lastprice);
|
||
|
||
//lastpriceLJ += orderRefund.refundprice;
|
||
//var log = new Wx_SzzyOrderPayUseLog(order.RESID, Convert.ToInt32(order.ORDERID), null, orderRefund.refundtype, orderRefund.refundtypename, "", orderRefund.refundprice, orderRefund.audittime ?? DateTime.Now, orderRefund.channel.Value, 5, lastpriceLJ, "退款取消使用");
|
||
////_payuselog.Add(log);
|
||
//db.Wx_SzzyOrderPayUseLog.Add(log);
|
||
//lastpriceLJ -= orderRefund.refundprice;
|
||
//var log2 = new Wx_SzzyOrderPayUseLog(order.RESID, Convert.ToInt32(order.ORDERID), null, orderRefund.refundtype, orderRefund.refundtypename, "", -orderRefund.refundprice, orderRefund.audittime ?? DateTime.Now, orderRefund.channel.Value, 6, lastpriceLJ, "退款减去金额");
|
||
////_payuselog.Add(log);
|
||
//db.Wx_SzzyOrderPayUseLog.Add(log2);
|
||
}
|
||
else if (deposit != null)
|
||
{
|
||
retMsg ret2 = StartRefund(db, model, uporder, eventInfo, 2);//第二步开始退款(锁定金额,不能退款)
|
||
if (!ret2.result)
|
||
{
|
||
trans.Rollback();//有错误,直接回滚,返回错误
|
||
return ret2;
|
||
}
|
||
|
||
retMsg ret3 = EndRefund(db, model, uporder, eventInfo, 2);// 3、完成退款 (解除金额锁定,进行退款)
|
||
if (!ret3.result)
|
||
{
|
||
trans.Rollback();//有错误,直接回滚,返回错误
|
||
return ret2;
|
||
}
|
||
|
||
//deposit.lastprice -= orderRefund.refundprice;//订金退款
|
||
//db.SaveChanges();
|
||
//var lastpriceLJ = db.WX_SzzyOrderDeposit.Where(m => m.resid == deposit.resid && m.isdelete == 0 && m.auditstatus == 1).Sum(m => m.lastprice);
|
||
//var log = new Wx_SzzyOrderPayUseLog(deposit.resid, null, deposit.id, orderRefund.refundtype, orderRefund.refundtypename, deposit.tradeno, -orderRefund.refundprice, orderRefund.audittime ?? DateTime.Now, orderRefund.channel.Value, 7, lastpriceLJ, "余额退款减去金额");
|
||
////_payuselog.Add(log);
|
||
//db.Wx_SzzyOrderPayUseLog.Add(log);
|
||
//WX_SzzyOrderDeposit_BL.SendInfoFormat(eventInfo, deposit, null, null);//将pay信息formrt
|
||
}
|
||
orderRefund.auditstatus = model.auditstatus;
|
||
orderRefund.auditor = model.auditor;
|
||
orderRefund.auditorname = model.auditorname;
|
||
orderRefund.audittime = model.audittime;
|
||
orderRefund.att2 = model.att2;
|
||
//var order = db.WX_SZZYORDER.FirstOrDefault(m => m.ORDERID == orderRefund.orderid);
|
||
//order.ORDERSTATUS = "7";
|
||
//order.ORDERSTATUSNAME = "已退款";
|
||
db.SaveChanges();
|
||
trans.Commit();
|
||
Common.EventBus.EventBus.Instance.Publish(eventInfo);//推送详细信息
|
||
|
||
#region 平台一退款回调
|
||
if (uporder != null)
|
||
{
|
||
if (uporder.CHANNEL >= 25000 && uporder.CHANNEL <= 26199)
|
||
{
|
||
Task.Run(() =>
|
||
{
|
||
new OrderService().CallBackRefundPT1(uporder.outorderno, orderRefund.audittime, orderRefund.refundprice);
|
||
});
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
trans.Rollback();
|
||
LogHelper.Error(e);
|
||
retMsg = new retMsg() { result = false, retcode = 500, retmsg = "系统错误!" };
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return retMsg;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 1、退订单 (退订单不需要锁,要实际再外包锁)
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <param name="uporder"></param>
|
||
/// <param name="eventInfo">推送信息</param>
|
||
/// <returns></returns>
|
||
public retMsg OrderRefund(zxdContext db, WX_SzzyOrderRefund model, WX_SZZYORDER uporder, OrderAndPayInfoEvent eventInfo, int isacturalrefund)
|
||
{
|
||
retMsg retMsg = new retMsg() { result = true, retcode = 200, retmsg = "succ" };
|
||
//修改状态
|
||
var orderRefund = db.WX_SzzyOrderRefund.FirstOrDefault(m => m.id == model.id);
|
||
var order = db.WX_SZZYORDER.FirstOrDefault(m => m.ORDERID == orderRefund.orderid);
|
||
var needRefpay = model.refundprice;//需要退款的总金额
|
||
|
||
var Alloldorderpays = db.WX_SzzyOrderPay.Where(p => p.orderid == order.ORDERID && p.isdelete == 0 && p.auditstatus == 1 && p.payprice == needRefpay).OrderBy(m => m.paydate).ToList();
|
||
var payn = db.WX_SzzyOrderPay.Where(p => p.orderid == order.ORDERID && p.isdelete == 0 && p.auditstatus == 1 && p.payprice > needRefpay).OrderBy(m => m.paydate).ToList();
|
||
var payn2 = db.WX_SzzyOrderPay.Where(p => p.orderid == order.ORDERID && p.isdelete == 0 && p.auditstatus == 1 && p.payprice < needRefpay).OrderBy(m => m.paydate).ToList();
|
||
Alloldorderpays.AddRange(payn);//根据金额,匹配原则,有相等取相等,无相等取大额,最后
|
||
Alloldorderpays.AddRange(payn2);//根据金额,匹配原则,有相等取相等,无相等取大额,最后
|
||
|
||
|
||
//之前已经退款的总金额,老数据退款需要用到
|
||
decimal refundprice = 0;
|
||
var oldRefunList = db.WX_SzzyOrderRefund.Where(m => m.orderid == order.ORDERID && m.isdelete == 0 && m.auditstatus == 1 && m.isold == 1).ToList();
|
||
if (oldRefunList != null && oldRefunList.Count() > 0)
|
||
{
|
||
refundprice = oldRefunList.Sum(m => m.refundprice);//已经退款
|
||
}
|
||
|
||
foreach (var xpay in Alloldorderpays)
|
||
{
|
||
var pay = db.WX_SzzyOrderPay.FirstOrDefault(m => m.id == xpay.id);
|
||
if (!pay.depositid.HasValue)//如果没有订金数据,需要补充一条订金数据
|
||
{
|
||
//var oldmy = db.WX_SzzyOrderDeposit.FirstOrDefault(m => m.payno == pay.payno && m.isdelete == 0 && m.auditstatus == 1 && m.orderid == pay.orderid && m.isbu==0);//用流水查看是否有数据
|
||
var oldmy = db.WX_SzzyOrderDeposit.FirstOrDefault(m => m.payno == pay.payno && m.isdelete == 0 && m.auditstatus == 1);//用流水查看是否有数据
|
||
if (oldmy != null)//表明有旧数据
|
||
{
|
||
oldmy.isbu = 5;//修改补充
|
||
oldmy.butime = DateTime.Now;//修补数据时间
|
||
oldmy.lastprice = 0;
|
||
oldmy.useprice = oldmy.payprice;
|
||
oldmy.frozenprice = 0;
|
||
pay.depositid = oldmy.id;//对ID 进行补充
|
||
db.SaveChanges();
|
||
}
|
||
else//实在找不到数据
|
||
{
|
||
var useprice = pay.payprice;
|
||
if (pay.payprice > refundprice)
|
||
{
|
||
useprice = pay.payprice - refundprice;//减去退款金额
|
||
refundprice = 0;//直接减去了
|
||
}
|
||
else//还有剩余,需要摊到其他流水
|
||
{
|
||
useprice = 0;
|
||
refundprice = refundprice - pay.payprice;
|
||
}
|
||
WX_SzzyOrderDeposit neworderDposit = new WX_SzzyOrderDeposit()
|
||
{
|
||
id = new SEQUENCES_BL().Seq_OrderDeposit(),
|
||
auditor = pay.auditor,
|
||
auditorname = pay.auditorname,
|
||
auditstatus = pay.auditstatus,
|
||
audittime = pay.audittime,
|
||
channel = pay.channel,
|
||
checkpaytime = pay.checkpaytime,
|
||
checkreslut = pay.checkreslut,
|
||
companycode = pay.companycode,
|
||
creator = pay.creator,
|
||
creatorname = pay.creatorname,
|
||
ctime = pay.ctime,
|
||
frozenprice = 0,
|
||
isdelete = pay.isdelete,
|
||
isuse = 0,
|
||
payprice = pay.payprice,
|
||
paydate = pay.paydate,
|
||
payname = pay.payname,
|
||
payno = pay.payno,
|
||
paytype = pay.paytype,
|
||
paytypename = pay.paytypename,
|
||
rejectremark = pay.rejectremark,
|
||
remark = pay.remark,
|
||
resid = order.RESID,
|
||
tradeno = pay.tradeno,
|
||
lastprice = 0,// pay.payprice,//补充的数据是,可用金额=支付金额
|
||
useprice = useprice,//一开始默认使用0
|
||
isbu = 1,
|
||
butime = DateTime.Now,
|
||
};
|
||
db.WX_SzzyOrderDeposit.Add(neworderDposit);
|
||
pay.depositid = neworderDposit.id;
|
||
db.SaveChanges();
|
||
}
|
||
|
||
}
|
||
decimal oldpayHasRefunPrice = 0;
|
||
var refundTuiMingxi = db.Wx_SzzyOrderRefund_Detail.Where(m => m.payid == pay.id && m.depositid == pay.depositid).ToList();
|
||
if (refundTuiMingxi != null && refundTuiMingxi.Count() > 0)
|
||
{
|
||
oldpayHasRefunPrice = refundTuiMingxi.Sum(m => m.price);//旧数据退款金额
|
||
}
|
||
|
||
var orderDeposit = db.WX_SzzyOrderDeposit.FirstOrDefault(p => p.id == pay.depositid && p.useprice > 0);//需要取大于与零的记录进行退款
|
||
if (orderDeposit != null)
|
||
{
|
||
//已经驳回,不需要在进行处理
|
||
if (orderDeposit.auditstatus == -1)
|
||
{
|
||
return new retMsg() { result = false, retcode = 300, retmsg = "exists" };
|
||
}
|
||
if (needRefpay == 0)//没有需要退款的金额了,不能够在继续退了
|
||
{
|
||
continue;
|
||
}
|
||
decimal[] threaPrice = { needRefpay, pay.payprice, orderDeposit.useprice.Value, pay.payprice - oldpayHasRefunPrice };//取最小的退款金额
|
||
var thisTimeNeedRefpay = threaPrice.Min();//取三个金额中最小的金额
|
||
if (thisTimeNeedRefpay < 0)//没有需要退款的金额了,不能够在继续退了
|
||
{
|
||
continue;
|
||
}
|
||
|
||
orderDeposit.useprice = orderDeposit.useprice - thisTimeNeedRefpay;
|
||
orderDeposit.lastprice += thisTimeNeedRefpay;//加回之前的金额
|
||
|
||
///退款明细入库
|
||
db.Wx_SzzyOrderRefund_Detail.Add(new Wx_SzzyOrderRefund_Detail()
|
||
{
|
||
payid = xpay.id,
|
||
depositid = orderDeposit.id,
|
||
orderid = model.orderid,
|
||
status = 1,
|
||
isdelete = 0,
|
||
refundid = model.id,
|
||
price = thisTimeNeedRefpay,
|
||
resid = orderDeposit.resid,
|
||
ctime = DateTime.Now
|
||
});
|
||
|
||
db.SaveChanges();
|
||
//SendInfoFormat(eventInfo, orderDeposit, null, null);//将订金信息formrt
|
||
|
||
var sumLastPrice = db.WX_SzzyOrderDeposit.Where(m => m.resid == orderDeposit.resid && m.isdelete == 0 && m.auditstatus == 1).Sum(m => m.lastprice);//获取总的金额
|
||
if (isacturalrefund == 1)//需要实际退款
|
||
{
|
||
var log = new Wx_SzzyOrderPayUseLog(orderDeposit.resid, Convert.ToInt32(order.ORDERID), orderDeposit.id, orderDeposit.paytype, orderDeposit.paytypename, orderDeposit.payno, thisTimeNeedRefpay, DateTime.Now, pay.channel.Value, 5, sumLastPrice, "订单取消使用");
|
||
db.Wx_SzzyOrderPayUseLog.Add(log);
|
||
}
|
||
else
|
||
{
|
||
var log = new Wx_SzzyOrderPayUseLog(orderDeposit.resid, Convert.ToInt32(order.ORDERID), orderDeposit.id, orderDeposit.paytype, orderDeposit.paytypename, orderDeposit.payno, thisTimeNeedRefpay, DateTime.Now, pay.channel.Value, 10, sumLastPrice, "退单取消使用");
|
||
db.Wx_SzzyOrderPayUseLog.Add(log);
|
||
}
|
||
db.SaveChanges();
|
||
//推送订金状态到坐席
|
||
//Common.EventBus.EventBus.Instance.Publish(new DepositRejectEvent(orderDeposit.id, orderDeposit.auditstatus, "", userId, userName, orderDeposit.channel.Value));
|
||
|
||
//return new retMsg() { result = true, retcode = 200, retmsg = "success" };
|
||
needRefpay = needRefpay - thisTimeNeedRefpay;
|
||
WX_SzzyOrderDeposit_BL.SendInfoFormat(eventInfo, orderDeposit, null, null);//将pay信息formrt
|
||
}
|
||
|
||
WX_SzzyOrderDeposit_BL.SendInfoFormat(eventInfo, null, null, pay);//将pay信息formrt
|
||
//SendInfoFormat(eventInfo, null, null, pay);//将订金信息formrt
|
||
}
|
||
///退款的金额太多了,不能够退款
|
||
if (needRefpay > 0)
|
||
{
|
||
retMsg = new retMsg() { result = false, retcode = 500, retmsg = "退款金额比订单多了:" + needRefpay };
|
||
return retMsg;
|
||
|
||
}
|
||
//WX_SzzyOrderDeposit_BL.SendInfoFormat(eventInfo, null, order, null);//将订单信息formrt
|
||
return retMsg;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 2、开始退款 (对金额开始锁定)
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <param name="uporder"></param>
|
||
/// <returns></returns>
|
||
public retMsg StartRefund(zxdContext db, WX_SzzyOrderRefund model, WX_SZZYORDER uporder, OrderAndPayInfoEvent eventInfo, int type = 1)
|
||
{
|
||
retMsg retMsg = new retMsg() { result = true, retcode = 200, retmsg = "succ" };
|
||
//修改状态
|
||
var orderRefund = db.WX_SzzyOrderRefund.FirstOrDefault(m => m.id == model.id);
|
||
var order = db.WX_SZZYORDER.FirstOrDefault(m => m.ORDERID == orderRefund.orderid);
|
||
|
||
var needRefpay = model.refundprice;//需要退款的总金额
|
||
|
||
var allDepositidS = db.WX_SzzyOrderPay.Where(m => m.orderid == model.orderid && m.isdelete == 0 && m.auditstatus == 1).Select(m => m.depositid).ToArray();
|
||
if (type == 2)
|
||
{
|
||
int?[] awbbnb = { model.orderid };
|
||
allDepositidS = awbbnb;
|
||
}
|
||
|
||
var AlloldorderDeposit = db.WX_SzzyOrderDeposit.Where(p => allDepositidS.Contains(p.id) && p.isdelete == 0 && p.auditstatus == 1 && p.lastprice == needRefpay).OrderBy(m => m.paydate).ToList();
|
||
var Deposit2 = db.WX_SzzyOrderDeposit.Where(p => allDepositidS.Contains(p.id) && p.isdelete == 0 && p.auditstatus == 1 && p.lastprice > needRefpay).OrderBy(m => m.paydate).ToList();
|
||
var Deposit3 = db.WX_SzzyOrderDeposit.Where(p => allDepositidS.Contains(p.id) && p.isdelete == 0 && p.auditstatus == 1 && p.lastprice < needRefpay).OrderBy(m => m.paydate).ToList();
|
||
AlloldorderDeposit.AddRange(Deposit2);//根据金额,匹配原则,有相等取相等,无相等取大额,最后
|
||
AlloldorderDeposit.AddRange(Deposit3);//根据金额,匹配原则,有相等取相等,无相等取大额,最后
|
||
|
||
|
||
|
||
//之前已经退款的总金额,老数据退款需要用到
|
||
//var refundprice = db.WX_SzzyOrderRefund.Where(m => m.orderid == order.ORDERID && m.isdelete == 0 && m.auditstatus == 1).Sum(m => m.refundprice);//已经退款
|
||
foreach (var xpay in AlloldorderDeposit)
|
||
{
|
||
if (needRefpay == 0)//没有需要退款的金额了,不能够在继续退了
|
||
{
|
||
continue;
|
||
}
|
||
var orderDeposit = db.WX_SzzyOrderDeposit.FirstOrDefault(p => p.id == xpay.id);//需要取大于与零的记录进行退款
|
||
decimal[] threaPrice = { needRefpay, orderDeposit.lastprice ?? 0 };
|
||
var thisTimeNeedRefpay = threaPrice.Min();//取三个金额中最小的金额
|
||
if (thisTimeNeedRefpay == 0)//没有需要退款的金额了,不能够在继续退了
|
||
{
|
||
continue;
|
||
}
|
||
///新增冻结日志
|
||
///
|
||
var frozen = new Wx_SzzyOrderRefund_Frozen()
|
||
{
|
||
ctime = DateTime.Now,
|
||
isdelete = 0,
|
||
|
||
price = thisTimeNeedRefpay,
|
||
refundid = model.id,
|
||
depositid = xpay.id,
|
||
auditstatus = 1,
|
||
auditor = model.auditor,
|
||
auditorname = model.auditorname,
|
||
audittime = model.audittime,
|
||
resid = xpay.resid
|
||
};
|
||
if (order != null)//订单退款
|
||
{
|
||
frozen.orderid = order.ORDERID;
|
||
}
|
||
db.Wx_SzzyOrderRefund_Frozen.Add(frozen);
|
||
|
||
|
||
orderDeposit.lastprice -= thisTimeNeedRefpay;//可用余额减去冻结金额
|
||
orderDeposit.frozenprice = (orderDeposit.frozenprice ?? 0) + thisTimeNeedRefpay;//设置冻结金额
|
||
|
||
db.SaveChanges();
|
||
//SendInfoFormat(eventInfo, orderDeposit, null, null);//将订金信息formrt
|
||
|
||
var sumLastPrice = db.WX_SzzyOrderDeposit.Where(m => m.resid == orderDeposit.resid && m.isdelete == 0 && m.auditstatus == 1).Sum(m => m.lastprice);//获取总的金额
|
||
var log = new Wx_SzzyOrderPayUseLog(orderDeposit.resid, frozen.orderid, orderDeposit.id, orderDeposit.paytype, orderDeposit.paytypename, orderDeposit.payno, -thisTimeNeedRefpay, DateTime.Now, orderDeposit.channel.Value, 8, sumLastPrice, "开始退款冻结金额");
|
||
db.Wx_SzzyOrderPayUseLog.Add(log);
|
||
db.SaveChanges();
|
||
//推送订金状态到坐席
|
||
needRefpay = needRefpay - thisTimeNeedRefpay;
|
||
WX_SzzyOrderDeposit_BL.SendInfoFormat(eventInfo, orderDeposit, null, null);//将pay信息formrt
|
||
}
|
||
///退款的金额太多了,不能够退款
|
||
if (needRefpay > 0)
|
||
{
|
||
retMsg = new retMsg() { result = false, retcode = 500, retmsg = "退款金额比可用余额多:" + needRefpay };
|
||
return retMsg;
|
||
|
||
}
|
||
return retMsg;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 3、完成退款 (解除金额锁定,进行退款)
|
||
/// </summary>
|
||
/// <param name="db"></param>
|
||
/// <param name="model"></param>
|
||
/// <param name="uporder"></param>
|
||
/// <param name="eventInfo"></param>
|
||
/// <param name="type">1:订单退款,2:余额退款</param>
|
||
/// <returns></returns>
|
||
public retMsg EndRefund(zxdContext db, WX_SzzyOrderRefund model, WX_SZZYORDER uporder, OrderAndPayInfoEvent eventInfo, int type = 1)
|
||
{
|
||
|
||
retMsg retMsg = new retMsg() { result = true, retcode = 200, retmsg = "succ" };
|
||
//修改状态
|
||
var orderRefund = db.WX_SzzyOrderRefund.FirstOrDefault(m => m.id == model.id);
|
||
var order = db.WX_SZZYORDER.FirstOrDefault(m => m.ORDERID == orderRefund.orderid);
|
||
|
||
var allFrozen = db.Wx_SzzyOrderRefund_Frozen.Where(m => m.refundid == model.id && m.isdelete == 0 && m.auditstatus == 1).ToList();//本次退款所有冻结的金额
|
||
|
||
foreach (var xpay in allFrozen)
|
||
{
|
||
|
||
var orderDeposit = db.WX_SzzyOrderDeposit.FirstOrDefault(p => p.id == xpay.depositid);//需要取大于与零的记录进行退款
|
||
orderDeposit.lastprice += xpay.price;//将金额解冻
|
||
orderDeposit.frozenprice = orderDeposit.frozenprice - xpay.price;//解冻金额
|
||
db.SaveChanges();
|
||
//SendInfoFormat(eventInfo, orderDeposit, null, null);//将订金信息formrt
|
||
var sumLastPrice = db.WX_SzzyOrderDeposit.Where(m => m.resid == orderDeposit.resid && m.isdelete == 0 && m.auditstatus == 1).Sum(m => m.lastprice);//获取总的金额
|
||
//解冻金额
|
||
var log = new Wx_SzzyOrderPayUseLog(orderDeposit.resid, xpay.orderid, orderDeposit.id, orderDeposit.paytype, orderDeposit.paytypename, orderDeposit.payno, +xpay.price, DateTime.Now, orderDeposit.channel.Value, 9, sumLastPrice, "解冻金额");
|
||
db.Wx_SzzyOrderPayUseLog.Add(log);
|
||
|
||
orderDeposit.lastprice -= xpay.price;//退款进去金额
|
||
db.SaveChanges();
|
||
var sumLastPrice2 = db.WX_SzzyOrderDeposit.Where(m => m.resid == orderDeposit.resid && m.isdelete == 0 && m.auditstatus == 1).Sum(m => m.lastprice);//获取总的金额
|
||
//退款金额
|
||
if (type == 1)
|
||
{
|
||
var log2 = new Wx_SzzyOrderPayUseLog(orderDeposit.resid, xpay.orderid, orderDeposit.id, orderDeposit.paytype, orderDeposit.paytypename, orderDeposit.payno, -xpay.price, DateTime.Now, orderDeposit.channel.Value, 6, sumLastPrice2, "完成退款");
|
||
db.Wx_SzzyOrderPayUseLog.Add(log2);
|
||
}
|
||
else
|
||
{
|
||
var log2 = new Wx_SzzyOrderPayUseLog(orderDeposit.resid, xpay.orderid, orderDeposit.id, orderDeposit.paytype, orderDeposit.paytypename, orderDeposit.payno, -xpay.price, DateTime.Now, orderDeposit.channel.Value, 7, sumLastPrice2, "余额退款");
|
||
db.Wx_SzzyOrderPayUseLog.Add(log2);
|
||
}
|
||
|
||
db.SaveChanges();
|
||
//推送订金状态到坐席
|
||
WX_SzzyOrderDeposit_BL.SendInfoFormat(eventInfo, orderDeposit, null, null);//将pay信息formrt
|
||
}
|
||
|
||
return retMsg;
|
||
}
|
||
|
||
|
||
public List<RefundDto> GetOrderRefund(DateTime startTime, DateTime? endTime = null)
|
||
{
|
||
using (var db = new zxdContext())
|
||
{
|
||
var query = from f in db.WX_SzzyOrderRefund
|
||
join o in db.WX_SZZYORDER on f.orderid equals o.ORDERID into foTmp
|
||
from fo in foTmp.DefaultIfEmpty()
|
||
where f.auditstatus == 1 && f.isdelete == 0 && f.refunddate >= startTime
|
||
select new RefundDto()
|
||
{
|
||
RefundDate = f.refunddate.Value,
|
||
RefundPrice = f.refundprice,
|
||
Channel = f.channel.Value,
|
||
ProductId = fo.PRODUCTID ?? 1008,
|
||
//ProductId = fo.SettleType ?? 1008,
|
||
OrderId = f.orderid
|
||
};
|
||
if (endTime.HasValue)
|
||
query = query.Where(p => p.RefundDate < endTime);
|
||
return query.ToList();
|
||
}
|
||
}
|
||
|
||
public List<RefundOrder> GetNotCurMonthRefundOrder(string starttime, string endtime)
|
||
{
|
||
//DateTime? stime = null;
|
||
//DateTime? etime = null;
|
||
//if (!string.IsNullOrEmpty(starttime))
|
||
//{
|
||
// stime = DateTime.Parse(starttime);
|
||
//}
|
||
//if (!string.IsNullOrEmpty(endtime))
|
||
//{
|
||
// etime = DateTime.Parse(endtime);
|
||
//}
|
||
|
||
var data = new List<RefundOrder>();
|
||
|
||
using (var db = new zxdContext())
|
||
{
|
||
var query = from f in db.WX_SzzyOrderRefund
|
||
join o in db.WX_SZZYORDER on f.orderid equals o.ORDERID
|
||
//where o.ISOPEN == 1 && f.auditstatus == 1 && f.refundprice > 10
|
||
where f.auditstatus == 1 //&& f.refundprice > 10
|
||
select new RefundOrder
|
||
{
|
||
orderid = f.orderid,
|
||
startRefundDate = f.refunddate.Value,
|
||
refundprice = f.refundprice,
|
||
channel = f.channel.Value,
|
||
productid = o.PRODUCTID.Value,
|
||
//productid = o.SettleType.Value,
|
||
endRefundDate = DateTime.Now,
|
||
arrivalpay = o.ARRIVALPAY.Value,
|
||
opendays2 = o.OPENDAYS.Value,
|
||
//otime = o.OTIME.Value,
|
||
otime = o.OTIME.HasValue ? o.OTIME.Value : o.ARRIVALTIME.Value,
|
||
needpay = o.NEEDPAY.Value,
|
||
refundtype = f.refundtype,
|
||
giftdays = o.giftdays,
|
||
settletype = o.SettleType,
|
||
subproductid = o.SUBPRODUCTID
|
||
};
|
||
|
||
//if (stime.HasValue && !etime.HasValue)
|
||
//{
|
||
// data = query.Where(p => p.otime >= stime).ToList();
|
||
//}
|
||
//else if (!stime.HasValue && etime.HasValue)
|
||
//{
|
||
// data = query.Where(p => p.otime < etime).ToList();
|
||
//}
|
||
//else if (stime.HasValue && etime.HasValue)
|
||
//{
|
||
// data = query.Where(p => p.otime >= stime && p.otime < etime).ToList();
|
||
//}
|
||
//else
|
||
//{
|
||
// data = query.ToList();
|
||
//}
|
||
|
||
data = query.ToList();
|
||
|
||
foreach (var item in data)
|
||
{
|
||
item.refunddate = int.Parse(item.startRefundDate.ToString("yyyyMM"));
|
||
var productArr = new List<int>() {
|
||
100743,100729,100730,100750,100719,100936,100747,100727,100726,100724,100725,100718
|
||
};
|
||
if (item.channel >= 26800 && item.channel <= 26899)
|
||
{
|
||
item.settletype = 1009;
|
||
}
|
||
if (productArr.Any(p => p == item.subproductid))
|
||
{
|
||
item.settletype = 1009;
|
||
}
|
||
//item.opendays = Convert.ToInt32(item.opendays2);
|
||
item.opendays = Convert.ToInt32(item.opendays2) + (item.giftdays ?? 0); //赠送
|
||
item.startRefundDate = Convert.ToDateTime(item.startRefundDate.ToString("d"));
|
||
item.endRefundDate = Convert.ToDateTime(item.otime.AddDays(item.opendays).ToString("d"));
|
||
if (item.refundtype == 11)
|
||
item.refundprice = item.refundprice * decimal.Parse("0.68607");
|
||
else if (item.refundtype == 12)
|
||
item.refundprice = item.refundprice * decimal.Parse("0.68760");
|
||
else if (item.refundtype == 13)
|
||
item.refundprice = item.refundprice * decimal.Parse("0.686");
|
||
}
|
||
var result = data
|
||
.GroupBy(c => new { c.orderid, c.startRefundDate, c.refunddate, c.channel, c.productid, c.arrivalpay, c.opendays, c.opendays2, c.otime, c.endRefundDate, c.needpay, c.settletype })
|
||
.Select(g => new RefundOrder
|
||
{
|
||
orderid = g.Key.orderid,
|
||
startRefundDate = g.Key.startRefundDate,
|
||
refunddate = g.Key.refunddate,
|
||
refundprice = g.Sum(p => p.refundprice),
|
||
channel = g.Key.channel,
|
||
productid = g.Key.productid,
|
||
endRefundDate = g.Key.endRefundDate,
|
||
arrivalpay = g.Key.arrivalpay,
|
||
opendays = g.Key.opendays,
|
||
opendays2 = g.Key.opendays2,
|
||
otime = g.Key.otime,
|
||
needpay = g.Key.needpay,
|
||
settletype = g.Key.settletype
|
||
});
|
||
|
||
|
||
return result.ToList();
|
||
}
|
||
}
|
||
|
||
public List<RefundDto2> GetRefundTotal(DateTime ftime)
|
||
{
|
||
var sql = @"
|
||
select CONVERT(DATE_FORMAT(f.audittime,'%Y%m'), SIGNED INTEGER) fmonth,sum(f.refundprice) refundprice
|
||
from wx_szzyorderrefund f
|
||
where f.auditstatus = 1 and f.audittime < @arg_ftime
|
||
group by DATE_FORMAT(f.audittime,'%Y%m')";
|
||
|
||
var param = new List<MySqlParameter> {
|
||
new MySqlParameter { ParameterName = "arg_ftime", DbType = DbType.DateTime, Value = ftime }
|
||
};
|
||
var ds = MySqlDbHelper.DataQueray(ConStringHelper.ZxdCRMConn, System.Data.CommandType.Text, sql, param.ToArray());
|
||
//return ds.Tables[0].ToList<ModulePriceDto>();
|
||
var list = new List<RefundDto2>();
|
||
foreach (DataRow row in ds.Tables[0].Rows)
|
||
{
|
||
list.Add(new RefundDto2() { fMonth = Convert.ToInt32(row[0]), refundPrice = Convert.ToDecimal(row[1]) });
|
||
}
|
||
return list;
|
||
}
|
||
|
||
public List<RefundDto2> GetNotUsedRefund(DateTime ftime)
|
||
{
|
||
var sql = @"
|
||
select a.fmonth, (a.refundprice + ifnull(b.refundprice,0)) refundprice
|
||
from
|
||
(
|
||
select CONVERT(DATE_FORMAT(f.audittime,'%Y%m'),SIGNED INTEGER) fmonth,sum(f.refundprice) refundprice
|
||
from wx_szzyorderrefund f
|
||
where f.auditstatus = 1 and f.audittime < @arg_ftime
|
||
and f.orderid not in(select m.orderid from zxdcrm_audit.wx_szzyordermodulerefund m)
|
||
and ((f.channel < 25000 or f.channel > 26199))
|
||
group by DATE_FORMAT(f.audittime,'%Y%m')
|
||
)a
|
||
left join
|
||
(
|
||
select CONVERT(DATE_FORMAT(f.audittime,'%Y%m'),SIGNED INTEGER) fmonth ,sum(f.refundprice) refundprice
|
||
from wx_szzyorderrefund f
|
||
where f.auditstatus = 1 and f.audittime < @arg_ftime
|
||
and f.orderid not in(select m.szzyorderid from zxdcrm_audit.wx_szzyordermodulerefund m)
|
||
and ((f.channel >= 25000 and f.channel <= 26199))
|
||
group by DATE_FORMAT(f.audittime,'%Y%m')
|
||
)b on a.fmonth = b.fmonth";
|
||
|
||
var param = new List<MySqlParameter> {
|
||
new MySqlParameter { ParameterName = "arg_ftime", DbType = DbType.DateTime, Value = ftime }
|
||
};
|
||
var ds = MySqlDbHelper.DataQueray(ConStringHelper.ZxdCRMConn, System.Data.CommandType.Text, sql, param.ToArray());
|
||
//return ds.Tables[0].ToList<ModulePriceDto>();
|
||
var list = new List<RefundDto2>();
|
||
foreach (DataRow row in ds.Tables[0].Rows)
|
||
{
|
||
list.Add(new RefundDto2() { fMonth = Convert.ToInt32(row[0]), refundPrice = Convert.ToDecimal(row[1]) });
|
||
}
|
||
return list;
|
||
}
|
||
|
||
public List<WX_SzzyOrderRefund> GetListByResid(string resid)
|
||
{
|
||
using (var db = new zxdContext())
|
||
{
|
||
var residStr = db.RES_CUSTOMER.Where(x => x.UMID == resid).FirstOrDefault()?.RESID;
|
||
var list1 = (from a in db.WX_SzzyOrderRefund
|
||
join b in db.WX_SzzyOrderDeposit on a.orderid equals b.id
|
||
where a.isdelete == 0
|
||
where a.auditstatus == 1
|
||
where b.resid == residStr
|
||
select a).ToList();
|
||
var list2 = (from a in db.WX_SzzyOrderRefund
|
||
join b in db.WX_SZZYORDER on a.orderid equals b.ORDERID
|
||
where a.isdelete == 0
|
||
where a.auditstatus == 1
|
||
where b.RESID == residStr
|
||
select a).ToList();
|
||
;
|
||
|
||
return list1.Union(list2).Where(x => x.orderid.ToString().Substring(0, 1) == "8").ToList();
|
||
}
|
||
}
|
||
}
|
||
|
||
public class OrderRefundView : WX_SzzyOrderRefund
|
||
{
|
||
public string resid { get; set; }
|
||
public string UMID { get; set; }
|
||
public DateTime? contracttime { get; set; }
|
||
public int? contractstatus { get; set; }
|
||
public string contractKey { get; set; }
|
||
}
|
||
|
||
public class RefundOrder
|
||
{
|
||
public int orderid { get; set; }
|
||
public DateTime startRefundDate { get; set; }
|
||
public int refunddate { get; set; }
|
||
public decimal refundprice { get; set; }
|
||
public int channel { get; set; }
|
||
public int productid { get; set; }
|
||
public DateTime endRefundDate { get; set; }
|
||
public decimal arrivalpay { get; set; }
|
||
public int opendays { get; set; }
|
||
public decimal opendays2 { get; set; }
|
||
public DateTime otime { get; set; }
|
||
public decimal needpay { get; set; }
|
||
public int refundtype { get; set; }
|
||
public int? giftdays { get; set; }
|
||
public int? settletype { get; set; }
|
||
public int subproductid { get; set; }
|
||
|
||
}
|
||
|
||
public class RefundDto
|
||
{
|
||
public DateTime RefundDate { get; set; }
|
||
public decimal RefundPrice { get; set; }
|
||
public int Channel { get; set; }
|
||
public int ProductId { get; set; }
|
||
public int OrderId { get; set; }
|
||
}
|
||
|
||
public class RefundDto2
|
||
{
|
||
public int fMonth { get; set; }
|
||
public decimal refundPrice { get; set; }
|
||
}
|
||
}
|