/// <summary> /// Generates a customer password request for this user /// </summary> public void GeneratePasswordRequest() { this.Comment = StringHelper.RandomString(12); this.Save(); string sep = Token.Instance.Store.StoreUrl.EndsWith("/") ? "" : "/"; string resetPasswordLink = Token.Instance.Store.StoreUrl + sep + "PasswordHelp.aspx?Key={0}&Check={1}"; resetPasswordLink = string.Format(resetPasswordLink, this.UserId, this.Comment); if (this.IsAdmin) { Logger.Audit(AuditEventType.PasswordRequest, true, string.Empty); } StoreEventEngine.CustomerPasswordRequest(this, resetPasswordLink); }
protected void GiftCertificatesGrid_RowCommand(object sender, GridViewCommandEventArgs e) { int index = AlwaysConvert.ToInt(e.CommandArgument); int GiftCertificateId = AlwaysConvert.ToInt(GiftCertificatesGrid.DataKeys[index].Value); GiftCertificate gc = FindGiftCertificate(GiftCertificateId); if (gc == null) { return; } IGiftCertKeyProvider provider = AbleContext.Container.Resolve <IGiftCertKeyProvider>(); GiftCertificateTransaction trans; if (e.CommandName.Equals("Activate")) { gc.SerialNumber = provider.GenerateGiftCertificateKey(); trans = new GiftCertificateTransaction(); trans.GiftCertificate = gc; trans.Amount = gc.Balance; trans.Description = "Gift certificate activated."; trans.OrderId = _Order.Id; trans.TransactionDate = LocaleHelper.LocalNow; gc.Transactions.Add(trans); gc.Save(); // Trigger Gift Certificate Activated / Validate Event StoreEventEngine.GiftCertificateValidated(gc, trans); BindGiftCertificatesGrid(); } else if (e.CommandName.Equals("Deactivate")) { gc.SerialNumber = ""; trans = new GiftCertificateTransaction(); trans.GiftCertificate = gc; trans.Amount = gc.Balance; trans.Description = "Gift certificate deactivated."; trans.OrderId = _Order.Id; trans.TransactionDate = LocaleHelper.LocalNow; gc.Transactions.Add(trans); gc.Save(); BindGiftCertificatesGrid(); } }
/// <summary> /// Cancel this order. /// </summary> /// <param name="voidPayments">If true, any payments in a voidable state will have be voided.</param> public void Cancel(bool voidPayments) { //VOID ANY INCOMPLETED PAYMENTS if (voidPayments) { int paymentCount = this.Payments.Count; for (int i = 0; i < paymentCount; i++) { Payment payment = this.Payments[i]; if (payment.IsVoidable) { payment.Void(); } } } // CANCEL ANY TAXES FROM INTEGRATED PROVIDERS TaxGatewayCollection taxGateways = Token.Instance.Store.TaxGateways; foreach (TaxGateway taxGateway in taxGateways) { ITaxProvider provider = taxGateway.GetProviderInstance(); if (provider != null) { try { provider.Cancel(this); } catch (Exception ex) { Logger.Error("Could not cancel with the configured tax provider: " + taxGateway.ClassId, ex); } } else { Logger.Error("Could not load the configured tax provider: " + taxGateway.ClassId); } } //TRIGGER THE ORDER CANCELLED EVENT StoreEventEngine.OrderCancelled(this); }
/// <summary> /// Updates order status of the given order /// </summary> /// <param name="order">The order for which to update the order status</param> /// <param name="newStatus">The new OrderStatus to set for the order</param> public static void UpdateOrderStatus(Order order, OrderStatus newStatus) { if (newStatus != null) { bool saveDirty = order.IsDirty; string originalStatusName = string.Empty; if (order.OrderStatus != null) { originalStatusName = order.OrderStatus.Name; } order.OrderStatusId = newStatus.OrderStatusId; Database database = Token.Instance.Database; DbCommand update = database.GetSqlStringCommand("UPDATE ac_Orders SET OrderStatusId = @orderStatusId WHERE OrderId = @orderId"); database.AddInParameter(update, "orderStatusId", System.Data.DbType.Int32, order.OrderStatusId); database.AddInParameter(update, "orderId", System.Data.DbType.Int32, order.OrderId); if (database.ExecuteNonQuery(update) > 0) { order.IsDirty = saveDirty; //ADJUST STOCK IF NEEDED if (Token.Instance.Store.EnableInventory) { if (newStatus.InventoryAction != InventoryAction.None) { try { string statusId, updateStatusId; if (newStatus.InventoryAction == InventoryAction.Destock) { statusId = "0"; updateStatusId = "1"; } else { statusId = "1"; updateStatusId = "0"; } Dictionary <int, string> LowStockProducts = new Dictionary <int, string>(); StringBuilder query = new StringBuilder(); query.Append("SELECT OI.OrderItemId,OI.Quantity,OI.ProductId,OI.OptionList"); query.Append(" FROM ac_OrderItems OI INNER JOIN ac_Products P ON OI.ProductId = P.ProductId"); query.Append(" WHERE OI.OrderId = @orderId AND OI.InventoryStatusId = " + statusId + " AND P.InventoryModeId > 0"); DbCommand select = database.GetSqlStringCommand(query.ToString()); database.AddInParameter(select, "@orderId", System.Data.DbType.Int32, order.OrderId); DataSet inventoriedProducts = database.ExecuteDataSet(select); foreach (DataRow row in inventoriedProducts.Tables[0].Rows) { if (newStatus.InventoryAction == InventoryAction.Destock) { int productId = (int)row[2]; bool lowStock; InventoryManager.Destock((short)row[1], productId, (row[3] == DBNull.Value) ? string.Empty : (string)row[3], out lowStock); if (lowStock) { LowStockProducts.Add(productId, (row[3] == DBNull.Value) ? string.Empty : (string)row[3]); } } else { InventoryManager.Restock((short)row[1], (int)row[2], (row[3] == DBNull.Value) ? string.Empty : (string)row[3]); } update = database.GetSqlStringCommand("UPDATE ac_OrderItems set InventoryStatusId = " + updateStatusId + " WHERE OrderItemId = @orderItemId"); database.AddInParameter(update, "@orderItemId", DbType.Int32, row[0]); database.ExecuteNonQuery(update); } if (LowStockProducts.Count > 0) { StoreEventEngine.LowInventoryItemPurchased(LowStockProducts); } } catch (Exception ex) { //IGNORE ERRORS Logger.Error("Error adjusting inventory levels for order number " + order.OrderId.ToString(), ex); } } } //CHECK IF ORDER STATUS IS CHANGING FROM ONE TO ANOTHER if (!string.IsNullOrEmpty(originalStatusName) && !originalStatusName.Equals(newStatus.Name)) { //UPDATE ORDER NOTES order.Notes.Add(new OrderNote(order.OrderId, Token.Instance.UserId, LocaleHelper.LocalNow, string.Format(Properties.Resources.OrderStatusUpdated, originalStatusName, newStatus.Name), NoteType.SystemPrivate)); order.Notes.Save(); //TRIGGER ORDER STATUS EVENT StoreEventEngine.OrderStatusUpdated(order, originalStatusName); } } } }
/// <summary> /// Recalculate the current payment status of an order /// </summary> /// <param name="triggerEvents">If true events are triggered on change of payment status</param> /// <remarks>We should not rely on this kind of recalculation for setting /// our statuses. If a status updates here, it is because it did not occur in /// some other, more appropriate place. Therefore we should log these occurrences as /// the warnings so they can be analyzed and corrected.</remarks> public void RecalculatePaymentStatus(bool triggerEvents) { //FIRST RECALCULATE THE STORED VALUES LSDecimal productSubtotal = this.GetProductSubtotal(); LSDecimal totalCharges = this.Items.TotalPrice(); LSDecimal totalPayments = this.Payments.TotalProcessed(); bool updated = OrderDataSource.UpdateCalculatedTotals(this, productSubtotal, totalCharges, totalPayments); //KEEP TRACK OF NEW STATUS TO DETECT CHANGES OrderPaymentStatus newStatus; //GET THE CURRENT BALANCE (EXCLUDING PENDING PAYMENTS) LSDecimal balance = (totalCharges - totalPayments); if (balance > 0) { //CHECK IF THE LAST PAYMENT RESULTED IN A PROBLEM Payment lastPayment = this.Payments.LastPayment; if ((lastPayment != null) && (lastPayment.IsFailed)) { newStatus = OrderPaymentStatus.Problem; } else { newStatus = OrderPaymentStatus.Unpaid; } } else { newStatus = OrderPaymentStatus.Paid; } //CHECK IF PAYMENT STATUS CHANGED if (this.PaymentStatus != newStatus) { OrderDataSource.UpdatePaymentStatus(this, newStatus); if (newStatus == OrderPaymentStatus.Paid) { if (balance == 0) { if (triggerEvents) { StoreEventEngine.OrderPaid(this); } else if (this.HasShippableItems) { StoreEventEngine.UpdateOrderStatus(StoreEvent.OrderPaid, this); } else { StoreEventEngine.UpdateOrderStatus(StoreEvent.OrderPaidNoShipments, this); } } else { if (triggerEvents) { StoreEventEngine.OrderPaidCreditBalance(this); } else { StoreEventEngine.UpdateOrderStatus(StoreEvent.OrderPaidCreditBalance, this); } } } } }