365 lines
16 KiB
C#
365 lines
16 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// statisticsController 的摘要描述
|
|
/// </summary>
|
|
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)
|
|
{
|
|
if (items.draft .StartsWith("["))
|
|
{
|
|
var jj = JsonConvert.DeserializeObject<JArray>(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());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var jj = JsonConvert.DeserializeObject<JObject>(items.draft);
|
|
foreach (var j in jj["pro_order_detail_items"])
|
|
{
|
|
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}<G{i},G{i}-F{i},0)";
|
|
|
|
i++;
|
|
}
|
|
|
|
}
|
|
else if (statistic_mode == "02")
|
|
{
|
|
var list = (from a in _db.pro_order
|
|
join b in _db.pro_order_detail on a.order_no equals b.order_no
|
|
join c in _db.followers on a.f_num equals c.num
|
|
join d in _db.activities on a.activity_num equals d.num
|
|
select new
|
|
{
|
|
a.order_no,
|
|
a.f_num,
|
|
a.activity_num,
|
|
b.qty,
|
|
b.price,
|
|
c.u_name
|
|
}).ToList();
|
|
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 = "應付";
|
|
i++;
|
|
var g = list.GroupBy(y => 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}<E{i},E{i}-D{i},0)";
|
|
i++;
|
|
}
|
|
}
|
|
else if (statistic_mode == "03")
|
|
{
|
|
var list = (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.followers on b.f_num equals d.num
|
|
select new
|
|
{
|
|
a.num,a.subject,b.order_no,order_detail_num=c.num,
|
|
b.f_num,d.u_name,c.price,c.qty
|
|
}).ToList();
|
|
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 = "應付";
|
|
i++;
|
|
var g = list.GroupBy(y => 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}<E{i},E{i}-D{i},0)";
|
|
i++;
|
|
}
|
|
}
|
|
|
|
// 儲存 Excel
|
|
excel.SaveAs(file);
|
|
}
|
|
|
|
return Ok(new { result = "Y", filename = $"rpt/{name}" });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Ok(new { result = "N", message = ex.Message});
|
|
//return BadRequest($"{ex.Message}{ex.StackTrace}");
|
|
}
|
|
}
|
|
|
|
} |