Search code examples
c#asp.net-mvcentity-frameworkcode-first

Relationship between classes Order-Return


I have my order class created, you can make Orders and View the orders. However now I am trying to create a "Returns" page that basically allows the user to enter a return reason and then print the reason/invoice. I have the orders create form however I am not sure how to link the 2 to say This Returns Belongs To This Order all I can do is create a generic return that is linked to nothing. I have set up the relationship Im just not sure how to connect the return to the specific order. I know this is a basic question, I just couldn't find anything online to help me. Im a student and an explanation would be very beneficial as I need to use similar methods to this in other aspects

Here is my controller to view MyOrders and the ReturnsForm

namespace T_shirt_Company_v3.Controllers
{
    public class MyOrderController : Controller
    {
        TshirtStoreDB db = new TshirtStoreDB();


        /// <summary>
        /// Returns a list of Orders made by the user
        /// </summary>
        /// <param name="date">choose date period viewing orders</param>
        /// <param name="order">Orders being viewed</param>
        /// <returns></returns>
        [Authorize]
        public ActionResult Index(string date, Order order)
        {
            TshirtStoreDB db = new TshirtStoreDB();
            string currentUser = this.User.Identity.GetUserName();

            List<T_shirt_Company_v3.ViewModels.MyOrdersViewModel> list = (from o in new TshirtStoreDB().Orders
                    .Where(o => o.Username == currentUser)
                    .OrderByDescending(o => o.OrderDate)
                    .Select(o => new MyOrdersViewModel()
                    {
                        OrderId = o.OrderId,
                        Address = o.Address,
                        FirstName = o.FirstName,
                        LastName = o.LastName,
                        City = o.City,
                        OrderDate = o.OrderDate,
                        PostalCode = o.PostalCode,
                        Total = o.Total,
                        HasBeenShipped = o.HasBeenShipped,
                        PostageList = o.PostageList,
                        Details = (from d in o.OrderDetails
                                   select new MyOrderDetails
                                   {
                                       Colour = d.Product.Colour,
                                       Quantity = d.Quantity,
                                       Title = d.Product.Title,
                                       UnitPrice = d.UnitPrice
                                   }).ToList()
                    }).ToList() select o).ToList();


                if (date != null)
                {
                DateTime today = DateTime.Now.AddDays(Convert.ToInt32(date) * -1);
                return View(list.Where(x => x.OrderDate >= today).ToList());
                }


            return View(list);
        }

        public ActionResult ReturnsForm()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult ReturnsForm([Bind(Include = "ReturnId,OrderId,ReturnDate,Reason")] returnDetails returnDetails)
        {
            if (ModelState.IsValid)
            {
                if (returnDetails != null)
                {
                    returnDetails.ReturnDate = DateTime.Now;
                }

                db.returnDetails.Add(returnDetails);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(returnDetails);
        }

    }
}

and my MyOrders view

@model List<T_shirt_Company_v3.ViewModels.MyOrdersViewModel>


@{
    ViewBag.Title = "My Orders";
}
<style>
    table, th, td {
        border: 0px solid black;
        border-collapse: collapse;
        margin-bottom:50px;
        padding-bottom:50px;
    }

    th, td {
        padding: 5px;
        border-spacing: 10px;
        text-align: center;
    }   
</style>

<center>
    <h1>My Orders</h1>
    <br />
    @using (Html.BeginForm("Index", "MyOrder", FormMethod.Get))
    {
        <text>Orders Made </text><select id="date" name="date">
            <option value="9999">All Orders</option>
            <option value="1">In the last day</option>
            <option value="7">In the last week</option>
            <option value="30">In the last month</option>
            <option value="365">In the last year</option>
        </select>
        <input type="submit" name="submit" value="Search" />
    }
    <table>
        @foreach (var m in Model)
        {

            <tr>
                @*<td style="background-color: #ffffe0"><b>Order Status</b> <br />@ViewBag.ShippedMessage</td>*@
                <td style="background-color: #ffffe0"><b>Order Status</b> <br />@(m.HasBeenShipped ? "Order has been shipped" : "Order is being processed") <br /> @ViewBag.PostageStatus</td> 
                <td style="background-color: #ffffe0"><b>Order Placed</b> <br />@m.OrderDate <br /> @m.PostageList</td>
                <td style="background-color: #ffffe0"><b>Dispatched to</b> <br />@m.FirstName @m.LastName</td>
                <td style="background-color: #ffffe0"><b>Delivery Address</b><br /> @m.Address <br /> @m.City <br /> @m.PostalCode <br /> </td>
                <td style="background-color: #ffffe0"><b>Total Cost</b><br /> £@m.Total</td>
                <td style="background-color: #ffffe0"><b>Order Number</b><br /> @m.OrderId</td>
            </tr>

            foreach (var d in m.Details)
            {

                <tr>
                    <td colspan="3" style="text-align: left; background-color:#ADD8E6;"><b>Product Name</b> @d.Title <br /><b>Colour</b> @d.Colour</td>
                    <td style="background-color: #ADD8E6"><b>Price: </b> £@d.UnitPrice</td>
                    <td colspan="2" style="background-color: #ADD8E6"><b>Quantity Ordered: </b> @d.Quantity</td>
                </tr>


            }

            <tr><td>@Html.ActionLink("Return Order", "ReturnsForm")</td></tr>
            <tr><td></td></tr>
            <tr><td></td></tr>
            <tr><td></td></tr>
        }


    </table>
</center>

My ReturnsCreate View

@model T_shirt_Company_v3.Models.returnDetails

@{
    ViewBag.Title = "ReturnsForm";
}

<h2>ReturnsForm</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <h4>returnDetails</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Reason, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Reason, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Reason, "", 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-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Classes

namespace T_shirt_Company_v3.Models
{
    //[Bind(Exclude = "OrderId")]
    public partial class Order
    {
        [ScaffoldColumn(false)]
        public int OrderId { get; set; }

        [ScaffoldColumn(false)]
        public System.DateTime OrderDate { get; set; }

        [ScaffoldColumn(false)]
        [Remote("CheckUserName", "Account")]
        public string Username { get; set; }

        [Required]
        [StringLength(16, ErrorMessage = "Your name is too long")]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [Required(ErrorMessage = "Your last name is required.")]
        [StringLength(16, ErrorMessage = "Last name is too long.")]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Required(ErrorMessage = "Address is required.")]
        public string Address { get; set; }

        [Required(ErrorMessage = "City is required.")]
        public string City { get; set; }

        [Required(ErrorMessage = "Postcode is required.")]
        [Display(Name = "Post Code")]
        public string PostalCode { get; set; }

        [Required(ErrorMessage = "Country is required.")]
        public string Country { get; set; }

        [Required(ErrorMessage = "Phone number is required.")]
        public string Phone { get; set; }

        [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}", ErrorMessage = "Email doesn't look like a valid email address.")]
        public string Email { get; set; }

        [System.ComponentModel.DataAnnotations.Compare("Email")]
        [Display(Name = "Confirm your email address")]
        public string EmailConfirm { get; set; }


        [ScaffoldColumn(false)]
        public string PaymentTransactionId { get; set; }


        [ScaffoldColumn(false)]
        public bool HasBeenShipped { get; set; }

        [ScaffoldColumn(false)]
        //[ReadOnly(true)]
        public decimal Total { get; set; }

        [Required]
        [Range(0, 2, ErrorMessage = "Select a delivery method")]
        public Postage? PostageList { get; set; }

        public CardDetails cardDetails { get; set; }
        //public List<CardDetails> cardDetails { get; set; }
        public List<OrderDetail> OrderDetails { get; set; }

        public int ReturnId { get; set; }
        public virtual returnDetails returns { get; set; }
    }

    public enum Postage {[Display(Name = "Standard Delivery - Free")]StandardDelivery, [Display(Name = "First Class Delivery - £5")]FirstClass, [Display(Name = "24 Hour Delivery - £10")]TwentyFourHour }

    public class returnDetails
    {
        [Key]
        public int ReturnId { get; set; }

        [ScaffoldColumn(false)]
        public System.DateTime ReturnDate { get; set; }

        [Required]
        public string Reason { get; set; }

        [ForeignKey("Order")]
        public int OrderId { get; set; }
        public virtual Order order { get; set; }
    }

}

Keys In the Return class

[ForeignKey("Order")]
public int OrderId { get; set; }
public virtual Order order { get; set; }

In the Order Class

public int ReturnId { get; set; }
public virtual returnDetails returns { get; set; }

Solution

  • In your MyOrders.cshtmlview, you need to generate a link to your ReturnsForm() method and pass the ID of the order

    @foreach (var m in Model)
    {
        ....
        @Html.ActionLink("Return Order", "ReturnsForm", new { orderID = m.OrderId })
    }
    

    and modify the method to

    public ActionResult ReturnsForm(int orderID)
    {
        returnDetails model = new returnDetails()
        {
            OrderId  = orderID
        };
        return View(model );
    }
    

    and then in your ReturnsCreate.cshtml view, include a hidden input for the property

    @Html.HiddenFor(m => m.OrderId )
    

    so is value will be bound when you post back the model.

    Side note: The code above uses your data model but that is poor practice and you should be using a view model for Returns