FeeAuditRepository.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. using EyeSoft.Logging;
  2. using NPOI.SS.Formula.Functions;
  3. using OASystem.Domain;
  4. using OASystem.Domain.Entities.Groups;
  5. using OASystem.Domain.ViewModels.Groups;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. namespace OASystem.Infrastructure.Repositories.Groups
  12. {
  13. /// <summary>
  14. /// 费用审核仓储
  15. /// </summary>
  16. public class FeeAuditRepository:BaseRepository<EntityBase,ViewBase>
  17. {
  18. public FeeAuditRepository(SqlSugarClient sqlSugar) : base(sqlSugar)
  19. {
  20. }
  21. /// <summary>
  22. /// 费用自动审核
  23. /// </summary>
  24. /// <param name="feeType">
  25. /// 1.酒店 76
  26. /// 2.op 79
  27. /// </param>
  28. /// <param name="diId">团组Id</param>
  29. /// <param name="dataId">数据Id(模块类型主表Id)</param>
  30. /// <returns></returns>
  31. public async Task<JsonView> FeeAutomaticAudit(int feeType, int diId, int dataId)
  32. {
  33. var _view = new JsonView() { Code = 201, Msg = "自动审核操作失败" };
  34. if (diId < 1) { _view.Msg = MsgTips.DiId; return _view; }
  35. if (dataId < 1) { _view.Msg = MsgTips.Id; return _view; }
  36. List<int> stids = new List<int>() { 17, 66 };
  37. var setData = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && stids.Contains(x.STid)).ToList();
  38. string _teamCurrency = string.Empty;
  39. decimal _rate = 0.00M;
  40. var groupInfo = _sqlSugar.Queryable< Grp_GroupCostParameter >().Where(x => x.IsDel ==0 && x.DiId == diId).First();
  41. if (groupInfo == null) { _view.Msg = $"团组成本信息未填写!"; return _view; }
  42. _teamCurrency = groupInfo.Currency;
  43. //币种验证 统一为currencycode三字码
  44. if (int.TryParse(_teamCurrency,out int currency))
  45. {
  46. _teamCurrency = setData.Find(x => x.Id == currency)?.Name ?? "";
  47. }
  48. _rate = groupInfo.Rate;
  49. string costContentSql = $"Select * From Grp_GroupCost";
  50. var costContents = _sqlSugar.SqlQueryable<GroupCostAuditView>(costContentSql).Where(x => x.IsDel == 0 && x.Diid == diId).ToList();
  51. if (costContents.Count < 1) { _view.Msg = $"团组成本信息未填写!"; return _view; }
  52. //处理 成本详细信息 日期为空
  53. for (int i = 0; i < costContents.Count; i++)
  54. {
  55. if (string.IsNullOrEmpty( costContents[i].Date))
  56. {
  57. int index = i - 1;
  58. if (index >= 0)
  59. {
  60. costContents[i].Date = costContents[index].Date;
  61. }
  62. }
  63. }
  64. if (feeType == 1)
  65. {
  66. var hotelCostInfo = _sqlSugar.Queryable<Grp_HotelReservations>().Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId).First();
  67. var hotelCostDetails = _sqlSugar.Queryable<Grp_HotelReservationsContent>().Where(x => x.IsDel == 0 && x.DiId == diId && x.HrId == dataId).ToList();
  68. if (hotelCostInfo == null)
  69. {
  70. _view.Msg = $"酒店费用数据未填写";
  71. return _view;
  72. }
  73. //验证币种是否相等
  74. string hotelCurrency = setData.Find(x => x.Id == hotelCostInfo.CardPriceCurrency)?.Name ?? "";
  75. if (hotelCurrency != _teamCurrency)
  76. {
  77. if (!hotelCurrency.Equals("CNY"))
  78. {
  79. _view.Msg = $"酒店预订费用币种与团组成本币种不一致,请手动审核";
  80. return _view;
  81. }
  82. }
  83. else _rate = 1.0000M;
  84. bool isAutoAudit = true; //是否自动审核
  85. DateTime checkIn = Convert.ToDateTime(hotelCostInfo.CheckInDate),
  86. checkOut = Convert.ToDateTime(hotelCostInfo.CheckOutDate);
  87. if (checkOut > checkIn) checkOut = checkOut.AddDays(-1); //房费计算,结束日期为前一天
  88. var hotelCostInfos = costContents.Where(x => Convert.ToDateTime(x.Date) >= checkIn && Convert.ToDateTime(x.Date) <= checkOut).ToList();
  89. if (hotelCostInfos.Count < 1) isAutoAudit = false;
  90. decimal otherFee = hotelCostDetails.Where(x => x.PriceType != 1).Sum(x => x.Price);
  91. if (otherFee > 0) { otherFee /= (checkOut-checkIn).Days; }
  92. var hotelCostInfosGroup = hotelCostInfos.GroupBy(x => x.Date);
  93. foreach (var item in hotelCostInfosGroup)
  94. {
  95. decimal hotelSingleRoomFee = item.Sum(x => x.HotelSingleRoomFee);
  96. decimal hotelDoubleRoomFee = item.Sum(x => x.HotelDoubleRoomFee);
  97. decimal hotelSuiteFee = item.Sum(x => x.HotelSuiteFee);
  98. decimal hotelSuiteRoomFee = item.Sum(x => x.HotelSuiteRoomFee);
  99. //1.判断费用是否 <= 成本费用
  100. //1.1 判断单间费用
  101. decimal singleRoomPrice = hotelCostInfo.SingleRoomPrice + otherFee;
  102. if (singleRoomPrice > 0) if (singleRoomPrice > hotelSingleRoomFee * _rate) isAutoAudit = false;
  103. //1.2 判断双人间费用
  104. decimal doubleRoomPrice = hotelCostInfo.DoubleRoomPrice + otherFee;
  105. if (doubleRoomPrice > 0) if (doubleRoomPrice > hotelDoubleRoomFee * _rate) isAutoAudit = false;
  106. //1.3 判断套房费用
  107. decimal suiteRoomPrice = hotelCostInfo.SuiteRoomPrice + otherFee;
  108. if (suiteRoomPrice > 0) if (suiteRoomPrice > hotelSuiteFee * _rate) isAutoAudit = false;
  109. //1.4 判断其他房型费用
  110. decimal otherRoomPrice = hotelCostInfo.OtherRoomPrice + otherFee;
  111. if (otherRoomPrice > 0) if (otherRoomPrice > hotelSuiteRoomFee * _rate) isAutoAudit = false;
  112. }
  113. //2.判断是否自动审核
  114. if (isAutoAudit)
  115. {
  116. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  117. .SetColumns(it => it.IsAuditGM == 3)
  118. .SetColumns(it => it.AuditGMOperate == 4)
  119. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  120. .Where(s => s.DIId == diId && s.CTable == 76 && s.CId == dataId)
  121. .ExecuteCommand();
  122. if (ccpUpdate > 0)
  123. {
  124. _view.Code = 200;
  125. _view.Msg = "自动审核执行成功";
  126. return _view;
  127. }
  128. }
  129. else {
  130. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  131. var ccpInfo = _sqlSugar.Queryable<Grp_CreditCardPayment>()
  132. .Where(s => s.DIId == diId && s.CTable == 76 && s.CId == dataId && s.IsAuditGM == 3)
  133. .First();
  134. if (ccpInfo != null)
  135. {
  136. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  137. .SetColumns(it => it.IsAuditGM == 0)
  138. .SetColumns(it => it.AuditGMOperate == 0)
  139. .SetColumns(it => it.AuditGMDate == string.Empty)
  140. .Where(s => s.Id == ccpInfo.Id)
  141. .ExecuteCommand();
  142. if (ccpUpdate > 0)
  143. {
  144. _view.Code = 200;
  145. _view.Msg = "费用超团组成本,自动审核撤销成功!";
  146. return _view;
  147. }
  148. }
  149. }
  150. }
  151. else if (feeType == 2)
  152. {
  153. //1.基础数据参数验证
  154. var priceType = new List<int>() { 1062 };
  155. var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  156. .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId && !priceType.Contains(x.PriceType))
  157. .First();
  158. //var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  159. // .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId )
  160. // .First();
  161. if (opinfos == null)
  162. {
  163. _view.Msg = $"OP费用费用类型属于“尾款”或者 内容未填写";
  164. return _view;
  165. }
  166. //1.含超时费用/超支费用 手动审核
  167. if (opinfos.SelectCheck.Contains("超时") || opinfos.SelectCheck.Contains("超支") || opinfos.SelectCheck.Contains("尾款"))
  168. {
  169. _view.Msg = @$"OP费用含尾款/超支/超时费用,请手动审核";
  170. return _view;
  171. }
  172. //1.参数验证
  173. var opCheckPriceTyeps = opinfos.SelectCheck.Split(',');
  174. var opCheckPriceTyepIds = setData.Where(x => opinfos.SelectCheck.Split(',').Contains(x.Name)).Select(x=>x.Id).ToList();
  175. var opContents = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservationsContent>()
  176. .Where(x => x.IsDel == 0 && x.DiId == diId && x.CTGGRId == dataId && opCheckPriceTyepIds.Contains(x.SId))
  177. .OrderBy(x => x.DatePrice, OrderByType.Asc)
  178. .ToList();
  179. if (opContents.Count < 1)
  180. {
  181. _view.Msg = $"OP费用费用内容未填写";
  182. return _view;
  183. }
  184. string opCurrencyName = setData.Find(x => x.Id == opContents[0].Currency)?.Name ?? "";
  185. //1.1币种验证
  186. if (!opCurrencyName.Equals(_teamCurrency))
  187. {
  188. if (!opCurrencyName.Equals("CNY"))
  189. {
  190. _view.Msg = $"OP费用币种与团组成本币种不一致,请手动审核";
  191. return _view;
  192. }
  193. }
  194. else _rate = 1.0000M;
  195. var opBasicDatas = setData.Where(x => x.STid == 17).ToList(); //费用类型基础数据
  196. bool isAutoAudit = true;
  197. if (!DateTime.TryParse(opinfos.ServiceStartTime, out DateTime startDt1) || !DateTime.TryParse(opinfos.ServiceEndTime, out DateTime endDt1))
  198. {
  199. _view.Msg = $"OP费用服务起止日期格式不正确!";
  200. return _view;
  201. }
  202. DateTime startDt = startDt1;
  203. DateTime endDt = endDt1;
  204. var opCostDatas = costContents.Where(it => Convert.ToDateTime(it.Date) >= startDt && Convert.ToDateTime(it.Date) <= endDt).ToList();
  205. if (opCostDatas.Count < 1)
  206. {
  207. _view.Msg = $"该时间段内团组成本未填写!";
  208. return _view;
  209. }
  210. var noAuditFeeTypeIds = new List<int> {
  211. 982 ,//982 车超时费 -- 暂无
  212. 96 ,//96 接送机费 -- 暂无
  213. 97 ,//97 其他费用 -- 暂无
  214. 992 ,//992 住补费用 -- 暂无
  215. 1059,//1059 导游超时费用 -- 暂无
  216. 1070,//1070 尾款金额 -- 暂无
  217. 1071,//1071 其他额外费用 -- 暂无
  218. 1073,//1073 翻译超时费 -- 暂无
  219. 1074,//1074 早餐超支费用 -- 暂无
  220. 1075,//1075 午餐超支费用 -- 暂无
  221. 1076,//1076 晚餐超支费用 -- 暂无
  222. };
  223. //费用类型筛选 包含 feeTypeIds && 包含这些类型费用大于0
  224. var noAuditFeeContents = opContents.Where(x => x.Price > 0 && noAuditFeeTypeIds.Contains(x.SId)).ToList();
  225. if (noAuditFeeContents.Count > 0)
  226. {
  227. _view.Msg = @$"OP费用含尾款/超支/超时费用,请手动审核";
  228. return _view;
  229. }
  230. //2.按天按项 检查费用是否超过预算
  231. var opDayContent = opContents.GroupBy(x => x.DatePrice);
  232. foreach (var item in opDayContent)
  233. {
  234. var opCostInfo = opCostDatas.Where(x => Convert.ToDateTime(x.Date) == item.Key).ToList();
  235. if (opCostInfo.Count < 1) continue;
  236. //车费 91
  237. var opCarCost = item.FirstOrDefault(x => x.SId == 91);
  238. if (opCarCost != null) if (opCarCost.Price > _rate * opCostInfo.Sum(x => x.CarFee)) isAutoAudit = false;
  239. //982 车超时费 -- 暂无
  240. //92 导游费
  241. var opGuideCost = item.FirstOrDefault(x => x.SId == 92);
  242. if (opGuideCost != null) if (opGuideCost.Price > _rate * opCostInfo.Sum(x => x.GuideFee)) isAutoAudit = false;
  243. //94 导游景点费
  244. var opGuideScenicCost = item.FirstOrDefault(x => x.SId == 94);
  245. if (opGuideScenicCost != null) if (opGuideScenicCost.Price > _rate * opCostInfo.Sum(x => x.GuideScenicFee)) isAutoAudit = false;
  246. //95 导游小费
  247. var opGuideTipCost = item.FirstOrDefault(x => x.SId == 95);
  248. if (opGuideTipCost != null) if (opGuideTipCost.Price > _rate * opCostInfo.Sum(x => x.GuideTipFee)) isAutoAudit = false;
  249. //983 导游餐补
  250. var opGuideMealCost = item.FirstOrDefault(x => x.SId == 983);
  251. if (opGuideMealCost != null) if (opGuideMealCost.Price > _rate * opCostInfo.Sum(x => x.GuideMealFee)) isAutoAudit = false;
  252. //984 导游房补
  253. var opGuideRoomCost = item.FirstOrDefault(x => x.SId == 984);
  254. if (opGuideRoomCost != null) if (opGuideRoomCost.Price > _rate * opCostInfo.Sum(x => x.GuideRoomFee)) isAutoAudit = false;
  255. //985 导游交通
  256. var opGuideTrafficCost = item.FirstOrDefault(x => x.SId == 985);
  257. if (opGuideTrafficCost != null) if (opGuideTrafficCost.Price > _rate * opCostInfo.Sum(x => x.GuideTrafficFee)) isAutoAudit = false;
  258. //96 接送机费 -- 暂无
  259. //97 其他费用 -- 暂无
  260. //979 司机工资
  261. var opDriverCost = item.FirstOrDefault(x => x.SId == 979);
  262. if (opDriverCost != null) if (opDriverCost.Price > _rate * opCostInfo.Sum(x => x.DriverFee)) isAutoAudit = false;
  263. //980 司机小费
  264. var opDriverTipCost = item.FirstOrDefault(x => x.SId == 980);
  265. if (opDriverTipCost != null) if (opDriverTipCost.Price > _rate * opCostInfo.Sum(x => x.DriverTipFee)) isAutoAudit = false;
  266. //981 司机餐补
  267. var opDriverMealCost = item.FirstOrDefault(x => x.SId == 981);
  268. if (opDriverMealCost != null) if (opDriverMealCost.Price > _rate * opCostInfo.Sum(x => x.DriverMealFee)) isAutoAudit = false;
  269. //988 客户早餐费用
  270. var opClientBreakfastCost = item.FirstOrDefault(x => x.SId == 988);
  271. if (opClientBreakfastCost != null) if (opClientBreakfastCost.Price > _rate * opCostInfo.Sum(x => x.ClientBreakfastFee)) isAutoAudit = false;
  272. //93 客户午餐费用
  273. var opClientLunchCost = item.FirstOrDefault(x => x.SId == 93);
  274. if (opClientLunchCost != null) if (opClientLunchCost.Price > _rate * opCostInfo.Sum(x => x.ClientLunchFee)) isAutoAudit = false;
  275. //989 客户晚餐费用
  276. var opClientDinnerCost = item.FirstOrDefault(x => x.SId == 989);
  277. if (opClientDinnerCost != null) if (opClientDinnerCost.Price > _rate * opCostInfo.Sum(x => x.ClientDinnerFee)) isAutoAudit = false;
  278. //990 景点门票费
  279. var opScenicTicketCost = item.FirstOrDefault(x => x.SId == 990);
  280. if (opScenicTicketCost != null) if (opScenicTicketCost.Price > _rate * opCostInfo.Sum(x => x.ScenicTicketFee)) isAutoAudit = false;
  281. //991 饮料/零食/水果
  282. var opDrinkSnackFruitCost = item.FirstOrDefault(x => x.SId == 991);
  283. if (opDrinkSnackFruitCost != null) if (opDrinkSnackFruitCost.Price > _rate * opCostInfo.Sum(x => x.DrinkSnackFruitFee)) isAutoAudit = false;
  284. //992 住补费用 -- 暂无
  285. //994 翻译费
  286. var opTranslatorCost = item.FirstOrDefault(x => x.SId == 994);
  287. if (opTranslatorCost != null) if (opTranslatorCost.Price > _rate * opCostInfo.Sum(x => x.TranslatorFee)) isAutoAudit = false;
  288. //1059 导游超时费用 -- 暂无
  289. //1070 尾款金额 -- 暂无
  290. //1071 其他额外费用 -- 暂无
  291. //1073 翻译超时费 -- 暂无
  292. //1074 早餐超支费用 -- 暂无
  293. //1075 午餐超支费用 -- 暂无
  294. //1076 晚餐超支费用 -- 暂无
  295. }
  296. //更改审核状态
  297. if (isAutoAudit)
  298. {
  299. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  300. .SetColumns(it => it.IsAuditGM == 3)
  301. .SetColumns(it => it.AuditGMOperate == 4)
  302. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  303. .Where(s => s.DIId == diId && s.CTable == 79 && s.CId == dataId)
  304. .ExecuteCommand();
  305. if (ccpUpdate > 0)
  306. {
  307. _view.Code = 200;
  308. _view.Msg = "自动审核执行成功!";
  309. return _view;
  310. }
  311. }
  312. else
  313. {
  314. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  315. var ccpInfo = _sqlSugar.Queryable<Grp_CreditCardPayment>()
  316. .Where(s => s.DIId == diId && s.CTable == 79 && s.CId == dataId && s.IsAuditGM == 3)
  317. .First();
  318. if (ccpInfo != null)
  319. {
  320. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  321. .SetColumns(it => it.IsAuditGM == 0)
  322. .SetColumns(it => it.AuditGMOperate == 0)
  323. .SetColumns(it => it.AuditGMDate == string.Empty)
  324. .Where(s => s.Id == ccpInfo.Id)
  325. .ExecuteCommand();
  326. if (ccpUpdate > 0)
  327. {
  328. _view.Code = 200;
  329. _view.Msg = "费用超团组成本,自动审核撤销成功!";
  330. return _view;
  331. }
  332. }
  333. }
  334. }
  335. else _view.Msg = $"请传入有效的feeType参数";
  336. return _view;
  337. }
  338. }
  339. }