Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,6 @@ MigrationBackup/
# App_Data directory - ignore all contents except .gitkeep
**/App_Data/*
!**/App_Data/.gitkeep

# macOS
**/.DS_Store
6 changes: 6 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"sdk": {
"version": "9.0.302",
"rollForward": "latestFeature"
}
}
118 changes: 0 additions & 118 deletions packages.lock.json

This file was deleted.

16 changes: 15 additions & 1 deletion src/Microsoft.eShopWeb.Web/Basket/Basket.Component.fs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,21 @@ module BasketComponent =
class' "esh-basket-image" ] ]
section [ class' "esh-basket-item esh-basket-item--middle col" ] [ raw item.ProductName ]
section [ class' "esh-basket-item esh-basket-item--middle col" ] [ raw (item.UnitPrice.ToString "C") ]
section [ class' "esh-basket-item esh-basket-item--middle col" ] [ raw (item.Quantity.ToString()) ]
section [ class' "esh-basket-item esh-basket-item--middle col" ] [
div [ class' "d-flex align-items-center" ] [
Elem.form
[ method "post"; action "/basket/update-quantity"; class' "d-inline me-1" ]
[ input [ type' "hidden"; name "id"; value $"{item.CatalogItemId}" ]
input [ type' "hidden"; name "quantity"; value $"{item.Quantity - 1}" ]
input [ class' "btn btn-outline-secondary btn-sm"; type' "submit"; value "-" ] ]
Elem.span [ class' "mx-2" ] [ raw (item.Quantity.ToString()) ]
Elem.form
[ method "post"; action "/basket/update-quantity"; class' "d-inline ms-1" ]
[ input [ type' "hidden"; name "id"; value $"{item.CatalogItemId}" ]
input [ type' "hidden"; name "quantity"; value $"{item.Quantity + 1}" ]
input [ class' "btn btn-outline-secondary btn-sm"; type' "submit"; value "+" ] ]
]
]
section [ class' "esh-basket-item esh-basket-item--middle col" ] [ raw ((decimal(item.Quantity) * item.UnitPrice).ToString "C" ) ]
section [ class' "esh-basket-item esh-basket-item--middle col" ]
[ Elem.form
Expand Down
31 changes: 31 additions & 0 deletions src/Microsoft.eShopWeb.Web/Basket/Basket.Domain.fs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,37 @@ module BasketDomain =
return None
}

let updateBasketItemQuantity (db: ShopContext) catalogItemId newQuantity =
async {
let! existingBasket =
(db.Baskets.Include(fun b -> b.Items).OrderBy(fun b -> b.Id)) |> tryFirstAsync

let basket = existingBasket |> defaultValue emptyBasket

try
// Find the basket item to update
let itemToUpdate =
db.BasketItems.Where(fun bi -> bi.CatalogItemId = catalogItemId && bi.BasketId = basket.Id)
|> Seq.tryHead

match itemToUpdate with
| Some item ->
if newQuantity > 0 then
item.Quantity <- newQuantity
do! saveChangesAsync' db |> Async.Ignore
return Some newQuantity
else
// Remove the item if quantity becomes 0 or negative
db.BasketItems.Remove(item) |> ignore
do! saveChangesAsync' db |> Async.Ignore
return Some 0
| None ->
return None
with exp ->
printfn $"Error updating quantity for item {catalogItemId} in basket"; printfn $"{exp}"
return None
}

let removeFromBasket (db: ShopContext) catalogItemId =
async {
let! existingBasket =
Expand Down
17 changes: 17 additions & 0 deletions src/Microsoft.eShopWeb.Web/Basket/Basket.Page.fs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,23 @@ module BasketPage =
| None -> Response.redirectPermanently "/basket?error=notfound"
| Some _ -> Response.redirectPermanently "/basket?removed=success"))

let updateQuantity: HttpHandler =
Services.inject<ShopContext> (fun db ->

let mapAsync = fun (form: FormCollectionReader) ->
let catalogItemId = form.TryGetGuid "id"
let quantity = form.TryGetInt "quantity"

match catalogItemId, quantity with
| Some id, Some qty -> BasketDomain.updateBasketItemQuantity db id qty |> Async.StartAsTask
| _ -> async { return None } |> Async.StartAsTask

Request.mapFormAsync mapAsync (fun result ->
match result with
| None -> Response.redirectPermanently "/basket?error=updatefailed"
| Some 0 -> Response.redirectPermanently "/basket?removed=success"
| Some qty -> Response.redirectPermanently $"/basket?updated={qty}"))

// This uses a more low-level approach to reading the form
let postAlternate: HttpHandler =
Services.inject<ShopContext> (fun db -> fun ctx ->
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.eShopWeb.Web/Microsoft.eShopWeb.Web.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
<ItemGroup>
<PackageReference Include="EntityFrameworkCore.FSharp" Version="6.0.7" />
<PackageReference Include="Falco" Version="4.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.7" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions src/Microsoft.eShopWeb.Web/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ module Program =
get "/basket" BasketPage.get
post "/basket" BasketPage.post
post "/basket/remove" BasketPage.remove
post "/basket/update-quantity" BasketPage.updateQuantity

get "/identity/account/login" LoginPage.handler

Expand Down
3 changes: 1 addition & 2 deletions src/Microsoft.eShopWeb.Web/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"applicationUrl": "https://localhost:7055",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HTTPS_PORT": "7055",
"DOTNET_WATCH_RESTART_ON_RUDE_EDIT": "true"
}
},
Expand All @@ -25,4 +24,4 @@
}
}
}
}
}
Loading
Loading