Shopizer网站模块构造

Modules

Modules are plug in pieces of code that can be added and used in Shopizer with minimum configuration and integration efforts. Modules can also represent classes that can be interchanged for other implementations for providing extra or different functionalities. Shopizer modules are implemented using Spring framework IOC bean container (http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in order to easily add or change module bean definitions. There are two main types of modules which are application and integration modules.

Application modules are functionalities that have been identified with the possibilities of being changed or enhanced according to specific merchant needs. For instance new price types can be added to the system or it is possible to change password generation algorithm or change order fulfillment item packing logic.

Integration modules are sub system integration piece of codes that can be added to Shopizer in order to integrate with an external system such as Paypal, AuthorizeNet payment systems or Canada Post shipping system. Module implementations reside in sm-core project under com.salesmanager.core.module package (integration & application) and sm-shop project com.salesmanager.integration (portlets – as of Shopizer version 1.1.3).

Each module must implement a specific interface according to the module type. Modules will be available at runtime by adding or modifying an entry to sm-core/conf/spring/sm-modules.xml or by adding a component annotation (@Component) to the implementation class.

Properties defined modules

Modules defined in sm-core/conf/spring/sm-modules.xml follow Spring IOC container bean definition. The following syntax represent a module configured using Spring bean definition configuration file.

<bean id="mypricemodule" class="com.salesmanager.core.module.impl.application.prices.MonthlyPriceModule"/>

Annotation defined module

The following syntax represent a module configured using annotation stereotype syntax. In order to support @Component syntax, make sure your package is defined in annotation scanning directive in sm-core/conf/spring/sm-core-config.xml

@Component("mypricemodule")
public class MyModule implements PriceModule {

Annotation scanning directive is currently defined for those packages

<!-- Bean annotation scanning -->
<context:annotation-config />
<context:component-scan base-package="com.salesmanager.core.service" />
<context:component-scan base-package="com.salesmanager.core.module" />

Integration modules and some of the application modules requiring configuration and visibility for selection by a merchant need to be defined in CORE_MODULES_SERVICES table

Column nameDescription
CORE_MD_SERVICES_IDAuto increment identifier
CORE_MD_SERVICES_CODEInternal service (see note 1)
CORE_MD_NAMEModule code (unique text identifier no white space or special characters) ie paypal
COUNTRY_ISO_CODE_2US or CA or GB or any country ISO CODE. If the module applies to all countries put XX
CORE_MD_SERVICES_SUBTYPEInternal service sub type code (see note 2)
CORE_MD_SERVICES_DESCRIPTIONTextual description
CORE_MD_SERVICES_LOGO_PATHA logo is used in admin panel (central) in shipping and payment modules sections (sm-central\WebContent\common\img\en\payment) and fr
CORE_MD_SERVICES_POSITIONPosition displayed in admin panel (central)
CORE_MD_SERVICES_VISIBLEBoolean 0 or 1
CORE_MD_SERVICES_NEWBoolean 0 or 1
CORE_MD_SERVICES_URLExternal system URL for reference
CORE_MD_SERVICES_DEV_PROTOCOLExternal system test environment (http / https)
CORE_MD_SERVICES_DEV_DOMAINExternal system test environment (www.systemdomain.com)
CORE_MD_SERVICES_DEV_PORTExternal system test environment
CORE_MD_SERVICES_DEV_ENVExternal system test environment
CORE_MD_SERVICES_PROD_PROTOCOLExternal system production environment (http / https)
CORE_MD_SERVICES_PROD_DOMAINExternal system production environment
CORE_MD_SERVICES_PROD_PORTExternal system production environment
CORE_MD_SERVICES_PROD_ENVExternal system production environment
CORE_MD_SERVICES_CONFIGURABLERequires the module to be configured - Boolean 0 or 1

Any new entry to the system can be added to <SHOPIZER>\schema\sql\data\shopizer_data.sql

note 1

Internal services
RESERVED CODES
1= Shipping
2= Payment
4= Price
20= Portlet

note 2

Internal service sub type code
Sub types are defined to provide more details on service codes. 
Here is the list of RESERVED sub types per service code
**Service Code 1 (Shipping)**   
 - sub type 0 -> Shipping quotes module
 - sub type 1 -> Address validation module
**Service Code 2 (Payment)**
 - sub type 0 -> non gateway payment module
 - sub type 1 -> gateway payment module
**Service Code 4 (Price)**
 - sub type 1 -> One time price module
 - sub type 2 -> Recursive price module
**Service Code 20 (Portlet)**
 - sub type 1 -> Store front portlet
 - sub type 2 -> Store front portlet

Integration modules

 

Example of a payment integration module

Payment modules can be added to Shopizer by following a few design and configuration directives. The following section describes in details the steps and the code required to integrate a new credit card payment gateway.

Suppose for example that you want to create a new payment module for credit card gateway system called 'netcharge' [this is a ficticious name]. To fully allow the configuration and the credit card processing through this system (netcharge) you will need to create:

sm-central\WebContent\payment\netcharge.jsp

This jsp file above will be displayed in Shopizer administration (central) allowing the configurations and settings to use netcharge gateway. A naming convention requires that jsp file to match the payment module name that will be used all across the system for identifying this external gateway system. Do not use any special charactes nor white spaces in your module name.

You will also need to create an action class to implement business logic in the administration section

sm-central\src\com\salesmanager\central\payment\PaymentnetchargeAction.java

This java class file above is the Struts action class in the administration section that will handle the creation, edition and delition of netcharge payment gateway configurations and settings. The structure of the new class is represented below.

By extending com.salesmanager.central.payment.PaymentModuleAction The new payment module will force the implementation of deletedisplayprepare and save methods for this module. A naming directive requires the name of the class to be Payment<module name>Action.class. A coding directive also uses IntegrationProperties and IntegrationKeys objects to store credentials and settings submited by the merchant. From that point you can look at the other payment gateway implementations and do precisely the same to implement the Action methods.

public class PaymentnetchargeAction extends PaymentModuleAction {
 
 
	private IntegrationProperties properties = new IntegrationProperties();
	private IntegrationKeys keys = new IntegrationKeys();
 
	@Override
	public void deleteModule() throws Exception {
		// TODO Auto-generated method stub
 
	}
 
	@Override
	public void displayModule() throws Exception {
		// TODO Auto-generated method stub
 
	}
 
	@Override
	public void prepareModule() throws Exception {
		// TODO Auto-generated method stub
 
	}
 
	@Override
	public void saveModule() throws Exception {
		// TODO Auto-generated method stub
 
	}
 
	public IntegrationProperties getProperties() {
		return properties;
	}
 
	public void setProperties(IntegrationProperties properties) {
		this.properties = properties;
	}
 
	public IntegrationKeys getKeys() {
		return keys;
	}
 
	public void setKeys(IntegrationKeys keys) {
		this.keys = keys;
	}
}

You will need to specify your module name in

sm-core\conf\resources\modules.properties (same for modules_<lang>.properties)

module.netcharge=Netcharge

Add the labels to be used in central configuration page

sm-core\conf\resources\central-payments.properties (same for central-payments_<lang>.properties)
label.payment.methods.netcharge.userid=User name
label.payment.methods.netcharge.password=Password
label.payment.methods.netcharge.storeid=Merchant id
label.payment.methods.title.netcharge =Net Charge
label.payment.methods.text.netcharge=<a href=\"http://www.netcharge.com/">Sign up for an account</a>.<br>Net Charge merchantid currency should match your store.
label.payment.methods.footer.netcharge=

You will need your payment module class. This class will be responsible to handle processing, authorization and credit transactions. This class is will build the transaction to Net Charge and handle the payment response. All payment implementation module must reside in com.salesmanager.core.module.impl.integration.payment package.

sm-core\src\com\salesmanager\core\module\impl\integration\payment\NetChargeTransactionImpl.java

Not that the module uses @Component annotation to declare the module name. Again you can look at the other modules to get an idea on how methods need to be implemented.

 
package com.salesmanager.core.module.impl.integration.payment;
/**
 * Manages credit card transactions with Net Charge API
 * @author Carl Samson
 *
 */
@Component("netcharge")
public class NetChargeTransactionImpl extends CreditCardGatewayTransactionImpl {
 
	@Override
	public GatewayTransactionVO authorizeAndCapture(IntegrationKeys keys,
			IntegrationProperties properties, MerchantStore store, Order order)
			throws TransactionException {
		//Will invoke make transaction 
		return null;
	}
 
	@Override
	public GatewayTransactionVO authorizeTransaction(IntegrationKeys keys,
			IntegrationProperties properties, MerchantStore store, Order order)
			throws TransactionException {
		//Will invoke make transaction 
		return null;
	}
 
	/**
	 * Invoked from admin panel to capture after an authorization 
	 */
	public GatewayTransactionVO captureTransaction(MerchantStore store,
			Order order) throws TransactionException {
		//Will invoke make transaction 
		return null;
	}
 
 
	/**
	 * no need to initialize a transaction
	 */
	public Map<String, String> initTransaction(
			CoreModuleService serviceDefinition, Order order)
			throws TransactionException {
		// TODO Auto-generated method stub
		return null;
	}
 
	/**
	 * no need to invoke any 'post transaction' url once completed
	 */
	public Order postTransaction(Order order) throws TransactionException {
		// TODO Auto-generated method stub
		return null;
	}
 
	/**
	 * Invoked from admin panel to refund after a capture 
	 */
	public GatewayTransactionVO refundTransaction(MerchantStore store,
			Order order, BigDecimal amount) throws TransactionException {
		// TODO Auto-generated method stub
		return null;
	}
 
	/**
	 * Retrieve transaction history
	 */
	public List<SalesManagerTransactionVO> retreiveTransactions(int merchantid,
			Order order) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
 
 
	private GatewayTransactionVO makeTransaction(String type,
			IntegrationKeys ik, IntegrationProperties props,
			MerchantStore store, Order order) throws TransactionException {
		//Handles processing for all transaction types
		return null;
 
	}
 
	public ConfigurationResponse getConfiguration(
			MerchantConfiguration configurations, ConfigurationResponse vo)
			throws Exception {
		//get payment gatemay configuration from MERCHANT_CONFIGURATION table
		return null;
	}
 
	public void storeConfiguration(int merchantid, HttpServletRequest request)
			throws Exception {
		// can be used to store merchant gateway configuration
 
	}
}

The implementation class extends CreditCardGatewayTransactionImpl. Administration panel and order fulfillment functions uses methods of the super classCreditCardGatewayTransactionImpl which delegates to the sub class the processing for capture (After pre-authorization), refund (after capture) and process transactions (pre-authorization or capture) Pre-authorization or capture are configured in the module option according to merchant's selection.

Finally here are the values for CORE_MODULES_SERVICES table for service discovery and meta information

Column nameDescription
CORE_MD_SERVICES_IDAuto increment identifier
CORE_MD_SERVICES_CODE2
CORE_MD_NAMEnetcharge
COUNTRY_ISO_CODE_2CA (if this service is available in US too, add a second row with US)
CORE_MD_SERVICES_SUBTYPE1
CORE_MD_SERVICES_DESCRIPTIONNetcharge payment gateway integration
CORE_MD_SERVICES_LOGO_PATH/payment/beanstream.gif
CORE_MD_SERVICES_POSITION4
CORE_MD_SERVICES_VISIBLE1
CORE_MD_SERVICES_NEW1
CORE_MD_SERVICES_URLwww.netcharge.com
CORE_MD_SERVICES_DEV_PROTOCOLhttps
CORE_MD_SERVICES_DEV_DOMAINtest.netcharge.com
CORE_MD_SERVICES_DEV_PORT443
CORE_MD_SERVICES_DEV_ENV/processTransaction
CORE_MD_SERVICES_PROD_PROTOCOLhttps
CORE_MD_SERVICES_PROD_DOMAINwww.netcharge.com
CORE_MD_SERVICES_PROD_PORT443
CORE_MD_SERVICES_PROD_ENV/processTransaction
CORE_MD_SERVICES_CONFIGURABLE1

More details to come on Shipping Modules

Application modules

 

Files modules

Files modules are bean classes used for uploading product images and digital downloads to the system. Currently defined in sm-core/conf/spring/sm-modules.xml

<bean id="localfile" class="com.salesmanager.core.module.impl.application.files.LocalFileImpl"/>
<bean id="productfile" singleton="false" class="com.salesmanager.core.module.impl.application.files.LocalFileImpl"/>

Product image file

localfile bean uploads products images and product options images to the server. Productfile bean uploads digital downloads to the server. Both modules used the same implementation which points to com.salesmanager.core.module.impl.application.files.LocalFileImpl. It is possible to change the implementation of digital products uploads (productfile) if those files have to be uploaded to Amazon S3 for instance.

Here is a code sample to upload a product image

ProductImageUtil image = new ProductImageUtil();
image.uploadCropedProductImages(imageFile, imageFileName, imageFileContentType,product, moduleConfigMap);

uploadCropedProductImages will upload the product image file on the server and will create a large, medium and small version of it for the catalogue listing and details and shopping cart pages. This method accepts a java.io.File (uploaded file on the server) uploaded using Struts 2 file upload principles (http://struts.apache.org/2.0.14/docs/file-upload.html). It also takes the uploaded file and its content type. The method also accepts the com.salesmanager.core.entity.catalog.Product entity and the catalog configuration map for resizing the image according to the template specification.

The moduleConfigMap HashMap object can be retrieved using the following code

 
ReferenceService rservice = (ReferenceService) ServiceFactory.getService(ServiceFactory.ReferenceService);
MerchantService service = (MerchantService) ServiceFactory.getService(ServiceFactory.MerchantService);
MerchantStore mStore = service.getMerchantStore(ctx.getMerchantid());
Map<String, String> moduleConfigMap = rservice.getModuleConfigurationsKeyValue(mStore.getTemplateModule(),mStore.getCountry());

To retrieve the current merchant store from sm-central (admin panel) in an Action class, first retrieve the Context object which contains Merchant and User information by doing

 
Context ctx = super.getContext();
Int merchantId = ctx.getMerchantId();

An example of this can be found in com.salesmanager.central.catalog.EditProductAction

Digital download file

To upload a digital product file, it is quite similar to the method above, but the invocation needs to be done on CatalogService in a transactional context. So the code will be

CatalogService cservice = (CatalogService) ServiceFactory.getService(ServiceFactory.CatalogService);
cservice.persistUploadProduct(product,productFile, productFileName,productFileContentType);

Files module use properties defined in sm-core/conf/properties/sm-core-config.properties

Product image upload

core.product.image.maxfilesize=3145728
core.product.image.contenttypes=image/pjpeg;image/gif;image/jpeg;image/jpg;image/png;image/tiff;image/x-png
core.product.image.cleanup=false
core.product.image.maxwidth=700
core.product.image.maxheight=700

Product file upload

core.product.file.maxfilesize=8000000
core.product.file.downloadmaxdays=2
core.product.file.downloadmaxcount=5

Branding files

core.branding.cart.contenttypes=image/pjpeg;image/gif;image/jpeg;image/jpg;image/png;image/tiff;image/x-png
core.branding.cart.maxfilesize=100000
core.branding.cart.cleanup=false
core.branding.cart.dirname=header
core.branding.banner.contenttypes=image/pjpeg;image/gif;image/jpeg;image/jpg;image/png;image/tiff;image/x-png
core.branding.banner.maxfilesize=100000
core.branding.banner.cleanup=true
core.branding.banner.dirname=banner

Other file uploads (logo, banner…)

Other file uploads use File modules directly. File module API can be invoked this way:

FileModule futil = (FileModule) SpringUtil.getBean("localfile");
String finalfilename = futil.uploadFile(ctx.getMerchantid(),"core.branding.cart",uploadFileName,uploadFileContentType);

core.branding.cart pecifies the group of properties defined in sm-core/conf/properties/sm-core-config.properties which identifies specifications for image size and types allowed in the system.

Prices Modules

Shopizer supports one to multiple prices per item. The system is configured out of the box to display and calculate one to multiple one time prices and one to multiple monthly prices. All those configured prices will be displayed in the product details page, in the shopping cart and during the checkout process.

It is possible to add new prices, for instances weekly recursive or annual recursive etc which should be displayed in a distinct row when applicable. In order to implement a new ProductPrice module, create a new class in com.salesmanager.core.module.impl.application.prices and make that class extend PriceModule interface

 
package com.salesmanager.core.module.impl.application.prices;
@Component("mypricemodule")
public class MyPriceModule implements PriceModule {
 
	public OrderTotalSummary calculateOrderPrice(Order order,
			OrderTotalSummary orderSummary, OrderProduct orderProduct,
			OrderProductPrice productPrice, String currency) {
		//calculate this price type and add it to OrderTotalSummary
	}
 
	public OrderTotalSummary calculateOrderPrice(Order order,
			OrderTotalSummary orderSummary, OrderProduct orderProduct,
			OrderProductPrice productPrice, String currency, Locale locale) {
		//calculate this price type and add it to OrderTotalSummary
 
	}
 
	public boolean isTaxApplicable() {
 
	}
 
	public BigDecimal getPrice(ProductPrice productPrice, String currency) {
 
	}
 
	public String getHtmlPriceFormated(String prefix,
			ProductPrice productPrice, Locale locale, String currency) {
		//return a string displaying how the price will be displayed
	}
 
	public String getPricePrefixText(String currency, Locale locale) {
		}
 
	public String getPriceSuffixText(String currency, Locale locale) {
	}
 
	public String getPriceText(String currency, Locale locale) {
		//price formatted as a text
 
	}
}

Your new price will have to be inserted into CORE_MODULES_SERVICE in order to be available in sm-central (admin panel) drop down list

Column nameDescription
CORE_MD_SERVICES_IDAuto increment identifier
CORE_MD_SERVICES_CODE4
CORE_MD_NAMEmypricemodule
COUNTRY_ISO_CODE_2XX
CORE_MD_SERVICES_SUBTYPE1 (one time) or 2 (recursive)
CORE_MD_SERVICES_DESCRIPTIONMy new payment module
CORE_MD_SERVICES_LOGO_PATHnull
CORE_MD_SERVICES_POSITION3
CORE_MD_SERVICES_VISIBLE1
CORE_MD_SERVICES_NEW0
CORE_MD_SERVICES_URLnull
CORE_MD_SERVICES_DEV_PROTOCOLnull
CORE_MD_SERVICES_DEV_DOMAINnull
CORE_MD_SERVICES_DEV_PORTnull
CORE_MD_SERVICES_DEV_ENVnull
CORE_MD_SERVICES_PROD_PROTOCOLnull
CORE_MD_SERVICES_PROD_DOMAINnull
CORE_MD_SERVICES_PROD_PORTnull
CORE_MD_SERVICES_PROD_ENVnull
CORE_MD_SERVICES_CONFIGURABLE0

Packing modules

Packing modules are classes responsible for preparing shipping quote calculation. There are many ways a merchant can ship items to customers and those modules should provide accuracy for specific shipping needs a merchant can have. The system has 2 packing algorithm included which are Item packing basis and Box packing basis. It is possible to implement and add other packing module. CalculateBoxPackingModule already does a lot when having to pack items together. From admin panel (sm-central) a configuration page is available for configuring your options.

To implement your own packing algorithm your class needs to implement CalculatePackingModule

@Component("bagpacking")
public class MyPackingModule implements CalculatePackingModule {
 
	public void storeConfiguration(int merchantid, ConfigurationResponse vo,
			HttpServletRequest request) throws Exception {
		// TODO Auto-generated method stub
 
	}
 
	public ConfigurationResponse getConfiguration(
			MerchantConfiguration configurations, ConfigurationResponse vo)
			throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
 
	public Collection<PackageDetail> calculatePacking(
			Collection<OrderProduct> products, MerchantConfiguration config,
			int merchantId) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
 
	public String getConfigurationOptionsFileName(Locale locale)
			throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
 
	public PackageDetail getConfigurationOptions(MerchantConfiguration config,
			String currency) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
}

getConfigurationOptionsFileName method can return a configuration jsp page specific to your module if your packing option needs to be configured. The jsp file needs to be named as your packing module, so in this case I will have a jsp bagpacking.jsp that I will drop in sm-central/WebContent/shipping directory. If no configuration is required, that method should return null.

storeConfiguration method will be invoked when the merchant submit your packing configuration option. ConfigurationResponse being the original values stored in the database. HttpServletRequest contain new configuration options submitted.

getConfiguration is a callback invoked when options are retrieved from the database in case extra manipulations are required. Simply return ConfigurationResponse when no manipulations are required in the packing options.

getConfigurationOptions return selected options to be displayed in optional module configuration jsp page. calculatePacking is the method invoked for shipping quotes during checkout or when creating an invoice. This method returns a Collection of PackageDetail which contains appropriate information for shipping quote calculation. Although the method is called calculatePacking, there is no cost calculation, but an organisation of items inside a Collection of PackageDetail.

Once your module class is implemented, a new entry in CORE_MODULES_SERVICES table is required for discovering this new module and for the option to be displayed in admin panel (sm-central)

Column nameDescription
CORE_MD_SERVICES_IDAuto increment identifier
CORE_MD_SERVICES_CODE1
CORE_MD_NAMEbagpacking
COUNTRY_ISO_CODE_2XX
CORE_MD_SERVICES_SUBTYPE1
CORE_MD_SERVICES_DESCRIPTIONMy new packing module
CORE_MD_SERVICES_LOGO_PATHnull
CORE_MD_SERVICES_POSITION3
CORE_MD_SERVICES_VISIBLE1
CORE_MD_SERVICES_NEW0
CORE_MD_SERVICES_URLnull
CORE_MD_SERVICES_DEV_PROTOCOLnull
CORE_MD_SERVICES_DEV_DOMAINnull
CORE_MD_SERVICES_DEV_PORTnull
CORE_MD_SERVICES_DEV_ENVnull
CORE_MD_SERVICES_PROD_PROTOCOLnull
CORE_MD_SERVICES_PROD_DOMAINnull
CORE_MD_SERVICES_PROD_PORTnull
CORE_MD_SERVICES_PROD_ENVnull
CORE_MD_SERVICES_CONFIGURABLE0 or 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值