using System;
using System.Collections.Generic;
using System.Linq;
using ECommerceSystem.Repository;
namespace ECommerceSystem.Domain
{
public class ECommerceSellerSystem
{
public ECommerceSellerSystem()
{
}
public ShoppingCartSelection AddSelectionToCustomerCart(ProductDescription product_description,ShoppingCart cart,int quantity)
{
return new ShoppingCartSelection(product_description, cart,quantity);
}
public Order MakeOrder(ShoppingCart cart,bool is_fast,bool is_gift_wrap)
{
//***************************************
//ISOLATION & SYNCHRO REQUIRED HERE LATER
//***************************************
//ProductDescriptions in Cart must be
//Changed to Items in Inventory here
//and a order must be created
//Item availability in inventory must
//be handled
//Use PRODUCTDESCRIPTIONID which is a
//FOREIGN KEY IN INVENTORY ITEM to pull
//items
Order order = new Order();
order.OrderedByCustomer = cart.CartOfCustomer;
order.IsGiftWrapped = is_gift_wrap;
order.IsFastShipping = is_fast;
IRepository<Item> item_repo = new DBRepository<Item>();
try
{
foreach (ShoppingCartSelection selection in cart.CartSelections)
{
for (int count = 0; count < selection.Quantity; count++)
{
Item inventory_item = NewItemMatchingProductDescription(selection.CurrentProduct);
if (inventory_item != null)
{
inventory_item.IsShopCarted = true;
item_repo.updateItem(inventory_item);
order.OrderItems.Add(inventory_item);
}
//else if it is null item is unavailable
//add selection to not available list in orders collection
else
order.NotAvailableItemDescriptions.Add(selection.CurrentProduct);
}
}
}
catch (Exception ex)
{
}
return order;
}
public void DestructShoppingCartBindingForItemsInOrder(Order order)
{
//************************************************************************
//The IsCartedState of Item exists only when a order is made. At the exit
//of making an order, the IsCarted state should be destroyed immaterial
//of whether order was made or not. A item will never be allowed to be carted
//permanently. A item can exist in inventory or in order but not in cart.SO,
// Whenever a Order object is destroyed
// call this method for that Order.It destroys the item bindings to cart.
//If a Order goes out of scope, before it goes out
// of scope, this method is called (example by using unload event handler etc).
//So a item will be paid or in inventory only. When a Order is made a item can be carted, but
//by the end of order lifetime item will cease to
// exist in cart because we set IsShopCarted to false.
//***************************************************************************
try
{
IRepository<Item> inventory_item_repo = new DBRepository<Item>();
foreach (Item item in order.OrderItems)
{
item.IsShopCarted = false;
inventory_item_repo.updateItem(item);
}
}
catch (Exception ex)
{
}
}
public Order ProcessAmountForOrder(Order order)
{
double total_order_amount = 0;
//Calculate Total Payment
foreach (Item item in order.OrderItems)
{
total_order_amount += item.ItemDescription.Price;
}
foreach (ProductDescription desc in order.NotAvailableItemDescriptions)
{
total_order_amount += desc.Price;
}
order.OrderCost = total_order_amount;
//Calculate Shipping cost
Shipping shipping = ProvideShippingInformation(total_order_amount, order.IsFastShipping, order.IsGiftWrapped);
if (shipping != null)
{
order.ShippingCharges = shipping.ShippingCharges;
}
return order;
}
public PaymentApprovedOrder MakeOrderPayment(Order order, Payment pay)
{
PaymentApprovedOrder paid_order = null;
NHibernateHelper nh = NHibernateHelper.Create();
using (NHibernate.ITransaction transaction = nh.Session.BeginTransaction())
{
IRepository<PaymentApprovedOrder> pay_order_repo = new DBRepository<PaymentApprovedOrder>();
IRepository<Shipping> shipping_repo = new DBRepository<Shipping>();
MarkItemAsOrdered(order);
paid_order = new PaymentApprovedOrder(order, pay);
pay_order_repo.addItem(paid_order);
//Item will have only two states - Is Ordered or Inventory item.
//The IsCartedState of Item exists only when a order is made. At the exit
//of making a order, the IsCarted state should be destroyed,
DestructShoppingCartBindingForItemsInOrder(order);
Shipping shipping = ProvideShippingInformation(order.OrderCost, order.IsFastShipping, order.IsGiftWrapped);
shipping.ShippingCharges = order.ShippingCharges;
shipping.PrimaryPaidOrderId = paid_order.PaymentApprovedOrderId;
shipping_repo.addItem(shipping);
transaction.Commit();
}
return paid_order;
}
public Shipping ProvideShippingInformation(double order_amount,bool is_fast_shipping,bool is_gift_wrapped)
{
//Important thing to note here is PaymentApprovedOrder is already saved in db
//no need to process a transaction to envelope both
Shipping shipping = null;
if (!is_fast_shipping)
{
shipping = new ParcelService(is_gift_wrapped);
}
else
{
//Fast Shipping - same day delivery - no time for gift wraps
//So only the latest date by which item should be sent - i.e today
//which is same day as order day
shipping = new FastShipping(DateTime.Today);
}
shipping.CalculateShippingCharges(order_amount);
//MostImportant thing is Shipping is abstract super class -
//having two concrete child classes
//We did not tell NHibernate which child class we are dealing with
return shipping;
}
public Item NewItemMatchingProductDescription(ProductDescription product_description)
{
Item inventory_item = null;
try
{
//create nhibernatehelper for query
NHibernateHelper nh = NHibernateHelper.Create();
string query_string = "from Item item1 where item1.ItemDescription = :description" +
" and item1.IsOrdered = :ordered_truth_value and item1.IsShopCarted = :karted_truth_value";
IList<Item> inventory_items_list = nh.Session.CreateQuery(query_string).
SetParameter<ProductDescription>("description", product_description).
SetParameter<bool>("ordered_truth_value", false).
SetParameter<bool>("karted_truth_value",false).List<Item>();
if (inventory_items_list != null && inventory_items_list.Count > 0)
inventory_item = inventory_items_list[0];
}
catch (Exception ex)
{
}
return inventory_item;
}
public void MarkItemAsOrdered(Order order)
{
//Isolation Control Required
try
{
foreach (Item inventory_item in order.OrderItems)
{
inventory_item.IsOrdered = true;
}
}
catch (Exception ex)
{
}
finally
{
}
}
public Shipping AddShippingInformation(bool is_primary, bool is_fast, long prime_id, string shipping_name, DateTime shipping_start_date, string tracking_number,bool is_gift_wrapped)
{
Shipping shipping = null;
IRepository<Shipping> shipping_repo = new DBRepository<Shipping>();
NHibernate.ISession session = null;
NHibernateHelper nh = NHibernateHelper.Create();
session = nh.Session;
if (is_primary)
{
string query_string = "from Shipping shipping1 where shipping1.PrimaryPaidOrderId = :prime_id";
shipping = session.CreateQuery(query_string).SetParameter<long>("prime_id",prime_id).UniqueResult<Shipping>();
if (shipping != null)
{
shipping.ShippingName = shipping_name;
shipping.ShippingStartDate = DateTime.Today;
if (shipping is FastShipping)
((FastShipping)shipping).TrackingNumber = tracking_number;
}
}
else
{
if (is_fast)
{
shipping = new FastShipping { ShippingName=shipping_name, ShippingStartDate=DateTime.Today, PrimaryPaidOrderId=null, TrackingNumber=tracking_number };
}
else
{
shipping = new ParcelService { ShippingName = shipping_name, ShippingStartDate = DateTime.Today, PrimaryPaidOrderId = null, IsGiftWrapped = is_gift_wrapped };
}
}
if (shipping != null)
{
using (NHibernate.ITransaction trans = session.BeginTransaction())
{
session.SaveOrUpdate(shipping);
trans.Commit();
}
}
return shipping;
}
public OrderShipment CreateOrderShipment(PaymentApprovedOrder paid_order, Shipping shipping)
{
return new OrderShipment(paid_order, shipping);
}
public void AddShipmentItem(OrderShipment order_shipment, string inventory_serial_code)
{
//The barcode scanner returns a string of inventory serial code.
//Item instance will have to be retrieved using serial code.
//Item in Inventory will have to be deleted inside Transaction.
//In the same transaction, the item has to be added to inventory.
NHibernateHelper nh = NHibernateHelper.Create();
using (NHibernate.ISession session = nh.Session)
{
string query_string = "from Item item1 where item1.InventorySerialCode = :code";
Item inventory_item = session.CreateQuery(query_string).SetParameter<string>("code", inventory_serial_code).UniqueResult<Item>();
if (inventory_item != null)
{
IRepository<Item> item_repository = new DBRepository<Item>();
IRepository<OrderShipment> order_shipment_repository = new DBRepository<OrderShipment>();
using (NHibernate.ITransaction trans = session.BeginTransaction())
{
inventory_item.PaidOrder.PaidOrderItems.Remove(inventory_item);
session.Delete(inventory_item);
order_shipment.ShipmentItems.Add(new ShipmentItem { InventorySerialCode = inventory_item.InventorySerialCode });
session.SaveOrUpdate(order_shipment);
trans.Commit();
}
}
}
}
}
}