@ -0,0 +1,100 @@ | |||
using eShopOnContainers.Core.Helpers; | |||
using eShopOnContainers.ViewModels.Base; | |||
using System; | |||
using System.Collections.ObjectModel; | |||
namespace eShopOnContainers.Core.Models.Basket | |||
{ | |||
public class BasketItem : ExtendedBindableObject | |||
{ | |||
private string _id; | |||
private string _productId; | |||
private string _productName; | |||
private decimal _unitPrice; | |||
private int _quantity; | |||
private string _pictureUrl; | |||
private ObservableCollection<int> _numbers; | |||
public BasketItem() | |||
{ | |||
Numbers = NumericHelper.GetNumericList(); | |||
} | |||
public string Id | |||
{ | |||
get { return _id; } | |||
set | |||
{ | |||
_id = value; | |||
RaisePropertyChanged(() => Id); | |||
} | |||
} | |||
public string ProductId | |||
{ | |||
get { return _productId; } | |||
set | |||
{ | |||
_productId = value; | |||
RaisePropertyChanged(() => ProductId); | |||
} | |||
} | |||
public string ProductName | |||
{ | |||
get { return _productName; } | |||
set | |||
{ | |||
_productName = value; | |||
RaisePropertyChanged(() => ProductName); | |||
} | |||
} | |||
public decimal UnitPrice | |||
{ | |||
get { return _unitPrice; } | |||
set | |||
{ | |||
_unitPrice = value; | |||
RaisePropertyChanged(() => UnitPrice); | |||
} | |||
} | |||
public int Quantity | |||
{ | |||
get { return _quantity; } | |||
set | |||
{ | |||
_quantity = value; | |||
RaisePropertyChanged(() => Quantity); | |||
} | |||
} | |||
public string PictureUrl | |||
{ | |||
get { return _pictureUrl; } | |||
set | |||
{ | |||
_pictureUrl = value; | |||
RaisePropertyChanged(() => PictureUrl); | |||
} | |||
} | |||
public decimal Total { get { return Quantity * UnitPrice; } } | |||
public ObservableCollection<int> Numbers | |||
{ | |||
get { return _numbers; } | |||
set | |||
{ | |||
_numbers = value; | |||
RaisePropertyChanged(() => Numbers); | |||
} | |||
} | |||
public override string ToString() | |||
{ | |||
return String.Format("Product Id: {0}, Quantity: {1}", ProductId, Quantity); | |||
} | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
using System.Collections.Generic; | |||
namespace eShopOnContainers.Core.Models.Basket | |||
{ | |||
public class CustomerBasket | |||
{ | |||
public string BuyerId { get; set; } | |||
public List<BasketItem> Items { get; set; } | |||
} | |||
} |
@ -0,0 +1,42 @@ | |||
using eShopOnContainers.Core.Models.Basket; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms; | |||
using System; | |||
namespace eShopOnContainers.Core.Services.Basket | |||
{ | |||
public class BasketMockService : IBasketService | |||
{ | |||
private CustomerBasket MockCustomBasket = new CustomerBasket | |||
{ | |||
BuyerId = "9245fe4a-d402-451c-b9ed-9c1a04247482", | |||
Items = new List<BasketItem> | |||
{ | |||
new BasketItem { Id = "1", PictureUrl = Device.OS != TargetPlatform.Windows ? "fake_product_01.png" : "Assets/fake_product_01.png", ProductId = "1", ProductName = ".NET Bot Blue Sweatshirt (M)", Quantity = 1, UnitPrice = 19.50M }, | |||
new BasketItem { Id = "2", PictureUrl = Device.OS != TargetPlatform.Windows ? "fake_product_04.png" : "Assets/fake_product_04.png", ProductId = "4", ProductName = ".NET Black Cupt", Quantity = 1, UnitPrice = 17.00M } | |||
} | |||
}; | |||
public async Task<CustomerBasket> GetBasketAsync(string guidUser) | |||
{ | |||
await Task.Delay(500); | |||
if(string.IsNullOrEmpty(guidUser)) | |||
{ | |||
return new CustomerBasket(); | |||
} | |||
return MockCustomBasket; | |||
} | |||
public async Task<CustomerBasket> UpdateBasketAsync(CustomerBasket customerBasket) | |||
{ | |||
await Task.Delay(500); | |||
MockCustomBasket = customerBasket; | |||
return MockCustomBasket; | |||
} | |||
} | |||
} |
@ -0,0 +1,53 @@ | |||
using System; | |||
using System.Threading.Tasks; | |||
using eShopOnContainers.Core.Services.RequestProvider; | |||
using eShopOnContainers.Core.Models.Basket; | |||
namespace eShopOnContainers.Core.Services.Basket | |||
{ | |||
public class BasketService : IBasketService | |||
{ | |||
private readonly IRequestProvider _requestProvider; | |||
public BasketService(IRequestProvider requestProvider) | |||
{ | |||
_requestProvider = requestProvider; | |||
} | |||
public async Task<CustomerBasket> GetBasketAsync(string guidUser) | |||
{ | |||
try | |||
{ | |||
UriBuilder builder = new UriBuilder(GlobalSetting.CatalogEndpoint); | |||
builder.Path = guidUser; | |||
string uri = builder.ToString(); | |||
CustomerBasket basket = | |||
await _requestProvider.GetAsync<CustomerBasket>(uri); | |||
return basket; | |||
} | |||
catch | |||
{ | |||
return new CustomerBasket | |||
{ | |||
BuyerId = guidUser, | |||
Items = new System.Collections.Generic.List<BasketItem>() | |||
}; | |||
} | |||
} | |||
public async Task<CustomerBasket> UpdateBasketAsync(CustomerBasket customerBasket) | |||
{ | |||
UriBuilder builder = new UriBuilder(GlobalSetting.CatalogEndpoint); | |||
string uri = builder.ToString(); | |||
var result = await _requestProvider.PostAsync(uri, customerBasket); | |||
return result; | |||
} | |||
} | |||
} |
@ -0,0 +1,11 @@ | |||
using eShopOnContainers.Core.Models.Basket; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Core.Services.Basket | |||
{ | |||
public interface IBasketService | |||
{ | |||
Task<CustomerBasket> GetBasketAsync(string guidUser); | |||
Task<CustomerBasket> UpdateBasketAsync(CustomerBasket customerBasket); | |||
} | |||
} |
@ -1,13 +0,0 @@ | |||
using eShopOnContainers.Core.Models.Orders; | |||
using System.Collections.ObjectModel; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Core.Services.Orders | |||
{ | |||
public interface IOrdersService | |||
{ | |||
Task<ObservableCollection<Order>> GetOrdersAsync(); | |||
Task<Order> GetCartAsync(); | |||
} | |||
} |
@ -1,39 +0,0 @@ | |||
using eShopOnContainers.Core.Models.Orders; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Core.Services.Orders | |||
{ | |||
public class OrdersMockService : IOrdersService | |||
{ | |||
public async Task<ObservableCollection<Order>> GetOrdersAsync() | |||
{ | |||
await Task.Delay(500); | |||
return new ObservableCollection<Order> | |||
{ | |||
new Order { SequenceNumber = 123, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = GetOrderItems() }, | |||
new Order { SequenceNumber = 132, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = GetOrderItems() }, | |||
new Order { SequenceNumber = 231, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = GetOrderItems() }, | |||
}; | |||
} | |||
public async Task<Order> GetCartAsync() | |||
{ | |||
await Task.Delay(500); | |||
return new Order { SequenceNumber = 0123456789, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Pending, OrderItems = GetOrderItems() }; | |||
} | |||
private List<OrderItem> GetOrderItems() | |||
{ | |||
return new List<OrderItem> | |||
{ | |||
new OrderItem { OrderId = Guid.NewGuid(), ProductId = 1, Discount = 15, ProductName = ".NET Bot Blue Sweatshirt (M)", Quantity = 1, UnitPrice = 16.50M }, | |||
new OrderItem { OrderId = Guid.NewGuid(), ProductId = 3, Discount = 0, ProductName = ".NET Bot Black Sweatshirt (M)", Quantity = 2, UnitPrice = 19.95M } | |||
}; | |||
} | |||
} | |||
} |
@ -1,9 +1,12 @@ | |||
using System.Threading.Tasks; | |||
using eShopOnContainers.Core.Models.Orders; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Core.Services.User | |||
{ | |||
public interface IUserService | |||
{ | |||
Task<Models.User.User> GetUserAsync(); | |||
Task<List<Order>> GetOrdersAsync(); | |||
} | |||
} | |||
} |
@ -0,0 +1,150 @@ | |||
using eShopOnContainers.Core.Models.Basket; | |||
using eShopOnContainers.Core.Models.Catalog; | |||
using eShopOnContainers.Core.Models.Orders; | |||
using eShopOnContainers.Core.Models.User; | |||
using eShopOnContainers.Core.Services.Basket; | |||
using eShopOnContainers.Core.Services.User; | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
using eShopOnContainers.ViewModels.Base; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using System.Windows.Input; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class BasketViewModel : ViewModelBase | |||
{ | |||
private User _user; | |||
private int _badgeCount; | |||
private ObservableCollection<BasketItem> _basketItems; | |||
private decimal _total; | |||
private IUserService _userService; | |||
private IBasketService _basketService; | |||
public BasketViewModel(IUserService userService, | |||
IBasketService basketService) | |||
{ | |||
_userService = userService; | |||
_basketService = basketService; | |||
} | |||
public int BadgeCount | |||
{ | |||
get { return _badgeCount; } | |||
set | |||
{ | |||
_badgeCount = value; | |||
RaisePropertyChanged(() => BadgeCount); | |||
} | |||
} | |||
public ObservableCollection<BasketItem> BasketItems | |||
{ | |||
get { return _basketItems; } | |||
set | |||
{ | |||
_basketItems = value; | |||
RaisePropertyChanged(() => BasketItems); | |||
} | |||
} | |||
public decimal Total | |||
{ | |||
get { return _total; } | |||
set | |||
{ | |||
_total = value; | |||
RaisePropertyChanged(() => Total); | |||
} | |||
} | |||
public ICommand CheckoutCommand => new Command(Checkout); | |||
public override async Task InitializeAsync(object navigationData) | |||
{ | |||
MessagingCenter.Subscribe<CatalogViewModel, List<BasketItem>>(this, MessengerKeys.UpdateBasket, (sender, arg) => | |||
{ | |||
BadgeCount = arg.Count; | |||
foreach (var basketItem in arg) | |||
{ | |||
AddBasketItem(basketItem); | |||
} | |||
}); | |||
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(this, MessengerKeys.AddProduct, (sender, arg) => | |||
{ | |||
BadgeCount++; | |||
AddCatalogItem(arg); | |||
}); | |||
MessagingCenter.Subscribe<OrderItem>(this, MessengerKeys.UpdateProduct, (sender) => | |||
{ | |||
ReCalculateTotal(); | |||
}); | |||
_user = await _userService.GetUserAsync(); | |||
BasketItems = new ObservableCollection<BasketItem>(); | |||
} | |||
private void AddCatalogItem(CatalogItem item) | |||
{ | |||
if (BasketItems.Any(o => o.ProductId.Equals(item.Id, StringComparison.CurrentCultureIgnoreCase))) | |||
{ | |||
var orderItem = BasketItems.First(o => o.ProductId.Equals(item.Id, StringComparison.CurrentCultureIgnoreCase)); | |||
orderItem.Quantity++; | |||
} | |||
else | |||
{ | |||
BasketItems.Add(new BasketItem | |||
{ | |||
ProductId = item.Id, | |||
ProductName = item.Name, | |||
PictureUrl = item.PictureUri, | |||
UnitPrice = item.Price, | |||
Quantity = 1 | |||
}); | |||
} | |||
ReCalculateTotal(); | |||
} | |||
private void AddBasketItem(BasketItem item) | |||
{ | |||
BasketItems.Add(item); | |||
ReCalculateTotal(); | |||
} | |||
private void ReCalculateTotal() | |||
{ | |||
Total = 0; | |||
foreach (var orderItem in BasketItems) | |||
{ | |||
Total += (orderItem.Quantity * orderItem.UnitPrice); | |||
} | |||
_basketService.UpdateBasketAsync(new CustomerBasket | |||
{ | |||
BuyerId = _user.GuidUser, | |||
Items = BasketItems.ToList() | |||
}); | |||
} | |||
private void Checkout() | |||
{ | |||
if (BasketItems.Any()) | |||
{ | |||
NavigationService.NavigateToAsync<CheckoutViewModel>(BasketItems); | |||
} | |||
} | |||
} | |||
} |
@ -1,117 +0,0 @@ | |||
using eShopOnContainers.Core.Helpers; | |||
using eShopOnContainers.Core.Models.Catalog; | |||
using eShopOnContainers.Core.Models.Orders; | |||
using eShopOnContainers.Core.Services.Orders; | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
using eShopOnContainers.ViewModels.Base; | |||
using System; | |||
using System.Collections.ObjectModel; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using System.Windows.Input; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class CartViewModel : ViewModelBase | |||
{ | |||
private int _badgeCount; | |||
private ObservableCollection<OrderItem> _orderItems; | |||
private decimal _total; | |||
private IOrdersService _orderService; | |||
public CartViewModel(IOrdersService orderService) | |||
{ | |||
_orderService = orderService; | |||
} | |||
public int BadgeCount | |||
{ | |||
get { return _badgeCount; } | |||
set | |||
{ | |||
_badgeCount = value; | |||
RaisePropertyChanged(() => BadgeCount); | |||
} | |||
} | |||
public ObservableCollection<OrderItem> OrderItems | |||
{ | |||
get { return _orderItems; } | |||
set | |||
{ | |||
_orderItems = value; | |||
RaisePropertyChanged(() => OrderItems); | |||
} | |||
} | |||
public decimal Total | |||
{ | |||
get { return _total; } | |||
set | |||
{ | |||
_total = value; | |||
RaisePropertyChanged(() => Total); | |||
} | |||
} | |||
public ICommand CheckoutCommand => new Command(Checkout); | |||
public override Task InitializeAsync(object navigationData) | |||
{ | |||
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(this, MessengerKeys.AddProduct, (sender, arg) => | |||
{ | |||
BadgeCount++; | |||
AddCartItem(arg); | |||
}); | |||
MessagingCenter.Subscribe<OrderItem>(this, MessengerKeys.UpdateProduct, (sender) => | |||
{ | |||
ReCalculateTotal(); | |||
}); | |||
OrderItems = new ObservableCollection<OrderItem>(); | |||
return base.InitializeAsync(navigationData); | |||
} | |||
private void AddCartItem(CatalogItem item) | |||
{ | |||
if (OrderItems.Any(o => o.ProductId == Convert.ToInt32(item.Id))) | |||
{ | |||
var orderItem = OrderItems.First(o => o.ProductId == Convert.ToInt32(item.Id)); | |||
orderItem.Quantity++; | |||
} | |||
else | |||
{ | |||
OrderItems.Add(new OrderItem | |||
{ | |||
ProductId = Convert.ToInt32(item.Id), | |||
ProductName = item.Name, | |||
ProductImage = item.PictureUri, | |||
UnitPrice = item.Price, | |||
Quantity = 1 | |||
}); | |||
} | |||
ReCalculateTotal(); | |||
} | |||
private void ReCalculateTotal() | |||
{ | |||
Total = 0; | |||
foreach (var orderItem in OrderItems) | |||
{ | |||
Total += orderItem.Total; | |||
} | |||
} | |||
private void Checkout() | |||
{ | |||
NavigationService.NavigateToAsync<CheckoutViewModel>(OrderItems); | |||
} | |||
} | |||
} |