Browse Source

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

LEIYI 7 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]")]
     public class GroupsController : ControllerBase
     {
+        private readonly ILogger<GroupsController> _logger;
         private readonly GrpScheduleRepository _grpScheduleRep;
         private readonly IMapper _mapper;
         private readonly DelegationInfoRepository _groupRepository;
@@ -81,7 +82,7 @@ namespace OASystem.API.Controllers
         private readonly HotelInquiryRepository _hotelInquiryRep;
         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,
             InvitationOfficialActivitiesRepository InvitationOfficialActivitiesRep, DelegationEnDataRepository delegationEnDataRep, EnterExitCostRepository enterExitCostRep
             , DelegationVisaRepository delegationVisaRep, MessageRepository message, VisaPriceRepository visaPriceRep, CarTouristGuideGroundRepository carTouristGuideGroundRep,
@@ -91,6 +92,7 @@ namespace OASystem.API.Controllers
             InvertedListRepository invertedListRep, VisaFeeInfoRepository visaFeeInfoRep, TicketBlackCodeRepository ticketBlackCodeRep, HotelInquiryRepository hotelInquiryRep,
             ThreeCodeRepository threeCodeRepository, FeeAuditRepository feeAuditRep)
         {
+            _logger = logger;
             _mapper = mapper;
             _grpScheduleRep = grpScheduleRep;
             _groupRepository = groupRepository;
@@ -1448,7 +1450,8 @@ namespace OASystem.API.Controllers
                     _detail.PriceName = priceModule;
 
                     _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;
 
-                                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)
-                                { 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)
-                                { 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)
-                                { 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)
-                                { 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;
                                 else roomFeeStr += "  0.00 * 0";
@@ -1602,7 +1618,9 @@ namespace OASystem.API.Controllers
                                 if (roomData != null)
                                 {
                                     _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 ? "是" : "否";
                                     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);
                                     hotelCost_day += @$"{item.First()?.Date ?? "-"}";
                                     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")}";
-                                    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")}";
-                                    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")}";
-                                    else { if (__isOther) hotelCost_day += @$"   套房:0.00"; }
+                                    //else { if (__isOther) hotelCost_day += @$"   套房:0.00"; }
                                     hotelCost_day += @$"</br>";
                                 }
 
@@ -1656,7 +1674,7 @@ namespace OASystem.API.Controllers
                                                           $"<span style='font-weight:800;'>{hotelReservations.HotelName} [{hotelReservations.CheckInDate} - {hotelReservations.CheckOutDate}]</span><br/>" +
                                                           $"信用卡金额:{_detail.WaitPay} ({hotelCurrncyName})<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}" +
                                                           $"{hotelGovernmentRentStr}" +
                                                           $"{hotelCityTaxStr}";
@@ -10040,8 +10058,9 @@ ORDER by  gctggrc.id DESC
                 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)
             {
@@ -10051,6 +10070,36 @@ ORDER by  gctggrc.id DESC
             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>
         /// 酒店预订
         /// Del 

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

@@ -1,4 +1,5 @@
 using Aspose.Cells;
+using NPOI.OpenXmlFormats.Dml.Diagram;
 using OASystem.API.OAMethodLib;
 using OASystem.Domain.Dtos.Statistics;
 using OASystem.Domain.Entities.Customer;
@@ -7,6 +8,8 @@ using OASystem.Domain.ViewModels.Financial;
 using OASystem.Domain.ViewModels.Statistics;
 using OASystem.Infrastructure.Repositories.Groups;
 using System.Data;
+using System.Linq;
+using System.Security.Cryptography.Xml;
 using static OASystem.API.OAMethodLib.GeneralMethod;
 using TypeInfo = OASystem.Domain.ViewModels.Statistics.TypeInfo;
 
@@ -4078,6 +4081,208 @@ WHERE
                 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
     }
 }

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

@@ -204,4 +204,15 @@ namespace OASystem.Domain.Dtos.Statistics
 
     #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>
-        /// 
         [SugarColumn(IsNullable = true, ColumnDataType = "varchar(80)")]
         public string ServiceStartTime { get; set; }
         /// <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.Text;
 using System.Threading.Tasks;
+using System.Xml.Linq;
 
 namespace OASystem.Domain.ViewModels.Financial
 {
@@ -926,10 +927,10 @@ namespace OASystem.Domain.ViewModels.Financial
     public class StatisticsInvitation
     {
         public int DIId { get; set; }
-        public string Country { get; set; }    }
+        public string Country { get; set; }
+    }
     #endregion
 
-
     #region 团组相关
 
     public class StatisticsGroupInfoEntity
@@ -970,6 +971,346 @@ namespace OASystem.Domain.ViewModels.Financial
         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
 }

+ 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.Entities.Groups;
 using OASystem.Domain.ViewModels.Groups;