Auction bidding logic

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












I am currently working on an Auction site with ASP.NET MVC and I have a functioning bidding process. On my items detail page I am showing the bids for that item in descending order for the amount and only including the current and previous leaders (1 (active) and 3 (superseded) in my BidStatusId property).



My auction bidding functions sort of like Ebay in that aspect ad I believe my logic is similar to their process as well. When a user clicks on a link to place a bid they are taken to my bid "Create" view page where they enter a max bid.



My code for creating a new Bid in my BidsController is below:



public ActionResult Create([Bind(Include = "BidId,ItemId,BidderId,MaxBid,CurBid,BidDate,BidStatusId")] Bid bid, Guid itemId, string usrId)

if (ModelState.IsValid)

Item item = db.Items.Find(itemId);
Bid activeBid = db.Bids.Find(item.ActiveBidId);
Usr usr = Usr.GetUsr(db, usrId);

//base case, starting bid
if (item.ActiveBidId == null && item.Bids.Count == 0)

bid.BidId = Guid.NewGuid();
bid.ItemId = item.ItemId;
bid.BidderId = usr.UsrId;
bid.BidDate = DateTime.Now;

bid.CurBid = item.InitialBid;
bid.BidStatusId = 1;
item.ActiveBidId = bid.BidId;
db.Bids.Add(bid);

else

//Validation for bid
if (bid.MaxBid < activeBid.CurBid)

ModelState.AddModelError(string.Empty, "Your maximum bid must be greater than the current bid."); //does not currently show the error on create page
return RedirectToAction("Create", "Bids", new itemId, usrId );


//If the user is the active bidder, they are updating their max bid
if (usr.UsrId == activeBid.Usr.UsrId)

activeBid.MaxBid = bid.MaxBid;

//They are bidding against another user
else

//Start creating new bid info
bid.BidId = Guid.NewGuid();
bid.ItemId = item.ItemId;
bid.BidderId = usr.UsrId;
bid.BidDate = DateTime.Now;

//1 is Active, 2 is Outbid, 3 is Superceded, 4 is inactive

//if bidder's max is higher than current bid's max, they are the new active bid
if (bid.MaxBid > activeBid.MaxBid)

//if the active bid isn't maxed out, then create a new maxed out autobid for that user
if(activeBid.CurBid != activeBid.MaxBid)

Bid activeMax = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 3, null, item, null, activeBid.Usr);
db.Bids.Add(activeMax);

activeBid.BidStatusId = 3;
//if the bid is less than the increment but more than current max, leave at max
if(bid.MaxBid < activeBid.MaxBid + item.IncrementBy)

bid.CurBid = bid.MaxBid;

//else increment the amount plus the current max bid
else

bid.CurBid = activeBid.MaxBid + item.IncrementBy;

bid.BidStatusId = 1;
item.ActiveBidId = bid.BidId;
db.Bids.Add(bid);

//if bidder's max is lower than the current bid's max, then an auto bid is created
// and the active bidder is still the active bidder with updated auto max bid
else if (bid.MaxBid < activeBid.MaxBid)

bid.CurBid = bid.MaxBid;
bid.BidStatusId = 2;
db.Bids.Add(bid);
activeBid.BidStatusId = 3;
Bid newActive;
if (activeBid.MaxBid < bid.MaxBid + item.IncrementBy)

newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 1, null, item, null, activeBid.Usr);

else

newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, bid.MaxBid + item.IncrementBy, DateTime.Now, 1, null, item, null, activeBid.Usr);

db.Bids.Add(newActive);
item.ActiveBidId = newActive.BidId;

//If the max's are the same then the activebidder is still the active bidder
//since he bid first, the bid will not show up on list currently (marked as outbid)
else if (bid.MaxBid == activeBid.MaxBid)

bid.CurBid = bid.MaxBid;
bid.BidStatusId = 2;
db.Bids.Add(bid);
activeBid.BidStatusId = 3;
Bid newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 1, null, item, null, activeBid.Usr);
db.Bids.Add(newActive);
item.ActiveBidId = newActive.BidId;




//Save changes to the db and redirect to the item's detail page
db.SaveChanges();
return RedirectToAction("Details", "Items", new id = itemId );




I believe my code as it stands does not enforce concurrency and is very rudimentary. I would like to know so that I can become a better programmer, (especially in MVC as I have only been using it for 5 days), if there are any improvements to my logic/process. Also if I am missing foresight as to what problems I could run into in the future coding like I am.




I am just looking to improve if anyone is willing to help me learn so I code in a more efficient way. My comments in my code outline what is going on and any problems that I am aware of.



Code for my "Create" Bid page:



div class="form-horizontal">
<h4>Bid</h4>
<hr />
@Html.ValidationSummary(true, "", new @class = "text-danger" )

<div class="form-group">
@Html.LabelFor(model => model.MaxBid, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.MaxBid, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.MaxBid, "", new @class = "text-danger" )
</div>
</div>


Code for my Bid Model



 public partial class Bid

public Bid()

this.Items = new HashSet<Item>();

public Bid(Guid bidId,Guid itemId, Guid bidderId, decimal maxBid, decimal curBid, DateTimeOffset bidDate,
int statusId, ICollection<Item> items, Item item, BidStatus bidStatus, Usr usr)

BidId = bidId;
BidderId = bidderId;
MaxBid = maxBid;
CurBid = curBid;
BidDate = bidDate;
BidStatusId = statusId;
Items = items;
Item = item;
BidStatus = bidStatus;
Usr = usr;


public System.Guid BidId get; set;
public System.Guid ItemId get; set;
public System.Guid BidderId get; set;

[Required(ErrorMessage = "Please enter a maximum bid")]
[Range(0, double.PositiveInfinity)]
public decimal MaxBid get; set;

public decimal CurBid get; set;
public System.DateTimeOffset BidDate get; set;
public int BidStatusId get; set;

public virtual ICollection<Item> Items get; set;
public virtual Item Item get; set;
public virtual BidStatus BidStatus get; set;
public virtual Usr Usr get; set;




Code for my Item Model



public partial class Item

public Item()

this.Bids = new HashSet<Bid>();


public System.Guid ItemId get; set;
public System.Guid CatId get; set;
public string ItemName get; set;
public string ItemDesc get; set;
public string ModelNo get; set;
public Nullable<decimal> RetailValue get; set;
public string ImageFileName get; set;
public System.DateTimeOffset StartDate get; set;
public System.DateTimeOffset EndDate get; set;
public decimal InitialBid get; set;
public decimal IncrementBy get; set;
public Nullable<System.Guid> ActiveBidId get; set;

public virtual Bid Bid get; set;
public virtual ICollection<Bid> Bids get; set;
public virtual Cat Cat get; set;







share|improve this question

















  • 1




    //does not currently show the error on create page is the goal to have the error show on the create page, or is that comment just stating that it doesn't show there because it is an implementation detail?
    – Sam Onela
    May 24 at 20:49










  • @SamOnela the goal is to have it show on the create page. I am trying to implement it to where is shows the error message right on the create page just like the data annotation error messages
    – C.Math
    May 24 at 20:57







  • 2




    Your return RedirectToAction("Create", "Bids", new itemId, usrId ); line of code makes no sense when you add a ModelStateError - its needs to be return View(bid); so the error message is displayed. And you can use a conditional validation attribute to validate that MaxBid is greater that CurBid so you get client and server side validation
    – Stephen Muecke
    May 25 at 0:51






  • 1




    There are numerous improvements that can be made, most importantly by using view model, and separating all that logic into a separate method/service so it can be independently unit tested. And its not clear why you have the Guid itemId and string usrId parameters (especially when Bid appears to contain a property ItemId). Suggest you add the models to your question so its easier to understand your code
    – Stephen Muecke
    May 25 at 0:56






  • 1




    @C.Math, I added comments about that in your SO Question
    – Stephen Muecke
    May 25 at 10:22
















up vote
0
down vote

favorite












I am currently working on an Auction site with ASP.NET MVC and I have a functioning bidding process. On my items detail page I am showing the bids for that item in descending order for the amount and only including the current and previous leaders (1 (active) and 3 (superseded) in my BidStatusId property).



My auction bidding functions sort of like Ebay in that aspect ad I believe my logic is similar to their process as well. When a user clicks on a link to place a bid they are taken to my bid "Create" view page where they enter a max bid.



My code for creating a new Bid in my BidsController is below:



public ActionResult Create([Bind(Include = "BidId,ItemId,BidderId,MaxBid,CurBid,BidDate,BidStatusId")] Bid bid, Guid itemId, string usrId)

if (ModelState.IsValid)

Item item = db.Items.Find(itemId);
Bid activeBid = db.Bids.Find(item.ActiveBidId);
Usr usr = Usr.GetUsr(db, usrId);

//base case, starting bid
if (item.ActiveBidId == null && item.Bids.Count == 0)

bid.BidId = Guid.NewGuid();
bid.ItemId = item.ItemId;
bid.BidderId = usr.UsrId;
bid.BidDate = DateTime.Now;

bid.CurBid = item.InitialBid;
bid.BidStatusId = 1;
item.ActiveBidId = bid.BidId;
db.Bids.Add(bid);

else

//Validation for bid
if (bid.MaxBid < activeBid.CurBid)

ModelState.AddModelError(string.Empty, "Your maximum bid must be greater than the current bid."); //does not currently show the error on create page
return RedirectToAction("Create", "Bids", new itemId, usrId );


//If the user is the active bidder, they are updating their max bid
if (usr.UsrId == activeBid.Usr.UsrId)

activeBid.MaxBid = bid.MaxBid;

//They are bidding against another user
else

//Start creating new bid info
bid.BidId = Guid.NewGuid();
bid.ItemId = item.ItemId;
bid.BidderId = usr.UsrId;
bid.BidDate = DateTime.Now;

//1 is Active, 2 is Outbid, 3 is Superceded, 4 is inactive

//if bidder's max is higher than current bid's max, they are the new active bid
if (bid.MaxBid > activeBid.MaxBid)

//if the active bid isn't maxed out, then create a new maxed out autobid for that user
if(activeBid.CurBid != activeBid.MaxBid)

Bid activeMax = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 3, null, item, null, activeBid.Usr);
db.Bids.Add(activeMax);

activeBid.BidStatusId = 3;
//if the bid is less than the increment but more than current max, leave at max
if(bid.MaxBid < activeBid.MaxBid + item.IncrementBy)

bid.CurBid = bid.MaxBid;

//else increment the amount plus the current max bid
else

bid.CurBid = activeBid.MaxBid + item.IncrementBy;

bid.BidStatusId = 1;
item.ActiveBidId = bid.BidId;
db.Bids.Add(bid);

//if bidder's max is lower than the current bid's max, then an auto bid is created
// and the active bidder is still the active bidder with updated auto max bid
else if (bid.MaxBid < activeBid.MaxBid)

bid.CurBid = bid.MaxBid;
bid.BidStatusId = 2;
db.Bids.Add(bid);
activeBid.BidStatusId = 3;
Bid newActive;
if (activeBid.MaxBid < bid.MaxBid + item.IncrementBy)

newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 1, null, item, null, activeBid.Usr);

else

newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, bid.MaxBid + item.IncrementBy, DateTime.Now, 1, null, item, null, activeBid.Usr);

db.Bids.Add(newActive);
item.ActiveBidId = newActive.BidId;

//If the max's are the same then the activebidder is still the active bidder
//since he bid first, the bid will not show up on list currently (marked as outbid)
else if (bid.MaxBid == activeBid.MaxBid)

bid.CurBid = bid.MaxBid;
bid.BidStatusId = 2;
db.Bids.Add(bid);
activeBid.BidStatusId = 3;
Bid newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 1, null, item, null, activeBid.Usr);
db.Bids.Add(newActive);
item.ActiveBidId = newActive.BidId;




//Save changes to the db and redirect to the item's detail page
db.SaveChanges();
return RedirectToAction("Details", "Items", new id = itemId );




I believe my code as it stands does not enforce concurrency and is very rudimentary. I would like to know so that I can become a better programmer, (especially in MVC as I have only been using it for 5 days), if there are any improvements to my logic/process. Also if I am missing foresight as to what problems I could run into in the future coding like I am.




I am just looking to improve if anyone is willing to help me learn so I code in a more efficient way. My comments in my code outline what is going on and any problems that I am aware of.



Code for my "Create" Bid page:



div class="form-horizontal">
<h4>Bid</h4>
<hr />
@Html.ValidationSummary(true, "", new @class = "text-danger" )

<div class="form-group">
@Html.LabelFor(model => model.MaxBid, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.MaxBid, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.MaxBid, "", new @class = "text-danger" )
</div>
</div>


Code for my Bid Model



 public partial class Bid

public Bid()

this.Items = new HashSet<Item>();

public Bid(Guid bidId,Guid itemId, Guid bidderId, decimal maxBid, decimal curBid, DateTimeOffset bidDate,
int statusId, ICollection<Item> items, Item item, BidStatus bidStatus, Usr usr)

BidId = bidId;
BidderId = bidderId;
MaxBid = maxBid;
CurBid = curBid;
BidDate = bidDate;
BidStatusId = statusId;
Items = items;
Item = item;
BidStatus = bidStatus;
Usr = usr;


public System.Guid BidId get; set;
public System.Guid ItemId get; set;
public System.Guid BidderId get; set;

[Required(ErrorMessage = "Please enter a maximum bid")]
[Range(0, double.PositiveInfinity)]
public decimal MaxBid get; set;

public decimal CurBid get; set;
public System.DateTimeOffset BidDate get; set;
public int BidStatusId get; set;

public virtual ICollection<Item> Items get; set;
public virtual Item Item get; set;
public virtual BidStatus BidStatus get; set;
public virtual Usr Usr get; set;




Code for my Item Model



public partial class Item

public Item()

this.Bids = new HashSet<Bid>();


public System.Guid ItemId get; set;
public System.Guid CatId get; set;
public string ItemName get; set;
public string ItemDesc get; set;
public string ModelNo get; set;
public Nullable<decimal> RetailValue get; set;
public string ImageFileName get; set;
public System.DateTimeOffset StartDate get; set;
public System.DateTimeOffset EndDate get; set;
public decimal InitialBid get; set;
public decimal IncrementBy get; set;
public Nullable<System.Guid> ActiveBidId get; set;

public virtual Bid Bid get; set;
public virtual ICollection<Bid> Bids get; set;
public virtual Cat Cat get; set;







share|improve this question

















  • 1




    //does not currently show the error on create page is the goal to have the error show on the create page, or is that comment just stating that it doesn't show there because it is an implementation detail?
    – Sam Onela
    May 24 at 20:49










  • @SamOnela the goal is to have it show on the create page. I am trying to implement it to where is shows the error message right on the create page just like the data annotation error messages
    – C.Math
    May 24 at 20:57







  • 2




    Your return RedirectToAction("Create", "Bids", new itemId, usrId ); line of code makes no sense when you add a ModelStateError - its needs to be return View(bid); so the error message is displayed. And you can use a conditional validation attribute to validate that MaxBid is greater that CurBid so you get client and server side validation
    – Stephen Muecke
    May 25 at 0:51






  • 1




    There are numerous improvements that can be made, most importantly by using view model, and separating all that logic into a separate method/service so it can be independently unit tested. And its not clear why you have the Guid itemId and string usrId parameters (especially when Bid appears to contain a property ItemId). Suggest you add the models to your question so its easier to understand your code
    – Stephen Muecke
    May 25 at 0:56






  • 1




    @C.Math, I added comments about that in your SO Question
    – Stephen Muecke
    May 25 at 10:22












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am currently working on an Auction site with ASP.NET MVC and I have a functioning bidding process. On my items detail page I am showing the bids for that item in descending order for the amount and only including the current and previous leaders (1 (active) and 3 (superseded) in my BidStatusId property).



My auction bidding functions sort of like Ebay in that aspect ad I believe my logic is similar to their process as well. When a user clicks on a link to place a bid they are taken to my bid "Create" view page where they enter a max bid.



My code for creating a new Bid in my BidsController is below:



public ActionResult Create([Bind(Include = "BidId,ItemId,BidderId,MaxBid,CurBid,BidDate,BidStatusId")] Bid bid, Guid itemId, string usrId)

if (ModelState.IsValid)

Item item = db.Items.Find(itemId);
Bid activeBid = db.Bids.Find(item.ActiveBidId);
Usr usr = Usr.GetUsr(db, usrId);

//base case, starting bid
if (item.ActiveBidId == null && item.Bids.Count == 0)

bid.BidId = Guid.NewGuid();
bid.ItemId = item.ItemId;
bid.BidderId = usr.UsrId;
bid.BidDate = DateTime.Now;

bid.CurBid = item.InitialBid;
bid.BidStatusId = 1;
item.ActiveBidId = bid.BidId;
db.Bids.Add(bid);

else

//Validation for bid
if (bid.MaxBid < activeBid.CurBid)

ModelState.AddModelError(string.Empty, "Your maximum bid must be greater than the current bid."); //does not currently show the error on create page
return RedirectToAction("Create", "Bids", new itemId, usrId );


//If the user is the active bidder, they are updating their max bid
if (usr.UsrId == activeBid.Usr.UsrId)

activeBid.MaxBid = bid.MaxBid;

//They are bidding against another user
else

//Start creating new bid info
bid.BidId = Guid.NewGuid();
bid.ItemId = item.ItemId;
bid.BidderId = usr.UsrId;
bid.BidDate = DateTime.Now;

//1 is Active, 2 is Outbid, 3 is Superceded, 4 is inactive

//if bidder's max is higher than current bid's max, they are the new active bid
if (bid.MaxBid > activeBid.MaxBid)

//if the active bid isn't maxed out, then create a new maxed out autobid for that user
if(activeBid.CurBid != activeBid.MaxBid)

Bid activeMax = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 3, null, item, null, activeBid.Usr);
db.Bids.Add(activeMax);

activeBid.BidStatusId = 3;
//if the bid is less than the increment but more than current max, leave at max
if(bid.MaxBid < activeBid.MaxBid + item.IncrementBy)

bid.CurBid = bid.MaxBid;

//else increment the amount plus the current max bid
else

bid.CurBid = activeBid.MaxBid + item.IncrementBy;

bid.BidStatusId = 1;
item.ActiveBidId = bid.BidId;
db.Bids.Add(bid);

//if bidder's max is lower than the current bid's max, then an auto bid is created
// and the active bidder is still the active bidder with updated auto max bid
else if (bid.MaxBid < activeBid.MaxBid)

bid.CurBid = bid.MaxBid;
bid.BidStatusId = 2;
db.Bids.Add(bid);
activeBid.BidStatusId = 3;
Bid newActive;
if (activeBid.MaxBid < bid.MaxBid + item.IncrementBy)

newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 1, null, item, null, activeBid.Usr);

else

newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, bid.MaxBid + item.IncrementBy, DateTime.Now, 1, null, item, null, activeBid.Usr);

db.Bids.Add(newActive);
item.ActiveBidId = newActive.BidId;

//If the max's are the same then the activebidder is still the active bidder
//since he bid first, the bid will not show up on list currently (marked as outbid)
else if (bid.MaxBid == activeBid.MaxBid)

bid.CurBid = bid.MaxBid;
bid.BidStatusId = 2;
db.Bids.Add(bid);
activeBid.BidStatusId = 3;
Bid newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 1, null, item, null, activeBid.Usr);
db.Bids.Add(newActive);
item.ActiveBidId = newActive.BidId;




//Save changes to the db and redirect to the item's detail page
db.SaveChanges();
return RedirectToAction("Details", "Items", new id = itemId );




I believe my code as it stands does not enforce concurrency and is very rudimentary. I would like to know so that I can become a better programmer, (especially in MVC as I have only been using it for 5 days), if there are any improvements to my logic/process. Also if I am missing foresight as to what problems I could run into in the future coding like I am.




I am just looking to improve if anyone is willing to help me learn so I code in a more efficient way. My comments in my code outline what is going on and any problems that I am aware of.



Code for my "Create" Bid page:



div class="form-horizontal">
<h4>Bid</h4>
<hr />
@Html.ValidationSummary(true, "", new @class = "text-danger" )

<div class="form-group">
@Html.LabelFor(model => model.MaxBid, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.MaxBid, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.MaxBid, "", new @class = "text-danger" )
</div>
</div>


Code for my Bid Model



 public partial class Bid

public Bid()

this.Items = new HashSet<Item>();

public Bid(Guid bidId,Guid itemId, Guid bidderId, decimal maxBid, decimal curBid, DateTimeOffset bidDate,
int statusId, ICollection<Item> items, Item item, BidStatus bidStatus, Usr usr)

BidId = bidId;
BidderId = bidderId;
MaxBid = maxBid;
CurBid = curBid;
BidDate = bidDate;
BidStatusId = statusId;
Items = items;
Item = item;
BidStatus = bidStatus;
Usr = usr;


public System.Guid BidId get; set;
public System.Guid ItemId get; set;
public System.Guid BidderId get; set;

[Required(ErrorMessage = "Please enter a maximum bid")]
[Range(0, double.PositiveInfinity)]
public decimal MaxBid get; set;

public decimal CurBid get; set;
public System.DateTimeOffset BidDate get; set;
public int BidStatusId get; set;

public virtual ICollection<Item> Items get; set;
public virtual Item Item get; set;
public virtual BidStatus BidStatus get; set;
public virtual Usr Usr get; set;




Code for my Item Model



public partial class Item

public Item()

this.Bids = new HashSet<Bid>();


public System.Guid ItemId get; set;
public System.Guid CatId get; set;
public string ItemName get; set;
public string ItemDesc get; set;
public string ModelNo get; set;
public Nullable<decimal> RetailValue get; set;
public string ImageFileName get; set;
public System.DateTimeOffset StartDate get; set;
public System.DateTimeOffset EndDate get; set;
public decimal InitialBid get; set;
public decimal IncrementBy get; set;
public Nullable<System.Guid> ActiveBidId get; set;

public virtual Bid Bid get; set;
public virtual ICollection<Bid> Bids get; set;
public virtual Cat Cat get; set;







share|improve this question













I am currently working on an Auction site with ASP.NET MVC and I have a functioning bidding process. On my items detail page I am showing the bids for that item in descending order for the amount and only including the current and previous leaders (1 (active) and 3 (superseded) in my BidStatusId property).



My auction bidding functions sort of like Ebay in that aspect ad I believe my logic is similar to their process as well. When a user clicks on a link to place a bid they are taken to my bid "Create" view page where they enter a max bid.



My code for creating a new Bid in my BidsController is below:



public ActionResult Create([Bind(Include = "BidId,ItemId,BidderId,MaxBid,CurBid,BidDate,BidStatusId")] Bid bid, Guid itemId, string usrId)

if (ModelState.IsValid)

Item item = db.Items.Find(itemId);
Bid activeBid = db.Bids.Find(item.ActiveBidId);
Usr usr = Usr.GetUsr(db, usrId);

//base case, starting bid
if (item.ActiveBidId == null && item.Bids.Count == 0)

bid.BidId = Guid.NewGuid();
bid.ItemId = item.ItemId;
bid.BidderId = usr.UsrId;
bid.BidDate = DateTime.Now;

bid.CurBid = item.InitialBid;
bid.BidStatusId = 1;
item.ActiveBidId = bid.BidId;
db.Bids.Add(bid);

else

//Validation for bid
if (bid.MaxBid < activeBid.CurBid)

ModelState.AddModelError(string.Empty, "Your maximum bid must be greater than the current bid."); //does not currently show the error on create page
return RedirectToAction("Create", "Bids", new itemId, usrId );


//If the user is the active bidder, they are updating their max bid
if (usr.UsrId == activeBid.Usr.UsrId)

activeBid.MaxBid = bid.MaxBid;

//They are bidding against another user
else

//Start creating new bid info
bid.BidId = Guid.NewGuid();
bid.ItemId = item.ItemId;
bid.BidderId = usr.UsrId;
bid.BidDate = DateTime.Now;

//1 is Active, 2 is Outbid, 3 is Superceded, 4 is inactive

//if bidder's max is higher than current bid's max, they are the new active bid
if (bid.MaxBid > activeBid.MaxBid)

//if the active bid isn't maxed out, then create a new maxed out autobid for that user
if(activeBid.CurBid != activeBid.MaxBid)

Bid activeMax = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 3, null, item, null, activeBid.Usr);
db.Bids.Add(activeMax);

activeBid.BidStatusId = 3;
//if the bid is less than the increment but more than current max, leave at max
if(bid.MaxBid < activeBid.MaxBid + item.IncrementBy)

bid.CurBid = bid.MaxBid;

//else increment the amount plus the current max bid
else

bid.CurBid = activeBid.MaxBid + item.IncrementBy;

bid.BidStatusId = 1;
item.ActiveBidId = bid.BidId;
db.Bids.Add(bid);

//if bidder's max is lower than the current bid's max, then an auto bid is created
// and the active bidder is still the active bidder with updated auto max bid
else if (bid.MaxBid < activeBid.MaxBid)

bid.CurBid = bid.MaxBid;
bid.BidStatusId = 2;
db.Bids.Add(bid);
activeBid.BidStatusId = 3;
Bid newActive;
if (activeBid.MaxBid < bid.MaxBid + item.IncrementBy)

newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 1, null, item, null, activeBid.Usr);

else

newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, bid.MaxBid + item.IncrementBy, DateTime.Now, 1, null, item, null, activeBid.Usr);

db.Bids.Add(newActive);
item.ActiveBidId = newActive.BidId;

//If the max's are the same then the activebidder is still the active bidder
//since he bid first, the bid will not show up on list currently (marked as outbid)
else if (bid.MaxBid == activeBid.MaxBid)

bid.CurBid = bid.MaxBid;
bid.BidStatusId = 2;
db.Bids.Add(bid);
activeBid.BidStatusId = 3;
Bid newActive = new Bid(Guid.NewGuid(), itemId, activeBid.Usr.UsrId, activeBid.MaxBid, activeBid.MaxBid, DateTime.Now, 1, null, item, null, activeBid.Usr);
db.Bids.Add(newActive);
item.ActiveBidId = newActive.BidId;




//Save changes to the db and redirect to the item's detail page
db.SaveChanges();
return RedirectToAction("Details", "Items", new id = itemId );




I believe my code as it stands does not enforce concurrency and is very rudimentary. I would like to know so that I can become a better programmer, (especially in MVC as I have only been using it for 5 days), if there are any improvements to my logic/process. Also if I am missing foresight as to what problems I could run into in the future coding like I am.




I am just looking to improve if anyone is willing to help me learn so I code in a more efficient way. My comments in my code outline what is going on and any problems that I am aware of.



Code for my "Create" Bid page:



div class="form-horizontal">
<h4>Bid</h4>
<hr />
@Html.ValidationSummary(true, "", new @class = "text-danger" )

<div class="form-group">
@Html.LabelFor(model => model.MaxBid, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.MaxBid, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.MaxBid, "", new @class = "text-danger" )
</div>
</div>


Code for my Bid Model



 public partial class Bid

public Bid()

this.Items = new HashSet<Item>();

public Bid(Guid bidId,Guid itemId, Guid bidderId, decimal maxBid, decimal curBid, DateTimeOffset bidDate,
int statusId, ICollection<Item> items, Item item, BidStatus bidStatus, Usr usr)

BidId = bidId;
BidderId = bidderId;
MaxBid = maxBid;
CurBid = curBid;
BidDate = bidDate;
BidStatusId = statusId;
Items = items;
Item = item;
BidStatus = bidStatus;
Usr = usr;


public System.Guid BidId get; set;
public System.Guid ItemId get; set;
public System.Guid BidderId get; set;

[Required(ErrorMessage = "Please enter a maximum bid")]
[Range(0, double.PositiveInfinity)]
public decimal MaxBid get; set;

public decimal CurBid get; set;
public System.DateTimeOffset BidDate get; set;
public int BidStatusId get; set;

public virtual ICollection<Item> Items get; set;
public virtual Item Item get; set;
public virtual BidStatus BidStatus get; set;
public virtual Usr Usr get; set;




Code for my Item Model



public partial class Item

public Item()

this.Bids = new HashSet<Bid>();


public System.Guid ItemId get; set;
public System.Guid CatId get; set;
public string ItemName get; set;
public string ItemDesc get; set;
public string ModelNo get; set;
public Nullable<decimal> RetailValue get; set;
public string ImageFileName get; set;
public System.DateTimeOffset StartDate get; set;
public System.DateTimeOffset EndDate get; set;
public decimal InitialBid get; set;
public decimal IncrementBy get; set;
public Nullable<System.Guid> ActiveBidId get; set;

public virtual Bid Bid get; set;
public virtual ICollection<Bid> Bids get; set;
public virtual Cat Cat get; set;









share|improve this question












share|improve this question




share|improve this question








edited May 25 at 20:51









200_success

123k14143399




123k14143399









asked May 24 at 20:02









C.Math

1072




1072







  • 1




    //does not currently show the error on create page is the goal to have the error show on the create page, or is that comment just stating that it doesn't show there because it is an implementation detail?
    – Sam Onela
    May 24 at 20:49










  • @SamOnela the goal is to have it show on the create page. I am trying to implement it to where is shows the error message right on the create page just like the data annotation error messages
    – C.Math
    May 24 at 20:57







  • 2




    Your return RedirectToAction("Create", "Bids", new itemId, usrId ); line of code makes no sense when you add a ModelStateError - its needs to be return View(bid); so the error message is displayed. And you can use a conditional validation attribute to validate that MaxBid is greater that CurBid so you get client and server side validation
    – Stephen Muecke
    May 25 at 0:51






  • 1




    There are numerous improvements that can be made, most importantly by using view model, and separating all that logic into a separate method/service so it can be independently unit tested. And its not clear why you have the Guid itemId and string usrId parameters (especially when Bid appears to contain a property ItemId). Suggest you add the models to your question so its easier to understand your code
    – Stephen Muecke
    May 25 at 0:56






  • 1




    @C.Math, I added comments about that in your SO Question
    – Stephen Muecke
    May 25 at 10:22












  • 1




    //does not currently show the error on create page is the goal to have the error show on the create page, or is that comment just stating that it doesn't show there because it is an implementation detail?
    – Sam Onela
    May 24 at 20:49










  • @SamOnela the goal is to have it show on the create page. I am trying to implement it to where is shows the error message right on the create page just like the data annotation error messages
    – C.Math
    May 24 at 20:57







  • 2




    Your return RedirectToAction("Create", "Bids", new itemId, usrId ); line of code makes no sense when you add a ModelStateError - its needs to be return View(bid); so the error message is displayed. And you can use a conditional validation attribute to validate that MaxBid is greater that CurBid so you get client and server side validation
    – Stephen Muecke
    May 25 at 0:51






  • 1




    There are numerous improvements that can be made, most importantly by using view model, and separating all that logic into a separate method/service so it can be independently unit tested. And its not clear why you have the Guid itemId and string usrId parameters (especially when Bid appears to contain a property ItemId). Suggest you add the models to your question so its easier to understand your code
    – Stephen Muecke
    May 25 at 0:56






  • 1




    @C.Math, I added comments about that in your SO Question
    – Stephen Muecke
    May 25 at 10:22







1




1




//does not currently show the error on create page is the goal to have the error show on the create page, or is that comment just stating that it doesn't show there because it is an implementation detail?
– Sam Onela
May 24 at 20:49




//does not currently show the error on create page is the goal to have the error show on the create page, or is that comment just stating that it doesn't show there because it is an implementation detail?
– Sam Onela
May 24 at 20:49












@SamOnela the goal is to have it show on the create page. I am trying to implement it to where is shows the error message right on the create page just like the data annotation error messages
– C.Math
May 24 at 20:57





@SamOnela the goal is to have it show on the create page. I am trying to implement it to where is shows the error message right on the create page just like the data annotation error messages
– C.Math
May 24 at 20:57





2




2




Your return RedirectToAction("Create", "Bids", new itemId, usrId ); line of code makes no sense when you add a ModelStateError - its needs to be return View(bid); so the error message is displayed. And you can use a conditional validation attribute to validate that MaxBid is greater that CurBid so you get client and server side validation
– Stephen Muecke
May 25 at 0:51




Your return RedirectToAction("Create", "Bids", new itemId, usrId ); line of code makes no sense when you add a ModelStateError - its needs to be return View(bid); so the error message is displayed. And you can use a conditional validation attribute to validate that MaxBid is greater that CurBid so you get client and server side validation
– Stephen Muecke
May 25 at 0:51




1




1




There are numerous improvements that can be made, most importantly by using view model, and separating all that logic into a separate method/service so it can be independently unit tested. And its not clear why you have the Guid itemId and string usrId parameters (especially when Bid appears to contain a property ItemId). Suggest you add the models to your question so its easier to understand your code
– Stephen Muecke
May 25 at 0:56




There are numerous improvements that can be made, most importantly by using view model, and separating all that logic into a separate method/service so it can be independently unit tested. And its not clear why you have the Guid itemId and string usrId parameters (especially when Bid appears to contain a property ItemId). Suggest you add the models to your question so its easier to understand your code
– Stephen Muecke
May 25 at 0:56




1




1




@C.Math, I added comments about that in your SO Question
– Stephen Muecke
May 25 at 10:22




@C.Math, I added comments about that in your SO Question
– Stephen Muecke
May 25 at 10:22















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195115%2fauction-bidding-logic%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195115%2fauction-bidding-logic%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation