How to save the record mutipule table using Asp.net MVC Json - asp.net-mvc

i am creating simple sales system for my final year project. i am creating a sales Form. attached the screen shot image below how the form look like.
after sales completed i need to save the data into multiple table along with the lastinsert id. if i click print invoice button. i have a tables in the database sales,sales product i shown the shot shotimage below.i don't how to save records into multipule table with lastinsert id.
enter image description here
Sales Table
id date subtotal
Sales_Product Table
id sales_id product_id price qty total
Code which i tried
jQuery
function addProject() {
var table_data = [];
$('#product_list tbody tr').each(function (row, tr) {
var sub = {
//these records i am going to add into sales table
'barcode': $(tr).find('td:eq(1)').text(),
'pname': $(tr).find('td:eq(2)').text(),
'pro_price': $(tr).find('td:eq(3)').text(),
'qty': $(tr).find('td:eq(4)').text(),
'total_cost': $(tr).find('td:eq(5)').text(),
};
table_data.push(sub);
});
//these records i am going to add into sales
var total = $("#total").val();
$.ajax({
type: 'POST',
url: '/product/Save',
dataType: 'JSON',
data: {
total: $('#total').val(), data: table_data
},
success: function (data) {
console.log(_data);
var msg;
if (isNew) {
msg = "Sales Completed";
}
last_id = data.last_id
window.location.href = "print.php?last_id=" + last_id;
$.alert({
title: 'Success!',
content: msg,
type: 'green',
boxWidth: '400px',
theme: 'light',
useBootstrap: false,
autoClose: 'ok|2000'
});
isNew = true;
},
error: function (xhr, status, error) {
alert(xhr);
}
});
}
Controller
[HttpPost]
public ActionResult Save(sale s)
{
bool status = false;
if (ModelState.IsValid)
{
using (saleEntities3 dc = new saleEntities3())
{
//Sales table
var v = dc.sales.Where(a => a.id == s.id).FirstOrDefault();
dc.sales.Add(v);
dc.SaveChanges();
v.id = s.id; // lastinsertid
//how to add into lastinsertid as a sales product table as a sales_id colum
//Sales product table i don't how to add
status = true;
}
}
return new JsonResult { Data = new { status = status } };
}
saleEntities3
public partial class saleEntities3 : DbContext
{
public saleEntities3()
: base("name=saleEntities3")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<product> products { get; set; }
public virtual DbSet<sale> sales { get; set; }
public virtual DbSet<sales_product> sales_product { get; set; }
}
}

To save in the Sales_Product table you need to save with the id of the saved sales according to your table structure
[HttpPost]
public ActionResult Save(sale s)
{
bool status = false;
if (ModelState.IsValid)
{
using (saleEntities3 dc = new saleEntities3())
{
//Sales table
var v = dc.sales.Where(a => a.id == s.id).FirstOrDefault();
dc.sales.Add(v);
dc.SaveChanges();
dc.sales_product.Add(new sales_product{
sales_id = s.id,
product_id = s.barcode, //I believe this is the product id
price = s.pro_price,
quantity = s.qty,
total = s.total_cost
});
dc.SaveChanges();
status = true;
}
}
return new JsonResult { Data = new { status = status } };
}

Related

How to post json object with multiple values to the Controller from Ajax

I have this Ajax post working for a single value but I need it to work with multiple values. What am I missing?
I have already tried to make the public class 'Value' a List AND Guid[]. I have tried to adjust the method parameter to List AND Value[]. Not sure what else to try.
Class:
public class Value
{
public Guid TimeId { get; set; }
}
Method:
public IActionResult ApproveAllTimesheets([FromBody]Value information)
View JS:
function SubAll() {
var selectedValues = $('#timesheet').DataTable().column(0).checkboxes.selected().toArray();
var instructions = {};
for (var TimeId in selectedValues) {
instructions[TimeId] = { TimeId: selectedValues[TimeId] };
}
var inst = JSON.stringify(instructions);
$.ajax({
url: "/Admin/ApproveAllTimesheets",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: inst,
success: function (result) {
alert(result);
},
error: function (xhr, textStatus) {
if (xhr.status == 401) { alert("Session Expired!"); window.location = "/Account"; }
else {
alert('Content load failed!', "info");
}
}
});
};
If I send through this object it works but I need to send through multiple values like my ajax post will do.
var instructions = { TimeId: "13246578-1234-7894-4562-456789123456" };
UPDATE #1
I found a structure that works for me by extending the class, now I just need to figure out how to create the correct object and array combination.
New Classes:
public class ValueContainer
{
public List<Value> MasterIds { get; set; }
}
public class Value
{
public Guid TimeId { get; set; }
}
Method:
public IActionResult ApproveAllTimesheets([FromBody]ValueContainer information)
Structure I need now (this works hard coded):
var jsonObject = {
"MasterIds": [{ TimeId: "13246578-1234-7894-4562-456789123450" }, { TimeId: "13246578-1234-7894-4562-456789123451" }, { TimeId: "13246578-1234-7894-4562-456789123452" }]
};
I'm still new to this stuff but what I see is that jsonObject is an object with a Key 'MasterIds' and the corresponding values are an array of objects with the key 'TimeId'...is this a correct evaluation?...and how to create it in code please?
You neec to create an array of objects and then set it in the container object :
var instructions = []; // an array
for (var i = 0; i < selectedValues.length; i++) {
instructions.push({ TimeId: selectedValues[i] };
}
var Value = {TimeId: instructions}; // creating object with property TimeId as array of guid
var inst = JSON.stringify(Value);
.......
....... your ajax code
and your class property should also be of type array:
public Guid[] TimeId { get; set; }

how to return back list of data from controller to knockout function to view page

This is my controller where i am returning back list of tags with the post:
public JsonResult GetPosts(int? id)
{
var varid = id;
var ret = (from post in db.Posts.ToList()
orderby post.PostedDate descending
select new
{
CityName = post.City.CityName,
TagName = post.Tags.ToList()
// TagName = post.Tags
}
}
I dont know, here, is this the way to return back all the tags selected.
Posts and Tags table are interconnected by many to many relation with a join table TagPost in database which contains TagId and PostId.
this is the knockout code:
function Post(data) {
var self = this;
data = data || {};
self.CityName = data.CityName || "";
self.TagName = data.TagName || "";
}
function viewModel() {
var self = this;
self.posts = ko.observableArray();
self.newMessage = ko.observable();
self.error = ko.observable();
self.loadPosts = function () {
// to load existing posts
$.ajax({
url: postApiUrl1,
data: { id: $("#Locations").val() },
datatype: "json",
contentType: "application/json",
cache: false,
type: 'Get'
})
.done(function (data) {
var mappedPosts = $.map(data, function (item)
{ return new Post(item); });
self.posts(mappedPosts);
})
.fail(function () {
error('unable to load posts');
});
}
This is the view page where i want to data-bind the cityName along with the tags:
<div>
<img src="~/assests/images/icon.png" alt=""><span><a data-bind="text: CityName"></a></span>
</div>
<div>
<img src="~/assests/images/tag.png" alt=""><span><a data-bind="text: TagName"></a></span>
</div>
Here, i want to return back all the tag name with comma seperated.Please someone suggest me what to do from here.
This is my Post class:
public class Post
{
[Key]
public int PostId { get; set; }
public string Message { get; set; }
public int? cityId { get; set; }
public IList<Tag> Tags { get; set; }
}
and this is my tag class:
public class Tag
{
public int TagId { get; set; }
public string TagName { get; set; }
public IList<Post> Posts { get; set; }
}
There is a many to many relationship between tag and post class so its creating a new join Table TagPost with column(TagId, PostId).
This is how i am inserting data to this table with on model creating:
modelBuilder.Entity<Tag>()
.HasMany(p => p.Posts)
.WithMany(t => t.Tags)
.Map(m =>
{
m.ToTable("TagPost");
m.MapLeftKey("TagId");
m.MapRightKey("PostId");
});
This should bring the data in the format you want:
var data = db.Posts.Include(x => x.Tags)
.Include(x => x.City)
.Where(x => x.PostId == id)
.SingleOrDefault();
var json = new {
PostId = data.PostId,
PostMessage = data.Message,
CityName = data.City.CityName,
Tags = string.Join(",", data.Tags.Select(t => t.TagName))
};
return Json(json, JsonRequestBehavior.AllowGet);
This will return the following Json:
{
"PostId": 1,
"PostMessage": "ABC",
"CityName": "Chicago",
"Tags": "C#,.NET,StackOverflow"
}
Just note that I've included the City using Include in the Post but in the model you posted, there's only the cityId. Perhaps you'll need to change that too.
EDIT
As per request, to return all posts and related tags change the code to this:
var data = db.Posts.Include(x => x.Tags)
.Include(x => x.City)
.ToList();
if (data.Count == 0)
return null; //Just return something if no post is found
var json = data.Select(x => new
{
PostId = x.PostId,
PostMessage = x.Message,
CityName = x.City.CityName,
Tags = string.Join(",", x.Tags.Select(t => t.TagName))
}).ToList();

Json Data from datatable

Here i have a problem with data table to convert json. This is my class called SearchCollection
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public int ClassGroupId { get; set; }
public string ClassName { get; set; }
public int ClassNumber { get; set; }
public int BookTypeId { get; set; }
public string BookType { get; set; }
I have collected a data from store procedure and pushed into the datatable, thats why am using ConvertToDatatable(), that time i got a datatable which contains 3 tables data
static DataTable ConvertToDatatable(IEnumerable<SearchCollection> list)
{
var dt = new DataTable();
dt.Columns.Add("CategoryId");
dt.Columns.Add("CategoryName");
dt.Columns.Add("ClassGroupId");
dt.Columns.Add("ClassName");
dt.Columns.Add("ClassNumber");
dt.Columns.Add("BookTypeId");
dt.Columns.Add("BookType");
foreach (var item in list)
{
var row = dt.NewRow();
row["CategoryId"] = item.CategoryId;
row["CategoryName"] = item.CategoryName;
row["ClassGroupId"] = item.ClassGroupId;
row["ClassName"] = item.ClassName;
row["ClassNumber"] = item.ClassNumber;
row["BookTypeId"] = item.BookTypeId;
row["BookType"] = item.BookType;
dt.Rows.Add(row);
}
return dt;
}
this contain 3 tables data.
So.. this is have tried to group the data, but here am getting the answer like category on top inside category shows booktype and inside booktype shows list of classnames, but i want 3 set of data
category {},booktype{},classnames{}
var result = rows.GroupBy(r => new { x = r["CategoryId"], y = r["CategoryName"] }).Select(g => new
{
CategoryId = g.Key.x,
CategoryName = g.Key.y,
BookTypes = g.GroupBy(r => new { h = r["BookTypeId"], i = r["BookType"] }).Select(g1 => new
{
BookTypeId = g1.Key.h,
BookType = g1.Key.i,
ClassNames = g1.Select(r => new
{
ClassGroupId = r["ClassGroupId"],
ClassName = r["ClassName"],
ClassNumber = r["ClassNumber"]
}),
}),
});
Rusult
This is my result
{ CategoryId:1 CategoryName:CD ClassGroupId:15 ClassName:I ClassNumber:1 BookTypeId:1 BookType:General CD}
{ CategoryId:2 CategoryName:DVD ClassGroupId:16 ClassName:II ClassNumber:2 BookTypeId:2 BookType:General DVD}
{ CategoryId:3 CategoryName:Book ClassGroupId:17 ClassName:III ClassNumber:3 BookTypeId:3 BookType:General Books}
But i want the result like this
+ Category={ CategoryId:1 CategoryName:CD
CategoryId:2 CategoryName:DVD
CategoryId:3 CategoryName:Book }
ClassGroup={ClassGroupId:15 ClassName:I ClassNumber:1
ClassGroupId:16 ClassName:II ClassNumber:2
ClassGroupId:17 ClassName:III ClassNumber:3}
BookType{ BookTypeId:1 BookType:General CD
BookTypeId:2 BookType:General DVD
BookTypeId:3 BookType:General Books
}
here my result is booktype is under category and classname under booktype. but i want the result just like 3 groups of records in single json, any one help just like category grouped collection, class grouped collection and book type collection in single json data.
Is this what you're looking for?
var result = new
{
Category = rows
.GroupBy(r => new
{
x = r["CategoryId"],
y = r["CategoryName"]
})
.Select(g => new
{
CategoryId = g.Key.x,
CategoryName = g.Key.y
}),
ClassGroup = rows
.GroupBy(r => new
{
x = r["ClassGroupId"],
y = r["ClassName"],
z = r["ClassNumber"]
})
.Select(g => new
{
ClassGroupId = g.Key.x,
ClassName = g.Key.y,
ClassNumber = g.Key.z
}),
BookType = rows
.GroupBy(r => new
{
x = r["BookTypeId"],
y = r["BookType"]
})
.Select(g => new
{
BookTypeId = g.Key.x,
BookType = g.Key.y
})
};
Fiddle: https://dotnetfiddle.net/h9qXqc

Show highcharts for database data

I have tried to display a chart for database data but I'm having some trouble. I've tried using json to high charts but it's not working. Could someone please explain to me how to show axis as date and to call this on viewpage?
public List<CustomerAccount> ChartData(long customerID)
{
List<CustomerAccount> chart = new List<CustomerAccount>();
List<CustomerAccount> points = new CustomerAccountDBMgr().ChartAccount(customerID).FindAll(e => e.AccountName != "Others");
if (null == points || points.Count == 0)
return null;
var val = (from item in points select new { CreatedAt = item.CreatedAt, OpeningBalance = item.OpeningBalance }).ToList();
foreach (var data in val)
{
CustomerAccount objCustomer = new CustomerAccount()
{
CreatedAt = data.CreatedAt,
OpeningBalance = data.OpeningBalance
};
chart.Add(objCustomer);
}
return chart;
}
Model
public class Chart1
{
public DateTime CreatedAt { get; set; }
public Double? OpeningBalance { get; set; }
public List<CustomerAccount> ChartData()
{
PersonalizeBL business=new PersonalizeBL();
var CustomerID = PERFICSSession.GetCustomerID();
List<CustomerAccount>point=business.ChartData(CustomerID);
return point;
}
}
Controller
public ActionResult Chart1()
{
if (!PERFICSSession.IsValidSession())
return View("Login");
Chart1 model = new Chart1();
Highcharts chart = new Highcharts("chart")
.InitChart(new Chart { DefaultSeriesType = ChartTypes.Line })
.SetTitle(new Title { Text = "Database Data" })
.SetXAxis(new XAxis { Type = AxisTypes.Datetime })
.SetYAxis(new[]
{
new YAxis
{
Title = new YAxisTitle { Text = "Amount" },
GridLineWidth = 1
}
})
.SetSeries(new[]
{
new Series
{
Name = "OpeningBalance",
Data = new Data((model.ChartData()).Select(x=>new points{X=DotNet.Highcharts.Helpers.Tools.GetTotalMilliseconds(x.CreatedAt),Y=x.OpeningBalance}).ToArray())
}
});
return View("Chart1");
}
Finally i found answere for this issue. i would have return view which object i did created from highcharts. i wrongly returned the view page name.
public ActionResult Chart1()
{
chartModel model = new chartModel();
var data = model.chartPlots(Session);
Highcharts chart = new Highcharts("chart")
.InitChart(new Chart { DefaultSeriesType = ChartTypes.Line })
.SetTitle(new Title { Text = "Database Data" })
.SetXAxis(new XAxis { Type = AxisTypes.Datetime })
.SetYAxis(new[]
{
new YAxis
{
Title = new YAxisTitle { Text = "Amount" },
GridLineWidth = 1
}
})
.SetSeries(new[]
{
new Series
{
Name = "OpeningBalance",
Data = new Data(data.Select(x=>new points{X=DotNet.Highcharts.Helpers.Tools.GetTotalMilliseconds(x.CreatedAt),Y=x.OpeningBalance}).ToArray())
}
});
return View(chart);
}
return View(chart);
}

Different objects to the same webgrid control

I have a list of csv files to choose from a dropdown list. The data for each csv is different. I'm pulling in csv files and want to display the data using the same webgrid. Would I pass dynamic object to the webgrid, so the webgrid can display the columns and values for all the csv data? If
Yes, you could use a dynamic view model:
public class MyViewModel
{
public string SelectedCsv { get; set; }
public IEnumerable<SelectListItem> AvailableCsv {
get
{
return new[]
{
new SelectListItem { Value = "foo.csv", Text = "foo.csv" },
new SelectListItem { Value = "bar.csv", Text = "bar.csv" },
new SelectListItem { Value = "baz.csv", Text = "baz.csv" },
};
}
}
public IEnumerable<object> Data { get; set; }
}
and then have a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Data = GetData("foo.csv"),
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
model.Data = GetData(model.SelectedCsv);
return View(model);
}
// TODO: move this method away in a repository and
// do the actual parsing of the CSV file
private IEnumerable<object> GetData(string csv)
{
if (csv == "foo.csv")
{
return new[]
{
new { col1 = "value1", col2 = "value2" },
new { col1 = "value1", col2 = "value2" },
};
}
else if (csv == "bar.csv")
{
return new[]
{
new { col1 = "bar value1", col2 = "bar value2", col3 = "bar value3" },
};
}
else if (csv == "baz.csv")
{
return new[]
{
new { col1 = "baz value1" },
new { col1 = "baz value2" },
new { col1 = "baz value3" },
};
}
throw new NotImplementedException();
}
}
and in the view:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.DropDownListFor(x => x.SelectedCsv, Model.AvailableCsv)
<button type="submit">OK</button>
}
#{
var grid = new WebGrid(Model.Data);
}
#grid.GetHtml()
As far as the parsing of the CSV file is concerned, if there's was a single thing you should never do, that would be to roll your own CSV parser.

Resources