http://wiki.ablecommerce.com/index.php?title=Special:NewPages&feed=atom&limit=50&offset=&namespace=0&username=&tagfilter=AbleCommerce Wiki - New pages [en]2024-03-29T01:03:59ZFrom AbleCommerce WikiMediaWiki 1.23.17http://wiki.ablecommerce.com/index.php/Extensionless_URLs_and_custom_error_pagesExtensionless URLs and custom error pages2016-08-24T06:42:31Z<p>Mazhar: Extensionless URLs and custom error pages moved to Extension less URLs and custom error pages</p>
<hr />
<div>If you are using extensionless URLs for your products or webpages you may notice that custom 404 error page may not be working for a missing extension less URL. In order make custom error pages work with extension less URLs in gold you will have add an extra piece of configuration. Following is a step by step guide about enabling custom error pages while using extension less URLs.<br />
<br />
* Edit your Website/web.config file<br />
* Locate following element<br />
<pre><br />
<system.webServer><br />
</pre><br />
* Add following configurations under system.webServer element<br />
<pre><br />
<httpErrors errorMode="Custom"><br />
<remove statusCode="404" subStatusCode="-1" /><br />
<error statusCode="404" subStatusCode="-1" path="/Errors/PageNotFound.aspx" responseMode="ExecuteURL" /><br />
</httpErrors><br />
</pre><br />
* If your install is running under Virtual Directory/Application for example yourstore.com/shop then make sure you have path prefixed with Virtual Directory/Application name. For example for /shop it should look like following<br />
<br />
<pre><br />
<httpErrors errorMode="Custom"><br />
<remove statusCode="404" subStatusCode="-1" /><br />
<error statusCode="404" subStatusCode="-1" path="Shop/Errors/PageNotFound.aspx" responseMode="ExecuteURL" /><br />
</httpErrors><br />
</pre><br />
* Save web.config file and now custom 404 error page should appear for missing extension less URLs.</div>Mazharhttp://wiki.ablecommerce.com/index.php/Custom_Field_Collections_for_All_EntitiesCustom Field Collections for All Entities2016-04-22T05:56:34Z<p>Naveed: /* API Changes and Details */</p>
<hr />
<div>== Introduction ==<br />
<br />
<br />
Custom Field collections support was only available for Product and User entities in AC7 and AC Gold. However for AbleCommerce Gold R12 the support level is extended and now this is available for all persist-able Entities. <br />
<br />
NOTE: For Products we can still use the Product.CustomFields property to access the custom fields collection, also for Users the User.Settings collection is still available. However for all entities including the Product and User entities a new collection property "ExtendedFields" is added in AbleCommerce Gold R12.<br />
<br />
== API Changes and Details == <br />
<br />
There are no database changes for this feature and it is a API only change. Also there is no front end/UI changes related to this feature. Basically it just makes it easy to associate some custom data to any entity quickly. For example in case if you want to pass some custom information along order then this can be done like this.<br />
<br />
<source lang="csharp"><br />
order.ExtendedFields["SPECIAL_LABEL"] = "This is a special order!";<br />
order.Save(false, false);<br />
</source><br />
<br />
Now this custom field can be accessed like this <br />
<br />
<source lang="csharp"><br />
string specialLabel = order.ExtendedFields["SPECIAL_LABEL"];<br />
</source><br />
<br />
if you want to remove this field then you have to do <br />
<br />
<source lang="csharp"><br />
order.ExtendedFields.Remove("SPECIAL_LABEL");<br />
order.Save(false, false);<br />
</source><br />
<br />
If you want to remove all fields associated with an order then you will have to<br />
<br />
<source lang="csharp"><br />
order.ExtendedFields.Clear();<br />
order.Save(false, false);<br />
</source><br />
<br />
As mentioned above that the ExtendedFields collection property is available for all persist-able entities and can be used same way as explained above.</div>Naveedhttp://wiki.ablecommerce.com/index.php/Release_HistoryRelease History2016-02-15T15:50:26Z<p>MikeR: </p>
<hr />
<div>AbleCommerce GOLD [http://help.ablecommerce.com/index.htm#upgrades/acgold/change_logs.htm Release History]</div>MikeRhttp://wiki.ablecommerce.com/index.php/Integrating_Google_Search_API_to_AC_GoldIntegrating Google Search API to AC Gold2015-08-31T11:28:44Z<p>MikeR: /* Google Search Engine API Integration sample Code */</p>
<hr />
<div>Google WebSearch service provides a powerful way to display search results for the customers to their own web sites. It also provides complete control over customizing search results. It is very easy to integrate Google Custom Search API in Ablecommerce. This article will discuss the integration of Google Custom Search API in ablecommerce.<br />
<br />
First of all, we need to define a Custom Search Engine using google control panel. Here is the step by step procedure to do this:<br />
<br />
To create a custom search engine:<br />
<br />
* Sign into Control Panel [https://cse.google.com/create/new] using your Google Account (create new account if you don't already have one).<br />
* In the Sites to search section, add the pages you want to include in your search engine. You can include any sites you want, not just the sites you own. You can include whole site URLs or individual pages URLs. You can also use URL patterns.<br />
* The name of your search engine will be automatically generated based on the URLs you select. You can change this name at any time.<br />
* Select the language of your search engine. This defines the language of the buttons and other design elements of your search engine, but doesn't affect the actual search results.<br />
* Click Create.<br />
<br />
Now the basic search engine setup is completed and ready to use. There are three required parameters that must be sent in search request, these parameters are:<br />
<br />
'''1. client'''<br />
<br />
The client parameter must be set to google-csbe<br />
<br />
'''2. output'''<br />
<br />
The output parameter specifies the format of the returned XML results; results can be returned with (xml) or without (xml_no_dtd) a reference to Google's DTD. We recommend setting this value to xml_no_dtd. Note: If you do not specify this parameter, then results will be returned in HTML instead of XML.<br />
<br />
'''3. cx'''<br />
<br />
The cx parameter which represents the unique ID of the CSE. This cx value can be obtained from Details section from search engine setup control panel.<br />
<br />
For more details and adding other advanced optional parameters, visit API reference guide here [https://developers.google.com/custom-search/docs/xml_results?hl=en]<br />
<br />
=Google Search Engine API Integration sample Code=<br />
<br />
You can [http://www.ablecommerce.com/patches/GoogleSearch.zip download the sample code].<br />
<br />
Place the downloaded code files to your website root directory. All you need now is to only replace the '''cx''' parameter value to your website's '''cx''' from google custom search engine setup page. Now access the GoogleSearch.aspx in browser and try searching some keywords, it should return the results as expected. You can customize your store header to use this new google search page.<br />
<br />
IMPORTANT: Google offers this free custom search engine (Custom Search Engine aka CSE) but it includes Google ads at the top of the search results. They also offer a paid plan (Google Site Search), which starts at $100 for 20K searches/year (50 queries per day).</div>Nadeemhttp://wiki.ablecommerce.com/index.php/Override_Default_Services_Implementation_for_AC_GoldOverride Default Services Implementation for AC Gold2013-08-12T14:32:22Z<p>Nadeem: /* How to override the default service implementations */</p>
<hr />
<div>== Introduction ==<br />
<br />
Different features in AbleCommerce GOLD are implemented via services, for example '''coupon calculator service''', '''checkout service''', '''shipping and tax quotes calculation service''' and etc. CommerceBuilder API makes these services available to be overridden by the custom implementations. Castle Windsor IOC Container is used to resolve the implementation of these services and it is fairly easy to override the default implementations of these services with a custom implementation.<br />
<br />
<br />
Each service has a defined interface that the service provider class has to implement. For example the default implementation of ship rate calculation service is defined by the interface "CommerceBuilder.Services.IShipRateQuoteCalculator" and is implemented by the class "CommerceBuilder.Services.ShipRateQuoteCalculator". You can provide your own custom implementation by implementing the service interface and update the Windsor config file to make use of use your custom implementation.<br />
<br />
<br />
It is not required to learn anything about Windsor or any other IOC container to override the default implementation of any service, however some information and help/tutorial links are provided at the end for completion.<br />
<br />
== How to override the default service implementations ==<br />
<br />
Follow these steps to override a default service implementation with your custom implementation:<br />
<br />
'''1.''' Implement the respective service interface, and compile the code to some assembly and copy the dll file at "~/Bin/" folder under your website.<br />
<br />
'''2.''' Locate the "~/App_Data/windsor.config" file and open for editing using some text editor.<br />
<br />
'''3.''' Define your custom service implementations in "~/App_Data/windsor.config" file. For example if you have a custom coupon calculator implementation, you can define it there like this:<br />
<pre><component id="MyCouponCalculator" service="CommerceBuilder.Services.ICouponCalculator, CommerceBuilder"<br />
type="MyCustomNamespace.MyCouponCalculator, MyCustomAssembly"/></pre><br />
<br />
The "service" attribute contains the assembly ("CommerceBuilder" in our case) and service interface information, while the "type" attribute contains information about your custom service implementing class and assembly.<br />
<br />
After changing/updating the "~/App_Data/windsor.config" file, restart the IIS, and AC Gold will start using your custom service implementation.<br />
<br />
<br />
'''Shortcut for websites deployed as web applications''' :<br />
<br />
For store websites configured as web applications, you can implement your custom services under "~/Code/" folder instead creating a separate assembly project for it. In this case you can use "AbleCommerce.Code" namespace. For example:<br />
<pre><component id="MyShipRateQuoteCalculator" service="CommerceBuilder.Services.IShipRateQuoteCalculator, CommerceBuilder"<br />
type="AbleCommerce.Code.MyShipRateQuoteCalculator, AbleCommerce"/></pre><br />
<br />
== List of services that can be overridden ==<br />
<br />
<br />
'''1. CommerceBuilder.Catalog.IUrlGenerator'''<br />
<br />
Interface to be implemented by catalog URL generators<br />
<br />
<br />
'''2. CommerceBuilder.Catalog.IUrlRewriter'''<br />
<br />
Interface that is to be implemented by URL rewrite providers<br />
<br />
<br />
'''3. CommerceBuilder.Catalog.IUrlCache'''<br />
<br />
Interface to be implemented by URL caching service<br />
<br />
<br />
'''4. CommerceBuilder.Eventing.IStoreEventsHandler'''<br />
<br />
Interface to be implemented by store events handler. This could be very useful for your own custom events handling.<br />
<br />
<br />
'''5. CommerceBuilder.Payments.IGiftCertKeyProvider''' <br />
<br />
Interface that a gift certificate key provider must implement<br />
<br />
<br />
'''6. CommerceBuilder.Services.ICouponCalculator'''<br />
<br />
Interface to be implemented by the coupon calculator service<br />
<br />
<br />
'''7. CommerceBuilder.Services.IInventoryManager'''<br />
<br />
Interface to be implemented by the inventory management service<br />
<br />
<br />
'''8. CommerceBuilder.Services.IAffiliateCalculator'''<br />
<br />
Interface to be implemented by the affiliate commissions calculating service<br />
<br />
<br />
'''9. CommerceBuilder.Services.IBasketCalculator'''<br />
<br />
Interface to be implemented by the service used for various basket related calculations<br />
<br />
<br />
'''10. CommerceBuilder.Services.Checkout.IBasketService'''<br />
<br />
Service interface for pre-checkout logic and basket calculations<br />
<br />
<br />
'''11. CommerceBuilder.Services.Checkout.ICheckoutService'''<br />
<br />
Interface to be implemented by the checkout service<br />
<br />
<br />
'''12. CommerceBuilder.Services.IDiscountCalculator'''<br />
<br />
Interface to be implemented by the discount calculator service<br />
<br />
<br />
'''13. CommerceBuilder.Services.Membership.IUserLocator'''<br />
<br />
Interface to be implemented by the user locator service<br />
<br />
<br />
'''14. CommerceBuilder.Services.IOrderCalculator'''<br />
<br />
Interface to be implemented by the service for performing various order calculations<br />
<br />
<br />
'''15. CommerceBuilder.Services.IOrderService'''<br />
<br />
Interface to be implemented by the service for processes business logic related to orders<br />
<br />
<br />
'''16. CommerceBuilder.Services.IPaymentMethodProvider'''<br />
<br />
Interface to be implemented by a service for payment method providers<br />
<br />
<br />
'''17. CommerceBuilder.Services.IShipRateQuoteCalculator'''<br />
<br />
Interface to be implemented by a service for calculation of ship rate quotes<br />
<br />
<br />
'''18. CommerceBuilder.Services.IVolumeDiscountProvider'''<br />
<br />
Interface to be implemented by a service for validating volume discounts<br />
<br />
<br />
'''19. CommerceBuilder.Services.IFullTextSearchService'''<br />
<br />
FTS service interface<br />
<br />
<br />
'''20. CommerceBuilder.Services.IMaintenanceWorker'''<br />
<br />
Interface to be implemented by the service that runs all maintenance routines for the current store context<br />
<br />
<br />
'''21. CommerceBuilder.Services.IPageTracker'''<br />
<br />
Interface to be implemented by the page tracking service<br />
<br />
<br />
'''22. CommerceBuilder.Services.ISQLFullTextSearchService'''<br />
<br />
SQL Full Text Search (FTS) service interface<br />
<br />
<br />
'''23. CommerceBuilder.Services.IOrderStatusService'''<br />
<br />
Interface to be implemented by the service that provides order status get/update services<br />
<br />
<br />
'''24. CommerceBuilder.Services.IStoreLocator'''<br />
<br />
Interface to be implemented by the store locator service<br />
<br />
<br />
'''25. CommerceBuilder.Services.IStoreSettingsProvider'''<br />
<br />
Interface to be implemented by the service that provides store settings for a given store<br />
<br />
<br />
'''26. CommerceBuilder.Shipping.IPostalCodeValidator'''<br />
<br />
Interface to be implemented by the postal code validator service<br />
<br />
<br />
'''27. CommerceBuilder.Seo.IRedirectService'''<br />
<br />
Interface to be implemented by the SEO redirect service<br />
<br />
<br />
'''28. CommerceBuilder.Utility.IAddressFormatter'''<br />
<br />
Interface to be implemented by the address formatter service<br />
<br />
== Sample Implementation ==<br />
A good example of how default services can be overridden is implementation of a custom event handler for your store. The following article explains how to implement a custom store event handler.<br />
[[How to hook and execute custom code against store events|Custom Store Event Handler Example]]<br />
<br />
== Inversion of Control ==<br />
<br />
Inversion of Control is a principle used by frameworks as a way to allow developers to extend the framework or create applications using it. The basic idea is that the framework is aware of the programmer's objects and makes invocations on them.<br />
<br />
This is the opposite of using an API, where the developer's code makes the invocations to the API code. Hence, frameworks invert the control: it is not the developer code that is in charge, instead the framework makes the calls based on some stimulus.<br />
<br />
You have probably been in situations where you have developed under the light of this principle, even though you were not aware of it.<br />
<br />
== Inversion of Control Container ==<br />
<br />
An Inversion of Control Container uses the principle stated above to (in a nutshell) manage classes. That is, their creation, destruction, lifetime, configuration, and dependencies. This way classes do not need to obtain and configure the classes they depend on. This dramatically reduces coupling in a system and, as a consequence, simplifies reuse and testability.<br />
<br />
There is some confusion created by people that think that 'Inversion of Control' is a synonym for 'Inversion of Control Container'. As stated, Inversion of control is a broader principle.<br />
<br />
Often people think that it is all about "injection", and broadcast that this is the primary purpose of IoC containers. In fact, "injection" is a consequence, a means to decouple, not the primary purpose.<br />
http://docs.castleproject.org/Windsor.Inversion-of-Control.ashx<br />
<br />
== Castle Windsor IOC Container ==<br />
For information about Castle Windsor IOC Container, help and tutorials check the official documentation:<br />
http://docs.castleproject.org/Windsor.MainPage.ashx<br />
<br />
== Asp.Net Tutorial ==<br />
<br />
http://docs.castleproject.org/Windsor.Windsor-tutorial-ASP-NET-MVC-3-application-To-be-Seen.ashx<br />
<br />
[[Category:AbleCommerce Gold]]</div>Naveedhttp://wiki.ablecommerce.com/index.php/FedEx_Connector_for_AbleCommerce_GoldFedEx Connector for AbleCommerce Gold2013-05-31T03:11:05Z<p>Sohaib: </p>
<hr />
<div>FedEx Shipping gateway integration is not officially available for AC gold yet, however an open source plugin is available which can be used as an alternate.<br />
<br />
== Download ==<br />
This plugin provides FedEx rating and tracking services for the AbleCommerce Gold shopping cart. To download latest builds and source code, check this link:<br />
http://fedexacgold.codeplex.com/<br />
<br />
== Installation == <br />
If you installed AbleCommerce using the website model, you can access the Release-WSP files. Just copy in the Admin and bin folders into your existing site. This will activate the plugin.<br />
<br />
If you installed AbleCommece using the web application project deployment, you have to do a few more steps. Download the Release-WAP files. You'll need to add the Admin files to your project and add a reference to the AblePlugins.FedEx library. Then rebuild the web application to activate the plugin.<br />
<br />
[[Category:AbleCommerce Gold]]</div>Naveedhttp://wiki.ablecommerce.com/index.php/How_to_hook_and_execute_custom_code_against_store_eventsHow to hook and execute custom code against store events2013-05-22T13:38:57Z<p>Sohaib: </p>
<hr />
<div>In past we saw this question from time to time where developers asking for the ability to intercept store events like Order Placed, Order Paid etc. The good news is, now it will be possiable to intercept all avilable event triggers in Gold R5 and upwards. We have incorporated the support to implement store event handling more like a service. Out of the box there is default event handling implemented and configured. In order to provide your custom handling you can create your cutom event handler by following certain rules and then can plug it in place of default one.<br />
<br />
Out of the box '''CommerceBuilder.Eventing.DefaultEventsHandler''' class provides the default event handling. If you want to override the default event handling completly then all you need is to implement '''CommerceBuilder.Eventing.IStoreEventsHandler''' interface. Alternativly you can also extend your class from '''CommerceBuilder.Eventing.DefaultEventsHandler''' and override specific event handler methods. Once you are done with your custom event handler you can register it into application by creating an entry in '''Website/App_Data/windsor.config''' file. This will hook your custom event handler and route the execution control to your custom class against events.<br />
<br />
Following class provides the custom event handling sample where we need are performing some actions against OrderPlaced and DigitalGoodActivated events. For OrderPlaced event we are simply creating and storing some order XML for some third party tool under App_Data while for DigitalGoodActivated we are passing generated URL for download from external website. For all other events we are simply calling the default implementations.<br />
<br />
''' MyEventsHandler.cs '''<br />
<br />
<pre><br />
namespace AbleExtensions<br />
{<br />
using System;<br />
using System.IO;<br />
using System.Xml.Serialization;<br />
using CommerceBuilder.DigitalDelivery;<br />
using CommerceBuilder.DomainModel;<br />
using CommerceBuilder.Eventing;<br />
using CommerceBuilder.Messaging;<br />
using CommerceBuilder.Orders;<br />
using CommerceBuilder.Utility;<br />
<br />
/// <summary><br />
/// This class extends the functionality implemented by DefaultEventHandler (Requires Gold R5 or Higher)<br />
/// </summary><br />
public class MyEventsHandler : DefaultEventsHandler<br />
{<br />
/// <summary><br />
/// This method provides the ability to intercept the ability to intercept OrderPlaced event and do some custom order processing before sending the Email.<br />
/// </summary><br />
/// <param name="o">sender object</param><br />
/// <param name="e">event arguments</param><br />
public override void OrderPlaced(object o, OrderPlacedEventArgs e)<br />
{<br />
/* <br />
* WE WANT TO SAVE SOME ORDER INFORMATION IN XML FORMAT TO CONSUME IT IN SOME THIRDPARTY SOFTWARE.<br />
* THESE XML FILES WILL BE STORED UNDER App_Data<br />
*/<br />
<br />
try<br />
{<br />
Order order = e.Order;<br />
MyOrder myOrder = new MyOrder() { Id = order.Id, OrderNumber = order.OrderNumber, TotalCharges = order.TotalCharges };<br />
<br />
// BUILD PATH TO APP_DATA FOLDER TO STORE THE XML FILES AND MAKE SURE FILE NAMES ARE UNIQUE<br />
string fileName = FileHelper.SafeMapPath(string.Format("~/App_Data/order-{0}.xml", order.Id));<br />
using (StreamWriter sw = new StreamWriter(fileName))<br />
{<br />
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyOrder));<br />
xmlSerializer.Serialize(sw, myOrder);<br />
sw.Flush();<br />
sw.Close();<br />
}<br />
<br />
}<br />
catch (Exception exp)<br />
{<br />
Logger.Error(exp.Message);<br />
}<br />
<br />
<br />
// AFTER DOING OUR CUSTOM PROCESSING WE NEED TO TRIGGER BASE EVENT HANDLER TO DO THE DEFAULT HANDLING<br />
base.OrderPlaced(o, e);<br />
}<br />
<br />
/// <summary><br />
/// This method helps us intercept the event when digital good is activated to generate custom download URLs.<br />
/// It will provide custom Email handling for this event.<br />
/// </summary><br />
/// <param name="o"></param><br />
/// <param name="e"></param><br />
public override void DigitalGoodActivated(object o, DigitalGoodActivatedEventArgs e)<br />
{<br />
string downloadUrl = GetDownloadUrl(e.OrderItemDigitalGood);<br />
<br />
OrderItemDigitalGood oidg = e.OrderItemDigitalGood;<br />
DigitalGood dg = oidg.DigitalGood;<br />
<br />
// LOAD ASSOCIATED EMAIL TEMPLATE<br />
EmailTemplate template = EntityLoader.Load<EmailTemplate>(dg.ActivationEmailId);<br />
if (template != null)<br />
{<br />
template.Parameters["downloadUrl"] = downloadUrl;<br />
template.Parameters["store"] = oidg.OrderItem.Order.Store;<br />
template.Parameters["digitalGood"] = oidg.DigitalGood;<br />
template.Parameters["customer"] = oidg.OrderItem.Order.User;<br />
template.Parameters["orderItem"] = oidg.OrderItem;<br />
template.Parameters["orderItemDigitalGood"] = oidg;<br />
template.Parameters["order"] = oidg.OrderItem.Order;<br />
<br />
// ALL PARAMTERS ARE SET, SEND THE EMAIL TEMPLATE IN ASYNC MANNER<br />
// IN EMAIL TEMPLATE DOWNLOAD URL CAN BE ACCESSED USING $downloadUrl variable.<br />
template.Send(true);<br />
}<br />
}<br />
<br />
public override void CustomerPasswordRequest(object o, CustomerPasswordRequestEventArgs e)<br />
{<br />
Logger.Info("CustomerPasswordRequest event");<br />
base.CustomerPasswordRequest(o, e);<br />
}<br />
<br />
public override void DigitalGoodDeactivated(object o, DigitalGoodDeactivatedEventArgs e)<br />
{<br />
Logger.Info("DigitalGoodDeactivated event");<br />
base.DigitalGoodDeactivated(o, e);<br />
}<br />
<br />
public override void GiftCertificateValidated(object o, GiftCertificateValidatedEventArgs e)<br />
{<br />
Logger.Info("GiftCertificateValidated event");<br />
base.GiftCertificateValidated(o, e);<br />
}<br />
<br />
public override void InventoryDestocked(object o, InventoryDestockedEventArgs e)<br />
{<br />
Logger.Info("InventoryDestocked event");<br />
base.InventoryDestocked(o, e);<br />
}<br />
<br />
public override void InventoryRestocked(object o, InventoryRestockedEventArgs e)<br />
{<br />
Logger.Info("InventoryRestocked event");<br />
base.InventoryRestocked(o, e);<br />
}<br />
<br />
public override void LicenseKeyFulfilled(object o, LicenseKeyFulfilledEventArgs e)<br />
{<br />
Logger.Info("LicenseKeyFulfilled event");<br />
base.LicenseKeyFulfilled(o, e);<br />
}<br />
<br />
public override void LicenseKeyReturned(object o, LicenseKeyReturnedEventArgs e)<br />
{<br />
Logger.Info("LicenseKeyReturned event");<br />
base.LicenseKeyReturned(o, e);<br />
}<br />
<br />
public override void LowInventoryItemPurchased(object o, LowInventoryItemPurchasedEventArgs e)<br />
{<br />
Logger.Info("LowInventoryItemPurchased event");<br />
base.LowInventoryItemPurchased(o, e);<br />
}<br />
<br />
public override void OrderCancelled(object o, OrderCancelledEventArgs e)<br />
{<br />
Logger.Info("OrderCancelled event");<br />
base.OrderCancelled(o, e);<br />
}<br />
<br />
public override void OrderNoteAddedByCustomer(object o, OrderNoteAddedByCustomerEventArgs e)<br />
{<br />
Logger.Info("OrderNoteAddedByCustomer event");<br />
base.OrderNoteAddedByCustomer(o, e);<br />
}<br />
<br />
public override void OrderNoteAddedByMerchant(object o, OrderNoteAddedByMerchantEventArgs e)<br />
{<br />
Logger.Info("OrderNoteAddedByMerchant event");<br />
base.OrderNoteAddedByMerchant(o, e);<br />
}<br />
<br />
public override void OrderPaid(object o, OrderPaidEventArgs e)<br />
{<br />
Logger.Info("OrderPaid event");<br />
base.OrderPaid(o, e);<br />
}<br />
<br />
public override void OrderPaidCreditBalance(object o, OrderPaidCreditBalanceEventArgs e)<br />
{<br />
Logger.Info("OrderPaidCreditBalance event");<br />
base.OrderPaidCreditBalance(o, e);<br />
}<br />
<br />
public override void OrderPaidNoShipments(object o, OrderPaidNoShipmentsEventArgs e)<br />
{<br />
Logger.Info("OrderPaidNoShipments event");<br />
base.OrderPaidNoShipments(o, e);<br />
}<br />
<br />
public override void OrderPaidPartial(object o, OrderPaidPartialEventArgs e)<br />
{<br />
Logger.Info("OrderPaidPartial event");<br />
base.OrderPaidPartial(o, e);<br />
}<br />
<br />
public override void OrderShipped(object o, OrderShippedEventArgs e)<br />
{<br />
Logger.Info("OrderShipped event");<br />
base.OrderShipped(o, e);<br />
}<br />
<br />
public override void OrderShippedPartial(object o, OrderShippedPartialEventArgs e)<br />
{<br />
Logger.Info("OrderShippedPartial event");<br />
base.OrderShippedPartial(o, e);<br />
}<br />
<br />
public override void OrderStatusUpdated(object o, OrderStatusUpdatedEventArgs e)<br />
{<br />
Logger.Info("OrderStatusUpdated event");<br />
base.OrderStatusUpdated(o, e);<br />
}<br />
<br />
public override void PaymentAuthorizationFailed(object o, PaymentAuthorizationFailedEventArgs e)<br />
{<br />
Logger.Info("PaymentAuthorizationFailed event");<br />
base.PaymentAuthorizationFailed(o, e);<br />
}<br />
<br />
public override void PaymentAuthorized(object o, PaymentAuthorizedEventArgs e)<br />
{<br />
Logger.Info("PaymentAuthorized event");<br />
base.PaymentAuthorized(o, e);<br />
}<br />
<br />
public override void PaymentCaptureFailed(object o, PaymentCaptureFailedEventArgs e)<br />
{<br />
Logger.Info("PaymentCaptureFailed event");<br />
base.PaymentCaptureFailed(o, e);<br />
}<br />
<br />
public override void PaymentCaptured(object o, PaymentCapturedEventArgs e)<br />
{<br />
Logger.Info("PaymentCaptured event");<br />
base.PaymentCaptured(o, e);<br />
}<br />
<br />
public override void PaymentCapturedPartial(object o, PaymentCapturedPartialEventArgs e)<br />
{<br />
Logger.Info("PaymentCapturedPartial event");<br />
base.PaymentCapturedPartial(o, e);<br />
}<br />
<br />
public override void PaymentRefunded(object o, PaymentRefundedEventArgs e)<br />
{<br />
Logger.Info("PaymentRefunded event");<br />
base.PaymentRefunded(o, e);<br />
}<br />
<br />
public override void PaymentRefundedPartial(object o, PaymentRefundedPartialEventArgs e)<br />
{<br />
Logger.Info("PaymentRefundedPartial event");<br />
base.PaymentRefundedPartial(o, e);<br />
}<br />
<br />
public override void ShipmentReturned(object o, ShipmentReturnedEventArgs e)<br />
{<br />
Logger.Info("ShipmentReturned event");<br />
base.ShipmentReturned(o, e);<br />
}<br />
<br />
public override void ShipmentReturnedPartial(object o, ShipmentReturnedPartialEventArgs e)<br />
{<br />
Logger.Info("ShipmentReturnedPartial event");<br />
base.ShipmentReturnedPartial(o, e);<br />
}<br />
<br />
public override void ShipmentShipped(object o, ShipmentShippedEventArgs e)<br />
{<br />
Logger.Info("ShipmentShipped event");<br />
base.ShipmentShipped(o, e);<br />
}<br />
<br />
#region UTILITY<br />
<br />
/// <summary><br />
/// This is just sample function and you will have to implement it according to your download provider. <br />
/// </summary><br />
/// <param name="item">OrderItemDigitalGood Item</param><br />
/// <returns>Download URL to download server</returns><br />
private string GetDownloadUrl(OrderItemDigitalGood item)<br />
{<br />
return string.Format("somedownloadserver.xyz.tld/download?id={0}&code={1}", item.Id, "URL validity code here");<br />
}<br />
<br />
public class MyOrder<br />
{<br />
public int Id { get; set; }<br />
public int OrderNumber { get; set; }<br />
public decimal TotalCharges { get; set; }<br />
}<br />
<br />
#endregion<br />
}<br />
}<br />
</pre><br />
<br />
Following is the windsor configuration to register our custom handler in application. All you need is to create one component entry in windsor.config file.<br />
<br />
''' windsor.config '''<br />
<br />
<pre><br />
<?xml version="1.0" encoding="utf-8"?><br />
<configuration><br />
<components><br />
<component id="MyEventHandler" service=" CommerceBuilder.Eventing.IStoreEventsHandler, CommerceBuilder" type="AbleExtensions.MyEventsHandler, AbleExtensions"/><br />
</components><br />
</configuration><br />
</pre><br />
<br />
[[Category:AbleCommerce Gold]]</div>Mazharhttp://wiki.ablecommerce.com/index.php/AbleCommerce_Gold_Web_ApiAbleCommerce Gold Web Api2013-03-21T11:08:24Z<p>Naveed: /* Introduction */</p>
<hr />
<div>== Introduction == <br />
<br />
AbleCommerce Web API allows you to interact with a subset of the store data. It can be used to interact with a subset of all data including Products, Categories, Users, Orders, Order Items and Order Shipments. It offers post / put / delete functionality for these domains.<br />
<br />
<br />
The Web API includes a help documentation generator and test harness. The help documentation can be accessed using a URL like this:<br />
<br />
<br />
/api/help<br />
<br />
<br />
This will list an index of all available functions. Clicking through to one of the functions shows examples. The test buttons on the help pages can be used to specify/send formatted data and read the responses. For detailed and up to date information about API usage check the integrated api help.<br />
<br />
For the above mentioned domains mostly two controllers are available for each, one is admin and one is for retail. The admin controller requires authorization and SSL, while the retail controller works over plain HTTP and does not require authentication. However retail controller will only let you examine public data. This is discussed in more details in next section.<br />
<br />
<br />
== Managing Web API Access ==<br />
<br />
Retail controllers are accessible to everyone (e.g. Product and Category controllers), while the admin controllers require SSL and authorization. Though all admin level users can access the admin controllers but to allow third parties to access the Web API without full admin rights a new User Role "Web API Access" is created. So, this way merchants can grant right to access Web API to specific users by assigning them to "Web API Access" role. For example Order, Shipment and User controllers require authorization and users with at least "Web API Access" rights can access those.<br />
<br />
== Version and Update History == <br />
<br />
A basic Web API feature was added for AbleCommerce Gold R4, and improved continuously with later releases. <br />
<br />
For AbleCommerce Gold R7 new admin and retail controllers were added for Category domain. And following new API end points were added for Products domain:<br />
<br />
/api/products/featured<br />
<br />
/api/products/topsellers<br />
<br />
/api/products/recentlyviewed<br />
<br />
/api/products/[productid]/related<br />
<br />
/api/products/[productid]/accessories<br />
<br />
<br />
For AbleCommerce Gold R12 new admin and retail controllers for Users, Orders, Order Items and Order Shipments are added.<br />
<br />
== Requirements ==<br />
<br />
Web API requires IIS7 using Integrated Pipeline mode.<br />
<br />
== API DETAILS ==<br />
<br />
Each controller allow performing different operations, and detailed help is available for each controller at your store "/api/help" page. For example here we list complete list of available functions for admin and retail controllers of Product domain:<br />
<br />
<br />
== AdminProducts : API DETAILS ==<br />
<br />
=== GET api/AdminProducts/List ===<br />
Gets all products.<br />
<br />
=== GET api/AdminProducts/List?id={id} ===<br />
Gets a specific product.<br />
<br />
=== GET api/AdminProducts/Featured ===<br />
Gets all featured products.<br />
<br />
=== GET api/AdminProducts/Related?id={id} === <br />
Gets related products.<br />
<br />
=== GET api/AdminProducts/Accessories?id={id} === <br />
Gets upsell products.<br />
<br />
=== POST api/AdminProducts/PostProduct ===<br />
Creates a product<br />
<br />
=== PUT api/AdminProducts/PutProduct?id={id} ===<br />
Updates a product<br />
<br />
=== DELETE api/AdminProducts/DeleteProduct?id={id} === <br />
Deletes a product.<br />
<br />
=== GET api/AdminProducts/List/{id} ===<br />
Gets a specific product.<br />
<br />
=== GET api/AdminProducts/Related/{id} ===<br />
Gets related products.<br />
<br />
=== GET api/AdminProducts/Accessories/{id} === <br />
Gets upsell products.<br />
<br />
=== PUT api/AdminProducts/PutProduct/{id} ===<br />
Updates a product<br />
<br />
=== DELETE api/AdminProducts/DeleteProduct/{id} === <br />
Deletes a product.<br />
<br />
=== GET api/AdminProducts/{id}/List ===<br />
Gets a specific product.<br />
<br />
=== GET api/AdminProducts/{id}/Related ===<br />
Gets related products.<br />
<br />
=== GET api/AdminProducts/{id}/Accessories === <br />
Gets upsell products.<br />
<br />
=== PUT api/AdminProducts/{id}/PutProduct ===<br />
Updates a product<br />
<br />
=== DELETE api/AdminProducts/{id}/DeleteProduct === <br />
Deletes a product.<br />
<br />
=== GET api/AdminProducts ===<br />
Gets all products.<br />
<br />
=== GET api/AdminProducts/{id} ===<br />
Gets a specific product.<br />
<br />
<br />
== Products : API DETAILS ==<br />
<br />
=== GET api/Products/List ===<br />
Gets all products.<br />
<br />
=== GET api/Products/List?id={id} ===<br />
Gets a specific product.<br />
<br />
=== GET api/Products/Featured ===<br />
Gets all featured products.<br />
<br />
=== GET api/Products/Featured?id={id} ===<br />
Gets a specific featured product.<br />
<br />
=== GET api/Products/TopSellers ===<br />
Gets all popular products.<br />
<br />
=== GET api/Products/MostViewed ===<br />
Gets most viewed products.<br />
<br />
=== GET api/Products/RecentlyViewed ===<br />
Gets all recently viewed products.<br />
<br />
=== GET api/Products/Related?id={id} ===<br />
Gets related products.<br />
<br />
=== GET api/Products/Accessories?id={id} ===<br />
Gets upsell products.<br />
<br />
=== GET api/Products/Reviews?id={id} ===<br />
Gets product reviews.<br />
<br />
=== GET api/Products/List/{id} ===<br />
Gets a specific product.<br />
<br />
=== GET api/Products/Featured/{id} ===<br />
Gets a specific featured product.<br />
<br />
=== GET api/Products/Related/{id} ===<br />
Gets related products.<br />
<br />
=== GET api/Products/Accessories/{id} ===<br />
Gets upsell products.<br />
<br />
=== GET api/Products/Reviews/{id} ===<br />
Gets product reviews.<br />
<br />
=== GET api/Products/{id}/List ===<br />
Gets a specific product.<br />
<br />
=== GET api/Products/{id}/Featured ===<br />
Gets a specific featured product.<br />
<br />
=== GET api/Products/{id}/Related ===<br />
Gets related products.<br />
<br />
=== GET api/Products/{id}/Accessories ===<br />
Gets upsell products.<br />
<br />
=== GET api/Products/{id}/Reviews ===<br />
Gets product reviews.<br />
<br />
=== GET api/Products ===<br />
Gets all products.<br />
<br />
=== GET api/Products/{id} ===<br />
Gets a specific product.<br />
<br />
== List of Available Fields for AdminProducts ==<br />
<pre><br />
Id<br />
Name<br />
Price<br />
CostOfGoods<br />
MSRP<br />
Weight<br />
Length<br />
Width<br />
Height<br />
Manufacturer<br />
Sku<br />
ModelNumber<br />
TaxCode<br />
Warehouse<br />
InStock<br />
InStockWarningLevel<br />
InventoryMode<br />
ThumbnailUrl<br />
ThumbnailAltText<br />
ImageUrl<br />
ImageAltText<br />
Summary<br />
Description<br />
ExtendedDescription<br />
Vendor<br />
CreatedDate<br />
LastModifiedDate<br />
IsFeatured<br />
IsProhibited<br />
AllowReviews<br />
AllowBackorder<br />
ExcludeFromFeed<br />
DisablePurchase<br />
MinQuantity<br />
MaxQuantity<br />
IsGiftCertificate<br />
WrapGroup<br />
Visibility<br />
Shippable<br />
</pre><br />
<br />
== List of Available Fields for Retail Products ==<br />
<pre><br />
Id<br />
Name<br />
Price<br />
MSRP<br />
Weight<br />
Length<br />
Width<br />
Height<br />
Manufacturer<br />
Sku<br />
ModelNumber<br />
ImageUrl<br />
ImageAltText<br />
Summary<br />
Description<br />
ExtendedDescription<br />
</pre><br />
<br />
== List of Available Fields for Users ==<br />
<pre><br />
Id<br />
Username<br />
Email<br />
AffiliateId<br />
IsApproved<br />
IsAnonymous<br />
IsLockedOut<br />
CreateDate<br />
LastActivityDate<br />
LastLoginDate<br />
Comment<br />
</pre><br />
<br />
== List of Available Fields for Categories and AdminCategories ==<br />
<pre><br />
Id<br />
ParentId<br />
Name<br />
Summary<br />
Description<br />
ThumbnailUrl<br />
ThumbnailAltText<br />
MetaDescription<br />
MetaKeywords<br />
Title<br />
HtmlHead<br />
</pre><br />
<br />
== List of Available Fields for Orders ==<br />
<pre><br />
Id<br />
OrderNumber<br />
OrderDate<br />
StoreId<br />
Store<br />
UserId<br />
UserName<br />
OrderStatus<br />
BillToFirstName<br />
BillToLastName<br />
BillToCompany<br />
BillToAddress1<br />
BillToAddress2<br />
BillToCity<br />
BillToProvince<br />
BillToPostalCode<br />
BillToCountryCode<br />
BillToPhone<br />
BillToFax<br />
BillToEmail<br />
ProductSubtotal<br />
TotalCharges<br />
TotalPayments<br />
Exported<br />
RemoteIP<br />
Referrer<br />
ShippingAmount<br />
TaxAmount<br />
</pre><br />
<br />
== List of Available Fields for Order Items ==<br />
<pre><br />
Id<br />
OrderId<br />
OrderItemTypeId<br />
OrderShipmentId<br />
Name<br />
VariantName<br />
Sku<br />
Price<br />
Weight<br />
CostOfGoods<br />
Quantity<br />
LineMessage<br />
OrderBy<br />
GiftMessage<br />
TaxRate<br />
TaxAmount<br />
KitList<br />
IsSubscription<br />
Frequency<br />
FrequencyUnitId<br />
</pre><br />
<br />
== List of Available Fields for Order Shipments ==<br />
<pre><br />
Id<br />
OrderId<br />
OrderNumber<br />
ShipMethod<br />
Warehouse<br />
ShipToFirstName<br />
ShipToLastName<br />
ShipToCompany<br />
ShipToAddress1<br />
ShipToAddress2<br />
ShipToCity<br />
ShipToProvince<br />
ShipToPostalCode<br />
ShipToCountry<br />
ShipToPhone<br />
ShipToFax<br />
ShipToEmail<br />
OriginCountry<br />
ShipToResidence<br />
ShipMessage<br />
ShipDate<br />
ProductSubtotal<br />
TotalCharges<br />
ShippingAmount<br />
</pre><br />
<br />
[[Category:AbleCommerce Gold]]</div>Naveedhttp://wiki.ablecommerce.com/index.php/How_to_add_a_Comment_field_to_the_user_page_-_AC_GoldHow to add a Comment field to the user page - AC Gold2013-01-18T09:46:41Z<p>Sohaib: </p>
<hr />
<div>Work in progress ....<br />
<br />
This article is not yet updated for AC Gold.<br />
<br />
Please refer to the old article from AC7 - [[How to add a Comment field to the User page]]</div>Sohaibhttp://wiki.ablecommerce.com/index.php/Custom_fields_for_user%27s_profile_-_AC_GoldCustom fields for user's profile - AC Gold2013-01-18T09:45:46Z<p>Sohaib: New page: Work in progress .... This article is not yet updated for AC Gold. Please refer to the old article from AC7 - Custom fields for user's profile</p>
<hr />
<div>Work in progress ....<br />
<br />
This article is not yet updated for AC Gold.<br />
<br />
Please refer to the old article from AC7 - [[Custom fields for user's profile]]</div>Sohaibhttp://wiki.ablecommerce.com/index.php/Code_for_Alert_when_there_are_reviews_to_approve_-_AC_GoldCode for Alert when there are reviews to approve - AC Gold2013-01-18T09:42:39Z<p>Sohaib: </p>
<hr />
<div>Work in progress ....<br />
<br />
This article is not yet updated for AC Gold.<br />
<br />
Please refer to the old article from AC7 - [[Code for Alert when there are reviews to approve]]</div>Sohaibhttp://wiki.ablecommerce.com/index.php/Database_-_AC_GoldDatabase - AC Gold2012-12-13T15:41:41Z<p>MikeR: New page: The database structure in AbleCommerce GOLD is very similar to that of previous 7.0.x releases. There are differences including: Nullable Dates</p>
<hr />
<div>The database structure in AbleCommerce GOLD is very similar to that of previous 7.0.x releases.<br />
<br />
There are differences including:<br />
<br />
[[Nullable Dates]]</div>MikeRhttp://wiki.ablecommerce.com/index.php/Making_Customer_Fields_Required_for_Product_Template_-_AC_GoldMaking Customer Fields Required for Product Template - AC Gold2012-12-03T16:25:30Z<p>Nadeem: New page: You can make requirement for a customer to enter text into a customer field. Let's suppose you have a product template that has two customer fields where they can enter a personalization l...</p>
<hr />
<div>You can make requirement for a customer to enter text into a customer field. Let's suppose you have a product template that has two customer fields where they can enter a personalization like a monogram for example. There is a way to require the customer enter something in that field before adding it to the cart.<br />
<br />
In order to accomplish this task edit the following file.<br />
<br />
<code><br />
<pre><br />
Code/ProductHelper.cs<br />
</pre><br />
</code><br />
<br />
Locate and replace the ''BuildProductChoices'' function with the following method and keep one more thing in your mind that replace the method in case that you haven't customized this method before otherwise replace operation will cause the lose of your customized work. In this situation you need to merge this code with your custom code.<br />
<br />
<code><br />
<pre><br />
public static void BuildProductChoices(Product product, PlaceHolder phChoices)<br />
{<br />
// ADD IN THE PRODUCT TEMPLATE CHOICES<br />
foreach (ProductTemplate template in product.ProductTemplates)<br />
{<br />
foreach (InputField input in template.InputFields)<br />
{<br />
if (!input.IsMerchantField)<br />
{<br />
// ADD THE CONTROL TO THE PLACEHOLDER<br />
phChoices.Controls.Add(new LiteralControl("<tr><td colspan=\"2\">"));<br />
phChoices.Controls.Add(new LiteralControl((input.UserPrompt + "<br />")));<br />
WebControl o = input.GetControl();<br />
if (o != null)<br />
{<br />
phChoices.Controls.Add(o);<br />
if (input.InputType == InputType.TextBox)<br />
{<br />
RequiredFieldValidator rfv = new RequiredFieldValidator();<br />
rfv.ID = "rfv" + input.Id.ToString();<br />
rfv.ControlToValidate = o.ID;<br />
rfv.Text = "*";<br />
rfv.ValidationGroup = "AddToBasket";<br />
phChoices.Controls.Add(rfv);<br />
}<br />
}<br />
phChoices.Controls.Add(new LiteralControl("</td></tr>"));<br />
}<br />
}<br />
}<br />
}<br />
</pre><br />
</code><br />
<br />
Now when order from store side the customer must have to provide some values for these fields, in other words you just made these fields mandatory and they can't be left blank.</div>Nadeemhttp://wiki.ablecommerce.com/index.php/How_to_disable_Wishlist_-_AC_GoldHow to disable Wishlist - AC Gold2012-12-03T16:20:13Z<p>Nadeem: New page: '''How to disable Wishlist feature in AbleCommerce''' Here are the detailed steps to disable Wishlist feature in AbleCommerce. * Go to Website/Conlib/StoreHeader.ascx file and locate. <pr...</p>
<hr />
<div>'''How to disable Wishlist feature in AbleCommerce'''<br />
Here are the detailed steps to disable Wishlist feature in AbleCommerce.<br />
<br />
* Go to Website/Conlib/StoreHeader.ascx file and locate.<br />
<pre><asp:HyperLink ID="WishlistLink" runat="server" NavigateUrl="~/Members/MyWishlist.aspx" class="wishlist" Text="Wishlist" ></pre><br />
<br />
and update it as<br />
<pre><%--<asp:HyperLink ID="WishlistLink" runat="server" NavigateUrl="~/Members/MyWishlist.aspx" class="wishlist" Text="Wishlist" >--%></pre><br />
* Go to your Website/ConLib/BuyProductDialog.ascx.cs file and locate <br />
<pre>AddToWishlistButton.Visible = AbleContext.Current.StoreMode == StoreMode.Standard;</pre><br />
and update it as <br />
<pre>AddToWishlistButton.Visible = false;</pre><br />
*Go to your Website/ConLib/BuyProductDialogOptoinList.ascx.cs file and locate <br />
<pre><br />
LinkButton lb2 = new LinkButton();<br />
</pre> <br />
and update it as<br />
<pre><br />
LinkButton lb2 = new LinkButton();<br />
lb2.Visible = false;<br />
</pre><br />
*Go to your Website/ConLib/Account/AccountTabMenu.ascx.cs file and locate following line of code<br />
<pre><br />
menuLinks.Add("Wishlist", "MyWishlist.aspx");<br />
</pre><br />
and update it as below<br />
<pre><br />
//menuLinks.Add("Wishlist", "MyWishlist.aspx");<br />
</pre><br />
*Go to your Website/Members/MyWishlist.aspx.cs file and locate following code line<br />
<pre>//VALIDATE THE WISHLIST</pre><br />
and update it as below<br />
<pre><br />
Response.Redirect("~/Default.aspx");<br />
//VALIDATE THE WISHLIST<br />
</pre></div>Nadeemhttp://wiki.ablecommerce.com/index.php/Show_minimum_to_maximum_price_range_on_product_page_-_AC_GoldShow minimum to maximum price range on product page - AC Gold2012-12-03T16:06:28Z<p>Nadeem: </p>
<hr />
<div>'''Show minimum to maximum price range on product page'''<br />
<br />
For example you have a product let's say T-Shirt with three different sizes Small, Medium, Large. Every size has a different price. Now on product display page you want the customer to see a price range showing minimum available price to maximum available price. <br />
<br />
This customization considers that you are using one option with product. This customization will not handle tax inclusive price display, no variants considerations and no kitting handling.<br />
<br />
* Edit your Website/Conlib/Utility/ProductPrice.ascx.cs file and locate following line of code<br />
<pre><br />
else<br />
{<br />
Price.Text = string.Format(_PriceFormat, priceWithVAT.LSCurrencyFormat("ulc"));<br />
}<br />
</pre><br />
<br />
and update it as below<br />
<pre><br />
else<br />
{<br />
decimal maxPrice = 0;<br />
foreach (ProductOption po in _Product.ProductOptions)<br />
{<br />
foreach (OptionChoice oc in po.Option.Choices)<br />
{<br />
if (oc.PriceModifier > maxPrice)<br />
maxPrice = oc.PriceModifier ?? 0;<br />
}<br />
}<br />
<br />
if (_Product.ProductOptions.Count > 0)<br />
Price.Text = string.Format(_PriceFormat, _Product.Price) + string.Format(" - {0}", _Product.Price + maxPrice);<br />
else<br />
Price.Text = string.Format(_PriceFormat, priceWithVAT.LSCurrencyFormat("ulc"));<br />
}<br />
</pre><br />
<br />
* Now create a Product with one option and then when adding its option choices specify price modifiers for each choice. Finally open the product page from retail side to see the changes.</div>Nadeemhttp://wiki.ablecommerce.com/index.php/Hide_Shipping_Estimates_-_AC_GoldHide Shipping Estimates - AC Gold2012-12-03T16:00:54Z<p>Sohaib: </p>
<hr />
<div>The Shipping Estimator appears automatically to the right in basket when items exist in the shopping cart. If you would prefer the estimator not to appear, it's very simple to do. <br />
<br />
First make a backup copy of the files in the website root folder. They will be Basket.aspx and Basket.aspx.cs.<br />
<br />
Open the Website/Basket.aspx file in your editor of choice. Look for this code towards the end of the file: <br />
<code><pre><br />
<uc2:BasketShippingEstimate ID="BasketShippingEstimate1" runat="server" /><br />
</pre></code><br />
<br />
<br />
Now change the uc1:Basket... line to look like this:<br />
<code><pre><br />
<uc2:BasketShippingEstimate ID="BasketShippingEstimate1" visible="false" runat="server" /><br />
</pre></code><br />
<br />
<br />
Now open Website/Basket.aspx.cs file and locate following line of code:<br />
<code><pre><br />
BasketShippingEstimate1.Visible = showShippingEstimate;<br />
</pre></code><br />
<br />
<br />
and update it to<br />
<code><pre><br />
//BasketShippingEstimate1.Visible = showShippingEstimate;<br />
</pre></code><br />
<br />
Save the file. Load your site and add something to your cart to verify the estimator no longer appears.<br />
<br />
<br />
[[Category:AbleCommerce Gold]]<br />
[[Category:Store Customization]]</div>Nadeemhttp://wiki.ablecommerce.com/index.php/Upgrading_from_AC_7.0.XUpgrading from AC 7.0.X2012-11-30T14:46:54Z<p>Sohaib: </p>
<hr />
<div>AC Gold R3 supports upgrading from AC 7.0.6 or 7.0.7 versions. We are planning to add the support to upgrade directly from 7.0.5 in next releases. AC Gold release 1 and R2 supports upgrading from 7.0.7.<br />
<br />
<br />
To upgrade from AC 7.0.x release to AC Gold follow these steps:<br />
<br />
<br />
1. Backup your database before upgrade/installation.<br />
<br />
2. Upgrade your existing store to AC7.0.7 ( or at lease to AC 7.0.6 if you are upgrading to Gold R3)<br />
<br />
3. While installing Gold provide the database details/connection string for your existing AC7.0.7 database, and select the option "This <br />
is an existing AC7 database to be upgraded." under "Database Connection" options.<br />
<br />
4. Continue with the install and it will upgrade your database for AC Gold version.<br />
<br />
<br />
[[Category:AbleCommerce 7]]</div>Naveedhttp://wiki.ablecommerce.com/index.php/Store_ContextStore Context2012-11-30T14:03:59Z<p>Naveed: New page: In past for AC 7.0.x versions we were initializing the store context like below: Token.Instance.InitStoreContext(StoreDataSource.Load(1)); However for AC Gold version its little differ...</p>
<hr />
<div>In past for AC 7.0.x versions we were initializing the store context like below:<br />
<br />
<br />
Token.Instance.InitStoreContext(StoreDataSource.Load(1));<br />
<br />
<br />
However for AC Gold version its little different and bit more simple:<br />
<br />
<br />
AbleContext.Current.Store = StoreDataSource.Load(1);</div>Naveedhttp://wiki.ablecommerce.com/index.php/Deprecated_Id_PropertiesDeprecated Id Properties2012-11-29T15:37:28Z<p>Sohaib: </p>
<hr />
<div>For AbleCommerce 7.0.[0-7] all entity classes had Id properties with class names which were also matching the database column name, for example "ProductId" property for Product class. <br />
<br />
For AbleCommerce Gold in all entity classes the Id property is renamed to "'''Id'''", though we still have alias properties with old names for backward compatibility. <br />
<br />
The underlying reason is a combination of NHibernate and generics. We have a single base "Entity" class. This class defines a property named Id and this is shared in common with all of our objects that are mapped to the database. This is the field that actually does the work, while the ProductId field is just an alias to the Id property. And the Id property is here to stay. It seemed odd to have two names for the same property so the alias was deprecated.<br />
<br />
To a lesser extent a reason was that common practice with NHibernate is to have a mapped field named Id. So if we had been starting from scratch we likely would have used Id as the table column name rather than ProductId to better match those patterns.<br />
<br />
Right now there is no plan to actually remove the properties. The obsolete warning was added to encourage people to prefer the Id property and also to ensure we updated all of our internal codes.<br />
<br />
NOTE: Though we have duplicate/repetitive properties for each entity class (e.g. ProductId and Id for Product class), using Id is preferred. All of our classes have an Id property (even the ones using composite keys).<br />
<br />
[[Category:AbleCommerce Gold]]</div>Naveedhttp://wiki.ablecommerce.com/index.php/WebPage_links_from_category_page_-_AC_GoldWebPage links from category page - AC Gold2012-11-19T15:43:49Z<p>Nadeem: </p>
<hr />
<div>If you have some webpages or have some dedicated category containing only the webpages and wants to make them visible to customers exploring that category. Then you have to change the display page for that category. In order to do this you have to do the following tasks<br />
<br />
<code><br />
<pre><br />
1)- Login as admin to the store.<br />
<br />
2)- Navigate to store side.<br />
<br />
3)- Locate and open the category containing the webpages.<br />
<br />
4)- Select Edit: categoryname<br />
<br />
5)- Select Display Page: value from one of the below<br />
<br />
* Category Details Page <br />
* Category Grid (Deep Item Display)<br />
* Category Grid (Shallow Item Display) (CategoryGrid2.aspx) <br />
* Category Grid (Deep Item Display) With Add To Basket (CategoryGrid3.aspx)<br />
* Category Grid (Shallow Item Display) With Category Data (CategoryGrid4.aspx)<br />
* Category List<br />
<br />
6) Click Update <br />
<br />
7)- Now you will see that webpages will be available within that category.<br />
<br />
8) You can manage display pages from admin using Manage Display Pages button from store footer as well<br />
<br />
</pre><br />
</code></div>Nadeemhttp://wiki.ablecommerce.com/index.php/Change_star_rating_images_-_AC_GoldChange star rating images - AC Gold2012-11-19T14:44:08Z<p>Sohaib: </p>
<hr />
<div>In AC Gold star rating images are theme specific. Changing them is very simple.<br />
<br />
Just go to the '''theme''' and in the '''/images/ratings''' folder update the image files.<br />
<br />
[[Category:AbleCommerce Gold]]</div>Nadeemhttp://wiki.ablecommerce.com/index.php/Adding_a_favicon_-_AC_GoldAdding a favicon - AC Gold2012-11-19T13:55:26Z<p>Nadeem: New page: Adding a favicon to any website is pretty simple. You just have to make sure that your favorite icon is present in your website home and that it is named '''favicon.ico'''. Older versions...</p>
<hr />
<div>Adding a favicon to any website is pretty simple. You just have to make sure that your favorite icon is present in your website home and that it is named '''favicon.ico'''.<br />
<br />
Older versions of IE only display favicons in your bookmarks, which they call "Favorites". In fact, the name favicon was coined to mean "Favorites icon". As time goes on, other browsers have begun making more widespread use of favicons: in the address bar, on tabs and so on. But IE only displays them after you create a bookmark. Also IE6 will display the favicon in the address bar, but only after it's been bookmarked.<br />
<br />
==Creating a favicon==<br />
You have a number of options for creating a favicon.<br />
<br />
*Create an image 16X16 pixels in size. Its better to restrict yourself to the standard Windows 16 colors, although 256 colors may also work fine. Save the image as an ICO file named "favicon.ico".<br />
*Use an existing image and get it converted to a favicon using some tool. You can find one such online tool here http://www.htmlkit.com/services/favicon/</div>Nadeemhttp://wiki.ablecommerce.com/index.php/Creating_Themes_-_AC_GoldCreating Themes - AC Gold2012-11-19T13:21:51Z<p>Sohaib: </p>
<hr />
<div>AC Gold makes use of ASP.NET themes and skins feature. Themes allow you to change the look and feel of your store the way you like. Themes offer a powerful framework for controlling display and layout of your store.<br />
<br />
Themes are located in the App_Themes folder in your store home. Each theme has its own folder. There are two default themes that are always present in your App_Themes folder.<br />
<br />
# '''Computer''': This is the default theme for your store. If no other theme is present or set this theme will be used.<br />
# '''AbleCommerceAdmin''': This is the default theme for merchant admin.<br />
<br />
By convention theme folder names that end with ''Admin'' are considered to be themes for merchant admin while all other themes are considered to be themes for the retail store.<br />
<br />
<br />
'''<br />
== Approaches to customization ==<br />
'''<br />
<br />
There can be two approaches to customizing the look and feel of your store.<br />
# Starting from an existing theme and gradually modifying it to get your desired result<br />
# Starting from a Photoshop mock up and getting it implemented on your store<br />
<br />
No 1 is relatively straightforward but does not always produce the results to the satisfaction of 'perfectionists'.<br />
<br />
No 2 is relatively difficult and requires greater skills in web-design. For your Photoshop design to exactly map or your store pages you may have to work with aspx controls at times. However with this approach you can achieve almost anything.<br />
<br />
I will briefly touch No 1. Starting from an existing theme and gradually modifying it to get your desired result.<br />
<br />
<br />
'''<br />
== Creating a New Theme ==<br />
'''<br />
<br />
Creating a new theme is as easy as creating a new folder in 'App_Themes'. For starters the best way to create a new theme is to copy one of the existing theme folders and rename it. Once you have done this your new theme is ready to be used in Ablecommerce except that it is yet to be customized according to your needs.<br />
<br />
<br />
'''<br />
== Customizing Themes ==<br />
'''<br />
<br />
A theme may contain a number of CSS files, ASP.NET skin files, images and etc. You will most likely be editing the CSS files and/or changing the images most of the time. To be able to best customize the look and feel of your theme you need to know a bit of CSS. If you are good at it you will find that you can do almost anything with your AC Gold store. Knowing a bit of graphics designing also helps a great deal in creating visually appealing sites.<br />
<br />
In any case whether you are an expert or novice you can always do the basic tweaking of your store. If you are looking for more than basic tweaking you always have an option of getting in contact with some web designer.<br />
<br />
[[Category:Store Design]]<br />
[[Category:AbleCommerce Gold]]</div>Nadeemhttp://wiki.ablecommerce.com/index.php/Data_Access_Layer_-_AC_GoldData Access Layer - AC Gold2012-11-19T12:28:55Z<p>Mazhar: /* Accessing Database */</p>
<hr />
<div>== The Database ==<br />
<br />
AC Gold database design is probably one of the best among the available shopping cart solutions. If you know a bit of databases, AC Gold database design is very easy to understand and follow. There are a few areas (e.g. Category and Catalog tables) that are slightly complex but in general you can just look at the database tables/fields and get a fair idea of what they are meant for.<br />
<br />
== Accessing Database ==<br />
<br />
Ablecommerce Gold makes use of NHibernate for data access. For the most part we just have to deal with the 'Objects' in C#. The code that we have written complies with ASP.NET Data Source Object Model. This helps a great deal in using these objects directly in ASP.NET. Here I will take the example of Affiliates and explain how they are represented/accessed in the database, in the C# code and in the ASP.NET code. You need to create a Class Library Project and put all your custom classes and HBM files in it. Finally you will reference the library in AbleCommerce website.<br />
<br />
== Affiliates in Database ==<br />
<br />
Here is how Affiliates are defined in database<br />
<code><pre><br />
CREATE TABLE ac_Affiliates ( <br />
AffiliateId INT IDENTITY NOT NULL,<br />
StoreId INT NOT NULL,<br />
Name NVARCHAR(100) NOT NULL,<br />
PayeeName NVARCHAR(100) NULL,<br />
FirstName NVARCHAR(30) NULL,<br />
LastName NVARCHAR(50) NULL,<br />
Company NVARCHAR(50) NULL,<br />
Address1 NVARCHAR(100) NULL,<br />
Address2 NVARCHAR(100) NULL,<br />
City NVARCHAR(50) NULL,<br />
Province NVARCHAR(50) NULL,<br />
PostalCode NVARCHAR(15) NULL,<br />
CountryCode CHAR(2) NULL,<br />
PhoneNumber NVARCHAR(50) NULL,<br />
FaxNumber NVARCHAR(50) NULL,<br />
MobileNumber NVARCHAR(50) NULL,<br />
WebsiteUrl NVARCHAR(255) NULL,<br />
Email NVARCHAR(255) NULL,<br />
CommissionRate DECIMAL(9,4) NOT NULL,<br />
CommissionIsPercent BIT NOT NULL,<br />
CommissionOnTotal BIT NOT NULL,<br />
ReferralPeriodId TINYINT NOT NULL,<br />
ReferralDays SMALLINT NOT NULL,<br />
GroupId INT NULL,<br />
PRIMARY KEY(AffiliateId))<br />
</pre></code><br />
<br />
== Affiliates in Code ==<br />
<br />
In Ablecommerce Gold .NET code there are a total of 9 C# files related to affiliates. This is almost always the case for any database object represented in AC Gold.<br />
<br />
<code><pre><br />
Affiliate.cs<br />
Affiliate.Generated.cs<br />
Affiliate.hbm.xml<br />
IAffiliateRepository.cs<br />
IAffiliateRepository.Generated.cs<br />
AffiliateRepository.cs<br />
AffiliateRepository.Generated.cs<br />
AffiliateDataSource.cs<br />
AffiliateDataSource.Generated.cs<br />
</pre></code><br />
<br />
Five of the above files are generated. Four of them are custom coded. Although there are 9 files there are only 3 classes and one interface(thanks to C# partial classes). The 'Affiliate' class that represents an affiliate and 'Affiliate.hbm' represents the nhibernate mappings. The 'IAffiliateRepository', and 'AffiliateRepository' class that provide repository implementation for Affiliate object for example load/save methods. AffiliateDataSource class is simply a wrapper around AffiliateRepository and does have same methods as repository class does but instead of using different logic for the methods it just uses repository class in its methods. The major purpose of these DataSource classes is to provide backward code compatibility plus to comply with ASP.NET Object Data Source model.<br />
<br />
== Entity ==<br />
<br />
Entity object encapsulates the data for corresponding database table. For example in case of Affiliates '''Affiliate.cs''', '''Affiliate.Generated.cs''' and '''Affiliate.hbm.xml''' provides the entity object implementations where CS files provide data and navigation properties and HBM file provides nhibernate mappings. All entity objects either extend from '''CommerceBuilder.DomainModel.Entity''' or '''CommerceBuilder.DomainModel.EntityWithTypedId<T>''' where T can be class representing composite key. These base classes does provide some useful functionality to these Entity objects for example Save() and Delete() methods.<br />
<br />
Below are the contents of Affiliate.hbm file or nhibernate mappings for affiliate entity.<br />
<br />
<pre><br />
<?xml version="1.0" encoding="utf-8"?><br />
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"><br />
<!-- Copyright (c) 2010 Able Solutions Corporation. All rights reserved. --><br />
<class name="CommerceBuilder.Marketing.Affiliate,CommerceBuilder" table="ac_Affiliates" lazy="true" dynamic-update="true"><br />
<id name="Id" column="AffiliateId" type="int"><br />
<generator class="native" /><br />
</id><br />
<many-to-one name="Store" column="StoreId" not-null="true" class="CommerceBuilder.Stores.Store,CommerceBuilder" /><br />
<property name="Name" column="Name" type="string" not-null="true" /><br />
<property name="PayeeName" column="PayeeName" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="FirstName" column="FirstName" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="LastName" column="LastName" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="Company" column="Company" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="Address1" column="Address1" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="Address2" column="Address2" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="City" column="City" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="Province" column="Province" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="PostalCode" column="PostalCode" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="CountryCode" column="CountryCode" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="PhoneNumber" column="PhoneNumber" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="FaxNumber" column="FaxNumber" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="MobileNumber" column="MobileNumber" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="WebsiteUrl" column="WebsiteUrl" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="Email" column="Email" type="CommerceBuilder.DomainModel.NullSafeString, CommerceBuilder" /><br />
<property name="CommissionRate" column="CommissionRate" type="Decimal" not-null="true" /><br />
<property name="CommissionIsPercent" column="CommissionIsPercent" type="Boolean" not-null="true" /><br />
<property name="CommissionOnTotal" column="CommissionOnTotal" type="Boolean" not-null="true" /><br />
<property name="ReferralPeriodId" column="ReferralPeriodId" type="byte" not-null="true" /><br />
<property name="ReferralDays" column="ReferralDays" type="short" not-null="true" /><br />
<many-to-one name="Group" column="GroupId" class="CommerceBuilder.Users.Group,CommerceBuilder" /><br />
<bag name="Orders" inverse="true" lazy="true" cascade="save-update" collection-type="CommerceBuilder.DomainModel.PersistableList`1[[CommerceBuilder.Orders.Order,CommerceBuilder]], CommerceBuilder"><br />
<key column="AffiliateId" /><br />
<one-to-many class="CommerceBuilder.Orders.Order,CommerceBuilder" /><br />
</bag><br />
<bag name="Users" inverse="true" lazy="true" cascade="save-update" collection-type="CommerceBuilder.DomainModel.PersistableList`1[[CommerceBuilder.Users.User,CommerceBuilder]], CommerceBuilder"><br />
<key column="AffiliateId" /><br />
<one-to-many class="CommerceBuilder.Users.User,CommerceBuilder" /><br />
</bag><br />
</class><br />
</hibernate-mapping><br />
</pre><br />
<br />
Below piece of code will save a new affiliate in database.<br />
<br />
<pre><br />
Affiliate affiliate = new Affiliate();<br />
affiliate.Name = "John Smith";<br />
affiliate.ReferralPeriod = AffiliateReferralPeriod.Persistent;<br />
affiliate.Save();<br />
</pre><br />
<br />
== Repository ==<br />
<br />
Repository holds the logic related to data save/load to/from database. In case of Affiliates '''IAffiliateRepository.cs'''<br />
'''IAffiliateRepository.Generated.cs''', '''AffiliateRepository.Generated.cs''' and '''AffiliateRepository.cs''' hold the repository implementations. Though there are four files but actually we are just dealing with one interface and one class by using partial class to keep the custom and generated code separate from each other. Every repository class implements the corresponding repository interface and extends either from '''CommerceBuilder.DomainModel.Repository<T>''' or '''CommerceBuilder.DomainModel.RepositoryWithTypedId<T,K>''' where T is entity type, K is composite key type. These class provides some common functionality for example Load, LoadAll, CountAll, Save and Delete methods. Following example code explain how to use repository object.<br />
<br />
<pre><br />
// USING IOC TO RESOLVE REPOSITORY<br />
IAffiliateRepository repository = AbleContext.Container.Resolve<IAffiliateRepository>();<br />
<br />
// LOAD SINGLE AFFILIATE BY ID<br />
Affiliate affiliate = repository.Load(1);<br />
<br />
// LOAD ALL AFFILIATES<br />
System.Collections.IList<Affiliate> affiliates = repository.LoadAll();<br />
<br />
// SAVE AFFILIATE<br />
affiliate.ReferralPeriod = AffiliateReferralPeriod.FirstOrder;<br />
repository.Save(affiliate);<br />
<br />
// DELETE AFFILIATE<br />
repository.Delete(affiliate);<br />
</pre><br />
<br />
== Data Source ==<br />
<br />
The main purpose of Data Source classes is to allow to work with ASP.NET Data Source Object Model. In case of Affiliates '''AffiliateDataSource.cs''' and '''AffiliateDataSource.Generated.cs''' implement data source. This data source can be considered as a wrapper around repository because it does have similar methods as we do on repository but instead of doing any database interaction all it does it to pass the information to underlying repository object. Every data source either extends '''CommerceBuilder.DomainModel.DataSource<T,R>''' or '''CommerceBuilder.DomainModel.DataSourceWithTypedId<T,K,R>''' where T is entity type, K is composite key type and R is repository type. Following code explain the Data Source object usage.<br />
<br />
<pre><br />
// LOAD SINGLE AFFILIATE BY ID<br />
Affiliate affiliate = AffiliateDataSource.Load(1);<br />
<br />
// LOAD ALL AFFILIATES<br />
System.Collections.IList<Affiliate> affiliates = AffiliateDataSource.LoadAll();<br />
<br />
// UPDATE AFFILIATE<br />
affiliate.ReferralPeriod = AffiliateReferralPeriod.FirstOrder;<br />
AffiliateDataSource.Update(affiliate);<br />
<br />
// DELETE AFFILIATE<br />
AffiliateDataSource.Delete(affiliate);<br />
</pre><br />
<br />
[[Category:AbleCommerce Gold]]</div>Mazharhttp://wiki.ablecommerce.com/index.php/Feature_Customization_-_AC_GoldFeature Customization - AC Gold2012-11-17T08:57:36Z<p>Mazhar: /* Misc */</p>
<hr />
<div><div id="cleanup" style="text-align: center; background: #ffe; margin: .75em 15%; padding: .5em; border: 1px solid #e3e3b0;"><br />
If you want to customize the '''look and feel''' of your store see '''[[Look and Feel Customization - AC Gold]]'''<br />
</div><br />
<br />
This section includes information and documentation on things that change '''how the store works''', see [[Look and Feel Customization - AC Gold]] for topics on changing '''how the store looks'''.<br />
<br />
<br />
== Store Customizations ==<br />
=== Store Display ===<br />
* [[Hide Shipping Estimates - AC Gold]]<br />
* [[Making Customer Fields Required for Product Template - AC Gold]]<br />
* [[WebPage links from category page - AC Gold]]<br />
* [[Show minimum to maximum price range on product page - AC Gold]]<br />
* [[How to disable Wishlist - AC Gold]]<br />
<br />
=== Adding Features ===<br />
<br />
<br />
<br />
== Merchant Admin Customizations ==<br />
* [[Code for Alert when there are reviews to approve - AC Gold]]<br />
* [[Custom fields for user's profile - AC Gold]]<br />
* [[How to add a Comment field to the user page - AC Gold]]<br />
<br />
== Customizing Emails ==<br />
* [[Customizing Email Templates | How do I customize email templates]]<br />
<br />
<br />
== Misc ==<br />
* [[How to create store-wide parameters accessible anywhere]]<br />
* [[Moving store database from shared provider to local install]]<br />
* [[Missing installation folders caused by unzip utility]]<br />
* [[ZIP Code only Shipping Estimate]]<br />
* [[How to hook and execute custom code against store events]]<br />
<br />
== External Links ==<br />
* [http://en.wikipedia.org/wiki/ASP.NET Asp.Net (wikipedia)]</div>Sohaibhttp://wiki.ablecommerce.com/index.php/Look_and_Feel_Customization_-_AC_GoldLook and Feel Customization - AC Gold2012-11-17T08:46:09Z<p>Nadeem: </p>
<hr />
<div><div id="cleanup" style="text-align: center; background: #ffe; margin: .75em 15%; padding: .5em; border: 1px solid #e3e3b0;"><br />
If you want to customize '''how the store works''' see '''[[Feature Customization - AC Gold]]'''<br />
</div><br />
<br />
This section includes information and documentation on things that change '''how the store looks''', see [[Feature Customization - AC Gold]] for topics on changing '''how the store works'''.<br />
<br />
* [[Creating Themes - AC Gold]]<br />
<br />
* [[Adding a favicon - AC Gold]]<br />
<br />
* [[Change star rating images - AC Gold]]<br />
<br />
<br />
== External Links ==<br />
* [http://help.ablecommerce.com/mergedProjects/ablecommerceGold/index.htm Customization Guide AC Gold] on the AbleCommerce help site<br />
* [http://en.wikipedia.org/wiki/Cascading_Style_Sheets Cascading Style Sheets (wikipedia)]<br />
* [https://addons.mozilla.org/en-US/firefox/addon/2104 FireFox HTML Viewer] This is a really handy tool. When enabled you can mouse over a area on a webpage and it will display it's CSS properties.<br />
* [https://addons.mozilla.org/en-US/firefox/addon/1843 FireFox Firebug] This is a really handy tool. When enabled you can change create and view styles on the fly,track styles sheets, debug javascript, explore the information of styles for some specific element by inspecting it through Firebug. A great support when customizing the pages.</div>Sohaibhttp://wiki.ablecommerce.com/index.php/Feature_CustomizationFeature Customization2012-11-17T08:40:23Z<p>Sohaib: New page: *Feature Customization - AC Gold *Feature Customization - AC7</p>
<hr />
<div>*[[Feature Customization - AC Gold]]<br />
*[[Feature Customization - AC7]]</div>Sohaibhttp://wiki.ablecommerce.com/index.php/Nullable_DatesNullable Dates2012-10-17T15:41:17Z<p>Loganr: </p>
<hr />
<div>In AbleCommerce 7.0.0 through AbleCommerce 7.0.7, many of our objects had DateTime properties that were nullable in the database. In these versions we would translate null into the value System.DateTime.MinValue when reading the records. When making business logic decisions the DateTime property would need to be checked against DateTime.MinValue to see if it was present.<br />
<br />
In AbleCommerce Gold the behavior changes slightly. Instead of translating null dates, our DateTime properties are nullable. This means the property can either be null or it can have a value. In order to use these DateTime properties you must be sure to factor in the possibility that the value does not exist in the database. In these cases you must decide how to handle that condition.<br />
<br />
A list of the properties that are nullable are below:<br />
<br />
{| class="wikitable" border="1" width="100%"<br />
|-<br />
!scope="col" | CLASS<br />
!scope="col" | PROPERTY<br />
!scope="col" | SIGNIFICANCE OF NULL<br />
|-<br />
| Coupon || StartDate || The coupon has no restriction on when it starts to be valid.<br />
|-<br />
| Coupon || EndDate|| The coupon has no restriction on when it ceases to be valid.<br />
|-<br />
| EmailList || LastSendDate || The email list has never been sent.<br />
|-<br />
| EmailListUser || LastSendDate || The email list has never been sent to this list member.<br />
|-<br />
| OrderItemDigitalGood || ActivationDate || The digital good has not been activated.<br />
|-<br />
| OrderItemDigitalGood || DownloadDate || The digital good has not been downloaded.<br />
|-<br />
| OrderShipment|| ShipDate || The order shipment has not been shipped.<br />
|-<br />
| Subscription|| ExpirationDate || The subscription has no expiration.<br />
|-<br />
| Payment|| CompletedDate || The payment has not yet been completed.<br />
|-<br />
| Special || StartDate || The special has no restriction on when it starts to be active.<br />
|-<br />
| Special || EndDate || The special has no restriction on when it ceases to be active.<br />
|-<br />
| Redirect || LastVisitedDate || The redirect has never been visited.<br />
|-<br />
| Currency || LastUpdate || The exchange rate for the currency has never been updated.<br />
|-<br />
| User || AffiliateReferralDate || The user has not been referred by an affiliate.<br />
|-<br />
| User || LastActivityDate || The user has never browsed the site.<br />
|-<br />
| User || LastLoginDate || The user has never logged in.<br />
|-<br />
| User || LastPasswordChangedDate || The user has never changed the password.<br />
|-<br />
| User || LastLockoutDate || The user has never been locked out.<br />
|}<br />
<br />
==Working with Nullable Dates==<br />
<br />
In customizing code with these properties you may notice from Intellisense that nullable dates act a little different from regular DateTime values. There are two different ways to decide if a DateTime has a value:<br />
<br />
<code>if (Coupon.StartDate.HasValue)</code><br />
<br />
OR<br />
<br />
<code>if (Coupon.StartDate != null)</code><br />
<br />
And when accessing the DateTime you need to use the Value property:<br />
<br />
<code>Coupon.StartDate.Value</code></div>Loganrhttp://wiki.ablecommerce.com/index.php/AbleCommerce_Gold_Code_DifferencesAbleCommerce Gold Code Differences2012-10-17T15:20:08Z<p>Naveed: </p>
<hr />
<div>If you are familiar with custom development in AC707 and prior, there are some notable differences in syntax when moving to AbleCommerce Gold. Some of the major differences are:<br />
<br />
[[Nullable Dates]]<br />
<br />
[[Deprecated Id Properties]]<br />
<br />
[[Store Context]]</div>Loganr