2014-09-30 72 views
0

我正在尝试创建发票。我有两个型号,Invoice & InvoiceItems使用型号列表创建记录

我可以使用硬编码值插入,但我希望能够使用TextBoxes即时创建发票。如何使用相同的视图插入一条记录,该记录将发票项目的数据和发票项目中的动态数据插入到两个表格中?我希望最终可以在处添加更多按钮,以便我可以保持在同一页面上并不断向同一张发票添加项目。你可以看到我在下面的尝试。

发票型号:

public class Invoice 
{ 
    [Key] 
    public int InvoiceId { get; set; } 
    public int ClientId { get; set; } 
    [Display(Name = "Amount")] 
    public decimal Amount { get; set; } 
    [Display(Name = "Invoice Creation Date")] 
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")] 
    public DateTime CreationDate { get; set; } 
    [Display(Name = "Invoice Due Date")] 
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")] 
    public DateTime DueDate { get; set; } 
    [Display(Name = "Notes")] 
    public string InvoiceNotes { get; set; } 

    public List<InvoiceDetails> InvoiceDetails { get; set; } 
    public List<Clients> Clients { get; set; } 
} 

InvoiceItem型号:

public class InvoiceDetails 
{ 
    [Key] 
    public int InvoiceDetailsId { get; set; } 
    public int InvoiceId { get; set; } 
    [DisplayName("Item Name")] 
    public string Name { get; set; } 
    [DisplayName("Item Note")] 
    public string Note { get; set; } 
    [DisplayName("Qty")] 
    public decimal? Quantity { get; set; } 
    [DisplayName("Rate/Hour")] 
    public decimal? Price { get; set; } 
    [DisplayName("Item Total")] 
    public decimal? Total { get; set; } 
} 

发票控制器:

private NovaDb _db = new NovaDb(); 
public ActionResult InvoiceInformation() 
    { 
     var invoice = new Invoice(); 

     invoice.InvoiceDetails = new List<InvoiceDetails>(); 

     return View(invoice); 
    } 

    [HttpPost] 
    public ActionResult InvoiceInformation(Invoice model) 
    { 
     if (ModelState.IsValid) 
     { 
      var invoices = new Invoice() 
      { 
       Amount = model.Amount, 
       CreationDate = model.CreationDate, 
       DueDate = model.DueDate, 
       InvoiceNotes = model.InvoiceNotes, 
       InvoiceId = model.InvoiceId, 
       ClientId = model.ClientId      
      }; 

      _db.Invoices.Add(invoices); 
      _db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     return View(model); 
    } 

发票查看:

@model NovaFinancial.Models.Invoice 

@{ 
ViewBag.Title = "InvoiceInformation"; 
} 

<h2>InvoiceInformation</h2> 

@using (Html.BeginForm()) { 
@Html.AntiForgeryToken() 
@Html.ValidationSummary(true) 

<fieldset> 
    <legend>Invoice</legend> 

    @Html.HiddenFor(model => model.InvoiceId) 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.ClientId) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.ClientId) 
     @Html.ValidationMessageFor(model => model.ClientId) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Amount) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Amount) 
     @Html.ValidationMessageFor(model => model.Amount) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.CreationDate) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.CreationDate) 
     @Html.ValidationMessageFor(model => model.CreationDate) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.DueDate) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.DueDate) 
     @Html.ValidationMessageFor(model => model.DueDate) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.InvoiceNotes) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.InvoiceNotes) 
     @Html.ValidationMessageFor(model => model.InvoiceNotes) 
    </div> 

    <div> 
     <table> 
      <tr> 
       <th>Name</th> 
       <th>Notes</th> 
       <th>Qty</th> 
       <th>Price</th> 
       <th>Total</th> 
      </tr> 
      @for (int i = 0; i < Model.InvoiceDetails.Count; i++) 
      { 
       @Html.HiddenFor(m=>m.InvoiceDetails[i].Name)  
       @Html.HiddenFor(m=>m.InvoiceDetails[i].Note) 
       @Html.HiddenFor(m=>m.InvoiceDetails[i].Quantity) 
       @Html.HiddenFor(m=>m.InvoiceDetails[i].Price) 
       @Html.HiddenFor(m=>m.InvoiceDetails[i].Total) 
       <tr> 
        <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Name) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Name)</td> 
        <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Note) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Note)</td> 
        <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Quantity) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Quantity)</td> 
        <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Price) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Price)</td> 
        <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Total) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Total)</td> 
       </tr> 
      }     
     </table> 
    </div> 

    <p> 
     <input type="submit" value="Save" /> 
    </p> 
</fieldset> 
} 
+0

那么,你的问题是什么? – Tobias 2014-09-30 19:03:45

+0

只是想检查你的问题是否取得了进展。它对我感兴趣,所以今天我花了一点时间来研究它。我可以用一件物品创建发票,但仍然试图弄清楚如何让多件物品通过。我知道使用相同名称的传递表单输入会给出一个数组,我觉得它可能包含密钥。 – 2014-10-02 20:21:08

回答

0

我摸索出“一”的解决方案,可能不是最好的,但它的工作原理。您仍然必须添加代码才能使其更加健壮,但总体框架就在那里。

在您的视图中,将所有发票明细(名称,数量,价格)的文本框保留为name属性的相同值,但请确保id的唯一性。我使用了一些jQuery和JavaScript来根据用户需要点击的按钮生成额外的行。例如,

<input type="text" name="Name" id="Name"> <!--first line item for Item Name--> 
<input type="number" name="Quantity" id="Quantity"> <!--first for Quanitity --> 

<input type="text" name="Name" id="Name2"> <!--second line item for Item Name--> 
<input type="number" name="Quantity" id="Quantity2"> <!-- second for Quanitity --> 

为InvoiceDetail线的值将传回服务器为以逗号分隔字符串(最好做某些您的项目名称没有逗号!)。在服务器端,

var Names = Request["Name"]; // this would yield something like "Labor,Parts" 

在控制器中,你需要解析字符串成阵列,并从他们创造的InvoiceDetail的实例。我写了一个私有方法来分割字符串,并将InvoiceDetail对象列表返回给操作方法。您有责任验证这些数据:客户端和服务器端都需要验证。

我做了一些实验。你可以在这里看到所有的代码:http://mefixme.blogspot.com/2014/10/aspnet-mvc-how-to-add-model-with.html

我希望这可以帮助你。