예제 #1
0
        public int New(OrderNew viewModel)
        {
            Order order = null;

            order = new Order() {
                Address1 = viewModel.Address1,
                Address2 = viewModel.Address2,
                City = viewModel.City,
                CountryId = viewModel.CountryCode,
                Country = db.Countries.First(c => c.Id == viewModel.CountryCode.ToLower()),
                Email = viewModel.Email,
                Firstname = viewModel.Firstname,
                Name = viewModel.Name,
                Salutation = viewModel.Salutation,
                Zip = viewModel.Zip,
                Comment = viewModel.Comment
            };

            var productIdsAndQtys = viewModel.Products.ToDictionary(
                k => k.Id,
                v => v.Qty);

            new ShopService().PlaceOrder(db, order, productIdsAndQtys);

            return order.Id;
        }
예제 #2
0
 /// <summary>
 /// Versandkosten berechnen.
 /// </summary>
 /// <param name="order"></param>
 /// <returns></returns>
 public decimal CalculateShippingCosts(Order order)
 {
     if (order.Country == null) { throw new AppException("Für die Versandkosten muss ein Land angegeben sein!"); }
     return order.OrderLines.Sum(ol => order.Country.ShippingCost(ol.Product.ShippingCategory));
 }
예제 #3
0
        /// <summary>
        /// Bestellung abgeben.
        /// </summary>
        /// <param name="order"></param>
        /// <param name="productIdsAndQtys"></param>
        public void PlaceOrder(Entities db, Order order, IDictionary<int, int> productIdsAndQtys)
        {
            using (var transaction = new TransactionScope()) {
                // Bestellung mit Datum versehen und in DB speichern.
                order.CreatedAt = DateTime.Now;
				// Die Bestellung muss erstmal ohne Bestellzeilen gespeichert werden,
				// damit wir eine BestellID aus der DB haben.
                db.Orders.Add(order);
                db.SaveChanges();

                foreach (var id in productIdsAndQtys.Keys) {
                    var product = db.Products
                        .Include(p => p.ShippingCategory) // Brauchen wird für die Versandkostenberechnung.
                        .FirstOrDefault(x => x.Id == id);
                    var qty = productIdsAndQtys[id];
                    if (product == null) {
                        throw new AppException(string.Format(
                            "Das Produkt mit der Id {0} ist nicht verfügbar!",
                            id));
                    }
                    // Nicht mehr genug vom Produkt auf Lager?
                    if (product.Available < qty) {
                        throw new AppException(string.Format(
                            "Von {0} ist/sind nur noch {1} Stück auf Lager. Bitte Menge anpassen.",
                            product.Name,
                            product.Available));
                    }

                    // Menge abziehen.
                    product.Available -= qty;

                    // Produkte zur Bestellung hinzufügen.
                    order.OrderLines.Add(new OrderLine() {
                        OrderId = order.Id,
                        ProductId = id,
						Product = product,
                        Qty = qty
                    });
                }
				// ...speichern.
                db.SaveChanges();

				// Preis berechnen
                order.SubTotalPrice = CalculateSubTotalPrice(order);
				// Versandkosten berechnen
                order.ShippingCosts = CalculateShippingCosts(order);

                // Validierung.
                var vc = new ValidationContext(order, null, null);
                Validator.ValidateObject(order, vc, true);

				// ...speichern.
                db.SaveChanges();

                // Bestätigungsmail verschicken.
                var mailBody = Nustache.Core.Render.StringToString(db.Parameters.First().MailMessageOrdered, order);
                MailService.SendMailToCustomer(order.Email, "Deine Bestellung bei lillypark.com", mailBody);

                transaction.Complete();
            }

			// Benachrichtgung an den Shopinhaber, dass eine neue
			// Bestellung eingegangen ist.
			// INFO: Wenn das Verschicken fehlschlägt, soll die Bestellung dennoch angenommen werden.
            var ownerMailBody = string.Format(@"
Hi Lilly/Hoonie,

guckst Du <a href=""http://lillypark.com/orders/details/{0}"">hier</a>.

Liebe Grüße,

Dein WebShop", order.Id);
            MailService.SendMailToOwner("Eine neue Bestellung ist eingegangen.", ownerMailBody);
        }
예제 #4
0
        /// <summary>
        /// Markiert einen Auftrag als verschickt.
        /// </summary>
        /// <param name="order"></param>
        public void ShipOrder(Entities db, Order order, string mailBody)
        {
            if (order == null) { throw new ArgumentNullException("order"); }

            order.ShippedAt = DateTime.Now;

            // Email an den Kunden schicken.
            MailService.SendMailToCustomer(order.Email, "Deine Bestellung wurde verschickt", mailBody);
            db.SaveChanges();
        }
예제 #5
0
        /// <summary>
        /// Markiert einen Auftrag als bezahlt.
        /// </summary>
        /// <param name="order"></param>
        public void PayOrder(Entities db, Order order, string mailBody=null)
        {
            if (order == null) { throw new ArgumentNullException("order"); }

            order.PaidAt = DateTime.Now; // TODO: Vielleicht hat der Kunde schon vorher gezahlt?

			// Wenn kein Bestätigungs-Mail-Body angegeben wurde, 
			// müssen wir den selber erstellen.
            var body = mailBody == null
                ? Nustache.Core.Render.StringToString(db.Parameters.First().MailMessagePaid, order)
                : mailBody;

            // Email an den Kunden schicken.
            MailService.SendMailToCustomer(order.Email, "Wir haben Deine Bezahlung erhalten", body);

            db.SaveChanges();
        }
예제 #6
0
		/// <summary>
		/// Berechnet den Preis aller Bestellzeilen (ohne Versandkosten oder ähnlichem).
		/// </summary>
		/// <param name="order"></param>
		/// <returns></returns>
        public decimal CalculateSubTotalPrice(Order order)
        {
            return order.OrderLines
                .Select(ol => ol.Product.Price * ol.Qty)
                .Sum();
        }
예제 #7
0
        /// <summary>
        /// Place a new order from an existing cart.
        /// </summary>
        /// <param name="cartId"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public Order CreateOrder(int cartId, CreateOrderRequest request)
        {
            // Validate request.
            var vc = new ValidationContext(request);
            Validator.ValidateObject(request, vc, true);

            lock (_orderLock) // Only one order at a time.
            {
                using (var tx = new TransactionScope())
                {
                    using (var db = new Entities())
                    {
                        // Get cart.
                        var cart = db.Carts
                            .Include(i => i.LineItems.Select(l => l.Product))
                            .Single(c => c.Id == cartId);

                        if (cart.OrderId.HasValue) {
                                throw new ApplicationException(string.Format(
                                    "Dieser Warenkorb ({0} wurde bereits bestellt!",
                                    cartId));
                        }

                        // Calcualte costs and taxes.
                        var shippingCosts = _ShippingService.CalculateShippingCosts(cartId, request.DeliveryAddress.CountryId);
                        var tax = _TaxService.TaxForCountry(cartId, request.DeliveryAddress.CountryId);

                        var da = request.DeliveryAddress;

                        // Create new Order.
                        var order = new Order
                        {
                            // Adressen
                            Address1 = da.Address1,
                            Address2 = da.Address2,
                            City = da.City,
                            CountryId = da.CountryId,
                            Email = da.Email,
                            Firstname = da.Firstname,
                            Name = da.Lastname,
                            Salutation = da.Salutation,
                            Zip = da.Zip,

                            ShippingCosts = shippingCosts,
                            Tax = tax,
                            SubTotalPrice = cart.Subtotal,
                            Total = cart.Subtotal + shippingCosts + tax,

                            CreatedAt = DateTime.UtcNow
                        };

                        // Order speicher.
                        db.Orders.Add(order);
                        db.SaveChanges();

                        // Alle Lineitems der Order zuweisen.
                        foreach (var lineItem in cart.LineItems)
                        {
                            if (lineItem.Product == null)
                            {
                                throw new ApplicationException(string.Format(
                                    "Das Produkt mit der Id {0} ist nicht verfügbar!",
                                    lineItem.ProductId));
                            }
                            if (lineItem.Product.Available < lineItem.Qty)
                            {
                                throw new ApplicationException(string.Format(
                                    "Von {0} ist/sind nur noch {1} Stück auf Lager. Bitte Menge anpassen.",
                                    lineItem.Product.Name,
                                    lineItem.Product.Available));
                            }

                            lineItem.Product.Available -= lineItem.Qty;
                            lineItem.OrderId = order.Id;
                        }

                        // Mark cart as ordered.
                        cart.OrderId = order.Id;

                        // Bestätigungsmail verschicken.
                        //var mailBody = Nustache.Core.Render.StringToString(db.Parameters.First().MailMessageOrdered, order);
                        //MailService.SendMailToCustomer(order.Email, "Deine Bestellung bei lillypark.com", mailBody);

                        // Commit!
                        tx.Complete();

                        return order;
                    }
                }
            }
        }
예제 #8
0
        public virtual ActionResult Index(PostOrderNew viewModel)
        {
            if (ModelState.IsValid) {

                try {
                    var order = new Order() {
                        Address1 = viewModel.Address1,
                        Address2 = viewModel.Address2,
                        City = viewModel.City,
                        CountryId = viewModel.CountryCode,
                        Country = db.Countries.First(c => c.Id == viewModel.CountryCode.ToLower()),
                        Email = viewModel.Email,
                        Firstname = viewModel.Firstname,
                        Name = viewModel.Name,
                        Salutation = viewModel.Salutation,
                        Zip = viewModel.Zip,
                        Comment = viewModel.Comment
                    };

                    var productIdsAndQtys = viewModel.Products.ToDictionary(
                        k => k.Id,
                        v => v.Qty);

                    new ShopService().PlaceOrder(db, order, productIdsAndQtys);

                    return viewModel.UsesPayPal
                        ? RedirectToAction("create", "paypal", new { orderId = order.Id })
                        : RedirectToAction("success", new { id = order.Id });

                }
                catch (AppException e) {
                    Error(e.Message);
                }
            }

			// ViewModel um die Länder anreichern.
            var vm = new OrderNew(db.Countries);
            return View("index", Mapper.Map(viewModel, vm));
        }