#region 查询导出物料报销情况
/// <summary>
/// 查询物料报销明细
/// </summary>
//[Chaolj.Apps.Core.Utils.GlobalContext.CheckApi]
public FileResult QueryMaterialPayStatus(FormCollection formData)
{
string qryString = this.Request.Params["qryString"].SafeConvert().ToStr();
DateTime beginDate = this.Request.Params["beginDate"].SafeConvert().ToDateTime().Date;
DateTime endDate = this.Request.Params["endDate"].SafeConvert().ToDateTime().Date;
#region 1. 查询数据
List<ZTZS.DAL.ZSERP.vMaterialSheetDetail> list = new List<ZTZS.DAL.ZSERP.vMaterialSheetDetail>(); // 物料出入库明细清单
// 1. 从老erp查询出相应的入库明细;
using (var erpdb = ZTZS.DAL.ZSERP.ZSErpContext.Create())
{
var qry = erpdb.vMaterialSheetDetail.Where(p => p.Transdate >= beginDate && p.Transdate < endDate && (p.SheetTypeNo == "PR" || p.SheetTypeNo == "RI"));
list = qry.ToList();
}
List<MaterialIsSettlement> listSettlement = new List<MaterialIsSettlement>(); // 已进入报销流程的单据;
// 2. 从新erp判定哪些明细已经报销;
using (var h3db2 = Chaolj.ZTBPM.DAL.H3Context.Create())
using (var h3Db = ZTZS.DAL.H3.H3Context.Create())
{
// 2.1 获取当前所有单据
var listBillNo = list.Select(m => m.SheetNo).Distinct().ToList();
// 2.2 查询当前单据列表,所有已进入报销流程的单据;
var billNos1 = h3db2.BD_ReceiveOrReturnOrder.Where(m => listBillNo.Contains(m.OrderNo)).Select(m => new MaterialIsSettlement { BillNo = m.OrderNo, InstanceId = m.INSTANCEID }).ToList();
var billNos2 = h3Db.报销材料报销入库单.Where(m => listBillNo.Contains(m.单据编号)).Select(m => new MaterialIsSettlement { BillNo = m.单据编号, InstanceId = m.INSTANCEID }).ToList();
// 2.3 用sql语句查询
string strBillNos = "";
for (int i = 0; i < listBillNo.Count(); i++)
{
strBillNos += "'" + listBillNo[i] + "'";
if (i < listBillNo.Count - 1) strBillNos += ",";
}
string strWhere = setConditionByOr(strBillNos, 50, "单据编号");
string sql = "SELECT * FROM h3.报销材料报销入库单 WHERE " + strWhere + "";
var billNos3Model = h3Db.Database.SqlQuery<MaterialSheetInSettlement>(sql).ToList();
var billNos3 = billNos3Model.Select(m => new MaterialIsSettlement { BillNo = m.单据编号, InstanceId = m.INSTANCEID }).ToList();
string strWhere4 = setConditionByOr(strBillNos, 50, "入库单编号");
string sql4 = "SELECT * FROM h3.材料零星报销入库单 WHERE " + strWhere4 + "";
var billNos4Model = h3Db.Database.SqlQuery<MaterialSheetLinXinSettlement>(sql4);
var billNos4 = billNos4Model.Select(m => new MaterialIsSettlement { BillNo = m.入库单编号, InstanceId = m.INSTANCEID }).ToList();
listSettlement.AddRange(billNos1);
listSettlement.AddRange(billNos2);
listSettlement.AddRange(billNos3);
listSettlement.AddRange(billNos4);
listSettlement = listSettlement.Distinct().ToList();
}
// 3. 从支付中心判定,哪些数据已经支付、待支付等状态;
List<string> listWorkflowId = new List<string>();
listWorkflowId = listSettlement.Select(m => m.InstanceId).ToList();
using (var erp = Chaolj.DAL.ERP.ERPContext2.Create())
{
// 已支付金额:FromTypeName in (材料_材料报销,材料_临星材料报销)
var qryPay = erp.vFI_Order_Payment.Where(p => listWorkflowId.Contains(p.InstanceId) && (p.Status == 2 || p.Status == 4)).Select(m => new { InstanceId = m.InstanceId }).ToList(); // 状态为:已结算、已完成;
listSettlement = (from a in listSettlement
join p in qryPay on a.InstanceId equals p.InstanceId into ap
from api in ap.DefaultIfEmpty()
select new MaterialIsSettlement
{
BillNo = a.BillNo,
InstanceId = a.InstanceId,
PayStatus = (api == null || api.InstanceId == null) ? "未支付" : "已支付"
}).ToList();
}
var result = (from a in list
join s in listSettlement on a.SheetNo equals s.BillNo into sa
from sai in sa.DefaultIfEmpty()
select new
{
Id = a.Id,
项目编码 = a.ProjectNo,
项目名称 = a.ProjectName,
供应商编码 = a.VenderCode,
供应商名称 = a.VenderName,
单据编码 = a.SheetNo,
Line = a.Line,
交易时间 = a.Transdate,
物料编码 = a.ItemNo,
类别 = a.ItemType,
大类 = a.ItemMainClass,
子类 = a.ItemSubClass,
FSB = a.FSB,
厂家 = a.Manufacturer,
规格 = a.Specification,
品牌 = a.Brand,
属性 = a.Property,
单位 = a.Uom,
数量 = a.Qty,
单价 = a.Price,
金额 = a.Amount,
描述 = a.Description,
单据状态 = a.Stat,
业务类型 = a.SheetTypeNo == "PR" ? "入库" : "退货",
报销状态 = (sai == null || sai.InstanceId == null) ? "未报销" : "已报销",
支付状态 = sai == null ? "" : sai.PayStatus
}).ToList();
#endregion
#region 2. 生成xls
#region 1.列头定义
List<string> lstTitle = new List<string>
{
"项目编码",// 0
"项目名称", // 1
"供应商编码",// 2
"供应商名称", // 3
"单据编码",// 4
"交易时间",// 5
"物料编码",//6
"类别",// 7
"大类",// 8
"子类",// 9
"FSB",// 10
"厂家",// 11
"规格",// 12
"品牌",// 13
"属性",// 14
"单位",// 15
"数量",// 16
"单价",// 17
"金额",// 18
"描述",// 19
"单据状态", // 20
"业务类型", // 21
"报销状态", // 22
"支付状态",// 23
};
#endregion
IWorkbook book = new HSSFWorkbook();
ISheet sheet = book.CreateSheet("Sheet1");
IRow rowTitle = sheet.CreateRow(0);
ICellStyle style = book.CreateCellStyle();
style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//垂直居中
for (int i = 0; i < lstTitle.Count; i++)
{
rowTitle.CreateCell(i).SetCellValue(lstTitle[i]);
}
if (list != null)
{
result.OrderBy(p => p.单据编码);
int start = 0;//记录同组开始行号
int end = 0;//记录同组结束行号
string temp = "";//记录上一行的值
for (int i = 0; i < result.Count(); i++)
{
IRow row = sheet.CreateRow(i + 1);
#region 单元格赋值
row.CreateCell(0).SetCellValue(result[i].项目编码);
row.CreateCell(1).SetCellValue(result[i].项目名称);
row.CreateCell(2).SetCellValue(result[i].供应商编码);
row.CreateCell(3).SetCellValue(result[i].供应商名称);
row.CreateCell(4).SetCellValue(result[i].单据编码);
row.CreateCell(5).SetCellValue(result[i].交易时间.ToString());
row.CreateCell(6).SetCellValue(result[i].物料编码);
row.CreateCell(7).SetCellValue(result[i].类别);
row.CreateCell(8).SetCellValue(result[i].大类);
row.CreateCell(9).SetCellValue(result[i].子类);
row.CreateCell(10).SetCellValue(result[i].FSB);
row.CreateCell(11).SetCellValue(result[i].厂家);
row.CreateCell(12).SetCellValue(result[i].规格);
row.CreateCell(13).SetCellValue(result[i].品牌);
row.CreateCell(14).SetCellValue(result[i].属性);
row.CreateCell(15).SetCellValue(result[i].单位);
row.CreateCell(16).SetCellValue(result[i].数量.ToString("f2"));
row.CreateCell(17).SetCellValue(result[i].单价.ToString("f4"));
row.CreateCell(18).SetCellValue(result[i].金额.ToString("f4"));
row.CreateCell(19).SetCellValue(result[i].描述);
row.CreateCell(20).SetCellValue(result[i].单据状态);
row.CreateCell(21).SetCellValue(result[i].业务类型);
row.CreateCell(22).SetCellValue(result[i].报销状态);
row.CreateCell(23).SetCellValue(result[i].支付状态);
#endregion
row.GetCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).SetCellType(CellType.String);
var cellText = row.Cells[0].StringCellValue;//获取当前行 第1列的单元格的值
if (cellText == temp)//上下行相等,记录要合并的最后一行
{
end = i;
}
else//上下行不等,记录
{
if (start != end)
{
//设置一个合并单元格区域,使用上下左右定义CellRangeAddress区域
//CellRangeAddress四个参数为:起始行,结束行,起始列,结束列
CellRangeAddress region = new CellRangeAddress(start + 1, end + 1, 0, 0);
sheet.AddMergedRegion(region);
}
start = i;
end = i;
temp = cellText;
}
}
}
#endregion
#region 3. 格式化并保存
for (int i = 0; i < 7; i++)
{
sheet.AutoSizeColumn(i);//i:根据标题的个数设置自动列宽
}
MemoryStream ms = new MemoryStream();
book.Write(ms);
ms.Seek(0, SeekOrigin.Begin);
#endregion
return File(ms, "application/vnd.ms-excel", "出入库物料报销明细.xls");
}
/// <summary>
/// 查询单据报销明细
/// </summary>
//[Chaolj.Apps.Core.Utils.GlobalContext.CheckApi]
public FileResult QueryMaterialSheetPayStatus(FormCollection formData)
{
string qryString = this.Request.Params["qryString"].SafeConvert().ToStr();
DateTime beginDate = this.Request.Params["beginDate"].SafeConvert().ToDateTime().Date;
DateTime endDate = this.Request.Params["endDate"].SafeConvert().ToDateTime().Date;
#region 1. 查询数据
List<ZTZS.DAL.ZSERP.MaterialSheet> list = new List<ZTZS.DAL.ZSERP.MaterialSheet>(); // 物料出入库明细清单
// 1. 从老erp查询出相应的入库明细;
using (var erpdb = ZTZS.DAL.ZSERP.ZSErpContext.Create())
{
var qry = erpdb.MaterialSheet.Where(p => p.Transdate >= beginDate && p.Transdate < endDate && p.Stat == "审核" && (p.SheetTypeNo == "PR" || p.SheetTypeNo == "RI"));
list = qry.ToList();
}
List<MaterialIsSettlement> listSettlement = new List<MaterialIsSettlement>(); // 已进入报销流程的单据;
// 2. 从新erp判定哪些明细已经报销;
using (var h3db2 = Chaolj.ZTBPM.DAL.H3Context.Create())
using (var h3Db = ZTZS.DAL.H3.H3Context.Create())
{
// 2.1 获取当前所有单据
var listBillNo = list.Select(m => m.SheetNo).Distinct().ToList();
// 2.2 查询当前单据列表,所有已进入报销流程的单据;
var billNos1 = h3db2.BD_ReceiveOrReturnOrder.Where(m => listBillNo.Contains(m.OrderNo)).Select(m => new MaterialIsSettlement { BillNo = m.OrderNo, InstanceId = m.INSTANCEID }).ToList();
var billNos2 = h3Db.报销材料报销入库单.Where(m => listBillNo.Contains(m.单据编号)).Select(m => new MaterialIsSettlement { BillNo = m.单据编号, InstanceId = m.INSTANCEID }).ToList();
// 2.3 用sql语句查询
string strBillNos = "";
for (int i = 0; i < listBillNo.Count(); i++)
{
strBillNos += "'" + listBillNo[i]+"'";
if (i < listBillNo.Count - 1) strBillNos += ",";
}
string strWhere = setConditionByOr(strBillNos, 50, "单据编号");
string sql = "SELECT * FROM h3.报销材料报销入库单 WHERE "+strWhere+"";
var billNos3Model = h3Db.Database.SqlQuery<MaterialSheetInSettlement>(sql).ToList();
var billNos3 = billNos3Model.Select(m => new MaterialIsSettlement { BillNo = m.单据编号, InstanceId = m.INSTANCEID }).ToList();
string strWhere4 = setConditionByOr(strBillNos, 50, "入库单编号");
string sql4 = "SELECT * FROM h3.材料零星报销入库单 WHERE " + strWhere4 + "";
var billNos4Model = h3Db.Database.SqlQuery<MaterialSheetLinXinSettlement>(sql4);
var billNos4 = billNos4Model.Select(m => new MaterialIsSettlement { BillNo = m.入库单编号, InstanceId = m.INSTANCEID }).ToList();
listSettlement.AddRange(billNos1);
listSettlement.AddRange(billNos2);
listSettlement.AddRange(billNos3);
listSettlement.AddRange(billNos4);
listSettlement = listSettlement.Distinct().ToList();
}
// 3. 从支付中心判定,哪些数据已经支付、待支付等状态;
List<string> listWorkflowId = new List<string>();
listWorkflowId = listSettlement.Select(m => m.InstanceId).ToList();
using (var erp = Chaolj.DAL.ERP.ERPContext2.Create())
{
// 已支付金额:FromTypeName in (材料_材料报销,材料_临星材料报销)
var qryPay = erp.vFI_Order_Payment.Where(p => listWorkflowId.Contains(p.InstanceId) && (p.Status == 2 || p.Status == 4)).Select(m => new { InstanceId = m.InstanceId }).ToList(); // 状态为:已结算、已完成;
listSettlement = (from a in listSettlement
join p in qryPay on a.InstanceId equals p.InstanceId into ap
from api in ap.DefaultIfEmpty()
select new MaterialIsSettlement
{
BillNo = a.BillNo,
InstanceId = a.InstanceId,
PayStatus = (api == null || api.InstanceId == null) ? "未支付" : "已支付"
}).ToList();
}
var result = (from a in list
join s in listSettlement on a.SheetNo equals s.BillNo into sa
from sai in sa.DefaultIfEmpty()
select new
{
Id = a.Id,
项目名称 = a.ProjectName,
供应商名称 = a.Vender,
单据编码 = a.SheetNo,
交易时间 = a.Transdate,
送货金额 = a.DeliveryAmount,
金额 = a.TotalAmount,
描述 = a.Description,
单据状态 = a.Stat,
业务类型 = a.SheetTypeNo == "PR" ? "入库" : "退货",
报销状态 = (sai == null || sai.InstanceId == null) ? "未报销" : "已报销",
支付状态 = sai == null ? "" : sai.PayStatus
}).ToList();
#endregion
#region 2. 生成xls
#region 1.列头定义
List<string> lstTitle = new List<string>
{
"项目名称", // 0
"供应商名称", // 1
"单据编码",// 2
"交易时间",// 3
"送货金额",// 4
"金额",// 5
"描述",// 6
"单据状态", // 7
"业务类型", // 8
"报销状态", // 9
"支付状态",// 10
};
#endregion
IWorkbook book = new HSSFWorkbook();
ISheet sheet = book.CreateSheet("Sheet1");
IRow rowTitle = sheet.CreateRow(0);
ICellStyle style = book.CreateCellStyle();
style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//垂直居中
for (int i = 0; i < lstTitle.Count; i++)
{
rowTitle.CreateCell(i).SetCellValue(lstTitle[i]);
}
if (list != null)
{
result.OrderBy(p => p.单据编码);
int start = 0;//记录同组开始行号
int end = 0;//记录同组结束行号
string temp = "";//记录上一行的值
for (int i = 0; i < result.Count(); i++)
{
IRow row = sheet.CreateRow(i + 1);
#region 单元格赋值
row.CreateCell(0).SetCellValue(result[i].项目名称);
row.CreateCell(1).SetCellValue(result[i].供应商名称);
row.CreateCell(2).SetCellValue(result[i].单据编码);
row.CreateCell(3).SetCellValue(result[i].交易时间.ToString());
row.CreateCell(4).SetCellValue(result[i].送货金额.Value.ToString("f2"));
row.CreateCell(5).SetCellValue(result[i].金额.ToString("f4"));
row.CreateCell(6).SetCellValue(result[i].描述);
row.CreateCell(7).SetCellValue(result[i].单据状态);
row.CreateCell(8).SetCellValue(result[i].业务类型);
row.CreateCell(9).SetCellValue(result[i].报销状态);
row.CreateCell(10).SetCellValue(result[i].支付状态);
#endregion
row.GetCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).SetCellType(CellType.String);
var cellText = row.Cells[0].StringCellValue;//获取当前行 第1列的单元格的值
if (cellText == temp)//上下行相等,记录要合并的最后一行
{
end = i;
}
else//上下行不等,记录
{
if (start != end)
{
//设置一个合并单元格区域,使用上下左右定义CellRangeAddress区域
//CellRangeAddress四个参数为:起始行,结束行,起始列,结束列
CellRangeAddress region = new CellRangeAddress(start + 1, end + 1, 0, 0);
sheet.AddMergedRegion(region);
}
start = i;
end = i;
temp = cellText;
}
}
}
#endregion
#region 3. 格式化并保存
for (int i = 0; i < 7; i++)
{
sheet.AutoSizeColumn(i);//i:根据标题的个数设置自动列宽
}
MemoryStream ms = new MemoryStream();
book.Write(ms);
ms.Seek(0, SeekOrigin.Begin);
#endregion
return File(ms, "application/vnd.ms-excel", "出入库单据报销明细.xls");
}
public string GetSqlIn(string sqlParam, string columnName)
{
int width = sqlParam.IndexOf("'", 1) - 1;
string temp = string.Empty;
for (int i = 0; i < sqlParam.Length; i += 1000 * (width + 3))
{
if (i + 1000 * (width + 3) - 1 < sqlParam.Length)
{
temp = temp + sqlParam.Substring(i, 1000 * (width + 3) - 1)
+ ") OR " + columnName + " IN (";
}
else
{
temp = temp + sqlParam.Substring(i, sqlParam.Length - i);
}
}
return temp;
}
/**
* 解决Oracle where条件中in条件超过1000大小 列表中的最大表达式数为 1000
* 把以逗号(',')分割的字符串分割成固定大小的多个组
* 把分割开的字符串用 or关键字拼接 然后查询
* param:以逗号分隔的字符串
* eachGroupNum:每组多少个数量
* field:SQL语句中哪个字段查询
*/
public String setConditionByOr(String param, int eachGroupNum, String field)
{
String[] paramArray = param.Split(',');
int inArrayNum = (paramArray.Length % eachGroupNum == 0) ? paramArray.Length / eachGroupNum : paramArray.Length / eachGroupNum + 1;
int m = 0;
int b = 0;
int n = eachGroupNum;
String[] p = new String[inArrayNum];
String[] sql = new String[inArrayNum];
for (int k = 0; k < paramArray.Length; ++k) {
if (b < inArrayNum) {
p[b] = "";
for (; m < n; ++m) {
if (m >= paramArray.Length) { break; }
int temp = b;
String[] tmp = p;
tmp[temp] = tmp[temp] + paramArray[m] + ",";
}
p[b] = p[b].Substring(0, p[b].LastIndexOf(","));
sql[b] = field + " in (" + p[b] + ")";
++b;
n += eachGroupNum;
}
}
String condition = "";
for (int j = 0; j < sql.Length; ++j) {
condition = condition + sql[j] + " or ";
}
condition = condition.Substring(0, condition.LastIndexOf(" or "));
return condition;
}
#endregion