FeeAuditRepository.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  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. /// 3.其他费用-出行物资 98
  28. /// </param>
  29. /// <param name="diId">团组Id</param>
  30. /// <param name="dataId">数据Id(模块类型主表Id)</param>
  31. /// <returns></returns>
  32. public async Task<JsonView> FeeAutomaticAudit(int feeType, int diId, int dataId)
  33. {
  34. var _view = new JsonView() { Code = 201, Msg = "自动审核操作失败" };
  35. if (diId < 1) { _view.Msg = MsgTips.DiId; return _view; }
  36. if (dataId < 1) { _view.Msg = MsgTips.Id; return _view; }
  37. var stids = new List<int>() { 17, 66, 91 };
  38. var setData = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && stids.Contains(x.STid)).ToList();
  39. string _teamCurrency = string.Empty;
  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. decimal _teamRate = groupInfo.Rate;
  44. //币种验证 统一为currencycode三字码
  45. if (int.TryParse(_teamCurrency,out int currency)) _teamCurrency = setData.Find(x => x.Id == currency)?.Name ?? "";
  46. string costContentSql = $"Select * From Grp_GroupCost";
  47. var costContents = _sqlSugar.SqlQueryable<GroupCostAuditView>(costContentSql).Where(x => x.IsDel == 0 && x.Diid == diId).ToList();
  48. if (costContents.Count < 1) { _view.Msg = $"团组成本信息未填写!"; return _view; }
  49. //处理 成本详细信息 日期为空
  50. for (int i = 0; i < costContents.Count; i++)
  51. {
  52. if (string.IsNullOrEmpty( costContents[i].Date))
  53. {
  54. int index = i - 1;
  55. if (index >= 0)
  56. {
  57. costContents[i].Date = costContents[index].Date;
  58. var dtBool = DateTime.TryParse(costContents[i].Date, out DateTime _dateTime);
  59. if (dtBool)
  60. {
  61. costContents[i].CurrTime = _dateTime;
  62. }
  63. }
  64. }
  65. else
  66. {
  67. var dtBool = DateTime.TryParse(costContents[i].Date, out DateTime _dateTime);
  68. if (dtBool)
  69. {
  70. costContents[i].CurrTime = _dateTime;
  71. }
  72. }
  73. }
  74. if (feeType == 1)
  75. {
  76. //1089 对冲账或其他 不在审核范围
  77. var hotelCostInfo = _sqlSugar.Queryable<Grp_HotelReservations>().Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId && x.CheckType != 1089).First();
  78. var hotelCostDetails = _sqlSugar.Queryable<Grp_HotelReservationsContent>().Where(x => x.IsDel == 0 && x.DiId == diId && x.HrId == dataId).ToList();
  79. if (hotelCostInfo == null)
  80. {
  81. _view.Msg = $"酒店费用数据未填写";
  82. QuashAudit(76, diId, dataId);
  83. return _view;
  84. }
  85. //酒店费用金额 == 0 不自动审核
  86. if (hotelCostInfo.CardPrice == 0.0000M)
  87. {
  88. _view.Msg = $"酒店费用金额 == 0 不自动审核";
  89. QuashAudit(76, diId, dataId);
  90. return _view;
  91. }
  92. //获取C表汇率
  93. decimal _rate = 1.0000M;
  94. var roomFeeInfo = hotelCostDetails.Where(x => x.PriceType == 1).First();
  95. if (roomFeeInfo == null)
  96. {
  97. _view.Msg = $"酒店房间费用付款数据未填写";
  98. return _view;
  99. }
  100. _rate = roomFeeInfo.Rate == 0.0000M ? 1.0000M : roomFeeInfo.Rate;
  101. bool isAutoAudit = true; //是否自动审核
  102. DateTime checkIn = Convert.ToDateTime(hotelCostInfo.CheckInDate),
  103. checkOut = Convert.ToDateTime(hotelCostInfo.CheckOutDate);
  104. if (checkOut > checkIn) checkOut = checkOut.AddDays(-1); //房费计算,结束日期为前一天
  105. var hotelCostInfos = costContents.Where(x => x.CurrTime >= checkIn && x.CurrTime <= checkOut).ToList();
  106. if (hotelCostInfos.Count < 1) isAutoAudit = false;
  107. decimal otherFee = hotelCostDetails.Where(x => x.PriceType != 1).Sum(x => x.Price * (x.Rate == 0.0000M ? 1.0000M : x.Rate));
  108. if (otherFee > 0) { otherFee /= (checkOut - checkIn).Days; }
  109. var hotelCostInfosGroup = hotelCostInfos.GroupBy(x => x.Date);
  110. foreach (var item in hotelCostInfosGroup)
  111. {
  112. var hotelSingleRoomFee = item.Sum(x => x.HotelSingleRoomFee) * _teamRate; //成本单间费用
  113. var hotelDoubleRoomFee = item.Sum(x => x.HotelDoubleRoomFee) * _teamRate; //成本双人间费用
  114. var hotelSuiteFee = item.Sum(x => x.HotelSuiteFee) * _teamRate; //成本套房费用
  115. var hotelSuiteRoomFee = item.Sum(x => x.HotelSuiteRoomFee) * _teamRate; //成本其他房型间费用
  116. //1.判断费用是否 <= 成本费用
  117. //1.1 判断单间费用
  118. decimal singleRoomPrice = (hotelCostInfo.SingleRoomPrice + otherFee) * _rate; //酒店录入费用
  119. if (singleRoomPrice > 0) if (singleRoomPrice > hotelSingleRoomFee) isAutoAudit = false;
  120. //1.2 判断双人间费用
  121. decimal doubleRoomPrice = (hotelCostInfo.DoubleRoomPrice + otherFee) * _rate;//酒店录入费用
  122. if (doubleRoomPrice > 0) if (doubleRoomPrice > hotelDoubleRoomFee) isAutoAudit = false;
  123. //1.3 判断套房费用
  124. decimal suiteRoomPrice = (hotelCostInfo.SuiteRoomPrice + otherFee) * _rate;//酒店录入费用
  125. if (suiteRoomPrice > 0) if (suiteRoomPrice > hotelSuiteFee) isAutoAudit = false;
  126. //1.4 判断其他房型费用
  127. decimal otherRoomPrice = (hotelCostInfo.OtherRoomPrice + otherFee) * _rate;//酒店录入费用
  128. if (otherRoomPrice > 0) if (otherRoomPrice > hotelSuiteRoomFee) isAutoAudit = false;
  129. }
  130. //2.判断是否自动审核
  131. if (isAutoAudit)
  132. {
  133. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  134. .SetColumns(it => it.IsAuditGM == 3)
  135. .SetColumns(it => it.AuditGMOperate == 4)
  136. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  137. .Where(s => s.DIId == diId && s.CTable == 76 && s.CId == dataId)
  138. .ExecuteCommand();
  139. if (ccpUpdate > 0)
  140. {
  141. _view.Code = 200;
  142. _view.Msg = "自动审核执行成功";
  143. return _view;
  144. }
  145. }
  146. else
  147. {
  148. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  149. var quashStatus = QuashAudit(76, diId, dataId);
  150. if (quashStatus)
  151. {
  152. _view.Code = 200;
  153. _view.Msg = "费用超团组成本,自动审核撤销成功!";
  154. return _view;
  155. }
  156. }
  157. }
  158. else if (feeType == 2)
  159. {
  160. //1.基础数据参数验证
  161. var priceType = new List<int>() {
  162. 1062 //1062 尾款
  163. };
  164. var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  165. .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId && !priceType.Contains(x.PriceType))
  166. .First();
  167. //var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  168. // .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId )
  169. // .First();
  170. if (opinfos == null)
  171. {
  172. _view.Msg = $"OP费用费用类型属于“尾款”或者 内容未填写";
  173. return _view;
  174. }
  175. //1.含超时费用/超支费用 手动审核
  176. if (opinfos.SelectCheck.Contains("超时") || opinfos.SelectCheck.Contains("超支") || opinfos.SelectCheck.Contains("尾款"))
  177. {
  178. _view.Msg = @$"OP费用含尾款/超支/超时费用,请手动审核";
  179. return _view;
  180. }
  181. //1.参数验证
  182. var opCheckPriceTyeps = opinfos.SelectCheck.Split(',');
  183. var opCheckPriceTyepIds = setData.Where(x => opinfos.SelectCheck.Split(',').Contains(x.Name)).Select(x => x.Id).ToList();
  184. var opContents = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservationsContent>()
  185. .Where(x => x.IsDel == 0 && x.DiId == diId && x.CTGGRId == dataId && opCheckPriceTyepIds.Contains(x.SId))
  186. .OrderBy(x => x.DatePrice, OrderByType.Asc)
  187. .ToList();
  188. if (opContents.Count < 1)
  189. {
  190. _view.Msg = $"OP费用费用内容未填写";
  191. return _view;
  192. }
  193. //获取C表汇率
  194. decimal _opRate = 1.0000M;
  195. var payInfo = _sqlSugar.Queryable<Grp_CreditCardPayment>().Where(x => x.IsDel == 0 && x.DIId == diId && x.CTable == 79 && x.CId == dataId).First();
  196. if (payInfo == null)
  197. {
  198. _view.Msg = $"OP费用付款数据未填写";
  199. return _view;
  200. }
  201. _opRate = payInfo.DayRate;
  202. string opCurrencyName = setData.Find(x => x.Id == opContents[0].Currency)?.Name ?? "";
  203. //团组、OP币种 验证是否一致
  204. if (opCurrencyName.Equals(_teamCurrency))
  205. {
  206. _opRate = payInfo.DayRate;
  207. _teamRate = payInfo.DayRate;
  208. }
  209. var opBasicDatas = setData.Where(x => x.STid == 17).ToList(); //费用类型基础数据
  210. bool isAutoAudit = true;
  211. if (!DateTime.TryParse(opinfos.ServiceStartTime, out DateTime startDt1) || !DateTime.TryParse(opinfos.ServiceEndTime, out DateTime endDt1))
  212. {
  213. _view.Msg = $"OP费用服务起止日期格式不正确!";
  214. return _view;
  215. }
  216. DateTime startDt = startDt1;
  217. DateTime endDt = endDt1;
  218. var opCostDatas = costContents.Where(it => Convert.ToDateTime(it.Date) >= startDt && Convert.ToDateTime(it.Date) <= endDt).ToList();
  219. if (opCostDatas.Count < 1)
  220. {
  221. _view.Msg = $"该时间段内团组成本未填写!";
  222. return _view;
  223. }
  224. var noAuditFeeTypeIds = new List<int> {
  225. 982 ,//982 车超时费 -- 暂无
  226. 96 ,//96 接送机费 -- 暂无
  227. 97 ,//97 其他费用 -- 暂无
  228. 992 ,//992 住补费用 -- 暂无
  229. 1059,//1059 导游超时费用 -- 暂无
  230. 1070,//1070 尾款金额 -- 暂无
  231. 1071,//1071 其他额外费用 -- 暂无
  232. 1073,//1073 翻译超时费 -- 暂无
  233. 1074,//1074 早餐超支费用 -- 暂无
  234. 1075,//1075 午餐超支费用 -- 暂无
  235. 1076,//1076 晚餐超支费用 -- 暂无
  236. };
  237. //费用类型筛选 包含 feeTypeIds && 包含这些类型费用大于0
  238. var noAuditFeeContents = opContents.Where(x => x.Price > 0 && noAuditFeeTypeIds.Contains(x.SId)).ToList();
  239. if (noAuditFeeContents.Count > 0)
  240. {
  241. _view.Msg = @$"OP费用含尾款/超支/超时费用,请手动审核";
  242. return _view;
  243. }
  244. //2.按天按项 检查费用是否超过预算
  245. var opDayContent = opContents.GroupBy(x => x.DatePrice);
  246. foreach (var item in opDayContent)
  247. {
  248. var opCostInfo = opCostDatas.Where(x => Convert.ToDateTime(x.Date) == item.Key).ToList();
  249. if (opCostInfo.Count < 1) continue;
  250. //车费 91
  251. var opCarCost = item.FirstOrDefault(x => x.SId == 91);
  252. if (opCarCost != null) if (opCarCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.CarFee)) isAutoAudit = false;
  253. //982 车超时费 -- 暂无
  254. //92 导游费
  255. var opGuideCost = item.FirstOrDefault(x => x.SId == 92);
  256. if (opGuideCost != null) if (opGuideCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.GuideFee)) isAutoAudit = false;
  257. //94 导游景点费
  258. var opGuideScenicCost = item.FirstOrDefault(x => x.SId == 94);
  259. if (opGuideScenicCost != null) if (opGuideScenicCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.GuideScenicFee)) isAutoAudit = false;
  260. //95 导游小费
  261. var opGuideTipCost = item.FirstOrDefault(x => x.SId == 95);
  262. if (opGuideTipCost != null) if (opGuideTipCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.GuideTipFee)) isAutoAudit = false;
  263. //983 导游餐补
  264. var opGuideMealCost = item.FirstOrDefault(x => x.SId == 983);
  265. if (opGuideMealCost != null) if (opGuideMealCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.GuideMealFee)) isAutoAudit = false;
  266. //984 导游房补
  267. var opGuideRoomCost = item.FirstOrDefault(x => x.SId == 984);
  268. if (opGuideRoomCost != null) if (opGuideRoomCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.GuideRoomFee)) isAutoAudit = false;
  269. //985 导游交通
  270. var opGuideTrafficCost = item.FirstOrDefault(x => x.SId == 985);
  271. if (opGuideTrafficCost != null) if (opGuideTrafficCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.GuideTrafficFee)) isAutoAudit = false;
  272. //96 接送机费 -- 暂无
  273. //97 其他费用 -- 暂无
  274. //979 司机工资
  275. var opDriverCost = item.FirstOrDefault(x => x.SId == 979);
  276. if (opDriverCost != null) if (opDriverCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.DriverFee)) isAutoAudit = false;
  277. //980 司机小费
  278. var opDriverTipCost = item.FirstOrDefault(x => x.SId == 980);
  279. if (opDriverTipCost != null) if (opDriverTipCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.DriverTipFee)) isAutoAudit = false;
  280. //981 司机餐补
  281. var opDriverMealCost = item.FirstOrDefault(x => x.SId == 981);
  282. if (opDriverMealCost != null) if (opDriverMealCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.DriverMealFee)) isAutoAudit = false;
  283. //988 客户早餐费用
  284. var opClientBreakfastCost = item.FirstOrDefault(x => x.SId == 988);
  285. if (opClientBreakfastCost != null) if (opClientBreakfastCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.ClientBreakfastFee)) isAutoAudit = false;
  286. //93 客户午餐费用
  287. var opClientLunchCost = item.FirstOrDefault(x => x.SId == 93);
  288. if (opClientLunchCost != null) if (opClientLunchCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.ClientLunchFee)) isAutoAudit = false;
  289. //989 客户晚餐费用
  290. var opClientDinnerCost = item.FirstOrDefault(x => x.SId == 989);
  291. if (opClientDinnerCost != null) if (opClientDinnerCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.ClientDinnerFee)) isAutoAudit = false;
  292. //990 景点门票费
  293. var opScenicTicketCost = item.FirstOrDefault(x => x.SId == 990);
  294. if (opScenicTicketCost != null) if (opScenicTicketCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.ScenicTicketFee)) isAutoAudit = false;
  295. //991 饮料/零食/水果
  296. var opDrinkSnackFruitCost = item.FirstOrDefault(x => x.SId == 991);
  297. if (opDrinkSnackFruitCost != null) if (opDrinkSnackFruitCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.DrinkSnackFruitFee)) isAutoAudit = false;
  298. //992 住补费用 -- 暂无
  299. //994 翻译费
  300. var opTranslatorCost = item.FirstOrDefault(x => x.SId == 994);
  301. if (opTranslatorCost != null) if (opTranslatorCost.Price * _opRate > _teamRate * opCostInfo.Sum(x => x.TranslatorFee)) isAutoAudit = false;
  302. //1059 导游超时费用 -- 暂无
  303. //1070 尾款金额 -- 暂无
  304. //1071 其他额外费用 -- 暂无
  305. //1073 翻译超时费 -- 暂无
  306. //1074 早餐超支费用 -- 暂无
  307. //1075 午餐超支费用 -- 暂无
  308. //1076 晚餐超支费用 -- 暂无
  309. }
  310. //更改审核状态
  311. if (isAutoAudit)
  312. {
  313. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  314. .SetColumns(it => it.IsAuditGM == 3)
  315. .SetColumns(it => it.AuditGMOperate == 4)
  316. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  317. .Where(s => s.DIId == diId && s.CTable == 79 && s.CId == dataId)
  318. .ExecuteCommand();
  319. if (ccpUpdate > 0)
  320. {
  321. _view.Code = 200;
  322. _view.Msg = "自动审核执行成功!";
  323. return _view;
  324. }
  325. }
  326. else
  327. {
  328. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  329. if (QuashAudit(79, diId, dataId))
  330. {
  331. _view.Code = 200;
  332. _view.Msg = "费用超团组成本,自动审核撤销成功!";
  333. return _view;
  334. }
  335. }
  336. }
  337. else if (feeType == 3)
  338. {
  339. #region 出行物资的功能及相关费用自动审核
  340. var isAutoAudit = false;
  341. var currModule = 98; //其他款项
  342. int groupSize = 0; // 团组人数
  343. var groupDetails = await _sqlSugar.Queryable<Grp_DelegationInfo>().Where(x => x.IsDel == 0 && x.Id == diId).FirstAsync();
  344. if (groupInfo != null) groupSize = groupDetails.VisitPNumber;
  345. decimal groupCostCNYTotal = costContents.Sum(x => x.TeFee) * _teamRate * groupSize; //团组成本出行物资总金额
  346. if (groupCostCNYTotal <= 0.00M)
  347. {
  348. _view.Msg = $"团组成本出行物资费用数据未填写";
  349. QuashAudit(currModule, diId, dataId);
  350. return _view;
  351. }
  352. var teNames = setData.Where(x => x.STid == 91).Select(x => x.Name).ToList();
  353. var otherFeeDatas = _sqlSugar.Queryable<Grp_DecreasePayments>()
  354. .InnerJoin<Grp_CreditCardPayment>((dp,ccp) => dp.Id == ccp.CId && ccp.CTable == 98 && ccp.IsDel == 0)
  355. .Where((dp, ccp) => dp.IsDel == 0 && dp.DiId == diId)
  356. .ToList();
  357. var ids = new List<int>();
  358. foreach (var item in otherFeeDatas)
  359. {
  360. if (item.PriceName.Contains("、"))
  361. {
  362. var priceNames = item.PriceName.Split('、');
  363. foreach (var priceName in priceNames)
  364. {
  365. if (teNames.Contains(priceName))
  366. {
  367. ids.Add(item.Id);
  368. continue;
  369. }
  370. }
  371. }
  372. else if(teNames.Contains(item.PriceName))
  373. {
  374. ids.Add(item.Id);
  375. }
  376. }
  377. ids = ids.Distinct().ToList();
  378. decimal otherFeeCNYTotal = otherFeeDatas.Where(x => ids.Contains(x.Id)).Sum(x => x.FeeTotal); //其他费用出行物资总金额
  379. if (otherFeeCNYTotal <= 0.00M)
  380. {
  381. _view.Msg = $"其他款项出行物资费用数据未填写";
  382. QuashAudit(currModule, diId, dataId);
  383. return _view;
  384. }
  385. if (otherFeeCNYTotal > groupCostCNYTotal)
  386. {
  387. _view.Msg = $"其他款项出行物资费用超出团组成本物资费用";
  388. QuashAudit(currModule, diId, dataId);
  389. return _view;
  390. }
  391. isAutoAudit = true;
  392. //2.判断是否自动审核
  393. if (isAutoAudit)
  394. {
  395. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  396. .SetColumns(it => it.IsAuditGM == 3)
  397. .SetColumns(it => it.AuditGMOperate == 4)
  398. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  399. .Where(s => s.DIId == diId && s.CTable == currModule && s.CId == dataId)
  400. .ExecuteCommand();
  401. if (ccpUpdate > 0)
  402. {
  403. _view.Code = 200;
  404. _view.Msg = "自动审核执行成功";
  405. return _view;
  406. }
  407. }
  408. else
  409. {
  410. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  411. var quashStatus = QuashAudit(currModule, diId, dataId);
  412. if (quashStatus)
  413. {
  414. _view.Code = 200;
  415. _view.Msg = "费用超团组成本,自动审核撤销成功!";
  416. return _view;
  417. }
  418. }
  419. #endregion
  420. }
  421. else _view.Msg = $"请传入有效的feeType参数";
  422. return _view;
  423. }
  424. /// <summary>
  425. /// hotel、op 撤销自动审核的数据
  426. /// </summary>
  427. /// <param name="type">
  428. /// 酒店 76
  429. /// op 79
  430. /// </param>
  431. /// <param name="diId"></param>
  432. /// <param name="dataId"></param>
  433. /// <returns></returns>
  434. private bool QuashAudit(int type, int diId, int dataId)
  435. {
  436. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  437. var ccpInfo = _sqlSugar.Queryable<Grp_CreditCardPayment>()
  438. .Where(s => s.DIId == diId && s.CTable == type && s.CId == dataId && s.IsAuditGM == 3)
  439. .First();
  440. if (ccpInfo != null)
  441. {
  442. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  443. .SetColumns(it => it.IsAuditGM == 0)
  444. .SetColumns(it => it.AuditGMOperate == 0)
  445. .SetColumns(it => it.AuditGMDate == string.Empty)
  446. .Where(s => s.Id == ccpInfo.Id)
  447. .ExecuteCommand();
  448. if (ccpUpdate > 0)
  449. {
  450. return true;
  451. }
  452. }
  453. return false;
  454. }
  455. //
  456. /// <summary>
  457. /// 费用自动审核
  458. /// </summary>
  459. /// <param name="feeType">
  460. /// 1.酒店 76
  461. /// 2.op 79
  462. /// </param>
  463. /// <param name="diId">团组Id</param>
  464. /// <param name="dataId">数据Id(模块类型主表Id)</param>
  465. /// <returns></returns>
  466. public string IsOverBudget(int feeType, int diId, int dataId)
  467. {
  468. string _view ="-";
  469. if (diId < 1) { return _view; }
  470. if (dataId < 1) { return _view; }
  471. List<int> stids = new List<int>() { 17, 66 };
  472. var setData = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && stids.Contains(x.STid)).ToList();
  473. string _teamCurrency = string.Empty;
  474. var groupInfo = _sqlSugar.Queryable<Grp_GroupCostParameter>().Where(x => x.IsDel == 0 && x.DiId == diId).First();
  475. if (groupInfo == null) { return _view; }
  476. _teamCurrency = groupInfo.Currency;
  477. //币种验证 统一为currencycode三字码
  478. if (int.TryParse(_teamCurrency, out int currency)) _teamCurrency = setData.Find(x => x.Id == currency)?.Name ?? "";
  479. string costContentSql = $"Select * From Grp_GroupCost";
  480. var costContents = _sqlSugar.SqlQueryable<GroupCostAuditView>(costContentSql).Where(x => x.IsDel == 0 && x.Diid == diId).ToList();
  481. if (costContents.Count < 1) { return _view; }
  482. //处理 成本详细信息 日期为空
  483. for (int i = 0; i < costContents.Count; i++)
  484. {
  485. if (string.IsNullOrEmpty(costContents[i].Date))
  486. {
  487. int index = i - 1;
  488. if (index >= 0)
  489. {
  490. costContents[i].Date = costContents[index].Date;
  491. }
  492. }
  493. }
  494. if (feeType == 1)
  495. {
  496. var hotelCostInfo = _sqlSugar.Queryable<Grp_HotelReservations>().Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId).First();
  497. var hotelCostDetails = _sqlSugar.Queryable<Grp_HotelReservationsContent>().Where(x => x.IsDel == 0 && x.DiId == diId && x.HrId == dataId).ToList();
  498. if (hotelCostInfo == null) return _view;
  499. //获取C表汇率
  500. decimal _rate = 1.0000M;
  501. var roomFeeInfo = hotelCostDetails.Where(x => x.PriceType == 1).First();
  502. if (roomFeeInfo == null) return _view;
  503. _rate = roomFeeInfo.Rate == 0.0000M ? 1.0000M : roomFeeInfo.Rate;
  504. bool isAutoAudit = true; //是否自动审核
  505. DateTime checkIn = Convert.ToDateTime(hotelCostInfo.CheckInDate),
  506. checkOut = Convert.ToDateTime(hotelCostInfo.CheckOutDate);
  507. if (checkOut > checkIn) checkOut = checkOut.AddDays(-1); //房费计算,结束日期为前一天
  508. var hotelCostInfos = costContents.Where(x => Convert.ToDateTime(x.Date) >= checkIn && Convert.ToDateTime(x.Date) <= checkOut).ToList();
  509. if (hotelCostInfos.Count < 1) isAutoAudit = false;
  510. decimal otherFee = hotelCostDetails.Where(x => x.PriceType != 1).Sum(x => x.Price * (x.Rate == 0.0000M ? 1.0000M : x.Rate));
  511. if (otherFee > 0) { otherFee /= (checkOut - checkIn).Days; }
  512. var hotelCostInfosGroup = hotelCostInfos.GroupBy(x => x.Date);
  513. foreach (var item in hotelCostInfosGroup)
  514. {
  515. decimal hotelSingleRoomFee = item.Sum(x => x.HotelSingleRoomFee);
  516. decimal hotelDoubleRoomFee = item.Sum(x => x.HotelDoubleRoomFee);
  517. decimal hotelSuiteFee = item.Sum(x => x.HotelSuiteFee);
  518. decimal hotelSuiteRoomFee = item.Sum(x => x.HotelSuiteRoomFee);
  519. //1.判断费用是否 <= 成本费用
  520. //1.1 判断单间费用
  521. decimal singleRoomPrice = (hotelCostInfo.SingleRoomPrice + otherFee) * _rate;
  522. if (singleRoomPrice > 0) if (singleRoomPrice > hotelSingleRoomFee * _rate) isAutoAudit = false;
  523. //1.2 判断双人间费用
  524. decimal doubleRoomPrice = (hotelCostInfo.DoubleRoomPrice + otherFee) * _rate;
  525. if (doubleRoomPrice > 0) if (doubleRoomPrice > hotelDoubleRoomFee * _rate) isAutoAudit = false;
  526. //1.3 判断套房费用
  527. decimal suiteRoomPrice = (hotelCostInfo.SuiteRoomPrice + otherFee) * _rate;
  528. if (suiteRoomPrice > 0) if (suiteRoomPrice > hotelSuiteFee * _rate) isAutoAudit = false;
  529. //1.4 判断其他房型费用
  530. decimal otherRoomPrice = (hotelCostInfo.OtherRoomPrice + otherFee) * _rate;
  531. if (otherRoomPrice > 0) if (otherRoomPrice > hotelSuiteRoomFee * _rate) isAutoAudit = false;
  532. }
  533. //2.判断是否自动审核
  534. if (isAutoAudit)
  535. {
  536. return $"未超预算";
  537. }
  538. }
  539. else if (feeType == 2)
  540. {
  541. //1.基础数据参数验证
  542. var priceType = new List<int>() { 1062 };
  543. var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  544. .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId && !priceType.Contains(x.PriceType))
  545. .First();
  546. //var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  547. // .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId )
  548. // .First();
  549. if (opinfos == null) return _view;
  550. //1.含超时费用/超支费用 手动审核
  551. if (opinfos.SelectCheck.Contains("超时") || opinfos.SelectCheck.Contains("超支") || opinfos.SelectCheck.Contains("尾款")) return _view;
  552. //1.参数验证
  553. var opCheckPriceTyeps = opinfos.SelectCheck.Split(',');
  554. var opCheckPriceTyepIds = setData.Where(x => opinfos.SelectCheck.Split(',').Contains(x.Name)).Select(x => x.Id).ToList();
  555. var opContents = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservationsContent>()
  556. .Where(x => x.IsDel == 0 && x.DiId == diId && x.CTGGRId == dataId && opCheckPriceTyepIds.Contains(x.SId))
  557. .OrderBy(x => x.DatePrice, OrderByType.Asc)
  558. .ToList();
  559. if (opContents.Count < 1) return _view;
  560. //获取C表汇率
  561. decimal _rate = 1.0000M;
  562. var payInfo = _sqlSugar.Queryable<Grp_CreditCardPayment>().Where(x => x.IsDel == 0 && x.DIId == diId && x.CTable == 79 && x.Id == dataId).First();
  563. if (payInfo == null) return _view;
  564. _rate = payInfo.DayRate;
  565. string opCurrencyName = setData.Find(x => x.Id == opContents[0].Currency)?.Name ?? "";
  566. var opBasicDatas = setData.Where(x => x.STid == 17).ToList(); //费用类型基础数据
  567. bool isAutoAudit = true;
  568. if (!DateTime.TryParse(opinfos.ServiceStartTime, out DateTime startDt1) || !DateTime.TryParse(opinfos.ServiceEndTime, out DateTime endDt1)) return _view;
  569. DateTime startDt = startDt1;
  570. DateTime endDt = endDt1;
  571. var opCostDatas = costContents.Where(it => Convert.ToDateTime(it.Date) >= startDt && Convert.ToDateTime(it.Date) <= endDt).ToList();
  572. if (opCostDatas.Count < 1) return _view;
  573. var noAuditFeeTypeIds = new List<int> {
  574. 982 ,//982 车超时费 -- 暂无
  575. 96 ,//96 接送机费 -- 暂无
  576. 97 ,//97 其他费用 -- 暂无
  577. 992 ,//992 住补费用 -- 暂无
  578. 1059,//1059 导游超时费用 -- 暂无
  579. 1070,//1070 尾款金额 -- 暂无
  580. 1071,//1071 其他额外费用 -- 暂无
  581. 1073,//1073 翻译超时费 -- 暂无
  582. 1074,//1074 早餐超支费用 -- 暂无
  583. 1075,//1075 午餐超支费用 -- 暂无
  584. 1076,//1076 晚餐超支费用 -- 暂无
  585. };
  586. //费用类型筛选 包含 feeTypeIds && 包含这些类型费用大于0
  587. var noAuditFeeContents = opContents.Where(x => x.Price > 0 && noAuditFeeTypeIds.Contains(x.SId)).ToList();
  588. if (noAuditFeeContents.Count > 0) return _view;
  589. //2.按天按项 检查费用是否超过预算
  590. var opDayContent = opContents.GroupBy(x => x.DatePrice);
  591. foreach (var item in opDayContent)
  592. {
  593. var opCostInfo = opCostDatas.Where(x => Convert.ToDateTime(x.Date) == item.Key).ToList();
  594. if (opCostInfo.Count < 1) continue;
  595. //车费 91
  596. var opCarCost = item.FirstOrDefault(x => x.SId == 91);
  597. if (opCarCost != null) if (opCarCost.Price * _rate > _rate * opCostInfo.Sum(x => x.CarFee)) isAutoAudit = false;
  598. //982 车超时费 -- 暂无
  599. //92 导游费
  600. var opGuideCost = item.FirstOrDefault(x => x.SId == 92);
  601. if (opGuideCost != null) if (opGuideCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideFee)) isAutoAudit = false;
  602. //94 导游景点费
  603. var opGuideScenicCost = item.FirstOrDefault(x => x.SId == 94);
  604. if (opGuideScenicCost != null) if (opGuideScenicCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideScenicFee)) isAutoAudit = false;
  605. //95 导游小费
  606. var opGuideTipCost = item.FirstOrDefault(x => x.SId == 95);
  607. if (opGuideTipCost != null) if (opGuideTipCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideTipFee)) isAutoAudit = false;
  608. //983 导游餐补
  609. var opGuideMealCost = item.FirstOrDefault(x => x.SId == 983);
  610. if (opGuideMealCost != null) if (opGuideMealCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideMealFee)) isAutoAudit = false;
  611. //984 导游房补
  612. var opGuideRoomCost = item.FirstOrDefault(x => x.SId == 984);
  613. if (opGuideRoomCost != null) if (opGuideRoomCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideRoomFee)) isAutoAudit = false;
  614. //985 导游交通
  615. var opGuideTrafficCost = item.FirstOrDefault(x => x.SId == 985);
  616. if (opGuideTrafficCost != null) if (opGuideTrafficCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideTrafficFee)) isAutoAudit = false;
  617. //96 接送机费 -- 暂无
  618. //97 其他费用 -- 暂无
  619. //979 司机工资
  620. var opDriverCost = item.FirstOrDefault(x => x.SId == 979);
  621. if (opDriverCost != null) if (opDriverCost.Price * _rate > _rate * opCostInfo.Sum(x => x.DriverFee)) isAutoAudit = false;
  622. //980 司机小费
  623. var opDriverTipCost = item.FirstOrDefault(x => x.SId == 980);
  624. if (opDriverTipCost != null) if (opDriverTipCost.Price * _rate > _rate * opCostInfo.Sum(x => x.DriverTipFee)) isAutoAudit = false;
  625. //981 司机餐补
  626. var opDriverMealCost = item.FirstOrDefault(x => x.SId == 981);
  627. if (opDriverMealCost != null) if (opDriverMealCost.Price * _rate > _rate * opCostInfo.Sum(x => x.DriverMealFee)) isAutoAudit = false;
  628. //988 客户早餐费用
  629. var opClientBreakfastCost = item.FirstOrDefault(x => x.SId == 988);
  630. if (opClientBreakfastCost != null) if (opClientBreakfastCost.Price * _rate > _rate * opCostInfo.Sum(x => x.ClientBreakfastFee)) isAutoAudit = false;
  631. //93 客户午餐费用
  632. var opClientLunchCost = item.FirstOrDefault(x => x.SId == 93);
  633. if (opClientLunchCost != null) if (opClientLunchCost.Price * _rate > _rate * opCostInfo.Sum(x => x.ClientLunchFee)) isAutoAudit = false;
  634. //989 客户晚餐费用
  635. var opClientDinnerCost = item.FirstOrDefault(x => x.SId == 989);
  636. if (opClientDinnerCost != null) if (opClientDinnerCost.Price * _rate > _rate * opCostInfo.Sum(x => x.ClientDinnerFee)) isAutoAudit = false;
  637. //990 景点门票费
  638. var opScenicTicketCost = item.FirstOrDefault(x => x.SId == 990);
  639. if (opScenicTicketCost != null) if (opScenicTicketCost.Price * _rate > _rate * opCostInfo.Sum(x => x.ScenicTicketFee)) isAutoAudit = false;
  640. //991 饮料/零食/水果
  641. var opDrinkSnackFruitCost = item.FirstOrDefault(x => x.SId == 991);
  642. if (opDrinkSnackFruitCost != null) if (opDrinkSnackFruitCost.Price * _rate > _rate * opCostInfo.Sum(x => x.DrinkSnackFruitFee)) isAutoAudit = false;
  643. //992 住补费用 -- 暂无
  644. //994 翻译费
  645. var opTranslatorCost = item.FirstOrDefault(x => x.SId == 994);
  646. if (opTranslatorCost != null) if (opTranslatorCost.Price * _rate > _rate * opCostInfo.Sum(x => x.TranslatorFee)) isAutoAudit = false;
  647. //1059 导游超时费用 -- 暂无
  648. //1070 尾款金额 -- 暂无
  649. //1071 其他额外费用 -- 暂无
  650. //1073 翻译超时费 -- 暂无
  651. //1074 早餐超支费用 -- 暂无
  652. //1075 午餐超支费用 -- 暂无
  653. //1076 晚餐超支费用 -- 暂无
  654. }
  655. //更改审核状态
  656. if (isAutoAudit) return _view;
  657. }
  658. else return _view;
  659. return _view;
  660. }
  661. }
  662. }