
Download Project (Full Project)
Step-1
In this tutorial we work in RDLC report. When add product submit. Then new tab open and the report show. Now first open our existing project where we are working. In this project first create stored procedure. This stored procedure responsible to give all customer and product details by inner join. Now execute commend. We can see our new stored procedure. Now update the .edmx for give the reference of this stored procedure. Then build the project.
Step-2
Now add dataset from solution explorer right click in our project then add new item.
Then select data under data select DataSet you can change the data set name also and add.
Now go to server explorer and drag and drop the stored procedure into dataset view.
Step-3
Now create asp.net web form page under the project. First right click add then select web then select web-form. Now change the name of the web-form like report, because RDLC report Display in this web-form. Now we can see the web-form source code. Then from toolbox drag and drop the report Viewer then go to designer view and set height and width from property.
Now right click in the project and go to solution explorer. Then right click the project and select reporting then add report. Then add report from reporting option. We can see the RDLC report design page. Now go to Design set in dataset from report data option and select report master details page click ok. We can see everything is added.
Step-4
Now insert page header and text boxes for some information by right click on the page add greed view for show the customer and order details list. In this page header add the title of the report by insert text box. And insert list by right click the view and insert table property’s now select dataset1. Now select list by group properties then click add and select invoice number click ok. Now after header add some text for show customer details. Now drag and drop the dataset1 property. Now add table to display product name, price, quantity, and amount in right by the set property. Now we also need column for sr.no. So insert column in left. And select the column and give the dataset name. Now add an amount by sum function “Add total after” and write total amount. In the aspx page now choose report in RDLC report. We can see the view code the report1 RDLC added. Then no need to dataset so removes the code and save it. Also no need object data source so remove it. Now add script manager from tool box. And give a title.
Now go to report aspx.cs file under create a privet method name as get report. This method receives a parameter like invoice and also this method non return type. Now create database object under class. Now select stored procedure and create report data source object under constructor pass the dataset object. In page load write “IsPostBack” method check. Get Report method pass a id parameter. Now add some JavaScript code in index view. And page load are data source insert object and refresh the data set. Now run the project.
Step-5
Given bellow the controller code:
using MasterDetailsDemo.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
namespace MasterDetailsDemo.Controllers
{
public class OrdersController : Controller
{
OnlineShopEntities db = new OnlineShopEntities();
public ActionResult Index()
{
List<Customer> OrderAndCustomerList = db.Customers.OrderByDescending(s=>s.OrderDate).ToList();
return View(OrderAndCustomerList);
}
[HttpPost]
public ActionResult Index(MyOrderViewModel model)
{
if (model.Id > 0)
{
Order or = db.Orders.SingleOrDefault(x => x.Id == model.Id);
or.Id = model.Id;
or.ProductName = model.ProductName;
or.Quantity = model.Quantity;
or.Price = model.Price;
or.Amount = model.Amount;
db.SaveChanges();
}
return View(model);
}
public ActionResult AddMoreOrder(int Id)
{
MyOrderViewModel model = new MyOrderViewModel();
Customer cus = db.Customers.SingleOrDefault(c => c.Id == Id);
model.Id = cus.Id;
model.CustomerId = cus.CustomerId;
return PartialView("Partial2", model);
}
public ActionResult AddMoreOrderSave(MyOrderViewModel model)
{
Order or = new Order();
or.OrderId = Guid.NewGuid();
or.ProductName = model.ProductName;
or.Quantity = model.Quantity;
or.Price = model.Price;
or.Amount = model.Amount;
or.CustomerId = model.CustomerId;
db.Orders.Add(or);
db.SaveChanges();
return View(model);
}
public ActionResult SaveOrder(string name, String address, Order[] order)
{
string result = "Error! Order Is Not Complete!";
if (name != null && address != null && order != null)
{
var cutomerId = Guid.NewGuid();
Customer model = new Customer();
model.CustomerId = cutomerId;
model.Name = name;
model.Address = address;
model.OrderDate = DateTime.Now;
db.Customers.Add(model);
foreach (var item in order)
{
var orderId = Guid.NewGuid();
Order O = new Order();
O.OrderId = orderId;
O.ProductName = item.ProductName;
O.Quantity = item.Quantity;
O.Price = item.Price;
O.Amount = item.Amount;
O.CustomerId = cutomerId;
db.Orders.Add(O);
}
db.SaveChanges();
result = "Success! Order Is Complete!";
}
return Json(result, JsonRequestBehavior.AllowGet);
}
public ActionResult EditOrder(int Id)
{
MyOrderViewModel model = new MyOrderViewModel();
Order or = db.Orders.SingleOrDefault(c => c.Id == Id);
model.Id = or.Id;
model.ProductName = or.ProductName;
model.Quantity = or.Quantity;
model.Price = or.Price;
model.Amount = or.Amount;
model.CustomerId = or.CustomerId;
return PartialView("Partial1", model);
}
// GET: Order/Edit/5
public ActionResult Edit(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Order order = db.Orders.Find(id);
if (order == null)
{
return HttpNotFound();
}
ViewBag.CustomerId = new SelectList(db.Customers, "CustomerId", "Name", order.CustomerId);
return View(order);
}
// POST: Order/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "OrderId,ProductName,Quantity,Price,Amount,CustomerId")] Order order)
{
if (ModelState.IsValid)
{
db.Entry(order).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CustomerId = new SelectList(db.Customers, "CustomerId", "Name", order.CustomerId);
return View(order);
}
// GET: Customer/Edit/5
public ActionResult EditCustomer(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
// POST: Customer/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditCustomer([Bind(Include = "CustomerId,Name,Address,OrderDate")] Customer customer)
{
if (ModelState.IsValid)
{
db.Entry(customer).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
}
}
Step-6
Given bellow the view code:
@model IEnumerable<MasterDetailsDemo.Models.Customer>
@{
ViewBag.Title = "Index";
}
<br /><br />
<div class="panel panel-default">
<div class="panel-heading">
<div class="row">
<h2 class="panel-title pull-left" style="margin-left:10px;">
<strong>Order Details</strong>
</h2>
<button style="margin-right:10px" class="btn btn-primary pull-right" onclick="addNewOrder()">New Order</button>
</div>
</div>
@*Receive All Database Data From Controller And Display Those Data In Client Side*@
<div id="accordion">
@if (Model.Count() != 0)
{
foreach (var item in Model)
{
<h3>
Invoice No: #@item.Id
<span class="pull-right">order Date: @item.OrderDate
<a href="#" class="btn btn-success btn-xs" onclick="AddMoreOrder(@item.Id)"><i class="glyphicon glyphicon-plus"></i></a>
</span>
</h3>
<div>
<div class="row">
<div class="col-lg-4 col-sm-5">
</div>
<div class="row mb-4">
<div class="col-sm-6">
<table id="tblCustomers" class="table">
<tr>
<th>Name</th>
<th>Address</th>
<th></th>
</tr>
<tr>
<td style="display:none" class="CustomerId">
<span> @item.CustomerId</span>
</td>
<td class="Name">
<span> @item.Name</span>
<input type="text" class="form-control" value="@item.Name" style="display:none" />
</td>
<td class="Address">
<span> @item.Address</span>
<input type="text" class="form-control" value="@item.Address" style="display:none" />
</td>
<td>
<a class="Edit btn btn-warning btn-sm" href="javascript:;">Edit</a>
<a class="Update btn btn-info btn-sm" href="javascript:;" style="display:none">Update</a>
<a class="Cancel btn btn-danger btn-sm" href="javascript:;" style="display:none">Cancel</a>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="panel-body">
<table class="table table-striped table-responsive">
<tbody>
<tr>
<td colspan="3">
<div class="table-responsive-sm">
<table class="table table-striped css-serial">
<thead>
<tr>
<th>#</th>
<th>Item</th>
<th>Quantity</th>
<th>Unit Cost</th>
<th>Total</th>
<th></th>
</tr>
</thead>
@{
var totalBill = 0;
}
@foreach (var order in item.Orders)
{
<tbody>
<tr id="row_@item.Id">
<td></td>
<td style="display:none">@item.Id</td>
<td>@order.ProductName</td>
<td>@order.Quantity</td>
<td>@order.Price</td>
<td>@order.Amount</td>
<td><a href="#" class="btn btn-danger btn-sm" onclick="EditOrder(@order.Id)" data-toggle="tooltip" title="Edit Product"><i class="glyphicon glyphicon-pencil"></i> </a></td>
@*<td>@Html.ActionLink(" ", "Edit", new { id = @order.OrderId }, new { @class = "btn btn-warning pull-right btn-sm glyphicon glyphicon-edit" })</td>*@
</tr>
</tbody>
totalBill = totalBill + @Convert.ToInt32(order.Amount);
}
</table>
<div class="row">
<div class="col-lg-4 col-sm-5">
</div>
<div class="col-lg-4 col-sm-5 ml-auto">
<table class="table table-clear">
<tbody>
<tr>
<td class="left">
<strong>Total Bill:</strong>
</td>
<td class="right">
<strong>$@totalBill</strong>
</td>
@*<td class="left">
<span class="pull-right" style="margin-right:200px;"><strong>Total Bill : </strong> @totalBill</span>
</td>*@
</tr>
</tbody>
</table>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
}
}
else
{
<div class="panel-body">
<h3 style="color:red;">Empty!</h3>
</div>
}
</div>
</div>
<div class="modal fade" id="newOrderModal">
<div class="modal-dialog modal-lg" style=" width 900px !important;">
<div class="modal-content">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal">×</a>
<h4>Add New Order</h4>
</div>
<form id="NewOrderForm">
<div class="modal-body">
@*Customer Details*@
<h5 style="color:#ff6347">Customer Details</h5>
<hr />
<div class="form-horizontal">
<input type="hidden" id="CustomerId" />
<div class="form-group">
<label class="control-label col-md-2">
Customer Name
</label>
<div class="col-md-4">
<input type="text" id="name" name="name" placeholder="Customer Name" class="form-control" />
</div>
<label class="control-label col-md-2">
Address
</label>
<div class="col-md-4">
<input type="text" id="address" name="address" placeholder="Customer Address" class="form-control" />
</div>
</div>
</div>
@*Order Details*@
<h5 style="margin-top:10px;color:#ff6347">Order Details</h5>
<hr />
<div class="form-horizontal">
<input type="hidden" id="OrderId" />
<div class="form-group">
<label class="control-label col-md-2">
Product Name
</label>
<div class="col-md-4">
<input type="text" id="productName" name="productName" placeholder="Product Name" class="form-control" />
</div>
<label class="control-label col-md-2">
Price
</label>
<div class="col-md-4">
<input type="number" id="price" name="price" placeholder="Product Price" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">
Quantity
</label>
<div class="col-md-4">
<input type="number" id="quantity" name="quantity" placeholder="Quantity" class="form-control" />
</div>
<div class="col-md-2">
<a id="addToList" class="btn btn-primary">Add To List</a>
</div>
</div>
<table id="detailsTable" class="table">
<thead>
<tr>
<th style="width:30%">Product</th>
<th style="width:10%">Qty</th>
<th style="width:25%">Unit Cost</th>
<th style="width:25%">Amount</th>
<th style="width:10%"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="reset" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="saveOrder" type="submit" class="btn btn-danger">Save Order</button>
</div>
</form>
</div>
</div>
</div>
<div class="modal fade" id="myModal1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal">×</a>
<h3 class="modal-title">Edi Order</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
</div>
</div>
</div>
</div>
<div class="modal fade" id="myModal2">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal">×</a>
<h3 class="modal-title">Edi Order</h3>
</div>
<div class="modal-body" id="myModalBodyDiv2">
</div>
</div>
</div>
</div>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script>
var EditOrder = function (id) {
var url = "/Orders/EditOrder?Id=" + id;
$("#myModalBodyDiv1").load(url, function () {
$("#myModal1").modal("show");
})
}
var AddMoreOrder=function(id){
var url="/Orders/AddMoreOrder?Id="+id;
$("#myModalBodyDiv2").load(url,function(){
$("#myModal2").modal("show");
})
}
</script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
@section scripts{
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(function () {
$("#accordion").accordion();
});
$(function () {
if ($("#tblCustomers tr").length > 0) {
//$("#tblCustomers tr:eq(0)").remove();
} else {
var row = $("#tblCustomers tr:last-child");
row.find(".Edit").hide();
row.find("span").html(' ');
}
});
function AppendRow(row, customerId, name, address) {
//Bind CustomerId.
$(".CustomerId", row).find("span").html(customerId);
//Bind Name.
$(".Name", row).find("span").html(name);
$(".Name", row).find("input").val(name);
//Bind Country.
$(".Address", row).find("span").html(address);
$(".Address", row).find("input").val(address);
row.find(".Edit").show();
row.find(".Delete").show();
$("#tblCustomers").append(row);
};
//Edit event handler.
$("body").on("click", "#tblCustomers .Edit", function () {
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find("input").length > 0) {
$(this).find("input").show();
$(this).find("span").hide();
}
});
row.find(".Update").show();
row.find(".Cancel").show();
$(this).hide();
});
//Cancel event handler.
$("body").on("click", "#tblCustomers .Cancel", function () {
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find("input").length > 0) {
var span = $(this).find("span");
var input = $(this).find("input");
input.val(span.html());
span.show();
input.hide();
}
});
row.find(".Edit").show();
row.find(".Update").hide();
$(this).hide();
});
//Update event handler.
$("body").on("click", "#tblCustomers .Update", function () {
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find("input").length > 0) {
var span = $(this).find("span");
var input = $(this).find("input");
span.html(input.val());
span.show();
input.hide();
}
});
row.find(".Edit").show();
row.find(".Cancel").hide();
$(this).hide();
var customer = {};
customer.CustomerId = row.find(".CustomerId").find("span").html();
customer.Name = row.find(".Name").find("span").html();
customer.Address = row.find(".Address").find("span").html();
$.ajax({
type: "POST",
url: "/Home/UpdateCustomer",
data: '{customer:' + JSON.stringify(customer) + '}',
contentType: "application/json; charset=utf-8",
dataType: "json"
});
});
//Show Modal.
function addNewOrder() {
$("#newOrderModal").modal();
}
//Add Multiple Order.
$("#addToList").click(function (e) {
e.preventDefault();
if ($.trim($("#productName").val()) == "" || $.trim($("#price").val()) == "" || $.trim($("#quantity").val()) == "") return;
var productName = $("#productName").val(),
price = $("#price").val(),
quantity = $("#quantity").val(),
detailsTableBody = $("#detailsTable tbody");
var productItem = '<tr><td>' + productName + '</td><td>' + quantity + '</td><td>' + price + '</td><td>' + (parseFloat(price) * parseInt(quantity)) + '</td><td><a data-itemId="0" href="#" class="deleteItem">Remove</a></td></tr>';
detailsTableBody.append(productItem);
clearItem();
});
//After Add A New Order In The List, Clear Clean The Form For Add More Order.
function clearItem() {
$("#productName").val('');
$("#price").val('');
$("#quantity").val('');
}
// After Add A New Order In The List, If You Want, You Can Remove It.
$(document).on('click', 'a.deleteItem', function (e) {
e.preventDefault();
var $self = $(this);
if ($(this).attr('data-itemId') == "0") {
$(this).parents('tr').css("background-color", "#ff6347").fadeOut(800, function () {
$(this).remove();
});
}
});
//After Click Save Button Pass All Data View To Controller For Save Database
function saveOrder(data) {
return $.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: "/Orders/SaveOrder",
data: data,
success: function (result) {
alert(result);
location.reload();
},
error: function () {
alert("Error!")
}
});
}
//Collect Multiple Order List For Pass To Controller
$("#saveOrder").click(function (e) {
e.preventDefault();
var orderArr = [];
orderArr.length = 0;
$.each($("#detailsTable tbody tr"), function () {
orderArr.push({
productName: $(this).find('td:eq(0)').html(),
quantity: $(this).find('td:eq(1)').html(),
price: $(this).find('td:eq(2)').html(),
amount: $(this).find('td:eq(3)').html()
});
});
var data = JSON.stringify({
name: $("#name").val(),
address: $("#address").val(),
order: orderArr
});
$.when(saveOrder(data)).then(function (response) {
console.log(response);
}).fail(function (err) {
console.log(err);
});
});
</script>
}
<style>
.css-serial {
counter-reset: serial-number; /* Set the serial number counter to 0 */
}
.css-serial td:first-child:before {
counter-increment: serial-number; /* Increment the serial number counter */
content: counter(serial-number); /* Display the counter */
}
.card {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0, 0, 0, 0.125);
border-radius: 0.25rem;
}
.card > hr {
margin-right: 0;
margin-left: 0;
}
.card > .list-group:first-child .list-group-item:first-child {
border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem;
}
.card > .list-group:last-child .list-group-item:last-child {
border-bottom-right-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
}
.card-body {
-webkit-box-flex: 1;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
padding: 1.25rem;
}
.card-title {
margin-bottom: 0.75rem;
}
.card-subtitle {
margin-top: -0.375rem;
margin-bottom: 0;
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link:hover {
text-decoration: none;
}
.card-link + .card-link {
margin-left: 1.25rem;
}
.card-header {
padding: 0.75rem 1.25rem;
margin-bottom: 0;
background-color: rgba(0, 0, 0, 0.03);
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
}
.card-header:first-child {
border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;
}
.card-header + .list-group .list-group-item:first-child {
border-top: 0;
}
</style>
Step-7
We can add new product and update existing product, also we can print as a docx file and download it. When we run the project then we can see the output.