生成销售表
This commit is contained in:
parent
24831a0661
commit
db87d00ead
@ -34,7 +34,7 @@
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<InstallUrl />
|
||||
<TargetCulture>zh-chs</TargetCulture>
|
||||
<ApplicationVersion>1.0.0.1</ApplicationVersion>
|
||||
<ApplicationVersion>1.0.0.2</ApplicationVersion>
|
||||
<AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
|
||||
<UpdateEnabled>true</UpdateEnabled>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
|
@ -10,6 +10,7 @@ namespace KellyReport_D.Model
|
||||
internal class ImportContext
|
||||
{
|
||||
public Workbook ImportWorkbook { get; set; }
|
||||
public List<Worksheet> SalesWorksheets { get; set; }
|
||||
public Microsoft.Office.Interop.Excel.Application Application { get; set; }
|
||||
public IList<ClientContact> ClientContactList { get; set; }
|
||||
public IList<SalesDetail> SalesDetails { get; set; }
|
||||
@ -19,6 +20,7 @@ namespace KellyReport_D.Model
|
||||
public string ClientName { get; set; }
|
||||
public string ProductNameEN { get; set; }
|
||||
public decimal TotalAmount { get; set; }
|
||||
public decimal Quantity { get; set; }
|
||||
public List<SalesDetail> Details { get; set; }
|
||||
}
|
||||
|
||||
@ -28,18 +30,18 @@ namespace KellyReport_D.Model
|
||||
{
|
||||
SalesName = grouped.Key,
|
||||
TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
|
||||
Quantity = grouped.Sum(x => x.Quantity ?? 0),
|
||||
Details = grouped.ToList()
|
||||
});
|
||||
|
||||
public IEnumerable<GroupedSalesDetailModel> GetGroupedSalesDetailByClientName(IList<SalesDetail> salesDetails)
|
||||
{
|
||||
return salesDetails
|
||||
.GroupBy(x => new { SalesName = x.SalesName.ToUpper(), x.ClientName, x.ProductNameEN })
|
||||
.GroupBy(x => new { SalesName = x.SalesName.ToUpper(), x.ClientName })
|
||||
.Select(grouped => new GroupedSalesDetailModel
|
||||
{
|
||||
SalesName = grouped.Key.SalesName,
|
||||
ClientName = grouped.Key.ClientName,
|
||||
ProductNameEN = grouped.Key.ProductNameEN,
|
||||
TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
|
||||
Details = grouped.ToList()
|
||||
});
|
||||
|
@ -7,7 +7,6 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using KellyReport_D.Model;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace KellyReport_D.Utils
|
||||
{
|
||||
@ -18,11 +17,12 @@ namespace KellyReport_D.Utils
|
||||
var importContext = new ImportContext()
|
||||
{
|
||||
Application = Globals.ThisAddIn.Application,
|
||||
ImportWorkbook = workbook
|
||||
ImportWorkbook = workbook,
|
||||
SalesWorksheets = new List<Worksheet>(),
|
||||
};
|
||||
|
||||
// 获取「客户资料」工作表
|
||||
readClientContact(importContext);
|
||||
ReadClientContact(importContext);
|
||||
// 读取「销售明细」工作表
|
||||
ReadSalesDetails(importContext);
|
||||
foreach (var userGroupedSalesDetail in importContext.GroupedSalesDetailBySalesName)
|
||||
@ -30,7 +30,146 @@ namespace KellyReport_D.Utils
|
||||
var userSheet = GenUserSalesDetailSheet(importContext, userGroupedSalesDetail);
|
||||
PrepareTotalHeader(userSheet);
|
||||
WriteSalesDetailsData(importContext, userGroupedSalesDetail, userSheet);
|
||||
|
||||
importContext.SalesWorksheets.Add(userSheet);
|
||||
}
|
||||
|
||||
GenSalesTotal(importContext);
|
||||
}
|
||||
|
||||
private static void GenSalesTotal(ImportContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
var totalWorksheet = CreateSheetIfNotExisted(app, "JQ Total(Total)");
|
||||
|
||||
PrepareTotalHeader(totalWorksheet);
|
||||
int totalRowIndex = 4;
|
||||
foreach (var userSheet in context.SalesWorksheets)
|
||||
{
|
||||
Range usedRange = userSheet.UsedRange;
|
||||
int rowIndexStart = 4;
|
||||
int rowIndexEnd = usedRange.Rows.Count;
|
||||
|
||||
int rowCount = rowIndexEnd - rowIndexStart + 1;
|
||||
if (rowCount > 1)
|
||||
{
|
||||
Range sourceRange = userSheet.Range[
|
||||
userSheet.Cells[rowIndexStart, 1],
|
||||
userSheet.Cells[rowIndexEnd, usedRange.Columns.Count]
|
||||
];
|
||||
|
||||
int totalRowIndexEnd = totalRowIndex + rowCount;
|
||||
Range targetRange = totalWorksheet.Range[
|
||||
totalWorksheet.Cells[totalRowIndex, 1],
|
||||
totalWorksheet.Cells[totalRowIndexEnd, usedRange.Columns.Count]
|
||||
];
|
||||
sourceRange.Copy(targetRange);
|
||||
totalRowIndex = totalRowIndexEnd;
|
||||
}
|
||||
}
|
||||
|
||||
totalWorksheet.Cells[totalRowIndex, 1].Value = "總結";
|
||||
var sumRange = totalWorksheet.Range[
|
||||
totalWorksheet.Cells[totalRowIndex, 1],
|
||||
totalWorksheet.Cells[totalRowIndex + 4, 5]
|
||||
];
|
||||
sumRange.Merge();
|
||||
|
||||
int sumColStart = 13; // L列是第12列
|
||||
totalWorksheet.Cells[totalRowIndex, 11].Value2 = "總銷量及金額(未稅)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, quantityColIndex].formula = $"=(SUM({quantityColLetter}4:{quantityColLetter}{totalRowIndex - 1})/2)";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, amountColIndex].formula = $"=((SUM({amountColLetter}4:{amountColLetter}{totalRowIndex - 1})/2) - {amountColLetter}{totalRowIndex + 2})/1.13";
|
||||
}
|
||||
string totalQuantityColLetter = GetColumnLetter(49);
|
||||
string totalAmountColLetter = GetColumnLetter(50);
|
||||
|
||||
totalWorksheet.Cells[totalRowIndex, 49].formula = $"=(SUM({totalQuantityColLetter}4:{totalAmountColLetter}{totalRowIndex - 1})/2)";
|
||||
totalWorksheet.Cells[totalRowIndex, 50].formula = $"=((SUM({totalAmountColLetter}4:{totalAmountColLetter}{totalRowIndex - 1})/2) - {totalAmountColLetter}{totalRowIndex + 2})/1.13";
|
||||
|
||||
|
||||
totalRowIndex++;
|
||||
totalWorksheet.Cells[totalRowIndex, 11].Value2 = "總銷量及金額(含稅)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, quantityColIndex].formula = $"=(SUM({quantityColLetter}4:{quantityColLetter}{totalRowIndex - 1})/2)";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, amountColIndex].formula = $"=(SUM({amountColLetter}4:{amountColLetter}{totalRowIndex - 1})/2)";
|
||||
}
|
||||
totalWorksheet.Cells[totalRowIndex, 49].formula = $"=(SUM({totalQuantityColLetter}4:{totalQuantityColLetter}{totalRowIndex - 1})/2)";
|
||||
totalWorksheet.Cells[totalRowIndex, 50].formula = $"=(SUM({totalAmountColLetter}4:{totalAmountColLetter}{totalRowIndex - 1})/2)";
|
||||
|
||||
totalRowIndex++;
|
||||
totalWorksheet.Cells[totalRowIndex, 11].Value2 = "總銷量及金額(外銷)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
totalWorksheet.Cells[totalRowIndex, quantityColIndex].Value2 = 0;
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
totalWorksheet.Cells[totalRowIndex, amountColIndex].Value2 = 0;
|
||||
}
|
||||
totalWorksheet.Cells[totalRowIndex, 49].Value2 = 0;
|
||||
totalWorksheet.Cells[totalRowIndex, 50].Value2 = 0;
|
||||
|
||||
totalRowIndex++;
|
||||
totalWorksheet.Cells[totalRowIndex, 11].Value2 = "總銷量及金額(內外銷)";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
int quantityColIndex = sumColStart + i * 3 + 1;
|
||||
string quantityColLetter = GetColumnLetter(quantityColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, quantityColIndex].formula = $"={quantityColLetter}{totalRowIndex - 3}+{quantityColLetter}{totalRowIndex - 1}";
|
||||
|
||||
int amountColIndex = sumColStart + i * 3 + 2;
|
||||
string amountColLetter = GetColumnLetter(amountColIndex);
|
||||
totalWorksheet.Cells[totalRowIndex, amountColIndex].formula = $"={amountColLetter}{totalRowIndex - 3}+{amountColLetter}{totalRowIndex - 1}";
|
||||
}
|
||||
totalWorksheet.Cells[totalRowIndex, 49].formula = $"={totalQuantityColLetter}{totalRowIndex - 3}+{totalQuantityColLetter}{totalRowIndex - 1}";
|
||||
totalWorksheet.Cells[totalRowIndex, 50].formula = $"={totalAmountColLetter}{totalRowIndex - 3}+{totalAmountColLetter}{totalRowIndex - 1}";
|
||||
|
||||
// 自适应所有已用列宽
|
||||
FormatSheetStyle(totalWorksheet);
|
||||
}
|
||||
|
||||
private static void FormatSheetStyle(Worksheet worksheet)
|
||||
{
|
||||
// 自适应所有已用列宽
|
||||
Range usedRange2 = worksheet.UsedRange;
|
||||
if (usedRange2 != null)
|
||||
{
|
||||
usedRange2.Columns.AutoFit();
|
||||
usedRange2.Borders.LineStyle = XlLineStyle.xlContinuous;
|
||||
usedRange2.Borders.Weight = XlBorderWeight.xlThin;
|
||||
}
|
||||
worksheet.Cells[4, 12].Select();
|
||||
|
||||
//worksheet.Application.ActiveWindow.SplitRow = 3;
|
||||
//worksheet.Application.ActiveWindow.SplitColumn = 10;
|
||||
worksheet.Application.ActiveWindow.FreezePanes = true;
|
||||
}
|
||||
|
||||
|
||||
// 列号转字母方法
|
||||
private static string GetColumnLetter(int col)
|
||||
{
|
||||
string colLetter = "";
|
||||
while (col > 0)
|
||||
{
|
||||
int mod = (col - 1) % 26;
|
||||
colLetter = (char)(65 + mod) + colLetter;
|
||||
col = (col - mod - 1) / 26;
|
||||
}
|
||||
return colLetter;
|
||||
}
|
||||
|
||||
public static void WriteSalesDetailsData(
|
||||
@ -40,15 +179,79 @@ namespace KellyReport_D.Utils
|
||||
)
|
||||
{
|
||||
int rowIndex = 4; // 从第四行开始写入数据
|
||||
var clientGroupedSalesDetail = context.GetGroupedSalesDetailByClientName(userGroupedSalesDetail.Details);
|
||||
foreach (var salesDetail in clientGroupedSalesDetail)
|
||||
var clientSalesList = context.GetGroupedSalesDetailByClientName(userGroupedSalesDetail.Details);
|
||||
foreach (var clientSalesDetail in clientSalesList)
|
||||
{
|
||||
ClientContact clientContact = context.ClientContactList.FirstOrDefault(x => x.Name == salesDetail.ClientName) ?? new ClientContact
|
||||
ClientContact clientContact = context.ClientContactList.FirstOrDefault(x => x.Name == clientSalesDetail.ClientName) ?? new ClientContact
|
||||
{
|
||||
Name = salesDetail.ClientName,
|
||||
Name = clientSalesDetail.ClientName,
|
||||
};
|
||||
|
||||
userSheet.Cells[rowIndex, 1].Value2 = salesDetail.SalesName;
|
||||
var productSalesList = clientSalesDetail.Details
|
||||
.GroupBy(x => x.ProductNameEN)
|
||||
.Select(grouped => new ImportContext.GroupedSalesDetailModel
|
||||
{
|
||||
SalesName = clientSalesDetail.SalesName,
|
||||
ClientName = clientSalesDetail.ClientName,
|
||||
ProductNameEN = grouped.Key,
|
||||
TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
|
||||
Quantity = grouped.Sum(x => x.Quantity ?? 0),
|
||||
Details = grouped.ToList()
|
||||
});
|
||||
rowIndex = WriteSalesDetailToSheet(userSheet, rowIndex, clientContact, productSalesList);
|
||||
|
||||
// 客户销量汇总
|
||||
var totalSales = new List<ImportContext.GroupedSalesDetailModel>()
|
||||
{
|
||||
new ImportContext.GroupedSalesDetailModel
|
||||
{
|
||||
SalesName = clientSalesDetail.SalesName,
|
||||
ClientName = clientSalesDetail.ClientName,
|
||||
ProductNameEN = "總銷售額",
|
||||
TotalAmount = clientSalesDetail.TotalAmount,
|
||||
Quantity = clientSalesDetail.Quantity,
|
||||
Details = clientSalesDetail.Details.Aggregate(
|
||||
new List<SalesDetail>(),
|
||||
(accDetail, curDetail) => {
|
||||
var monthSales = accDetail.FirstOrDefault(x => x.Month == curDetail.Month);
|
||||
if (monthSales == null)
|
||||
{
|
||||
monthSales = new SalesDetail
|
||||
{
|
||||
Month = curDetail.Month,
|
||||
SalesName = curDetail.SalesName,
|
||||
ProductNameEN = "總銷售額",
|
||||
Quantity = 0,
|
||||
Tax = 0,
|
||||
TotalAmount = 0,
|
||||
PriceWithTax = 0,
|
||||
AmountWithoutTax = 0
|
||||
};
|
||||
accDetail.Add(monthSales);
|
||||
}
|
||||
|
||||
monthSales.Quantity += curDetail.Quantity;
|
||||
monthSales.Tax += curDetail.Tax;
|
||||
monthSales.TotalAmount += curDetail.TotalAmount;
|
||||
//monthSales.PriceWithTax += curDetail.PriceWithTax;
|
||||
monthSales.AmountWithoutTax += curDetail.AmountWithoutTax;
|
||||
|
||||
return accDetail;
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
rowIndex = WriteSalesDetailToSheet(userSheet, rowIndex, clientContact, totalSales);
|
||||
}
|
||||
|
||||
FormatSheetStyle(userSheet);
|
||||
}
|
||||
|
||||
private static int WriteSalesDetailToSheet(Worksheet userSheet, int rowIndex, ClientContact clientContact, IEnumerable<ImportContext.GroupedSalesDetailModel> salesDetailList)
|
||||
{
|
||||
foreach (var productSalesDetail in salesDetailList)
|
||||
{
|
||||
userSheet.Cells[rowIndex, 1].Value2 = productSalesDetail.SalesName;
|
||||
userSheet.Cells[rowIndex, 2].Value2 = clientContact.Region;
|
||||
userSheet.Cells[rowIndex, 3].Value2 = clientContact.Industry;
|
||||
userSheet.Cells[rowIndex, 4].Value2 = clientContact.AnnualCapacity;
|
||||
@ -58,9 +261,57 @@ namespace KellyReport_D.Utils
|
||||
userSheet.Cells[rowIndex, 8].Value2 = clientContact.Purchaser;
|
||||
userSheet.Cells[rowIndex, 9].Value2 = clientContact.PurchaserPhone;
|
||||
userSheet.Cells[rowIndex, 10].Value2 = clientContact.Address;
|
||||
userSheet.Cells[rowIndex, 11].Value2 = salesDetail.ProductNameEN;
|
||||
userSheet.Cells[rowIndex, 11].Value2 = productSalesDetail.ProductNameEN;
|
||||
|
||||
// 计算每月的数量和金额
|
||||
int monthCol = 13; // L列是第12列
|
||||
for (int i = 1; i < 13; i++)
|
||||
{
|
||||
int monthCounter = 0;
|
||||
var monthDetail = productSalesDetail.Details.Where(x => x.Month == $"{i}月")
|
||||
.Aggregate(new SalesDetail()
|
||||
{
|
||||
Month = $"{i}月",
|
||||
Quantity = 0,
|
||||
TotalAmount = 0,
|
||||
PriceWithTax = 0,
|
||||
AmountWithoutTax = 0,
|
||||
Tax = 0
|
||||
}, (accSalesModel, curSalesModel) =>
|
||||
{
|
||||
accSalesModel.Quantity += (curSalesModel.Quantity ?? 0);
|
||||
accSalesModel.TotalAmount += (curSalesModel.TotalAmount ?? 0);
|
||||
accSalesModel.PriceWithTax += (curSalesModel.PriceWithTax ?? 0);
|
||||
monthCounter++;
|
||||
|
||||
return accSalesModel;
|
||||
});
|
||||
if (monthCounter > 1)
|
||||
{
|
||||
monthDetail.PriceWithTax = monthDetail.PriceWithTax / monthCounter;
|
||||
}
|
||||
|
||||
if (monthDetail == null)
|
||||
{
|
||||
userSheet.Cells[rowIndex, monthCol + (i - 1) * 3].Value2 = 0; // 單價
|
||||
userSheet.Cells[rowIndex, monthCol + (i - 1) * 3 + 1].Value2 = 0; // 數量
|
||||
userSheet.Cells[rowIndex, monthCol + (i - 1) * 3 + 2].Value2 = 0; // 金額
|
||||
}
|
||||
else
|
||||
{
|
||||
userSheet.Cells[rowIndex, monthCol + (i - 1) * 3].Value2 = monthDetail.PriceWithTax ?? 0; // 單價
|
||||
userSheet.Cells[rowIndex, monthCol + (i - 1) * 3 + 1].Value2 = monthDetail.Quantity ?? 0; // 數量
|
||||
userSheet.Cells[rowIndex, monthCol + (i - 1) * 3 + 2].Value2 = monthDetail.TotalAmount ?? 0; // 总额
|
||||
}
|
||||
}
|
||||
userSheet.Cells[rowIndex, 49].Value = productSalesDetail.Quantity;
|
||||
userSheet.Cells[rowIndex, 50].Value = productSalesDetail.TotalAmount;
|
||||
|
||||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
public static void PrepareTotalHeader(Worksheet userSheet)
|
||||
@ -126,15 +377,37 @@ namespace KellyReport_D.Utils
|
||||
|
||||
|
||||
private static Worksheet GenUserSalesDetailSheet(
|
||||
Model.ImportContext context,
|
||||
Model.ImportContext.GroupedSalesDetailModel groupedSalesDetail
|
||||
ImportContext context,
|
||||
ImportContext.GroupedSalesDetailModel groupedSalesDetail
|
||||
)
|
||||
{
|
||||
var app = context.Application;
|
||||
var salesName = groupedSalesDetail.SalesName ?? "UNKONW";
|
||||
string sheetName = $"JQ Total({salesName.ToUpper()})";
|
||||
Worksheet userSheet = null;
|
||||
Worksheet userSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||
Range usedRange = userSheet.UsedRange;
|
||||
if (usedRange != null && usedRange.Cells.Count > 1)
|
||||
{
|
||||
usedRange.Clear();
|
||||
}
|
||||
|
||||
return userSheet;
|
||||
}
|
||||
|
||||
private static Worksheet CreateSheetIfNotExisted(Microsoft.Office.Interop.Excel.Application app, string sheetName)
|
||||
{
|
||||
Worksheet userSheet = null;
|
||||
foreach (Worksheet item in app.Worksheets)
|
||||
{
|
||||
if (item.Name == sheetName)
|
||||
{
|
||||
userSheet = item;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if (userSheet == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 新建工作表并命名
|
||||
@ -143,19 +416,7 @@ namespace KellyReport_D.Utils
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 已存在则获取
|
||||
userSheet = app.Worksheets[sheetName] as Worksheet;
|
||||
try
|
||||
{
|
||||
Range usedRange = userSheet.UsedRange;
|
||||
if (usedRange != null && usedRange.Cells.Count > 1)
|
||||
{
|
||||
usedRange.Clear();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 无 UsedRange 可忽略
|
||||
throw new FormatException("创建或获取用户工作表失败,请检查是否存在同名工作表。");
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,7 +437,7 @@ namespace KellyReport_D.Utils
|
||||
{
|
||||
SalesDetail item = new SalesDetail
|
||||
{
|
||||
SalesName = rawSalesDetailData[i, 1]?.ToString() ?? "",
|
||||
SalesName = rawSalesDetailData[i, 1]?.ToString() ?? "UNKNOWN",
|
||||
Month = rawSalesDetailData[i, 2]?.ToString() ?? "",
|
||||
InvoiceDate = rawSalesDetailData[i, 3] is double invoiceDate ? DateTime.FromOADate(invoiceDate) : (DateTime?)null,
|
||||
OrderNumber = rawSalesDetailData[i, 4]?.ToString() ?? "",
|
||||
@ -233,9 +494,9 @@ namespace KellyReport_D.Utils
|
||||
try
|
||||
{
|
||||
// 获取「銷售年度預估」工作表
|
||||
readSalesForecastData(context);
|
||||
ReadSalesForecastData(context);
|
||||
// 获取「產品年度預估」工作表
|
||||
readProductForecastData(context);
|
||||
ReadProductForecastData(context);
|
||||
|
||||
GenBussenessSheet(context);
|
||||
}
|
||||
@ -361,7 +622,7 @@ namespace KellyReport_D.Utils
|
||||
}
|
||||
|
||||
|
||||
private static void readClientContact(ImportContext context)
|
||||
private static void ReadClientContact(ImportContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
|
||||
@ -396,7 +657,7 @@ namespace KellyReport_D.Utils
|
||||
context.ClientContactList = clientContactList;
|
||||
}
|
||||
|
||||
private static void readProductForecastData(GenForecaseContext context)
|
||||
private static void ReadProductForecastData(GenForecaseContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
|
||||
@ -434,7 +695,7 @@ namespace KellyReport_D.Utils
|
||||
context.ProductForecastList = productForecastList;
|
||||
}
|
||||
|
||||
private static void readSalesForecastData(GenForecaseContext context)
|
||||
private static void ReadSalesForecastData(GenForecaseContext context)
|
||||
{
|
||||
var app = context.Application;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user