I'm certain this is a total noob issue. I am currently dealing with two main entities:
Request - A request to be sent to the purchasing department detailing information relevant to a purchase request.
namespace Purchasing.Models
{
public class Request
{
public long ID { get; set; }
[DisplayName("Total")]
[Required]
public decimal total { get; set; }
[DisplayName("Date Created")]
public DateTime dateCreated { get; set; }
[DisplayName("Date Updated")]
public DateTime dateModified { get; set; }
[DisplayName("Reason for Purchase")]
[Required]
public string justification { get; set; }
[Required]
//[ForeignKey("User_ID")]
public string userID { get; set; }
[DisplayName("Current Status")]
public Enums.RequestStatus status { get; set; }
[DisplayName("Items")]
[Required]
public virtual ICollection<RequestLine> RequestLines { get; set; }
[DisplayName("Budget")]
[Required]
public long budgetID { get; set; }
}
public class RequestDbContext : DbContext
{
public RequestDbContext() : base("RequestDbContext")
{
}
public static RequestDbContext Create()
{
return new RequestDbContext();
}
public DbSet<Request> Requests { get; set; }
public System.Data.Entity.DbSet<RequestLine> RequestLines { get; set; }
public System.Data.Entity.DbSet<Budget> Budgets { get; set; }
}
}
RequestLine - Line item details for a single item to be included in a purchasing request.
namespace Purchasing.Models
{
public class RequestLine
{
public long ID { get; set; }
[DisplayName("Description")]
[Required]
public string description { get; set; }
[DisplayName("Quantity")]
[Required]
public decimal quantity { get; set; }
[DisplayName("Price")]
[Required]
public decimal price { get; set; }
[DisplayName("Amount")]
public decimal amount { get; set; }
public long requestID { get; set; }
[Required]
[ForeignKey("ID")]
public Request Request { get; set; }
}
}
What I am trying to accomplish is a view where RequestLines can be added to a Request before the Request is posted.
RequestController:
// GET: Request/Create
public ActionResult Create()
{
string userID = User.Identity.GetUserId();
ApplicationUser currentUser = userDb.Users.FirstOrDefault(x => x.Id == userID);
if(currentUser != null)
{
ViewData["UserFullName"] = currentUser.FirstName + " " + currentUser.LastName;
ViewData["UserDepartment"] = currentUser.Department.ToString();
}
Request request = new Request();
request.dateCreated = DateTime.Now;
request.RequestLines = new List<RequestLine>();
request.userID = currentUser.Id.ToString();
return View(request);
}
// POST: Request/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,total,dateCreated,dateModified,justification,userID,status,RequestLines")] Request request)
{
if (ModelState.IsValid)
{
request.status = Enums.RequestStatus.New;
foreach (RequestLine reqLine in request.RequestLines)
{
request.total += reqLine.amount;
reqLine.requestID = request.ID;
db.RequestLines.Add(reqLine);
}
db.Requests.Add(request);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(request);
}
Ultimately what I'm trying achieve is a view for creating requests that will allow a user to create RequestLines for the Request and have them displayed in the create view before posting the overall Request.
Request/Create.cshtml (The table is displayed now by Angular, but no back-end data binding is performed.
@model Purchasing.Models.Request
@using Purchasing.Models
@{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal" ng-controller="reqLineCtrl">
<h4>Request</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-2">
<b>@ViewData["UserFullName"]</b>
</div>
<div class="col-md-2">
<b>@ViewData["UserDepartment"]</b>
</div>
<div class="col-md-2">
</div>
<div class="col-md-2">
<b>@Model.dateCreated.ToString("MM/dd/yyyy")</b>
</div>
</div>
<hr/>
<div class="form-group">
<div class="col-md-2">
<label class="control-label" for="items">Items</label>
</div>
<div class="col-md-10">
<table class="table" id="items">
<caption><b>Request Total: ${{total | currency}}</b></caption>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
<tr ng-repeat="reqLine in lines">
<td>{{reqLine.description}}</td>
<td>{{reqLine.quantity}}</td>
<td>{{reqLine.price | currency}}</td>
<td>{{reqLine.price * reqLine.quantity | currency}}</td>
</tr>
</table>
</div>
</div>
<div class="form-inline">
<div class="form-group col-md-2">
<label class="control-label col-md-6" for="quantity">Quantity</label>
<div class="col-md-6">
<input type="text" id="quantity" class="form-control" ng-model="line.quantity">
</div>
</div>
<div class="form-group col-md-5">
<label class="control-label col-md-2" for="description">Description</label>
<div class="col-md-10">
<input type="text" id="description" class="form-control" ng-model="line.description">
</div>
</div>
<div class="form-group col-md-2">
<label class="control-label col-md-6" for="price">Price</label>
<div class="col-md-6">
<input type="text" id="price" class="form-control" ng-model="line.price">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Add Item" class="btn btn-primary" ng-click="enterLine(line)"/>
</div>
</div>
</div>
<br/>
<hr/>
<div class="form-group">
@Html.LabelFor(model => model.justification, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.justification, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.justification, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
I've found multiple tutorials regarding Html.RenderPartial, Html.Action, Ajax.BeginForm() and I haven't been able to really adapt them to what I'm trying to accomplish. I'm not opposed to sending JsonResults. I'm developing a MEAN stack app that I'm having none of these problems with, so I'm comfortable with JSON. Ultimately, I know there has to be a cleaner, more standardized way of doing this, as it seems to be a common operation of web applications.
I hate to admit, but I've been stuck at this point for three weeks, with most of my time spent in tutorials trying to find a solution. Any help would be greatly appreciated, even if it's just pointing me to a tutorial that actually has the answer I need.