部门统计和产品汇总
This commit is contained in:
parent
4ce03e8fda
commit
c3f2d905cf
@ -34,7 +34,7 @@
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<InstallUrl />
|
||||
<TargetCulture>zh-chs</TargetCulture>
|
||||
<ApplicationVersion>1.0.0.2</ApplicationVersion>
|
||||
<ApplicationVersion>1.0.0.4</ApplicationVersion>
|
||||
<AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
|
||||
<UpdateEnabled>true</UpdateEnabled>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
|
@ -38,6 +38,9 @@ namespace KellyReport_D.Utils
|
||||
|
||||
// 更新业务预估表
|
||||
UpdateEstimatedTable(importContext);
|
||||
UpdateDeptartmentSummary(importContext);
|
||||
|
||||
GenProductSummarySheet(importContext);
|
||||
}
|
||||
|
||||
private static void UpdateEstimatedTable(ImportContext importContext)
|
||||
@ -523,9 +526,9 @@ namespace KellyReport_D.Utils
|
||||
{
|
||||
SalesName = rawSalesDetailData[i, 1]?.ToString() ?? "UNKNOWN",
|
||||
Month = rawSalesDetailData[i, 2]?.ToString() ?? "",
|
||||
InvoiceDate = rawSalesDetailData[i, 3] is double invoiceDate ? DateTime.FromOADate(invoiceDate) : (DateTime?)null,
|
||||
DeliveryDate = rawSalesDetailData[i, 3] is double invoiceDate ? DateTime.FromOADate(invoiceDate) : (DateTime?)null,
|
||||
OrderNumber = rawSalesDetailData[i, 4]?.ToString() ?? "",
|
||||
DeliveryDate = rawSalesDetailData[i, 5] is double deliveryDate ? DateTime.FromOADate(deliveryDate) : (DateTime?)null,
|
||||
InvoiceDate = rawSalesDetailData[i, 5] != null ? DateTime.Parse(rawSalesDetailData[i, 5]?.ToString()) : (DateTime?)null,
|
||||
InvoiceNumber = rawSalesDetailData[i, 6]?.ToString() ?? "",
|
||||
ClientName = rawSalesDetailData[i, 7]?.ToString() ?? "",
|
||||
ProductNameEN = rawSalesDetailData[i, 8]?.ToString() ?? "",
|
||||
@ -562,7 +565,7 @@ namespace KellyReport_D.Utils
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async void GenForecast(System.Windows.Forms.Button button)
|
||||
public static void GenForecast(System.Windows.Forms.Button button)
|
||||
{
|
||||
String originLabel = button.Text;
|
||||
if (button != null)
|
||||
@ -580,7 +583,8 @@ namespace KellyReport_D.Utils
|
||||
// 获取「銷售年度預估」工作表
|
||||
ReadSalesForecastData(context);
|
||||
// 获取「產品年度預估」工作表
|
||||
ReadProductForecastData(context);
|
||||
//ReadProductForecastData(context);
|
||||
GenDepartmentSummary(context);
|
||||
|
||||
GenBussenessSheet(context);
|
||||
}
|
||||
@ -839,5 +843,306 @@ namespace KellyReport_D.Utils
|
||||
context.SalesForecastList = salesForecastInputList;
|
||||
context.MonthData = monthData;
|
||||
}
|
||||
|
||||
public static void GenProductSummarySheet(ImportContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
|
||||
string sheetName = $"產品年度預估";
|
||||
Worksheet productSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||
productSheet.Activate();
|
||||
|
||||
var yearList = context.SalesDetails
|
||||
.Where(x => x.InvoiceDate.HasValue)
|
||||
.Select(x => x.InvoiceDate.Value.Year)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
yearList.ForEach(yearNumber =>
|
||||
{
|
||||
Range usedRange = productSheet.UsedRange;
|
||||
|
||||
Range turnOverRange = usedRange.Find(What: $"{yearNumber}-Turnover", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
if (turnOverRange == null)
|
||||
{
|
||||
Range estimateRange = usedRange.Find(What: $"{yearNumber}-Estimate", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
int insertCol = 2;
|
||||
if (estimateRange != null)
|
||||
{
|
||||
insertCol = estimateRange.Column;
|
||||
}
|
||||
|
||||
Range insertRange = productSheet.Columns[$"{GetColumnLetter(insertCol)}:{GetColumnLetter(insertCol + 5)}"];
|
||||
insertRange.EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight);
|
||||
insertRange = productSheet.Columns[$"{GetColumnLetter(insertCol)}:{GetColumnLetter(insertCol + 5)}"];
|
||||
insertRange.ClearFormats();
|
||||
|
||||
productSheet.Cells[1, insertCol].Value2 = $"{yearNumber}-Turnover";
|
||||
|
||||
productSheet.Cells[2, insertCol].Value2 = "數量";
|
||||
productSheet.Cells[2, insertCol + 1].Value2 = "金額(含稅)";
|
||||
productSheet.Cells[2, insertCol + 2].Value2 = "金額(未稅)";
|
||||
productSheet.Cells[2, insertCol + 3].Value2 = "平均單價";
|
||||
productSheet.Cells[2, insertCol + 4].Value2 = "成長率";
|
||||
var growthRange = productSheet.Range[
|
||||
productSheet.Cells[2, insertCol + 4],
|
||||
productSheet.Cells[2, insertCol + 5]
|
||||
];
|
||||
growthRange.Merge();
|
||||
|
||||
turnOverRange = productSheet.Range[
|
||||
productSheet.Cells[1, insertCol],
|
||||
productSheet.Cells[1, insertCol + 5]
|
||||
];
|
||||
turnOverRange.Merge();
|
||||
}
|
||||
|
||||
var productSalesList = context.SalesDetails
|
||||
.Where(x => x.InvoiceDate.HasValue && x.InvoiceDate.Value.Year == yearNumber)
|
||||
.GroupBy(x => x.ProductNameEN)
|
||||
.Select(grouped => new ImportContext.GroupedSalesDetailModel()
|
||||
{
|
||||
ProductNameEN = grouped.Key,
|
||||
Quantity = grouped.Sum(x => x.Quantity ?? 0),
|
||||
TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
|
||||
Details = grouped.ToList()
|
||||
})
|
||||
.ToList();
|
||||
|
||||
Range totalRange = usedRange.Find(What: $"總計", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
int totalRowCount = usedRange.Rows.Count + 1;
|
||||
if (totalRange != null)
|
||||
{
|
||||
totalRowCount = totalRange.Row;
|
||||
}
|
||||
|
||||
int startColIndex = turnOverRange.Column;
|
||||
var quantityColLetter = GetColumnLetter(startColIndex);
|
||||
var amountColLetter = GetColumnLetter(startColIndex + 1);
|
||||
var amountNoTaxColLetter = GetColumnLetter(startColIndex + 2);
|
||||
var prevQuantityColLetter = GetColumnLetter(startColIndex + 6);
|
||||
var prevAmountColLetter = GetColumnLetter(startColIndex + 7);
|
||||
var prevAmountNoTaxColLetter = GetColumnLetter(startColIndex + 8);
|
||||
|
||||
foreach (var productSalesSummary in productSalesList)
|
||||
{
|
||||
var curProductName = productSalesSummary.ProductNameEN;
|
||||
// look for the product row
|
||||
// if not exists then create a new row
|
||||
Range productRange = usedRange.Find(
|
||||
What: curProductName,
|
||||
LookIn: XlFindLookIn.xlValues,
|
||||
LookAt: XlLookAt.xlWhole,
|
||||
SearchOrder: XlSearchOrder.xlByRows,
|
||||
SearchDirection: XlSearchDirection.xlNext,
|
||||
MatchCase: false
|
||||
);
|
||||
|
||||
if (productRange == null)
|
||||
{
|
||||
productSheet.Rows[totalRowCount].Insert();
|
||||
productSheet.Cells[totalRowCount, 1].Value2 = curProductName;
|
||||
productRange = productSheet.Cells[totalRowCount, 1];
|
||||
|
||||
totalRowCount += 1;
|
||||
}
|
||||
|
||||
int curRowIndex = productRange.Row;
|
||||
|
||||
productSheet.Cells[curRowIndex, startColIndex].Value2 = productSalesSummary.Quantity;
|
||||
productSheet.Cells[curRowIndex, startColIndex + 1].Value2 = productSalesSummary.TotalAmount;
|
||||
productSheet.Cells[curRowIndex, startColIndex + 2].formula = $"={amountColLetter}{curRowIndex}/1.13";
|
||||
productSheet.Cells[curRowIndex, startColIndex + 3].formula = $"={amountColLetter}{curRowIndex}/${quantityColLetter}{curRowIndex}";
|
||||
|
||||
productSheet.Cells[curRowIndex, startColIndex + 4].formula = $"={quantityColLetter}{curRowIndex}/${prevQuantityColLetter}{curRowIndex}";
|
||||
productSheet.Cells[curRowIndex, startColIndex + 5].formula = $"={amountColLetter}{curRowIndex}/${prevAmountColLetter}{curRowIndex}";
|
||||
|
||||
productSheet.Cells[curRowIndex, startColIndex + 4].NumberFormat = "0.00%";
|
||||
productSheet.Cells[curRowIndex, startColIndex + 5].NumberFormat = "0.00%";
|
||||
}
|
||||
|
||||
productSheet.Cells[totalRowCount, 1].Value2 = "總計";
|
||||
productSheet.Cells[totalRowCount, startColIndex].formula = $"=SUM({quantityColLetter}5:{quantityColLetter}{totalRowCount - 1})";
|
||||
productSheet.Cells[totalRowCount, startColIndex + 1].formula = $"=SUM({amountColLetter}5:{amountColLetter}{totalRowCount - 1})";
|
||||
productSheet.Cells[totalRowCount, startColIndex + 2].formula = $"=SUM({amountNoTaxColLetter}5:{amountNoTaxColLetter}{totalRowCount - 1})";
|
||||
|
||||
productSheet.Cells[totalRowCount + 1, 1].Value2 = "備註";
|
||||
productSheet.Cells[totalRowCount + 1, startColIndex].formula = $"={quantityColLetter}{totalRowCount}/{prevQuantityColLetter}{totalRowCount}";
|
||||
productSheet.Cells[totalRowCount + 1, startColIndex + 1].formula = $"={amountColLetter}{totalRowCount}/{prevAmountColLetter}{totalRowCount}";
|
||||
productSheet.Cells[totalRowCount + 1, startColIndex + 2].formula = $"={amountNoTaxColLetter}{totalRowCount}/{prevAmountNoTaxColLetter}{totalRowCount}";
|
||||
|
||||
productSheet.Cells[totalRowCount + 1, startColIndex].NumberFormat = "0.00%";
|
||||
productSheet.Cells[totalRowCount + 1, startColIndex + 1].NumberFormat = "0.00%";
|
||||
productSheet.Cells[totalRowCount + 1, startColIndex + 2].NumberFormat = "0.00%";
|
||||
});
|
||||
|
||||
FormatSheetStyle(productSheet);
|
||||
}
|
||||
|
||||
public static void GenDepartmentSummary(GenForecaseContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
|
||||
string sheetName = $"部门统计";
|
||||
Worksheet deptSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||
deptSheet.Activate();
|
||||
|
||||
deptSheet.Cells[1, 1].Value2 = "鈞全";
|
||||
deptSheet.Range[deptSheet.Cells[1, 1], deptSheet.Cells[2, 1]].Merge();
|
||||
|
||||
var yearList = context.SalesForecastList
|
||||
.Select(x => x.Year)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
Range initUsedRange = deptSheet.UsedRange;
|
||||
|
||||
Range totalRange = initUsedRange.Find(What: $"Total", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
int totalRowIndex = initUsedRange.Rows.Count + 1;
|
||||
if (totalRange != null)
|
||||
{
|
||||
totalRowIndex = totalRange.Row;
|
||||
}
|
||||
|
||||
yearList.ForEach(yearNumber =>
|
||||
{
|
||||
Range curYearRange = deptSheet.UsedRange.Find(What: $"{yearNumber}", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
int startCol = deptSheet.UsedRange.Column + 1;
|
||||
if (curYearRange != null)
|
||||
{
|
||||
startCol = curYearRange.Column;
|
||||
}
|
||||
|
||||
var startColLetter = GetColumnLetter(startCol);
|
||||
var endColLetter = GetColumnLetter(startCol + 3);
|
||||
|
||||
Range prevYearRange = deptSheet.UsedRange.Find(What: $"{yearNumber - 1}", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
int prevStartCol = 0;
|
||||
string prevForecastColLetter = "";
|
||||
string prevTurnoverColLetter = "";
|
||||
if (prevYearRange != null)
|
||||
{
|
||||
prevStartCol = prevYearRange.Column;
|
||||
prevForecastColLetter = GetColumnLetter(prevStartCol);
|
||||
prevTurnoverColLetter = GetColumnLetter(prevStartCol + 1);
|
||||
}
|
||||
|
||||
deptSheet.Range[$"{startColLetter}:{endColLetter}"]
|
||||
.EntireColumn
|
||||
.Insert(XlInsertShiftDirection.xlShiftToRight);
|
||||
|
||||
deptSheet.Cells[1, 2].Value2 = $"{yearNumber}";
|
||||
deptSheet.Range[deptSheet.Cells[1, startCol], deptSheet.Cells[1, startCol + 3]].Merge();
|
||||
|
||||
deptSheet.Cells[2, startCol].Value2 = "Forecast";
|
||||
deptSheet.Cells[2, startCol + 1].Value2 = "Turnover";
|
||||
deptSheet.Cells[2, startCol + 2].Value2 = "成長率";
|
||||
deptSheet.Cells[2, startCol + 3].Value2 = "達成率";
|
||||
|
||||
var forcastColLetter = startColLetter;
|
||||
var turnoverColLetter = GetColumnLetter(startCol + 1);
|
||||
foreach (var salesForecast in context.SalesForecastList.Where(x => x.Name.ToUpper() != "TOTAL"))
|
||||
{
|
||||
var salesName = salesForecast.Name;
|
||||
Range curUsedRange = deptSheet.UsedRange;
|
||||
|
||||
Range salesNameRange = curUsedRange.Find(What: $"{salesName}", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
if (salesNameRange == null)
|
||||
{
|
||||
deptSheet.Rows[totalRowIndex].Insert();
|
||||
deptSheet.Cells[curUsedRange.Rows.Count + 1, 1].Value2 = salesName;
|
||||
|
||||
salesNameRange = deptSheet.Cells[curUsedRange.Rows.Count + 1, 1];
|
||||
totalRowIndex++;
|
||||
}
|
||||
|
||||
deptSheet.Cells[salesNameRange.Row, startCol].Value2 = salesForecast.Total;
|
||||
if (prevYearRange != null)
|
||||
{
|
||||
deptSheet.Cells[salesNameRange.Row, startCol + 2].formula = $"=SUM({forcastColLetter}{salesNameRange.Row} - {prevTurnoverColLetter}{salesNameRange.Row})/{forcastColLetter}{salesNameRange.Row}";
|
||||
deptSheet.Cells[salesNameRange.Row, startCol + 2].NumberFormat = "0.00%";
|
||||
}
|
||||
deptSheet.Cells[salesNameRange.Row, startCol + 3].formula = $"={turnoverColLetter}{salesNameRange.Row}/{forcastColLetter}{salesNameRange.Row}";
|
||||
deptSheet.Cells[salesNameRange.Row, startCol + 3].NumberFormat = "0.00%";
|
||||
}
|
||||
|
||||
deptSheet.Cells[totalRowIndex, 1].Value2 = "Total";
|
||||
deptSheet.Cells[totalRowIndex, startCol].formula = $"=SUM({forcastColLetter}3:{forcastColLetter}{totalRowIndex - 1})";
|
||||
deptSheet.Cells[totalRowIndex, startCol + 1].formula = $"=SUM({turnoverColLetter}3:{turnoverColLetter}{totalRowIndex - 1})";
|
||||
|
||||
if (prevYearRange != null)
|
||||
{
|
||||
deptSheet.Cells[totalRowIndex, startCol + 2].formula = $"=SUM({forcastColLetter}{totalRowIndex} - {prevTurnoverColLetter}{totalRowIndex})/{forcastColLetter}{totalRowIndex}";
|
||||
deptSheet.Cells[totalRowIndex, startCol + 2].NumberFormat = "0.00%";
|
||||
}
|
||||
deptSheet.Cells[totalRowIndex, startCol + 3].formula = $"={turnoverColLetter}{totalRowIndex}/{forcastColLetter}{totalRowIndex}";
|
||||
deptSheet.Cells[totalRowIndex, startCol + 3].NumberFormat = "0.00%";
|
||||
});
|
||||
|
||||
FormatSheetStyle(deptSheet);
|
||||
}
|
||||
|
||||
public static void UpdateDeptartmentSummary(ImportContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
|
||||
string sheetName = $"部门统计";
|
||||
Worksheet deptSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||
deptSheet.Activate();
|
||||
|
||||
var yearList = context.SalesDetails.Where(x => x.InvoiceDate.HasValue).Select(x => x.InvoiceDate.Value.Year).Distinct().ToList();
|
||||
|
||||
yearList.ForEach(yearoNumber =>
|
||||
{
|
||||
Range yearRange = deptSheet.UsedRange.Find(What: $"{yearoNumber}", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
if (yearRange == null)
|
||||
{
|
||||
Console.WriteLine("Cannot find year column in department summary: {0}", yearoNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
var startCol = yearRange.Column;
|
||||
var startColLetter = GetColumnLetter(startCol);
|
||||
var turnoverColLetter = GetColumnLetter(startCol + 1);
|
||||
|
||||
Range totalRange = deptSheet.UsedRange.Find(What: $"Total", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
int totalRowIndex = deptSheet.UsedRange.Rows.Count + 1;
|
||||
if (totalRange != null)
|
||||
{
|
||||
totalRowIndex = totalRange.Row;
|
||||
}
|
||||
|
||||
var salesDetails = context.SalesDetails
|
||||
.Where(x => x.InvoiceDate.HasValue && x.InvoiceDate.Value.Year == yearoNumber && x.SalesName.ToUpper() != "TOTAL")
|
||||
.GroupBy(x => x.SalesName)
|
||||
.Select(grouped => new
|
||||
{
|
||||
SalesName = grouped.Key,
|
||||
Turnover = grouped.Sum(x => x.TotalAmount ?? 0)
|
||||
})
|
||||
.ToList();
|
||||
|
||||
foreach (var salesDetail in salesDetails)
|
||||
{
|
||||
var salesName = salesDetail.SalesName;
|
||||
Range curUsedRange = deptSheet.UsedRange;
|
||||
|
||||
Range salesNameRange = curUsedRange.Find(What: $"{salesName}", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||
|
||||
if (salesNameRange != null)
|
||||
{
|
||||
deptSheet.Cells[salesNameRange.Row, startCol + 1].Value2 = salesDetail.Turnover;
|
||||
}
|
||||
}
|
||||
|
||||
deptSheet.Cells[totalRowIndex, startCol + 1].formula = $"=SUM({turnoverColLetter}3:{turnoverColLetter}{totalRowIndex - 1})";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user