Click here to Skip to main content
14,836,532 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am very new to programming in general and am seeking some guidance on how to achive what I need to.

I need to import an Excel file (Already doing so using DocumentFormat.OpenXml) and use the data in the Excel file to create an order header and detail JSON payload for our ERP. The ERP accepts the JSON data via Web API.

The Payload needs to look like this:

JavaScript
{
  "CustomerNumber": "1400",
  "OrderDescription": "Order Entry",
  "OrderDate": "2020-01-15",
  "InvoiceWillBeProduced": true,
  "InvoiceNumber" : "IN123456",
  "OrderDetails": [
    {
      "LineType": "Item",
      "Item": "A1-105/0",
      "Location": "1",
      "QuantityOrdered": 20,
      "QuantityShipped": 20,
      "UnitPrice": 100.50,
      "DiscountAmt": 10.05
    },
    {
      "LineType": "Item",
      "Item": "A1-103/0",
      "Location": "1",
      "QuantityOrdered": 10,
      "QuantityShipped": 10,
      "UnitPrice": 50.50,
      "DiscountAmt": 5.05
    }
  ]
}


The biggest concern is the OrderDetails section where I would need multiple items to be attached to one Order Header.

The Excel file contains columns InvoiceNumber,Customer,Date,ItemCode,QuantityOrdered,Price,Discount

Each customer might have multiple records, but the one unique value per order is the Invoice Number. Therefor I was considering somehow grouping the data by invoice number and add the details in. However, I have never done this before and need some guidance, please.

Thank you in advance.

What I have tried:

So far I have tried dumping the Excel data into a DataTable and iterating over it with a foreach loop. This works great if there is only one order detail item, but not when there are multiple order detail items
Posted
Updated 2-Feb-21 17:20pm
Comments
CHill60 2-Feb-21 8:54am
   
Perhaps if you share the code we can help you overcome the problem
DoubleD1982 2-Feb-21 23:49pm
   
Here is the code that I currently have.
DataTable dtExcel = new DataTable();            using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(fname, false))            {                WorkbookPart ekPart = sDoc.WorkbookPart;                IEnumerable<Sheet> sheets = sDoc.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();                string relationshipId = sheets.First().Id.Value;                WorksheetPart wksPart = (WorksheetPart)sDoc.WorkbookPart.GetPartById(relationshipId);                Worksheet wkSheet = wksPart.Worksheet;                SheetData sheetData = wkSheet.GetFirstChild<SheetData>();                IEnumerable<Row> rows = sheetData.Descendants<Row>();                foreach (Cell cell in rows.ElementAt(0))                {                    dtExcel.Columns.Add(GetCellValue(sDoc, cell));                }                foreach(Row row in rows)                {                    DataRow tempRow = dtExcel.NewRow();                    for (int i = 0; i < row.Descendants<Cell>().Count(); i++)                    {                        tempRow[i] = GetCellValue(sDoc, row.Descendants<Cell>().ElementAt(i));                    }                    dtExcel.Rows.Add(tempRow);                }            }            foreach (DataRow orderItems in dtExcel.Rows)            {                                var detail = new                {                    Item = orderItems[4].ToString(),                    QuantityOrdered = Convert.ToInt32(orderItems[5]),                    QuantityShipped = Convert.ToInt32(orderItems[5]),                    PricingUnitPrice = Convert.ToDouble(orderItems[6]),                    OrderDiscountAmount = Convert.ToDouble(orderItems[8])                };                var order = new                {                    CustomerNumber = orderItems["CUSTOMER"].ToString(),                    DefaultLocationCode = orderItems["LOCATION"].ToString(),                    InvoiceWillBeProduced = true,                    OrderDate = "26-01-2021",                    ShipmentNumber = orderItems["INNUMBER"].ToString(),                    InvoiceNumber = orderItems["INNUMBER"].ToString(),                    ShipmentDate = "26-01-2021",                    InvoiceDate = "26-01-2021",                    OrderDetails = new[]  { detail }                };

1 solution

You're implying the "invoice" portion is repeated / duplicated when there are multiple details.

Therefore, keep adding details to your "OrderDetails" WHILE the invoice number is the same as the previous detail (as you read).

Once the Invoice # changes, create a new "payload".

This assumes all your Excel data rows are at least sorted by Invoice #.
   
Comments
DoubleD1982 2-Feb-21 23:55pm
   
Thanks Gerry. I think I might know what you're getting at and it makes sense. Can you please help me make further sense of it with a code sample? The Excel sheet is sorted by invoice number. Here is what my code currently looks like:
DataTable dtExcel = new DataTable();
using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(fname, false))
{
	WorkbookPart ekPart = sDoc.WorkbookPart;
	IEnumerable<Sheet> sheets = sDoc.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
	string relationshipId = sheets.First().Id.Value;
	WorksheetPart wksPart = (WorksheetPart)sDoc.WorkbookPart.GetPartById(relationshipId);
	Worksheet wkSheet = wksPart.Worksheet;
	SheetData sheetData = wkSheet.GetFirstChild<SheetData>();
	IEnumerable<Row> rows = sheetData.Descendants<Row>();
	foreach (Cell cell in rows.ElementAt(0))                
	{
		dtExcel.Columns.Add(GetCellValue(sDoc, cell));
	}
    foreach(Row row in rows)                
	{
		DataRow tempRow = dtExcel.NewRow();
		for (int i = 0; i < row.Descendants<Cell>().Count(); i++)                    
		{
			tempRow[i] = GetCellValue(sDoc, row.Descendants<Cell>().ElementAt(i));
		}
		dtExcel.Rows.Add(tempRow);
	}
}
foreach (DataRow orderItems in dtExcel.Rows)            
{
	var detail = new{
		Item = orderItems[4].ToString(),
		QuantityOrdered = Convert.ToInt32(orderItems[5]),
		QuantityShipped = Convert.ToInt32(orderItems[5]),
		PricingUnitPrice = Convert.ToDouble(orderItems[6]),
		OrderDiscountAmount = Convert.ToDouble(orderItems[8]) };
                
	var order = new{
        CustomerNumber = orderItems["CUSTOMER"].ToString(),
		DefaultLocationCode = orderItems["LOCATION"].ToString(),
		InvoiceWillBeProduced = true,
		OrderDate = "26-01-2021",
		ShipmentNumber = orderItems["INNUMBER"].ToString(),
		InvoiceNumber = orderItems["INNUMBER"].ToString(),
		ShipmentDate = "26-01-2021",
		InvoiceDate = "26-01-2021",
		OrderDetails = new[]  { detail } };
CHill60 3-Feb-21 4:29am
   
I've tidied up your code so that it is readable
CHill60 3-Feb-21 4:50am
   
I can't give a code sample at the moment, but the logic Gerry is describing is
1. Capture the Invoice Number in Row 1
2. Create an "Invoice" object
3. Loop through all rows in the dataset or excel worksheet
4. If the invoice number of the current row is NOT the same as captured number
5.       "close" current invoice
6.       Capture new invoice number
7.       Create new invoice object
8. Add current row as "detail" to current invoice
9. Next row
DoubleD1982 3-Feb-21 6:03am
   
Thanks for this. I will try and figure it out. If you can, please will you provide a code example?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900