using System;
using System.Data;
using System.Data.Common;
using System.Collections;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Data.OleDb;
using Microsoft.CommerceServer.Runtime;
using Microsoft.CommerceServer.Runtime.Pipelines;
using Microsoft.CommerceServer.Runtime.Configuration;
using Microsoft.CommerceServer.Runtime.Orders;
using Microsoft.CommerceServer.Internal.Marketing;
using Microsoft.CommerceServer.Interop;
using Microsoft.CommerceServer.Interop.Targeting;
using Microsoft.CommerceServer.Interop.Caching;
using Microsoft.CommerceServer.Catalog;
using Microsoft.CommerceServer.Orders;
namespace CS2007PipelineConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting the application.");
OrderContext orderCtx = OrderContext.Create(Constants.SiteName);
ConsolePipelineHelper pipeLineHelper = new ConsolePipelineHelper(Constants.SiteName, orderCtx);
// Create a GUID for the user's ID, and then
// create a new Basket object.
Guid userId = Guid.NewGuid();
Basket basket = orderCtx.GetBasket(userId);
Console.WriteLine("Populating the user's basket.");
pipeLineHelper.PopulateCart(ref basket);
// Create and run each of the three orders
// pipelines.
// You must have the pipeline files in the
// "pipelines" subdirectory of the folder from
// which you run this application.
String pipelineDir = Environment.CurrentDirectory + @"\pipelines\";
Console.WriteLine("Running the Basket pipeline.");
pipeLineHelper.RunPipeline(basket, false, false, "Basket", pipelineDir + "basket.pcf");
Console.WriteLine("Running the Total pipeline.");
pipeLineHelper.RunPipeline(basket, false, false, "Total", pipelineDir + "total.pcf");
Console.WriteLine("Running the Checkout pipeline.");
pipeLineHelper.RunPipeline(basket, true, false, "Checkout", pipelineDir + "checkout.pcf");
// Save the basket as a completed order.
Console.WriteLine("Saving the order.");
PurchaseOrder order = basket.SaveAsOrder();
Console.WriteLine("Application completed!");
Console.ReadLine();
}
}
class ConsolePipelineHelper
{
PipelineInfo basketPipe, totalPipe, checkoutPipe;
CommerceResourceCollection resources;
bool catalogContextCreated = false;
String webSiteName;
CatalogContext catalogContext;
OrderContext orderCtx;
public ConsolePipelineHelper(String siteName, OrderContext orderContext)
{
resources = new CommerceResourceCollection(siteName);
webSiteName = siteName;
orderCtx = orderContext;
}
public String SiteName
{
get
{
return webSiteName;
}
set
{
webSiteName = (String)value;
}
}
public void PopulateCart(ref Basket basket)
{
// Add an address to the basket.
String addressId = Guid.NewGuid().ToString();
OrderAddress addr = new OrderAddress("HomeAddress", addressId);
basket.Addresses.Add(addr);
// Add an order form to the basket.
basket.OrderForms.Add(new OrderForm("MainOrderForm"));
//Add an item to the basket.
LineItem buyItem = new LineItem(Constants.catalogName, Constants.productId, Constants.variantId, 1);
buyItem.ShippingMethodId = GetShippingMethodID();
basket.OrderForms[0].LineItems.Add(buyItem);
//Add a credit card payment to the basket.
CreditCardPayment ccPmt = new CreditCardPayment(addressId, GetPaymentMethodID());
ccPmt.CreditCardIdentifier = ccPmt.PaymentId.ToString();
ccPmt.ExpirationMonth = 3;
ccPmt.ExpirationYear = DateTime.Today.Year + 3;
}
// At least one credit card payment method must be
// configured for the site.
public Guid GetPaymentMethodID()
{
Guid creditCardPaymentMethodId = Guid.Empty;
Boolean ccPmtMethodFound = false;
// Get all payment methods.
DataSet pmtMethods = orderCtx.GetPaymentMethods();
DataTableReader reader = pmtMethods.CreateDataReader();
IEnumerator readerEnum = reader.GetEnumerator();
while (readerEnum.MoveNext() && !ccPmtMethodFound)
{
DbDataRecord rec = (DbDataRecord)readerEnum.Current;
switch (rec.GetInt32(rec.GetOrdinal("PaymentType")))
{
case (int)PaymentMethodTypes.CreditCard:
creditCardPaymentMethodId = rec.GetGuid(rec.GetOrdinal("PaymentMethodId"));
ccPmtMethodFound = true;
break;
}
}
if (ccPmtMethodFound == false)
throw new ApplicationException("At least one credit card pamyment method must be defined.");
return creditCardPaymentMethodId;
}
// At least one shipping method must be configured for
// the site.
public Guid GetShippingMethodID()
{
Guid shippingMethodId = Guid.Empty;
Boolean shipMethodFound = false;
// Get all shipping methods in the default language.
DataSet shipMethods = orderCtx.GetShippingMethods();
DataTableReader reader = shipMethods.CreateDataReader();
IEnumerator readerEnum = reader.GetEnumerator();
while (readerEnum.MoveNext() && !shipMethodFound)
{
DbDataRecord rec = (DbDataRecord)readerEnum.Current;
shippingMethodId = rec.GetGuid(rec.GetOrdinal("ShippingMethodId"));
shipMethodFound = true;
}
if (shipMethodFound == false)
throw new ApplicationException("At least one shipping method must be defined.");
return shippingMethodId;
}
public void CheckPipelineResultAndPrintWarnings(OrderGroup og, PipelineExecutionResult res)
{
// Check the error collections.
if (res == PipelineExecutionResult.Warning)
{
Console.WriteLine("The pipeline generated warnings.");
foreach (OrderForm of in og.OrderForms)
{
Console.WriteLine("_Basket_Errors Collection for OrderForm " + og.OrderForms.IndexOf(of) + ": ");
foreach (String basketError in (SimpleList)of["_Basket_Errors"])
Console.WriteLine("\t" + basketError);
Console.WriteLine("_Purchase_Errors Collection for OrderForm " + og.OrderForms.IndexOf(of) + ": ");
foreach (String poError in (SimpleList)of["_Purchase_Errors"])
Console.WriteLine("\t" + poError);
}
Console.WriteLine();
}
}
public PipelineExecutionResult RunPipeline(OrderGroup og, bool transacted, bool loggingEnabled, String pipelineName, String pipelinePath)
{
PipelineBase pipeline;
PipelineExecutionResult res;
PipelineInfo pipeInfo = CreatePipelineInfo(pipelineName);
pipeline = new Microsoft.CommerceServer.Runtime.Pipelines.OrderPipeline(pipelineName, pipelinePath, loggingEnabled, pipelineName + ".log", transacted);
res = og.RunPipeline(pipeInfo, pipeline);
CheckPipelineResultAndPrintWarnings(og, res);
// Release unmanaged resources.
pipeInfo.Dispose();
return res;
}
public PipelineInfo CreatePipelineInfo(String pipelineName)
{
PipelineInfo pipeInfo;
switch (pipelineName.ToLower())
{
case "basket":
if (basketPipe == null)
{
basketPipe = new PipelineInfo(pipelineName);
AddDataToPipelineInfo(ref basketPipe);
}
return basketPipe;
case "total":
if (totalPipe == null)
{
totalPipe = new PipelineInfo(pipelineName);
AddDataToPipelineInfo(ref totalPipe);
}
return totalPipe;
case "checkout":
if (checkoutPipe == null)
{
checkoutPipe = new PipelineInfo(pipelineName);
AddDataToPipelineInfo(ref checkoutPipe);
}
return checkoutPipe;
default:
pipeInfo = new PipelineInfo(pipelineName);
AddDataToPipelineInfo(ref pipeInfo);
return pipeInfo;
}
}
private void AddDataToPipelineInfo(ref PipelineInfo pipeInfo)
{
CacheManagerClass cacheManager = null;
MessageManagerClass msgManager = null;
// Add the collection of payment processors.
PipelineBase creditCardPipelineProcessor = new Microsoft.CommerceServer.Runtime.Pipelines.OrderPipeline("CreditCardProcessor", Constants.creditCardPaymentProcessortPcfFilePath, false, Constants.LogFilePath + "\\CreditCard.log", true);
PipelineCollection pipeCollection = new PipelineCollection();
pipeCollection.Add("CreditCardProcessor", creditCardPipelineProcessor);
pipeInfo["pipelines"] = pipeCollection;
try
{
// Create the CacheManager object.
cacheManager = new CacheManagerClass();
// Create the MessageManager object.
msgManager = new MessageManagerClass();
// Add error message strings for both the
// current culture and the default culture.
AddMessagesToMessageManager(msgManager, CultureInfo.CurrentUICulture.ToString(), 1033);
AddMessagesToMessageManager(msgManager, "en-US", 1033);
// Populate the dictionary components.
ConfigureMarketingSystem(pipeInfo, cacheManager);
ConfigureOrderSystem(pipeInfo, cacheManager);
ConfigureCatalogSystem(pipeInfo);
pipeInfo["MessageManager"] = msgManager;
pipeInfo["CommerceResources"] = resources;
pipeInfo["cachemanager"] = cacheManager;
// You must specify the Discounts cache name
// when running in a non-ASP.NET environment.
pipeInfo.DiscountsCacheName = "Discounts";
}
finally
{
// Release unmanaged resources.
if (cacheManager != null)
Marshal.ReleaseComObject(cacheManager);
if (msgManager != null)
Marshal.ReleaseComObject(msgManager);
}
}
public void AddMessagesToMessageManager(MessageManagerClass msgMgr, String language, int locale)
{
msgMgr.AddLanguage(language, locale);
msgMgr.AddMessage("pur_badsku", "One or more items were removed from the basket", language);
msgMgr.AddMessage("pur_noitems", "No items were found in the basket", language);
msgMgr.AddMessage("pur_badplacedprice", "Placed price was not correct", language);
msgMgr.AddMessage("pur_discount_changed", "One or more discounts have changed", language);
msgMgr.AddMessage("pur_discount_removed", "One or more discounts no longer apply", language);
msgMgr.AddMessage("pur_badshipping", "Unable to complete order: cannot compute shipping cost", language);
msgMgr.AddMessage("pur_badhandling", "Unable to complete order: cannot compute handling cost", language);
msgMgr.AddMessage("pur_badtax", "Unable to complete order: cannot compute tax", language);
msgMgr.AddMessage("pur_badcc", "The credit-card number you provided is not valid. Please verify your payment information or use a different card", language);
msgMgr.AddMessage("pur_badpayment", "There was a problem authorizing your credit. Please verify your payment information or use a different card", language);
msgMgr.AddMessage("pur_badverify", "Changes to the data require your review. Please review and re-submit", language);
msgMgr.AddMessage("pur_out_of_stock", "At least one item is out of stock", language);
msgMgr.AddMessage("unknown_shipping_method", "The selected shipping method is not currently available. Please choose another shipping method", language);
}
void ConfigureMarketingSystem(PipelineInfo pipeInfo, CacheManagerClass cacheManager)
{
CommerceResource marketingResource = resources["Marketing"];
string marketingConnStr = marketingResource["connstr_db_marketing"].ToString();
string cleanedMarketingConnStr;
CleanSqlClientConnectionString(marketingConnStr, out cleanedMarketingConnStr);
DictionaryClass marketingCacheDict = new DictionaryClass();
marketingCacheDict["ConnectionString"] = marketingConnStr;
marketingCacheDict["DefaultLanguage"] = marketingResource["s_DefaultMarketingSystemLanguage"].ToString();
ExpressionEvaluator exprEval = null;
try
{
// Create the expression evaluator.
IExpressionStoreAdapter evaluatorStoreAdapter = new MarketingExpressionStoreAdapter(cleanedMarketingConnStr);
exprEval = new ExpressionEvaluator();
exprEval.Connect(evaluatorStoreAdapter);
pipeInfo["Evaluator"] = exprEval;
// Set entries in the discounts cache.
cacheManager.set_RefreshInterval("Discounts", 0);
cacheManager.set_RetryInterval("Discounts", 60);
cacheManager.set_CacheObjectProgId("Discounts", "Commerce.Dictionary");
cacheManager.set_LoaderProgId("Discounts", "Commerce.CSFLoadDiscounts");
marketingCacheDict["Evaluator"] = exprEval;
cacheManager.set_LoaderConfig("Discounts", marketingCacheDict);
cacheManager.set_WriterConfig("Discounts", marketingCacheDict);
cacheManager.set_WriterProgId("Discounts", "Commerce.CSFWriteEvents");
// Set entries in the advertising cache.
cacheManager.set_RefreshInterval("Advertising", 300);
cacheManager.set_RetryInterval("Advertising", 60);
cacheManager.set_CacheObjectProgId("Advertising", "Commerce.Dictionary");
cacheManager.set_LoaderProgId("Advertising", "Commerce.CSFLoadAdvertisements");
cacheManager.set_WriterConfig("Advertising", marketingCacheDict);
cacheManager.set_WriterProgId("Advertising", "Commerce.CSFWriteEvents");
}
finally
{
// Release unmanaged resources.
if (exprEval != null)
Marshal.ReleaseComObject(exprEval);
if (marketingCacheDict != null)
Marshal.ReleaseComObject(marketingCacheDict);
}
}
void ConfigureOrderSystem(PipelineInfo pipeInfo, CacheManagerClass cacheManager)
{
CommerceResource transactionConfigResource = resources["Transaction Config"];
string transactionConfigConnStr = transactionConfigResource["connstr_db_TransactionConfig"].ToString();
string cleanedTxConfigConnStr = null;
CleanSqlClientConnectionString(transactionConfigConnStr, out cleanedTxConfigConnStr);
Microsoft.CommerceServer.Runtime.IDictionary shippingMethodCacheDict = new DictionaryClass();
shippingMethodCacheDict["ConnectionString"] = cleanedTxConfigConnStr;
shippingMethodCacheDict["TableName"] = "txVirtual_Directory";
Microsoft.CommerceServer.Runtime.IDictionary paymentMethodCacheDict = new DictionaryClass();
paymentMethodCacheDict["ConnectionString"] = cleanedTxConfigConnStr;
paymentMethodCacheDict["TableName"] = "txVirtual_Directory";
pipeInfo["TransactionConfigConnectionString"] = transactionConfigConnStr;
try
{
// Set entries in the shipping method cache.
cacheManager.set_RefreshInterval("ShippingManagerCache", 0);
cacheManager.set_RetryInterval("ShippingManagerCache", 30);
cacheManager.set_CacheObjectProgId("ShippingManagerCache", "Commerce.Dictionary");
cacheManager.set_LoaderProgId("ShippingManagerCache", "Commerce.ShippingMethodCache");
cacheManager.set_LoaderConfig("ShippingManagerCache", shippingMethodCacheDict);
cacheManager.set_WriterConfig("ShippingManagerCache", shippingMethodCacheDict);
// Set entries in the payment method cache.
cacheManager.set_RefreshInterval("PaymentMethodCache", 0);
cacheManager.set_RetryInterval("PaymentMethodCache", 30);
cacheManager.set_CacheObjectProgId("PaymentMethodCache", "Commerce.Dictionary");
cacheManager.set_LoaderProgId("PaymentMethodCache", "Commerce.PaymentMethodCache");
cacheManager.set_LoaderConfig("PaymentMethodCache", paymentMethodCacheDict);
cacheManager.set_WriterConfig("PaymentMethodCache", paymentMethodCacheDict);
}
finally
{
// Release unmanaged resources.
if (shippingMethodCacheDict != null)
Marshal.ReleaseComObject(shippingMethodCacheDict);
}
}
void ConfigureCatalogSystem(PipelineInfo pipeInfo)
{
if (!catalogContextCreated)
{
CatalogSiteAgent siteAgent = new CatalogSiteAgent();
siteAgent.SiteName = SiteName;
// Configure the catalog cache.
CacheConfiguration catCacheConfiguration = new CacheConfiguration();
catCacheConfiguration.SchemaCacheTimeout = catCacheConfiguration.ItemInformationCacheTimeout =
catCacheConfiguration.ItemHierarchyCacheTimeout = catCacheConfiguration.ItemRelationshipsCacheTimeout =
catCacheConfiguration.ItemAssociationsCacheTimeout = catCacheConfiguration.CatalogCollectionCacheTimeout =
TimeSpan.FromMinutes(5);
// Create a CatalogContext object with the
// cache configurations.
catalogContext = CatalogContext.Create(siteAgent, catCacheConfiguration);
catalogContextCreated = true;
}
pipeInfo["CatalogContext"] = catalogContext;
}
public static bool CleanSqlClientConnectionString(string connectionString, out string cleaned)
{
const string PROVIDER_TOKEN = "Provider";
cleaned = null;
try
{
OleDbConnectionStringBuilder builder = new OleDbConnectionStringBuilder(connectionString);
builder.Remove(PROVIDER_TOKEN);
cleaned = builder.ConnectionString;
return true;
}
catch (ArgumentException)
{
// If the connection string is not formatted
// correctly, ignore the exception and return
// false.
return false;
}
}
}
public class Constants
{
// In the following, replace "StarterSite" with the
// name of your site.
public const string SiteName = "StarterSite";
// Replace the paths with the paths to your pipelines
// and log file, relative to the directory from which
// you run this program.
public const string emptyPaymentProcessortPcfFilePath = @"Pipelines\EmptyPaymentProcessor.pcf";
public const string creditCardPaymentProcessortPcfFilePath = @"Pipelines\CreditCard.pcf";
public const string LogFilePath = @"Pipelines\Log";
// Replace "Adventure Works Catalog" with the name
// of your product catalog, replace "AW078-04" with
// a product ID, and replace "6" with the variant
// ID of the product.
public const string catalogName = "Adventure Works Catalog";
public const string productId = "AW078-04";
public const string variantId = "6";
}
}