using DocumentFormat.OpenXml.Wordprocessing; using MINOM.COM.Utility; using Model.ViewModel; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NPOI.SS.UserModel; using OfficeOpenXml; using System; using System.Collections.Generic; using System.Data.SqlClient; using System.IO; using System.Linq; using System.Text; using System.Web; using System.Web.Http; /// /// statisticsController 的摘要描述 /// public class statisticsController: ApiController { //獲取於活動統計相關的數據 private Model.ezEntities _db = new Model.ezEntities(); public statisticsController() { // // TODO: 在這裡新增建構函式邏輯 // } [HttpPost] [Route("api/statistics/activitylist")] public IHttpActionResult GetStatisticsActivityList() { //獲取活動列表 var activityList = _db.activities.OrderByDescending(x => x.reg_time).ToList(); return Ok(activityList); } [HttpPost] [Route("api/statistics/activitycountlist")] public IHttpActionResult GetActivityCountList(int page=1,int pagesize=10, [FromUri] string[] sortby = null, [FromUri] bool[] sortdesc = null ) { //獲取多個活動統計列表,如果一個獲取超過五十個,則返回空 if (pagesize > 50) { return Ok(); } var qry = _db.activities.OrderByDescending(x => x.reg_time); var data = qry.Skip((page - 1) * pagesize).Take(pagesize).ToList(); var list = new { items = data.Select(x => new { id = x.num, order_count = x.pro_order.Count(), pw_count = x.pro_order.SelectMany(b => b.pro_order_detail).Count(), activity_name = x.subject, receivable = x.pro_order.SelectMany(a => a.pro_order_detail).Select(c => c.price).Sum(), startdate = x.startDate_solar, enddate = x.endDate_solar, //register_status = EnumHelper.GetDescription((ActivityRegisterStatus)x.ActivityRegisterStatus), //hold_status = EnumHelper.GetDescription((ActivityHoldStatus)x.ActivityHoldStatus), //gdz_peoples = x.pro_order.SelectMany(a => a.pro_order_detail).Where(b => b.actItem?.actItem_kind?.IsGDZ == true).Count(), }), count =qry.Count() }; return Ok(list); } [HttpPost] [Route("api/statistics/activitycount")] public IHttpActionResult GetActivityCount(int id) { //獲取單個活動統計數據 var qry = _db.activities.Where(a => a.num == id); if (qry == null) { return Ok(); } var data = new { list = qry.Select(a => new { id = a.num, order_count = a.pro_order.Count(), order_price_total = a.pro_order.SelectMany(b => b.pro_order_detail).Select(c => c.price).Sum() }) }; return Ok(data); } [HttpPost] [Route("api/statistics/GDZCount")] public IHttpActionResult GetActivityGDZCount(int activity_num) { var qry = _db.pro_order_detail.Include("follower").Where(a => a.pro_order.activity_num == activity_num); if (qry == null) { return Ok(); } var data = new { all_count = _db.pro_order.Where(a => a.activity_num == activity_num).Count(), all_gdz_count = qry .Where(a => a.actItem.act_bom.Any(b => b.package_num == null && b.item_num == a.actItem_num)) .Select(a => a.order_no) .Distinct() .Count(), gdz_item_counts = qry.Where(a => !a.actItem.subject.Contains("大牌位")) .GroupBy(a => new { item_num = a.actItem.num, item_name = a.actItem.subject, price = a.actItem.price }) .Select(g => new { item_num = g.Key.item_num, item_name = g.Key.item_name, price = g.Key.price, count = g.Count(),//功德項目的數量 total_price = g.Where(x => x.price != null).Sum(x => x.price), // ⚠️ 潛在 N+1 查詢:在 GroupBy 投影中執行新查詢 // g.Select(...).ToList() 會立即執行,然後用 Contains 做子查詢 // 若 g 數量很多,建議重構為 join 或分兩階段查詢以提升效能 followers = _db.pro_order .Where(h => g.Select(x => x.order_no).Distinct().ToList().Contains(h.order_no)) .Select(k => k.follower.u_name) .Distinct() .ToList(), amountsByFollower = g .GroupBy(x => x.pro_order.follower.u_name) .Select(fg => new { follower = fg.Key, amount = fg.Where(x => x.price != null).Sum(x => x.price) }) .ToList() }) .OrderByDescending(x => x.price) .ToList() }; return Ok(data); } [HttpPost] [Route("api/statistics/GetStatistic")] public IHttpActionResult GetStatistic(string statistic_mode) { try { var drafts = (from a in _db.transfer_register select a).ToList(); string rootPath = HttpRuntime.AppDomainAppPath; string name = $"output{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"; string fileName = Path.Combine(new string[] { rootPath, "rpt", name }); var file = new FileInfo($"{fileName}"); // 檔案路徑 using (var excel = new ExcelPackage()) { LogUtility log = new LogUtility(); // 建立分頁 var ws = excel.Workbook.Worksheets.Add("MySheet"); var data = (from a in _db.activities join b in _db.pro_order on a.num equals b.activity_num join c in _db.pro_order_detail on b.order_no equals c.order_no //join d in _db.activity_relating on a.num equals d.activity_num join f in _db.actItems on c.actItem_num equals f.num select new { a.num, a.subject, b.order_no, b.f_num, order_detail_num = c.num, c.actItem_num, item_subject = f.subject, c.qty, c.price }).ToList(); int i = 0; i++; if (statistic_mode == "01") { ws.Cells[i, 1].Value = "序號"; ws.Cells[i, 2].Value = "法會名稱"; ws.Cells[i, 3].Value = "功德項目"; ws.Cells[i, 4].Value = "數量"; ws.Cells[i, 5].Value = "單價"; ws.Cells[i, 6].Value = "小計"; ws.Cells[i, 7].Value = "實收"; ws.Cells[i, 8].Value = "應收"; ws.Cells[i, 9].Value = "應付"; i++; var list = data.GroupBy(x => new { x.num, x.subject, x.actItem_num, x.item_subject }).Select(y => new { y.Key.num, y.Key.subject, y.Key.actItem_num, y.Key.item_subject, qty = y.Where(q => q.num == y.Key.num && q.actItem_num == y.Key.actItem_num).Select(q => q.qty).Sum(), price = y.Where(p => p.num == y.Key.num && p.actItem_num == y.Key.actItem_num).Select(p => p.price).FirstOrDefault() }).ToList(); foreach (var item in list) { ws.Cells[i, 1].Value = i - 1; ws.Cells[i, 2].Value = item.subject; ws.Cells[i, 3].Value = item.item_subject; ws.Cells[i, 4].Value = item.qty.Value; ws.Cells[i, 5].Value = item.price.Value; ws.Cells[i, 6].Formula = $"=D{i}*E{i}"; var draftList = (from a in drafts where a.activity_num == item.num select a).ToList(); decimal payed = 0; foreach (var items in draftList) { if (items.draft != null) { var jj = JsonConvert.DeserializeObject(items.draft); log.writeLogPath(jj.ToString()); foreach (var j in jj) { if (item.subject == j["activity_name"].ToString() && item.item_subject == j["actitem_name"].ToString()) { payed = payed + decimal.Parse(j["reconcile"].ToString()); } } } } ws.Cells[i, 7].Value = payed; ws.Cells[i, 8].Formula = $"=if(F{i}>G{i},F{i}-G{i},0)"; ws.Cells[i, 9].Formula = $"=if(F{i} new { y.f_num, y.u_name }).Select(y => new { y.Key.f_num, y.Key.u_name, total = y.Where(x => x.f_num == y.Key.f_num).Select(x => x.price * x.qty).Sum() }); foreach (var item in g) { ws.Cells[i, 1].Value = i - 1; ws.Cells[i, 2].Value = item.f_num; ws.Cells[i, 3].Value = item.u_name; ws.Cells[i, 4].Value = item.total; var dd = (from a in drafts where a.f_num == item.f_num select a).ToList(); decimal payed = 0; foreach (var d in dd) { payed = payed + (decimal)d.check_amount;// -(decimal)d.remain_amount; } ws.Cells[i, 5].Value = payed; ws.Cells[i, 6].Formula = $"=if(D{i}>E{i},D{i}-E{i},0)"; ws.Cells[i, 7].Formula = $"=if(D{i} new { y.num, y.subject, y.f_num, y.u_name }).Select(y=>new { y.Key.num,y.Key.subject,y.Key.f_num,y.Key.u_name, total=y.Where(x=>x.num==y.Key.num&&x.f_num==y.Key.f_num).Select(x=>x.price*x.qty).Sum() }); foreach (var item in g) { ws.Cells[i, 1].Value = i - 1; ws.Cells[i, 2].Value = item.subject; ws.Cells[i, 3].Value = item.u_name; ws.Cells[i, 4].Value = item.total; var dd = drafts.Where (y=>y.activity_num==item.num&&y.f_num==item.f_num). Select(y => new { y.check_amount, y.remain_amount }).ToList(); ws.Cells[i, 5].Value = dd.Sum(y=>y.check_amount); ws.Cells[i, 6].Formula = $"=if(D{i}>E{i},D{i}-E{i},0)"; ws.Cells[i, 7].Formula = $"=if(D{i}