Browse Source

酒店自动审核、费用审核、卡类型、酒店提示显示修改

LEIYI 8 months ago
parent
commit
437340695e

+ 63 - 14
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -40,6 +40,7 @@ namespace OASystem.API.Controllers
     [Route("api/[controller]/[action]")]
     [Route("api/[controller]/[action]")]
     public class GroupsController : ControllerBase
     public class GroupsController : ControllerBase
     {
     {
+        private readonly ILogger<GroupsController> _logger;
         private readonly GrpScheduleRepository _grpScheduleRep;
         private readonly GrpScheduleRepository _grpScheduleRep;
         private readonly IMapper _mapper;
         private readonly IMapper _mapper;
         private readonly DelegationInfoRepository _groupRepository;
         private readonly DelegationInfoRepository _groupRepository;
@@ -81,7 +82,7 @@ namespace OASystem.API.Controllers
         private readonly HotelInquiryRepository _hotelInquiryRep;
         private readonly HotelInquiryRepository _hotelInquiryRep;
         private readonly FeeAuditRepository _feeAuditRep;
         private readonly FeeAuditRepository _feeAuditRep;
 
 
-        public GroupsController(IMapper mapper, SqlSugarClient sqlSugar, GrpScheduleRepository grpScheduleRep, DelegationInfoRepository groupRepository,
+        public GroupsController(ILogger<GroupsController> logger, IMapper mapper, SqlSugarClient sqlSugar, GrpScheduleRepository grpScheduleRep, DelegationInfoRepository groupRepository,
             TaskAssignmentRepository taskAssignmentRep, AirTicketResRepository airTicketResRep, DecreasePaymentsRepository decreasePaymentsRep,
             TaskAssignmentRepository taskAssignmentRep, AirTicketResRepository airTicketResRep, DecreasePaymentsRepository decreasePaymentsRep,
             InvitationOfficialActivitiesRepository InvitationOfficialActivitiesRep, DelegationEnDataRepository delegationEnDataRep, EnterExitCostRepository enterExitCostRep
             InvitationOfficialActivitiesRepository InvitationOfficialActivitiesRep, DelegationEnDataRepository delegationEnDataRep, EnterExitCostRepository enterExitCostRep
             , DelegationVisaRepository delegationVisaRep, MessageRepository message, VisaPriceRepository visaPriceRep, CarTouristGuideGroundRepository carTouristGuideGroundRep,
             , DelegationVisaRepository delegationVisaRep, MessageRepository message, VisaPriceRepository visaPriceRep, CarTouristGuideGroundRepository carTouristGuideGroundRep,
@@ -91,6 +92,7 @@ namespace OASystem.API.Controllers
             InvertedListRepository invertedListRep, VisaFeeInfoRepository visaFeeInfoRep, TicketBlackCodeRepository ticketBlackCodeRep, HotelInquiryRepository hotelInquiryRep,
             InvertedListRepository invertedListRep, VisaFeeInfoRepository visaFeeInfoRep, TicketBlackCodeRepository ticketBlackCodeRep, HotelInquiryRepository hotelInquiryRep,
             ThreeCodeRepository threeCodeRepository, FeeAuditRepository feeAuditRep)
             ThreeCodeRepository threeCodeRepository, FeeAuditRepository feeAuditRep)
         {
         {
+            _logger = logger;
             _mapper = mapper;
             _mapper = mapper;
             _grpScheduleRep = grpScheduleRep;
             _grpScheduleRep = grpScheduleRep;
             _groupRepository = groupRepository;
             _groupRepository = groupRepository;
@@ -1448,7 +1450,8 @@ namespace OASystem.API.Controllers
                     _detail.PriceName = priceModule;
                     _detail.PriceName = priceModule;
 
 
                     _detail.PayType = initDatas.Find(it => it.Id == entity.PayDId)?.Name ?? "-";
                     _detail.PayType = initDatas.Find(it => it.Id == entity.PayDId)?.Name ?? "-";
-                    _detail.CardType = initDatas.Find(it => it.Id == entity.CTDId)?.Name ?? "-";
+                    if (_detail.PayType.Equals("现金")) _detail.CardType = "-";
+                    else _detail.CardType = initDatas.Find(it => it.Id == entity.CTDId)?.Name ?? "-";
 
 
 
 
                     /*
                     /*
@@ -1527,16 +1530,29 @@ namespace OASystem.API.Controllers
                                 //是否比较房型价格
                                 //是否比较房型价格
                                 bool __isSingle = false, __isDouble = false, __isSuite = false, __isOther = false;
                                 bool __isSingle = false, __isDouble = false, __isSuite = false, __isOther = false;
 
 
-                                roomFeeStr += $"<br/><span style='width:70px;display: inline-block;'></span>";
+                                //roomFeeStr += $"<br/><span style='width:70px;display: inline-block;'></span>";
+                                roomFeeStr += $"<br/>";
 
 
                                 if (hotelReservations.SingleRoomPrice > 0)
                                 if (hotelReservations.SingleRoomPrice > 0)
-                                { roomFeestr1 += $"单间:{hotelReservations.SingleRoomPrice.ToString("#0.00")} * {hotelReservations.SingleRoomCount}"; __isSingle = true; }
+                                {
+                                    roomFeestr1 += $"<span style='width:70px;display: inline-block;'></span>单间:{hotelReservations.SingleRoomPrice.ToString("#0.00")} * {hotelReservations.SingleRoomCount}<br/>";
+                                    __isSingle = true;
+                                }
                                 if (hotelReservations.DoubleRoomPrice > 0)
                                 if (hotelReservations.DoubleRoomPrice > 0)
-                                { roomFeestr1 += $"双人间:{hotelReservations.DoubleRoomPrice.ToString("#0.00")} * {hotelReservations.DoubleRoomCount}"; __isDouble = true; }
+                                {
+                                    roomFeestr1 += $"<span style='width:70px;display: inline-block;'></span>双人间:{hotelReservations.DoubleRoomPrice.ToString("#0.00")} * {hotelReservations.DoubleRoomCount}<br/>";
+                                    __isDouble = true;
+                                }
                                 if (hotelReservations.SuiteRoomPrice > 0)
                                 if (hotelReservations.SuiteRoomPrice > 0)
-                                { roomFeestr1 += $"套房:{hotelReservations.SuiteRoomPrice.ToString("#0.00")} * {hotelReservations.SuiteRoomCount}"; __isSuite = true; }
+                                {
+                                    roomFeestr1 += $"<span style='width:70px;display: inline-block;'></span>套房:{hotelReservations.SuiteRoomPrice.ToString("#0.00")} * {hotelReservations.SuiteRoomCount}<br/>";
+                                    __isSuite = true;
+                                }
                                 if (hotelReservations.OtherRoomPrice > 0)
                                 if (hotelReservations.OtherRoomPrice > 0)
-                                { roomFeestr1 += $"其他:{hotelReservations.OtherRoomPrice.ToString("#0.00")} * {hotelReservations.OtherRoomCount}"; __isOther = true; }
+                                {
+                                    roomFeestr1 += $"<span style='width:70px;display: inline-block;'></span>其他:{hotelReservations.OtherRoomPrice.ToString("#0.00")} * {hotelReservations.OtherRoomCount}";
+                                    __isOther = true;
+                                }
 
 
                                 if (roomFeestr1.Length > 0) roomFeeStr += roomFeestr1;
                                 if (roomFeestr1.Length > 0) roomFeeStr += roomFeestr1;
                                 else roomFeeStr += "  0.00 * 0";
                                 else roomFeeStr += "  0.00 * 0";
@@ -1602,7 +1618,9 @@ namespace OASystem.API.Controllers
                                 if (roomData != null)
                                 if (roomData != null)
                                 {
                                 {
                                     _detail.PayType = initDatas.Find(it => it.Id == roomData.PayDId)?.Name ?? "-";
                                     _detail.PayType = initDatas.Find(it => it.Id == roomData.PayDId)?.Name ?? "-";
-                                    _detail.CardType = initDatas.Find(it => it.Id == roomData.CTDId)?.Name ?? "-";
+
+                                    if (_detail.PayType.Equals("现金")) _detail.CardType = "-";
+                                    else _detail.CardType = initDatas.Find(it => it.Id == roomData.CTDId)?.Name ?? "-";
 
 
                                     roomBool = roomData.IsOppay == 1 ? "是" : "否";
                                     roomBool = roomData.IsOppay == 1 ? "是" : "否";
                                     roomFee = roomData.Price;
                                     roomFee = roomData.Price;
@@ -1636,13 +1654,13 @@ namespace OASystem.API.Controllers
                                     hotelCsotTotal += item.Sum(x => x.HotelSingleRoomFee) + item.Sum(x => x.HotelDoubleRoomFee) + item.Sum(x => x.HotelSuiteRoomFee) + item.Sum(x => x.HotelSuiteFee);
                                     hotelCsotTotal += item.Sum(x => x.HotelSingleRoomFee) + item.Sum(x => x.HotelDoubleRoomFee) + item.Sum(x => x.HotelSuiteRoomFee) + item.Sum(x => x.HotelSuiteFee);
                                     hotelCost_day += @$"{item.First()?.Date ?? "-"}";
                                     hotelCost_day += @$"{item.First()?.Date ?? "-"}";
                                     if (item.Sum(x => x.HotelSingleRoomFee) != 0) hotelCost_day += @$"   单间:{item.Sum(x => x.HotelSingleRoomFee).ToString("#0.00")}";
                                     if (item.Sum(x => x.HotelSingleRoomFee) != 0) hotelCost_day += @$"   单间:{item.Sum(x => x.HotelSingleRoomFee).ToString("#0.00")}";
-                                    else { if (__isSingle) hotelCost_day += @$"   单间:0.00"; }
+                                    //else { if (__isSingle) hotelCost_day += @$"   单间:0.00"; }
                                     if (item.Sum(x => x.HotelDoubleRoomFee) != 0) hotelCost_day += @$"   双人间:{item.Sum(x => x.HotelDoubleRoomFee).ToString("#0.00")}";
                                     if (item.Sum(x => x.HotelDoubleRoomFee) != 0) hotelCost_day += @$"   双人间:{item.Sum(x => x.HotelDoubleRoomFee).ToString("#0.00")}";
-                                    else { if (__isDouble) hotelCost_day += @$"   双人间:0.00"; }
+                                    //else { if (__isDouble) hotelCost_day += @$"   双人间:0.00"; }
                                     if (item.Sum(x => x.HotelSuiteRoomFee) != 0) hotelCost_day += @$"   小套房/豪华套房:{item.Sum(x => x.HotelSuiteRoomFee).ToString("#0.00")}";
                                     if (item.Sum(x => x.HotelSuiteRoomFee) != 0) hotelCost_day += @$"   小套房/豪华套房:{item.Sum(x => x.HotelSuiteRoomFee).ToString("#0.00")}";
-                                    else { if (__isSuite) hotelCost_day += @$"   小套房/豪华套房:0.00"; }
+                                    //else { if (__isSuite) hotelCost_day += @$"   小套房/豪华套房:0.00"; }
                                     if (item.Sum(x => x.HotelSuiteFee) != 0) hotelCost_day += @$"   套房:{item.Sum(x => x.HotelSuiteFee).ToString("#0.00")}";
                                     if (item.Sum(x => x.HotelSuiteFee) != 0) hotelCost_day += @$"   套房:{item.Sum(x => x.HotelSuiteFee).ToString("#0.00")}";
-                                    else { if (__isOther) hotelCost_day += @$"   套房:0.00"; }
+                                    //else { if (__isOther) hotelCost_day += @$"   套房:0.00"; }
                                     hotelCost_day += @$"</br>";
                                     hotelCost_day += @$"</br>";
                                 }
                                 }
 
 
@@ -1656,7 +1674,7 @@ namespace OASystem.API.Controllers
                                                           $"<span style='font-weight:800;'>{hotelReservations.HotelName} [{hotelReservations.CheckInDate} - {hotelReservations.CheckOutDate}]</span><br/>" +
                                                           $"<span style='font-weight:800;'>{hotelReservations.HotelName} [{hotelReservations.CheckInDate} - {hotelReservations.CheckOutDate}]</span><br/>" +
                                                           $"信用卡金额:{_detail.WaitPay} ({hotelCurrncyName})<br/>" +
                                                           $"信用卡金额:{_detail.WaitPay} ({hotelCurrncyName})<br/>" +
                                                           $"房间说明: {hotelReservations.Remark} <br/>" +
                                                           $"房间说明: {hotelReservations.Remark} <br/>" +
-                                                          $"房间费用: {roomCode} {roomName} 当时汇率 {roomData?.Rate.ToString("#0.0000")}{roomFeeStr}  <br/>是否由地接代付:{roomBool}<br/><br/>" +
+                                                          $"房间费用: {roomCode} {roomName} 当时汇率 {roomData?.Rate.ToString("#0.0000")}{roomFeeStr}  是否由地接代付:{roomBool}<br/><br/>" +
                                                           $"{hotelBreakfastStr}" +
                                                           $"{hotelBreakfastStr}" +
                                                           $"{hotelGovernmentRentStr}" +
                                                           $"{hotelGovernmentRentStr}" +
                                                           $"{hotelCityTaxStr}";
                                                           $"{hotelCityTaxStr}";
@@ -10040,8 +10058,9 @@ ORDER by  gctggrc.id DESC
                 await AppNoticeLibrary.SendChatMsg_GroupStatus_ApplyFee(ccpId, sign, QiyeWeChatEnum.GuoJiaoLeaderChat);
                 await AppNoticeLibrary.SendChatMsg_GroupStatus_ApplyFee(ccpId, sign, QiyeWeChatEnum.GuoJiaoLeaderChat);
 
 
                 //自动审核
                 //自动审核
-                await _feeAuditRep.FeeAutomaticAudit(1, _dto.DiId, hotelId);
+                var autoAdit = await _feeAuditRep.FeeAutomaticAudit(1, _dto.DiId, hotelId);
 
 
+                _logger.LogInformation($"【酒店自动审核】【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】执行调用   调用结果:{JsonConvert.SerializeObject(autoAdit)}");
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
@@ -10051,6 +10070,36 @@ ORDER by  gctggrc.id DESC
             return Ok(_view);
             return Ok(_view);
         }
         }
 
 
+        /// <summary>
+        /// 酒店自动审核测试
+        /// Add Or Edit 
+        /// </summary>
+        /// <param name="_dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> PostHotelAutoAuditTest(int diid,int dataId)
+        {
+            
+
+            #region 应用推送
+
+            try
+            {
+                //自动审核
+                await _feeAuditRep.FeeAutomaticAudit(1, diid, dataId);
+
+            }
+            catch (Exception ex)
+            {
+
+                return Ok(JsonView(false, "操作失败"));
+            }
+            #endregion
+
+            return Ok(JsonView(false,"操作成功"));
+        }
+
         /// <summary>
         /// <summary>
         /// 酒店预订
         /// 酒店预订
         /// Del 
         /// Del 

+ 205 - 0
OASystem/OASystem.Api/Controllers/StatisticsController.cs

@@ -1,4 +1,5 @@
 using Aspose.Cells;
 using Aspose.Cells;
+using NPOI.OpenXmlFormats.Dml.Diagram;
 using OASystem.API.OAMethodLib;
 using OASystem.API.OAMethodLib;
 using OASystem.Domain.Dtos.Statistics;
 using OASystem.Domain.Dtos.Statistics;
 using OASystem.Domain.Entities.Customer;
 using OASystem.Domain.Entities.Customer;
@@ -7,6 +8,8 @@ using OASystem.Domain.ViewModels.Financial;
 using OASystem.Domain.ViewModels.Statistics;
 using OASystem.Domain.ViewModels.Statistics;
 using OASystem.Infrastructure.Repositories.Groups;
 using OASystem.Infrastructure.Repositories.Groups;
 using System.Data;
 using System.Data;
+using System.Linq;
+using System.Security.Cryptography.Xml;
 using static OASystem.API.OAMethodLib.GeneralMethod;
 using static OASystem.API.OAMethodLib.GeneralMethod;
 using TypeInfo = OASystem.Domain.ViewModels.Statistics.TypeInfo;
 using TypeInfo = OASystem.Domain.ViewModels.Statistics.TypeInfo;
 
 
@@ -4078,6 +4081,208 @@ WHERE
                 remark = groupPeopleNumStr
                 remark = groupPeopleNumStr
             }));
             }));
         }
         }
+
+        /// <summary>
+        ///  团组数据统计
+        ///  OP 成本   
+        /// </summary>
+        /// <param name="_dto"></param>
+        /// <returns></returns>
+        [HttpPost("StatisticsOP")]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> StatisticsOP(StatisticsOPDto _dto)
+        {
+            if (_dto.Year < 1) return Ok(JsonView(false, "Year参数错误!"));
+            if (_dto.Type < 1 || _dto.Type > 2) return Ok(JsonView(false, "Type参数错误!"));
+
+
+            int thisYear = _dto.Year, lastYear = _dto.Year - 1;
+            string beginDt = $"{lastYear}-01-01 00:00:00",
+                   endDt = $"{thisYear}-12-31 23:59:59";
+           
+
+
+            string sql = string.Format(@"
+SELECT
+  temp.Id,
+  DiId,
+  PaymentTime,
+  [Year],
+  [Quarter],
+  [Month],
+  Area,
+  FeeType,
+  sd1.Name AS FeeTypeName,
+  FeeSubType,
+  sd2.Name AS FeeSubTypeName,
+  CONVERT(DECIMAL(12, 2), Price * Qauntity * ExchangeRate) AS Price
+FROM
+  (
+    SELECT
+      ctggr.Id,
+      ctggr.DiId,
+      ctggr.Area,
+      CASE
+        WHEN ctggr.PriceType IS NULL THEN 1069
+        ELSE ctggr.PriceType
+      END AS FeeType,
+      ctggrc.SId AS FeeSubType,
+      ctggrc.Price,
+      CASE
+        WHEN ctggrc.Count IS NULL THEN 1
+        ELSE ctggrc.Count
+      END AS Qauntity,
+      ccp.DayRate AS ExchangeRate,
+      ctggrc.CreateTime AS PaymentTime,
+      YEAR(ctggrc.CreateTime) AS [Year],
+      CONVERT(INT,DATENAME(QUARTER, ctggrc.CreateTime)) AS [Quarter],
+      MONTH(ctggrc.CreateTime) AS [Month]
+    FROM
+      Grp_CarTouristGuideGroundReservations ctggr
+      INNER JOIN Grp_CarTouristGuideGroundReservationsContent ctggrc ON ctggr.Id = ctggrc.CTGGRId
+      AND ctggrc.IsDel = 0
+      INNER JOIN Grp_CreditCardPayment ccp ON ctggr.Id = ccp.CId
+      AND ccp.CTable = 79
+      AND ccp.IsDel = 0
+    WHERE
+      ctggr.IsDel = 0
+      AND ctggrc.SId != 1070 --费用子项筛掉尾款
+      AND ctggrc.Price > 0 --筛选真实存在的数据
+      AND ccp.IsPay = 1
+  ) temp
+  LEFT JOIN Sys_SetData sd1 ON FeeType = sd1.Id
+  LEFT JOIN Sys_SetData sd2 ON FeeSubType = sd2.Id
+WHERE
+  temp.Area NOT LIKE '%尾款%'  -- 筛选掉尾款相关信息
+  AND temp.FeeType != 1062 --费用类型筛选掉全款和首付款数据
+  AND temp.PaymentTime BETWEEN CONVERT(datetime,'{0}') AND CONVERT(datetime,'{1}')
+ORDER BY
+  temp.[Year],
+  temp.[Quarter],
+  temp.[Month]
+", beginDt,endDt);
+
+            var opInfos = await _sqlSugar.SqlQueryable<StatisticsOP>(sql).ToListAsync();
+
+            //处理地区相关信息
+            var countrys = await _sqlSugar.Queryable<Grp_NationalTravelFee>().Where(x => x.IsDel == 0).ToListAsync();
+
+            for (int i = 0; i < opInfos.Count; i++)
+            {
+                string country = string.Empty,city =string.Empty;
+
+                int dataId = 0;
+                bool isCountryId = int.TryParse(opInfos[i].Area, out dataId);
+                string[] citySelecter = new string[] {"其他城市","所有城市" };
+                if (isCountryId)
+                {
+                    var countryInfo = countrys.Find(x => x.Id == dataId);
+                    country = countryInfo?.Country ?? "";
+                    if (citySelecter.Contains(countryInfo?.City)) city = country;
+                    else city = countryInfo?.City ?? "";
+
+                }
+                else
+                {
+                    var countryInfo1 = countrys.Find(x => opInfos[i].Area.Contains(x.Country));
+                    if (countryInfo1 != null)
+                    {
+                        country = countryInfo1?.Country ?? "";
+                        city = countryInfo1?.City ?? country;
+                        var countryInfo2 = countrys.Find(x => opInfos[i].Area.Contains(x.City));
+
+                        if (citySelecter.Contains(countryInfo2?.City)) city = country;
+                        else city = countryInfo2?.City ?? country;
+
+                    }
+                    else
+                    {
+                        var countryInfo2 = countrys.Find(x => opInfos[i].Area.Contains(x.City));
+
+                        if (countryInfo2 != null)
+                        {
+                            country = countryInfo2?.Country ?? "";
+                            city = countryInfo2?.City ?? "";
+
+                            if (citySelecter.Contains(countryInfo2?.City)) city = country;
+
+                        }
+                    }
+                }
+                opInfos[i].Country = country;
+                opInfos[i].City = city;
+            }
+
+            if (_dto.Type == 1)
+            {
+                //同比增长率=(本期数-同期数)/ 同期数
+                var yearData = opInfos.GroupBy(x => x.ParentFeeName)
+                                      .Select(x => new StatisticsOPYOY(
+                                                   feeId: x.FirstOrDefault()?.ParentFeeId ?? 0,
+                                                   feeName: x.Key,
+                                                   currPeriodFee: x.Where(x => x.Year == thisYear).Sum(x => x.Price),
+                                                   samePeriodFee: x.Where(x => x.Year == lastYear).Sum(x => x.Price),
+                                                   currPeriodGroupTotal: x.Where(x => x.Year == thisYear).Select(x => x.DiId).Distinct().Count(),
+                                                   samePeriodGroupTotal: x.Where(x => x.Year == lastYear).Select(x => x.DiId).Distinct().Count(),
+                                                   subFeeData: x.GroupBy(x1 => x1.FeeSubType)
+                                                                .Select(x1 => new StatisticsOPSubFeeYOY(
+                                                                              feeId: x1.Key,
+                                                                              feeName: x1.FirstOrDefault()?.FeeSubTypeName ?? "",
+                                                                              currPeriodFee: x1.Where(x1 => x1.Year == thisYear).Sum(x1 => x1.Price),
+                                                                              samePeriodFee: x1.Where(x1 => x1.Year == lastYear).Sum(x1 => x1.Price),
+                                                                              currPeriodGroupTotal: x1.Where(x1 => x1.Year == thisYear).Select(x1 => x1.DiId).Distinct().Count(),
+                                                                              samePeriodGroupTotal: x1.Where(x1 => x1.Year == lastYear).Select(x1 => x1.DiId).Distinct().Count(),
+                                                                              cityData: x1.GroupBy(x2 => x2.City)
+                                                                                          .Select(x2 => new StatisticsOPCityYOY(
+                                                                                                        cityName: x2.Key,
+                                                                                                        currPeriodGroupTotal: x2.Where(x2 => x2.Year == thisYear).Select(x2 => x2.DiId).Distinct().Count(),
+                                                                                                        samePeriodGroupTotal: x2.Where(x2 => x2.Year == lastYear).Select(x2 => x2.DiId).Distinct().Count(),
+                                                                                                        currPeriodFee: x2.Where(x2 => x2.Year == thisYear).Sum(x2 => x2.Price),
+                                                                                                        samePeriodFee: x2.Where(x2 => x2.Year == lastYear).Sum(x2 => x2.Price)
+                                                                                              ))
+                                                                                          .ToArray()
+                                                                    ))        
+                                                                .ToArray()
+                                             ))
+                                      .OrderBy(x => x.FeeId)
+                                      .ToList();
+                return Ok(JsonView(true, "操作成功!", yearData));
+            }
+            else if (_dto.Type == 2)
+            {
+                var monthData = new List<dynamic>();
+
+                //var data1 = opInfos.GroupBy(x => x.Month)
+                //                   .Select(x => new
+                //                   {
+                //                       monthId = x.Key,
+                //                       month = Enum.IsDefined(typeof(MonthEnum), (int)x.Key) ? ((MonthEnum)(int)x.Key).GetEnumDescription() : "",
+                //                       monthData = x.GroupBy(x1 => x1.ParentFeeId)
+                //                                    .Select(x1 => new StatisticsOPYOY(
+                //                                            feeId: x1.Key,
+                //                                            feeName: x1.FirstOrDefault(x1 => x1.Year == thisYear)?.ParentFeeName ?? "",
+                //                                            currPeriodFee: x1.Where(x1 => x1.Year == thisYear).Sum(x1 => x1.Price),
+                //                                            samePeriodFee: x1.Where(x1 => x1.Year == lastYear).Sum(x1 => x1.Price),
+                //                                            currPeriodGroupTotal: x1.Where(x1 => x1.Year == thisYear).Select(x1 => x1.DiId).Distinct().Count(),
+                //                                            samePeriodGroupTotal: x1.Where(x1 => x1.Year == lastYear).Select(x1 => x1.DiId).Distinct().Count()
+                //                                            //cityData: x1.GroupBy(x2 => x2.City)
+                //                                            //            .Select(x2 => new StatisticsOPCityYOY(
+                //                                            //                    cityName: x2.Key,
+                //                                            //                    currPeriodGroupTotal: x2.Where(x2 => x2.Year == thisYear).Select(x2 => x2.DiId).Distinct().Count(),
+                //                                            //                    samePeriodGroupTotal: x2.Where(x2 => x2.Year == lastYear).Select(x2 => x2.DiId).Distinct().Count(),
+                //                                            //                    currPeriodFee: x2.Where(x2 => x2.Year == thisYear).Sum(x2 => x2.Price),
+                //                                            //                    samePeriodFee: x2.Where(x2 => x2.Year == lastYear).Sum(x2 => x2.Price)
+                //                                            //                    )
+                //                                            //            ).ToArray()
+                //                                            )
+                //                                    )
+                //                                    .OrderBy(x1 => x1.FeeId)
+                //                                    .ToList()
+                //                   }).ToList();
+                //return Ok(JsonView(true, "操作成功!", data1));
+            }
+            return Ok(JsonView(false, "操作失败!"));
+        }
         #endregion
         #endregion
     }
     }
 }
 }

+ 11 - 0
OASystem/OASystem.Domain/Dtos/Statistics/MarketingSalesDto.cs

@@ -204,4 +204,15 @@ namespace OASystem.Domain.Dtos.Statistics
 
 
     #endregion
     #endregion
 
 
+
+    public class StatisticsOPDto
+    {
+        public int Year { get; set; }
+        /// <summary>
+        /// 1 年、2 月
+        /// </summary>
+        public int Type { get; set; }
+    }
+
+
 }
 }

+ 0 - 1
OASystem/OASystem.Domain/Entities/Groups/Grp_CarTouristGuideGroundReservations.cs

@@ -64,7 +64,6 @@ namespace OASystem.Domain.Entities.Groups
         /// <summary>
         /// <summary>
         /// 服务时间起
         /// 服务时间起
         /// </summary>
         /// </summary>
-        /// 
         [SugarColumn(IsNullable = true, ColumnDataType = "varchar(80)")]
         [SugarColumn(IsNullable = true, ColumnDataType = "varchar(80)")]
         public string ServiceStartTime { get; set; }
         public string ServiceStartTime { get; set; }
         /// <summary>
         /// <summary>

+ 86 - 0
OASystem/OASystem.Domain/Enums/MonthEnum.cs

@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.Enums
+{
+    /// <summary>
+    /// 月份枚举
+    /// </summary>
+    public enum MonthEnum
+    {
+        /// <summary>
+        /// 一月
+        /// </summary>
+        [Description("一月")]
+        Jan = 1,
+        /// <summary>
+        /// 二月
+        /// </summary>
+        [Description("二月")]
+        Feb,
+        /// <summary>
+        /// 三月
+        /// </summary>
+        [Description("三月")]
+        Mar,
+        /// <summary>
+        /// 四月
+        /// </summary>
+        [Description("四月")]
+        Apr,
+        /// <summary>
+        /// 五月
+        /// </summary>
+        [Description("五月")]
+        May,
+        /// <summary>
+        /// 六月
+        /// </summary>
+        [Description("六月")]
+        Jun,
+        /// <summary>
+        /// 七月
+        /// </summary>
+        [Description("七月")]
+        Jul,
+        /// <summary>
+        /// 八月
+        /// </summary>
+        [Description("八月")]
+        Aug,
+        /// <summary>
+        /// 九月
+        /// </summary>
+        [Description("九月")]
+        Sep,
+        /// <summary>
+        /// 十月
+        /// </summary>
+        [Description("十月")]
+        Oct,
+        /// <summary>
+        /// 十一月
+        /// </summary>
+        [Description("十一月")]
+        Nov,
+        /// <summary>
+        /// 十二月
+        /// </summary>
+        [Description("十二月")]
+        Dec,
+    }
+    
+    static class EnumExtensions
+    {
+        public static string GetDescription(this Enum val)
+        {
+            var field = val.GetType().GetField(val.ToString());
+            var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
+            return customAttribute == null ? val.ToString() : ((DescriptionAttribute)customAttribute).Description;
+        }
+    }
+}

+ 343 - 2
OASystem/OASystem.Domain/ViewModels/Financial/Fin_DailyFeePaymentView.cs

@@ -8,6 +8,7 @@ using System.Globalization;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using System.Xml.Linq;
 
 
 namespace OASystem.Domain.ViewModels.Financial
 namespace OASystem.Domain.ViewModels.Financial
 {
 {
@@ -926,10 +927,10 @@ namespace OASystem.Domain.ViewModels.Financial
     public class StatisticsInvitation
     public class StatisticsInvitation
     {
     {
         public int DIId { get; set; }
         public int DIId { get; set; }
-        public string Country { get; set; }    }
+        public string Country { get; set; }
+    }
     #endregion
     #endregion
 
 
-
     #region 团组相关
     #region 团组相关
 
 
     public class StatisticsGroupInfoEntity
     public class StatisticsGroupInfoEntity
@@ -970,6 +971,346 @@ namespace OASystem.Domain.ViewModels.Financial
         public int VisitPNumber { get; set; }
         public int VisitPNumber { get; set; }
     }
     }
 
 
+    #endregion
+
+    #region OP
+    public class StatisticsOP
+    {
+        /*
+         * OP统计图(实际成本同比年/月)
+         *分块:如车费/导游费/导游交通/接送机费/司机工资/翻译费 	
+         *用于判断实际成本是否有增长【真实使用的时候估计是2025年和2024年对比,2023年的数据格式和数据量有问题】
+         * 
+         * 车费:91	车费  982 车超时费
+         * 导游费:92 导游费  985 导游交通  1059 导游超时费用
+         * 司机费:979 司机工资    
+         * 小费:980 司机小费 95 导游小费
+         * 接送机费:96 接送机费  
+         * 餐费:93	客户午餐费用  981 司机餐补  983	导游餐补  988 客户早餐费用  989	客户晚餐费用  
+         *       1074 早餐超支费用  1075 午餐超支费用  1076 晚餐超支费用
+         * 住补费:992 住补费用  984 导游房补
+         * 景点费:94 导游景点费  990	景点门票费  1085 景点门票超支费用
+         * 翻译费:994 翻译费  1073	翻译超时费
+         * 饮料/零食/水果费:991 饮料/零食/水果
+         * 其他费:97 其他费用  1071 其他额外费用
+         */
+        //车费
+        private static int[] _carFeeIds = new int[] {
+                                            91,   //车费
+                                            982,  //车超时费
+                                        };
+        //导游费
+        private static int[] _guideFeeIds = new int[] {
+                                                92,   //导游费
+                                                985,  //导游交通
+                                                1059, //导游超时费用
+                                            };
+        //司机费
+        private static int[] _driverFeeIds = new int[]{
+                                                979,  //司机工资
+                                            };
+        //小费
+        private static int[] _tipsFeeIds = new int[] {
+                                               980,  //司机小费
+                                               95,   //导游小费
+                                            };
+        //接送机费
+        private static int[] _airportTransferFeeIds = new int[] {
+                                                         96,  //接送机费
+                                                      };
+        //餐费
+        private static int[] _mealFeeIds = new[] {
+                                          93,  //客户午餐费用
+                                          981, //司机餐补
+                                          983, //导游餐补
+                                          988, //客户早餐费用
+                                          989, //客户晚餐费用
+                                          1074,//早餐超支费用
+                                          1075,//午餐超支费用
+                                          1076,//晚餐超支费用
+                                       };
+        //住补费
+        private static int[] _sububoFeeIds = new[] {
+                                         992,  //住补费用  
+                                         984,  //导游房补
+                                       };
+        //景点费
+        private static int[] _scenicSpotFeeIds = new[] {
+                                        94,  //导游景点费  
+                                        990, //景点门票费  
+                                        1085,//景点门票超支费用
+                                       };
+        //翻译费
+        private static int[] _translationFeeIds = new[] {
+                                                994,  //翻译费  
+                                                1073, //翻译超时费
+                                               };
+        //饮料/零食/水果费
+        private static int[] _DSFFeeIds = new int[] {
+                                             991,  //饮料/零食/水果
+                                         };
+        //其他费
+        private static int[] _otherFeeIds = new int[] {
+                                                97,  //其他费用  
+                                                1071,//其他额外费用
+                                            };
+
+
+        public int Id { get; set; }
+        public int DiId { get; set; }
+        public DateTime PaymentTime { get; set; }
+        public int Year { get; set; }
+        public int Quarter { get; set; }
+        public int Month { get; set; }
+        public string Area { get; set; }
+        public string Country { get; set; }
+        public string City { get; set; }
+        public int ParentFeeId {
+            get
+            {
+                return int.TryParse(GetFeeParentInfo(FeeSubType, 1), out int id) ? id : 0;
+            }
+        }
+        public string ParentFeeName
+        {
+            get
+            {
+                return GetFeeParentInfo(FeeSubType, 2);
+            }
+        }
+
+        public string ParentFeeRemark { get; set; }
+        public int FeeType { get; set; }
+        public string FeeTypeName { get; set; }
+        public int FeeSubType { get; set; }
+        public string FeeSubTypeName { get; set; }
+
+        public decimal Price { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="subFee"></param>
+        /// <param name="type">1 id 2 name 3 备注 </param>
+        /// <returns></returns>
+        private static string GetFeeParentInfo(int subFee,int type)
+        {
+           int id = -1;
+           string name =string.Empty;
+           string remark = string.Empty;
+            // 车费:91 车费  982 车超时费
+            if (_carFeeIds.Contains(subFee))
+            {
+                id = 1;
+                name = "车费";
+                remark = "费用组成:车费、车超时费";
+            }
+            // 导游费:92 导游费  985 导游交通  1059 导游超时费用
+            if (_guideFeeIds.Contains(subFee))
+            {
+                id = 2;
+                remark = "费用组成:导游费、导游交通、导游超时费用";
+                name = "导游费";
+            }
+            // 司机费:979 司机工资
+            if (_driverFeeIds.Contains(subFee))
+            {
+                id = 3;
+                remark = "费用组成:司机工资";
+                name = "司机费";
+            }
+            // 小费:980 司机小费 95 导游小费
+            if (_tipsFeeIds.Contains(subFee))
+            {
+                id = 4;
+                remark = "费用组成:司机小费、导游小费";
+                name = "小费";
+            }
+            // 接送机费:96 接送机费
+            if (_airportTransferFeeIds.Contains(subFee))
+            {
+                id = 5;
+                remark = "费用组成:接送机费";
+                name = "接送机费";
+            }
+            // 餐费:93 客户午餐费用  981 司机餐补  983   导游餐补  988 客户早餐费用  989   客户晚餐费用
+            // 1074 早餐超支费用  1075 午餐超支费用  1076 晚餐超支费用
+            if (_mealFeeIds.Contains(subFee))
+            {
+                id = 6;
+                remark = "费用组成:客户早餐费用、客户午餐费用、客户晚餐费用、司机餐补、导游餐补、早餐超支费用、午餐超支费用、晚餐超支费用";
+                name = "餐费";
+            }
+            // 住补费:992 住补费用  984 导游房补
+            if (_sububoFeeIds.Contains(subFee))
+            {
+                id = 7;
+                remark = "费用组成:住补费用、导游房补";
+                name = "住补费";
+            }
+            // 景点费:94 导游景点费  990 景点门票费  1085 景点门票超支费用
+            if (_scenicSpotFeeIds.Contains(subFee))
+            {
+                id = 8;
+                remark = "费用组成:导游景点费、景点门票费、景点门票超支费用";
+                name = "景点费";
+            }
+            // 翻译费:994 翻译费  1073 翻译超时费
+            if (_translationFeeIds.Contains(subFee))
+            {
+
+                id = 9;
+                remark = "费用组成:翻译费、翻译超时费";
+                name = "翻译费";
+            }
+            // 饮料/ 零食 / 水果费:991 饮料 / 零食 / 水果
+            if (_DSFFeeIds.Contains(subFee))
+            {
+                id = 10;
+                remark = "费用组成:饮料/零食/水果费";
+                name = "饮料/零食/水果费";
+            }
+            // 其他费用:97 其他费用  1071 其他额外费用
+            if (_otherFeeIds.Contains(subFee))
+            {
+                id = 11;
+                remark = "费用组成:其他费用、其他额外费用";
+                name = "其他费用";
+            }
+
+            string returnStr = string.Empty;
+            if (type == 1) returnStr = id.ToString();
+            else if (type == 2) returnStr = name;
+            else if (type == 3) returnStr = remark;
+
+            return returnStr;
+        }
+    }
+
+
+      
+
+
+
+    public class StatisticsOPYOY
+    {
+        public int FeeId { get; set; }
+        public string FeeName { get; set; }
+        /// <summary>
+        /// 本期
+        /// </summary>
+        public decimal CurrPeriodFee { get; set; }
+        /// <summary>
+        /// 同期
+        /// </summary>
+        public decimal SamePeriodFee { get; set; }
+        public decimal Yoy { get; set; }
+        public int CurrPeriodGroupTotal { get; set; }
+        public int SamePeriodGroupTotal { get; set; }
+        public StatisticsOPSubFeeYOY[] SubFeeData { get; set; }
+
+        public StatisticsOPYOY() { }
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="year"></param>
+        /// <param name="month"></param>
+        /// <param name="thisAmount"></param>
+        /// <param name="lastAmount"></param>
+        /// <param name="thisIds"></param>
+        /// <param name="lastIds"></param>
+        public StatisticsOPYOY(int feeId, string feeName, decimal currPeriodFee, decimal samePeriodFee,
+           int currPeriodGroupTotal ,int samePeriodGroupTotal, StatisticsOPSubFeeYOY[] subFeeData)
+        {
+            this.FeeId = feeId;
+            this.FeeName = feeName;
+            this.CurrPeriodFee = currPeriodFee;
+            this.SamePeriodFee = samePeriodFee;
+            decimal _yoy = 0.00M;
+            if (samePeriodFee != 0.00M)
+            {
+                _yoy = (currPeriodFee - samePeriodFee) / samePeriodFee;
+            }
+
+            this.Yoy = decimal.Parse(_yoy.ToString("0.##")); 
+            this.CurrPeriodGroupTotal = currPeriodGroupTotal;
+            this.SamePeriodGroupTotal = samePeriodGroupTotal;
+            this.SubFeeData = subFeeData;
+        }
+    }
+
+    public class StatisticsOPSubFeeYOY : StatisticsOPYOY
+    {
+        public StatisticsOPCityYOY[] CityData { get; set; }
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="year"></param>
+        /// <param name="month"></param>
+        /// <param name="thisAmount"></param>
+        /// <param name="lastAmount"></param>
+        /// <param name="thisIds"></param>
+        /// <param name="lastIds"></param>
+        public StatisticsOPSubFeeYOY(int feeId, string feeName, decimal currPeriodFee, decimal samePeriodFee,
+           int currPeriodGroupTotal, int samePeriodGroupTotal, StatisticsOPCityYOY[] cityData)
+        {
+            this.FeeId = feeId;
+            this.FeeName = feeName;
+            this.CurrPeriodFee = currPeriodFee;
+            this.SamePeriodFee = samePeriodFee;
+            decimal _yoy = 0.00M;
+            if (samePeriodFee != 0.00M)
+            {
+                _yoy = (currPeriodFee - samePeriodFee) / samePeriodFee;
+            }
+
+            this.Yoy = decimal.Parse(_yoy.ToString("0.##"));
+            this.CurrPeriodGroupTotal = currPeriodGroupTotal;
+            this.SamePeriodGroupTotal = samePeriodGroupTotal;
+            this.CityData = cityData;
+        }
+    }
+
+
+    public class StatisticsOPCityYOY
+    {
+        public string CityName { get; set; }
+
+        public int CurrPeriodGroupTotal { get; set; }
+        public int SamePeriodGroupTotal { get; set; }
+
+        /// <summary>
+        /// 本期
+        /// </summary>
+        public decimal CurrPeriodFee { get; set; }
+        /// <summary>
+        /// 同期
+        /// </summary>
+        public decimal SamePeriodFee { get; set; }
+        public decimal Yoy { get; set; }
+
+        public StatisticsOPCityYOY() { }
+
+        public StatisticsOPCityYOY(string cityName, decimal currPeriodFee, decimal samePeriodFee,
+            int currPeriodGroupTotal,int samePeriodGroupTotal) 
+        {
+            this.CityName = cityName;
+            this.CurrPeriodGroupTotal = currPeriodGroupTotal;
+            this.SamePeriodGroupTotal = samePeriodGroupTotal;
+            this.CurrPeriodFee = currPeriodFee;
+            this.SamePeriodFee = samePeriodFee;
+            string _yoy = "0.00";
+            if (samePeriodFee != 0)
+            {
+                _yoy = ((currPeriodFee - samePeriodFee) / samePeriodFee).ToString("0.##");
+            }
+
+            this.Yoy = decimal.Parse(_yoy);
+        }
+
+    }
+
     #endregion
     #endregion
     #endregion
     #endregion
 }
 }

+ 2 - 1
OASystem/OASystem.Infrastructure/Repositories/Groups/FeeAuditRepository.cs

@@ -1,4 +1,5 @@
-using NPOI.SS.Formula.Functions;
+using EyeSoft.Logging;
+using NPOI.SS.Formula.Functions;
 using OASystem.Domain;
 using OASystem.Domain;
 using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.ViewModels.Groups;
 using OASystem.Domain.ViewModels.Groups;