Sum up columns in MVC C# Razor View - c#

I am wondering if I can sum up decimal in all the columns that are dynamically generated in razor view without having to change this in controller and viewModel. I will be happy to try jQuery option as well.
ViewModel
public class LedgerViewModel
{
public LedgerViewModel(int PayCategoryCount)
{
PayCollection = new List<decimal>(new decimal[PayCategoryCount]);
}
public DateTime PDate { get; set; }
public class MonthlyPaymentsVM
{ public int PayCategoryId { get; set; }
[DisplayFormat(DataFormatString = "{0:MMMM yyyy}")]
public DateTime Date { get; set; }
public IEnumerable<string> PaymentCategories { get; set; }
public List<LedgerViewModel> Payments { get; set; }
public List<LedgerViewModel> Member { get; set; }
}
controller
public ActionResult Report(int year, int no, string nom, Guid gcode)
{
DateTime startdate = (new DateTime(DateTime.Now.Year - 1, 7, 1));
DateTime enddate = (new DateTime(DateTime.Now.Year, 7, 1));
DateTime date = DateTime.Now;
//get all payments
var a = from of in db.OfflinePayMents.Include(i => i.Customer).Include(i => i.PaymentCategory).ToList().Where(x => x.PDate >= startdate && x.PDate < enddate && x.POK && x.CustomerGuid=gcode) select new { of.Customer, of.PaymentCategory, of.CustomerID, of.PaymentCategoryID, of.PDate, of.TxnId, of.Pay, of.PType };
var grouped = a.GroupBy(x => new { customer = x.CustomerID, PaymentCategory = x.PaymentCategory.PaymentCategoryID, txn = x.TxnId, pd = x.PDate, x.PType }).Select(x => new
{
Name = x.First().Customer.Name,
Customer = x.First().Customer,
PaymentCategory = x.First().PaymentCategory,
Txn = x.First().TxnId,
Pd = x.First().PDate,
PType = x.First().PType,
cid = x.First().PaymentCategoryID,
Pay= x.Sum(y => y.Pay)
});
var data = grouped.GroupBy(x => x.Txn);
var PaymentCategories = db.PaymentCategories.OrderBy(z => z.Order);
var PayCategoryCount = PaymentCategories.Count();
var PaymentCategoryIDs = PaymentCategories.Select(x => x.PaymentCategoryID).ToList();
var model = new MonthlyPaymentsVM()
{
//Member = members,
Date = date,
PaymentCategories = PaymentCategories.Select(z => z.PaymentCategoryTitle),
Payments = new List<LedgerViewModel>()
};
foreach (var group in data)
{
LedgerViewModel payment = new LedgerViewModel(PaymentCategoryCount);
var pd = group.First().Pd;
payment.PDate = pd;
foreach (var item in group)
{
int index = PaymentCategoryIDs.IndexOf(item.PaymentCategory.PaymentCategoryID);
if (index < 0)
{
payment.PayCollection[index + 1] = item.Pay;
}
else
{
payment.PayCollection[index] = item.Pay;
}
payment.Total += item.Pay;
}
model.Payments.Add(payment);
}
return View(model);
}
Razor View
<table class="doubleborder" width="99%" border="0" align="center" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Date</th>
#foreach (var payname in Model.PaymentCategories)
{
<th>#payname</th>
}
</tr>
</thead>
<tbody>
#foreach (var item in Model.Payments)
{
<tr>
<td>#item.PayDate.ToString("dd/MM/yyyy")</td>
#foreach (var amount in item.PayCollection)
{
<td>#amount.ToString("c")</td>
}
</tr>
}
<tr class="doubleborder">
<td>Total:</td>
#foreach (var item in Model.PaymentCategories)
{
<td>
looking at getting sum totals of each column here
</td>
}
</tr>
</tbody>
</table>
So this groups by customer. The payments are grouped by transaction Date and are iterated in the foreach loop in the view.
Thanks if you are able to help.

If I understand your model correctly, this is what you are looking for:
#Model.Payments.Sum(i => i.Paycollection.Sum(x => x.amount));
Update, based on your comment: (and assuming that all the columns have value for all the PaymentCollections)
#for(int i = 0 ; i < PaymentCategories.Count(); i++)
{
<td>
Model.Payments.Sum(x => x.PayCollection[i]); //this will throw an exception if the value at index is not defined
</td>
}

Related

Display Field Name in a View Using Linq

I want to display the property name of a field in a view(report).
The Model:
public class Report
{
[Display(Name ="Total Attendance")]
public int Attendance { get; set; }
[Display(Name = "Total Offering")]
[DataType(DataType.Currency)]
public double Amount { get; set; }
[Display(Name = "District Name")]
public int LocationId { get; set; }
[ForeignKey("LocationId")]
public Location Location { get; set; }
[Display(Name = "Weekly Service")]
public int WeeklyServiceId { get; set; }
[ForeignKey("WeeklyServiceId")]
[Display(Name = "Weekly Service")]
public WeeklyService WeeklyService { get; set; }
public DateTime? Sdate { get; set; }
public DateTime? Edate { get; set; }
public string UsherName { get; set; }
public string LocationName { get; set; }
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Report(Report model)
{
var startDate = model.Sdate;
var endDate = model.Edate;
var QueryResult = (from pay in _context.PaymentRecords.Include(p=>p.Location).Include(p=>p.WeeklyService)
//join a in _context.Locations on pay.LocationId equals a.Id
//join c in _context.WeeklyServices on pay.WeeklyServiceId equals c.Id
where (pay.DepositDate.Date >= startDate)
where (pay.DepositDate.Date <= endDate)
group pay by new { pay.LocationId,pay.WeeklyServiceId} into g
orderby g.Key.LocationId
select new Report
{
LocationId= g.Key.LocationId,
Attendance = g.Sum(x => x.Attendance),
Amount = g.Sum(x => x.Amount),
WeeklyServiceId =g.Key.WeeklyServiceId
});
return View("Report", QueryResult);
}
The View/Report
<table class="table table-striped table-bordered" id="myTable">
<thead class="thead-dark">
<tr>
<th>SN</th>
<th>#Html.DisplayNameFor(model => model.Location)</th>
<th>#Html.DisplayNameFor(model => model.Attendance)</th>
<th>#Html.DisplayNameFor(model => model.Amount)</th>
<th>#Html.DisplayNameFor(model => model.WeeklyService)</th>
</tr>
</thead>
<tbody>
#if (Model.Count() > 0)
{
int c = 0;
foreach (var item in Model)
{
c++;
<tr>
<td>#c</td>
<td>#Html.DisplayFor(modelItem => item.Location.Name)</td>
<td>#Html.DisplayFor(modelItem=>item.Attendance)</td>
<td>#item.Amount.ToString("C")</td>
<td>#Html.DisplayFor(modelItem=>item.WeeklyService.Name)</td>
</tr>
}
}
else
{
}
</tbody>
</table>
Result of the Above
Note that Location is a model which has Name as a property as well as WeeklyService. But if i change the table data to LocationId and WeeklyServiceId, it will display the results with the Id. But I want it to display the Name of the Location and WeeklyService instead of their Ids.
Here is an exmaple of what we mean in the comments.
You do not Initialize correctly the Report object.
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Report(Report model)
{
var startDate = model.Sdate;
var endDate = model.Edate;
var QueryResult = (from pay in _context.PaymentRecords.Include(p=>p.Location).Include(p=>p.WeeklyService).ToList()
//join a in _context.Locations on pay.LocationId equals a.Id
//join c in _context.WeeklyServices on pay.WeeklyServiceId equals c.Id
where (pay.DepositDate.Date >= startDate)
where (pay.DepositDate.Date <= endDate)
group pay by new { pay.LocationId,pay.WeeklyServiceId} into g
orderby g.Key.LocationId
select new Report
{
LocationId= g.Key.LocationId,
Attendance = g.Sum(x => x.Attendance),
Amount = g.Sum(x => x.Amount),
WeeklyServiceId =g.Key.WeeklyServiceId
Location = g.Select(pp => pp.Location).First() // This is what you are missing
WeeklyService = g.Select(pp => pp.WeeklyService ).First()// Also this
});
return View("Report", QueryResult);
}
The Location and WeeklyService is null. They are never initialized.
I am surprised you do not get a Null Ref Exception. You never mentioned one.
I am saying this because of the (item => item.Location.Name) in your View.
Hope this helps.
Note careful with client side evaluation and EF core 3 https://github.com/dotnet/efcore/issues/17878 , https://github.com/dotnet/efcore/issues/17068
Also taken from the docs: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#linq-queries-are-no-longer-evaluated-on-the-client

Convert day of month to weekday format for table in LINQ

for part of my program I need to read given values in the past week, group them by weekday and then display them in a table in MVC. I have managed to display a long list of numerical days (showing repeats) with their matching data but I need the format to be from monday-sunday which means it would have to combine values that occur on the same day.
My controller:
public ActionResult Index(string TimeState)
{
DateTime currentDate = DateTime.Now;
DateTime today = DateTime.Today;
DateTime week = DateTime.Today.AddDays(-7);
string userID = User.Identity.GetUserId();
string email = (from x in db.Users where x.Id == userID select x.Email).FirstOrDefault();
IEnumerable<ValuesList> valuesList = from x in db.UsageDatas
where week <= x.Time && x.Time <= today && x.UserEmail == email
select new ValuesList
{
Dates = x.Time.Day.ToString(),
Values = x.Delta ,
};
State state = new State
{
state = TimeState,
valuesLists = valueList,
selectedDate = "0"
};
return View(state);
}
View:
<div class="Table Heading"><h3>Recent Water Usage</h3></div>
#{
}
<table class="greyGridTable">
<thead>
<tr>
<th>Date</th>
<th>Value</th>
</tr>
</thead>
#foreach (var item in Model.valuesLists)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Dates)
</td>
<td>
#Html.DisplayFor(modelItem => item.Values)
</td>
</tr>
}
</table>
</div>
Model:
public class State
{
public string state { get; set; }
public IEnumerable<ValuesList> valuesLists { get;set;}
public string TimeState { get; set; }
public string selectedDate { get; set; }
}
public class ValuesList
{
public string Dates { get; set; }
public string Values { get; set; }
}
what the current table looks like:
note: its showing the current month day*
My LINQ is pretty limited so any insight would be highly appreciated.
here is the new error
You want to adding today's data?
If yes.
DateTime today = DateTime.Today;
DateTime tomorrow = today.AddDays(1);
DateTime week = today.AddDays(-7); // or -6 think about it
string userID = User.Identity.GetUserId();
string email = (from x in db.Users where x.Id == userID select x.Email).FirstOrDefault();
var valuesList = db.UsageDatas
.Where(x => x.Time >= week && x.Time < tomorrow && x.UserEmail == email)
//.AsEnumerable() //posible need it for execute sql before take DayOfWeek
.GroupBy(x => x.Time.DayOfWeek)
.Select(x => new
{
DayOfWeek = x.Key,
Values = x.Select(m => m.Delta).Aggregate((a, b) => a + "," + b)
})
.OrderBy(m => m.DayOfWeek)
.Select(x => new ValuesList
{
Dates = x.DayOfWeek.ToString(),
Values = x.Values
});
Group by DayOfWeek and aggregate Delta as you want
For sum of Deltas: (but it's crutch)
Values = x.Select(x =>
{
int.TryParse(x, out var value);
return value;
})
.Sum()

looping through dictionary inside dictionary in jquery

I'm trying to set values to table containing textboxes in each cell. For instance a table having a first column containing names, and rest of the columns containing textboxes to add marks of the given assignment for individual students. For that I used dictionary to hold given marks by the instructor and when the page is load, the marks are set to the relevant textboxes. however my iteration over Dictionary in jquery doesn't seem to be really working. I'm missing somewhere in loop. Below is my code.
public class StudentAssignments
{
public string Id { get; set; }
public Models.Assignment assignment { get; set; }
public Models.User user { get; set; }
public DateTime? SubmissionDate { get; set; }
public string Result { get; set; }
public Models.File assignmentfiles {get;set;}
}
public class Assignment
{
public string Id { get; set; }
public string batchid { get; set; }
public List<SelectListItem> batchnumber { get; set; }
public string Title { get; set; }
public string Description { get; set; }
[DataType(DataType.Date)]
public DateTime? DueDate { get; set; }
public Models.File file { get; set; }
}
public class File
{
public string strId { get; set; }
public string strName { get; set; }
public string strPath { get; set; }
public string strSize { get; set; }
}
InstructorController.cs
[HttpPost]
public ActionResult AssignedStudents(string id)
{
//Get Student Assignments
Models.StudentAssignments studentAssignment = new Models.StudentAssignments();
Context.Assignment contAssignment = new Context.Assignment();
CreateUser contUser = new CreateUser();
Dictionary<string, Dictionary<string, List<Models.StudentAssignments>>> dict =
new Dictionary<string, Dictionary<string, List<Models.StudentAssignments>>>();
var studentslist = contStudent.getAllStudentBatchList().Where(p => p.batchId == id).Select(p => p.studentId).ToList();
var assignmentid = contAssignment.lstAssignment().Where(p => p.batchid == id).Select(p=>p.Id).ToList();
foreach(var items in studentslist)
{
dict.Add(items.ToString(), new Dictionary<string, List<Models.StudentAssignments>>());
foreach (var item1 in assignmentid)
{
dict[items].Add(item1.ToString(), GetStudentFiles(items, item1));
}
}
ViewBag.StudentAssignment = dict;
}
private List<Models.StudentAssignments> GetStudentFiles(string stdid, string assgnid)
{
Context.Assignment contAssignment = new Context.Assignment();
CreateUser contuser = new CreateUser();
List<Models.StudentAssignments> lstassgn = new List<Models.StudentAssignments>();
var details = (from t1 in contAssignment.GetStudentAssignments()
join
t2 in contAssignment.GetStudentAssignmentsFiles() on
t1.Id equals t2.assignment.Id
join t3 in contuser.GetAllUsers() on t1.user.Id equals t3.Id
where t1.assignment.Id == assgnid && t1.user.Id == stdid
select new { t1,t2,t3 }).ToList();
foreach (var item in details)
{
Models.StudentAssignments assignment = new Models.StudentAssignments();
assignment.assignment = new Models.Assignment();
assignment.Id = item.t1.Id;
assignment.Result = item.t1.Result;
assignment.assignmentfiles = new Models.File();
assignment.assignmentfiles.strId = item.t2.Id;
assignment.assignmentfiles.strPath = item.t2.assignmentfiles.strPath;
assignment.user = new Models.User();
assignment.user.Id = item.t3.Id;
assignment.user.FirstName = item.t3.FirstName;
assignment.user.LastName = item.t3.LastName;
lstassgn.Add(assignment);
}
return lstassgn;
}
AssignedStudents.cshtml
<div class="col-md-12">
<h2>Submitted Assignments</h2>
<table class="table table-bordered table-responsive table-hover" id="tbl">
<tr>
<th>
Name
</th>
<th>
Assignment 1
</th>
</tr>
#foreach (var item in ViewBag.StudentAssignment)
{
bool flag = true;
<tr class="item">
#foreach (var item1 in item.Value)
{
foreach (var item2 in item1.Value)
{
if (flag == true)
{
<td>
#item2.user.FirstName
</td>
flag = false;
}
break;
}
<td>
#foreach (var item2 in item1.Value)
{
<img src="#" />
}
#foreach (var item2 in item1.Value)
{
if (item2.Result != null && item2.Result != "Pending")
{
<div><input type="text" value="#item2.Result" class="txtbox" id=#Guid.NewGuid().ToString() disabled="disabled"/></div>
}
else
{
<div><input type="text" class="txtbox" id=#Guid.NewGuid().ToString() /></div>
}
<input type="hidden" id="stdassgnid" value="#item2.Id" />
break;
}
</td>
}
</tr>
}
</table>
<input type="button" id="saveResult" value="Save Result" class="btn btn-success" />
</div>
Edited:-
Since I've managed to pass the results in the required textboxes. I'm here surrounded by another issue which is the next assignment submission. The first column contains the submitted marks already, and this time instructor would carry out the marking of the next assignment. Therefore, The system would look for the next column as the previous column already contains marks.
$("#saveResult").click(function () {
$("#tbl tr.item").each(function () {
$(this).find("input.txtbox").attr("disabled", "disabled");
var Mkrs = $(this).find("input.txtbox").val();
var Id = $(this).find("#stdassgnid").val();
alert(Mkrs)
$.ajax({
type: "POST",
url: '#Url.Action("UpdateResult", "Assignment")',
data: { Marks: Mkrs, studentAssgnId: Id},
dataType: "json",
success: function (data) {
if(data.message!=null)
{
alert(data.message)
}
}
})
});

Html table not populating from ViewModel

I am trying to populate an HTML table with data from a table in my database. The issue is simply that the HTML table is not getting populated with any data.
Here is the ViewModel:
public class TestViewModel
{
public string MatchedId { get; set; }
public string UnmatchedId { get; set; }
public string Auth { get; set; }
public DateTime CreditDate { get; set; }
public string CreditNumber { get; set; }
public decimal CreditAmount { get; set; }
public DateTime DeniedDate { get; set; }
public int DeniedReasonId { get; set; }
public string DeniedNotes { get; set; }
}
Controller Action:
[HttpPost]
public ActionResult UploadValidationTable(HttpPostedFileBase csvFile)
{
var inputFileDescription = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true
};
var cc = new CsvContext();
var filePath = uploadFile(csvFile.InputStream);
var model = cc.Read<Credit>(filePath, inputFileDescription);
try
{
var entity = new Entities();
//model here is the .csv, doesn't have anything to do with this issue
foreach (var item in model)
{
var tc = new TemporaryCsvUpload
{
Id = item.Id,
CreditAmount = item.CreditAmount,
CreditDate = item.CreditDate,
CreditNumber = item.CreditNumber,
DeniedDate = item.DeniedDate,
DeniedReasonId = item.DeniedReasonId,
DeniedNotes = item.DeniedNotes
};
entity.TemporaryCsvUploads.Add(tc);
}
entity.SaveChanges();
System.IO.File.Delete(filePath);
//This is where the database table is getting filled
entity.Database.ExecuteSqlCommand("Insert into CsvReport Select p.Id as MatchedId, case when p.Id is null then t.Id end as UnmatchedId, p.Auth,p.CreditDate, p.CreditNumber,p.CreditAmount, p.DeniedDate,p.DeniedReasonId, p.DeniedNotes from TemporaryCsvUpload t left join PermanentTable p on p.Id = t.Id;");
TempData["Success"] = "Updated Successfully";
}
catch (LINQtoCSVException)
{
TempData["Error"] = "Upload Error: Ensure you have the correct header fields and that the file is of .csv format.";
}
return View("Upload");
}
View:
#model IEnumerable<TestProject.TestViewModel>
#if (Model != null)
{
foreach (var item in Model.Where(x => x.IdMatched != null))
{
<tr>
<td>
#item.MatchedId
</td>
<td>
#item.Auth
</td>
<td>
#item.CreditDate
</td>
<td>
#item.CreditNumber
</td>
<td>
#item.CreditAmount
</td>
<td>
#item.DeniedDate
</td>
<td>
#item.DeniedReasonId
</td>
<td>
#item.DeniedNotes
</td>
</tr>
}
}
It's a little weird because I am populating the database with an SQL command. What am I missing here? Do I need to try and pass it through the controller action? Let me know if you need more information. Thanks!
Edit
I tried to pass the instance through, but I may still be doing it incorrectly:
var testModel = new TestViewModel();
return View("Upload", testModel);
Here is what its padding through:
public class TestViewModel
{
public IEnumerable<Test> Test { get; set; }
}
Made an answer so essentially the view doesn't know what to render you need to pass an actual filled model (in your case an IEnumerable to the view). This can be done using the method:
View("Upload", viewModelList);
Controller.View docs on MSDN
It looks like you are not adding any data to your view model.
If your view model is a collection of Test objects, you need to add some
Test objects to the collection.
var model = new TestViewModel()
{
Test = new List<Test>() { new Test(), new Test(), ... }
}
return View("Upload", model);

grouping and displaying models in a view

I am having trouble with grouping a list, and then building a model that represents that list and displaying the results in a table within a view. For example:
List of items ordered
Date
CustomerId
Location
Item
Price
Quantity
How would I correctly model and display that list in a table if I wanted to group the list by location? And what if I wanted to group the list by two properties, for example, Location and CustomerId?
Here is my model:
public class ViewInvoice
{
public string ClientLocation { get; set; }
public List<DetailsGroup> Details { get; set; }
public class DetailsGroup
{
public List<string> Product { get; set; }
public List<string> ProductSize { get; set; }
public List<string> PackageType { get; set; }
public List<DateTime> OrderDate { get; set; }
public List<DateTime> DeliveryDate { get; set; }
public List<int> OrderNumber { get; set; }
public List<decimal> Price { get; set; }
public List<int> ItemQuantity { get; set; }
}
}
I am trying to display this model in a table within my razor view. Here is that code:
#using MyModel.MyTools.Orders.SumOrder
#model SumOrder
#{
ViewBag.Title = "View Invoice";
}
<h2>View Invoice</h2>
<table>
#foreach(var prod in Model.OCI)
{
<tr>
<td>
#prod.ClientLocation
</td>
</tr>
foreach (var orderItem in prod.Details)
{
<tr>
<td>
#orderItem.Product
</td>
<td>
#orderItem.ItemQuantity
</td>
</tr>
}
}
</table>
The first row in the table displays correctly, which is the name of a city, but in the next row I get this:
System.Collections.Generic.List1[System.String] System.Collections.Generic.List1[System.Int32]
Can someone explain to me why I can not get the list returned in a readable format, and how to correct this problem?
Here is the code I used to group the list for the ViewInvoice model:
public SumOrder(List<orders_Cart> order)
{
// create list of order cart item
List<OrderCartItems> cartItems = new List<OrderCartItems>();
// convert orders to ocm
foreach(var item in order)
{
var newCartItem = new OrderCartItems();
try
{
newCartItem.Product = db.product_Product.FirstOrDefault(p =>
p.Id == item.ProductId).ProductDescription ?? "none";
}
catch (Exception)
{
newCartItem.Product = "none";
}
try
{
newCartItem.ClientForProduct = MyTool.OrdersFindClientLocation(
(int) item.ClientForOrdersId);
}
catch (Exception)
{
newCartItem.ClientForProduct = new object[3];
}
try
{
newCartItem.ProductSize = db.products_Size.FirstOrDefault(p => p.Id ==
item.ProductSizeId).ProductSizeCode ?? "none";
}
catch (Exception)
{
newCartItem.ProductSize = "none";
}
try
{
newCartItem.PackageType = db.packaging_PackageType.FirstOrDefault(p =>
p.Id == item.PackageTypeId).PackageTypeCode ?? "none";
}
catch (Exception)
{
newCartItem.PackageType = "none";
}
newCartItem.OrderDate = (DateTime) item.OrderDate;
newCartItem.DeliveryDate = (DateTime) item.DeliveryDate;
newCartItem.OrderNumber = (int) item.OrderNumber;
newCartItem.Price = (decimal) item.Price;
newCartItem.ClientLocation = MyTool.OrdersFindClientLocation(
(int) item.ClientForOrdersId, null);
newCartItem.ItemQuantity = (int) item.Quantity;
cartItems.Add(newCartItem);
}
// group the cartItems according to location
List<ViewInvoice> ordersGrouped = cartItems.GroupBy(c => new
{c.ClientLocation})
.OrderBy(c => c.Key.ClientLocation).Select(s =>
new ViewInvoice()
{
ClientLocation = s.Key.ClientLocation,
Details = new List<ViewInvoice.DetailsGroup>()
{
new ViewInvoice.DetailsGroup()
{
Product = s.Select(p => p.Product).ToList(),
ItemQuantity = s.Select(p => p.ItemQuantity).ToList(),
DeliveryDate = s.Select(p => p.DeliveryDate).ToList(),
OrderDate = s.Select(p => p.OrderDate).ToList(),
OrderNumber = s.Select(p => p.OrderNumber).ToList(),
PackageType = s.Select(p => p.PackageType).ToList(),
Price = s.Select(p => p.Price).ToList(),
ProductSize = s.Select(p => p.ProductSize).ToList()
}
}
}).ToList();
// set the OCI property
OCI = ordersGrouped;
};
Ok, I finally solved my problem. I initially over-thought the problem. I simplified my model, and added some simple logic to my view.
Here is the updated Model:
public class ViewInvoice
{
public string ClientLocation { get; set; }
public List<string> Product { get; set; }
public List<string> ProductSize { get; set; }
public List<string> PackageType { get; set; }
public List<DateTime> OrderDate { get; set; }
public List<DateTime> DeliveryDate { get; set; }
public List<int> OrderNumber { get; set; }
public List<decimal> Price { get; set; }
public List<int> ItemQuantity { get; set; }
}
the updated code used to group the list for the Model:
// group the cartItems according to location
List<ViewInvoice> ordersGrouped = cartItems.GroupBy(c => new
{c.ClientLocation})
.OrderBy(c => c.Key.ClientLocation).Select(s =>
new ViewInvoice()
{
ClientLocation = s.Key.ClientLocation,
Product = s.Select(p => p.Product).ToList(),
ItemQuantity = s.Select(p => p.ItemQuantity).ToList(),
DeliveryDate = s.Select(p => p.DeliveryDate).ToList(),
OrderDate = s.Select(p => p.OrderDate).ToList(),
OrderNumber = s.Select(p => p.OrderNumber).ToList(),
PackageType = s.Select(p => p.PackageType).ToList(),
Price = s.Select(p => p.Price).ToList(),
ProductSize = s.Select(p => p.ProductSize).ToList()
}).ToList();
and the updated view:
#using MyModel.MyTools.Orders.SumOrder
#model SumOrder
#{
ViewBag.Title = "View Invoice";
}
<h2>View Invoice</h2>
#{
int i = 0;
}
<table>
#foreach(var mod in Model.OCI)
{
var modCount = #mod.Product.Count();
<tr>
<th>#mod.ClientLocation</th>
</tr>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
foreach (var items in mod.Product)
{
<tr>
<td>
#mod.Product.ElementAtOrDefault(i)
</td>
<td>
#mod.Price.ElementAtOrDefault(i)
</td>
</tr>
i++;
}
}
</table>
This solution clearly allows me to iterate through the model reproducing any required rows or cells along the way. Played Russian roulette for two days over this problem. Hope this saves some others some time.

Categories

Resources