Added ability to extend using modules

master
Mark Moffat 2020-01-03 18:51:24 +10:30
parent 2e5dfd576c
commit 5546341c1c
8 changed files with 62 additions and 40 deletions

View File

@ -200,11 +200,6 @@ payments and the sitemap for search engine indexing.
This email is used for any email receipts which are sent by your website. This email is used for any email receipts which are sent by your website.
##### Free shipping threshold
expressCart allows for the addition of a free shipping threshold. The cart will remove the shipping costs once the order has exceeded the `Free shipping threshold`
value. If the value of the cart is beneath the `Free shipping threshold`, the cart will add the `Flat shipping rate` to the total amount.
##### Payment Gateway ##### Payment Gateway
This determines which payment gateway to use. You will also need to configure your payment gateway configuration file here: `/config/<gateway_name>.json` This determines which payment gateway to use. You will also need to configure your payment gateway configuration file here: `/config/<gateway_name>.json`
@ -321,6 +316,9 @@ The Instore config file is located: `/config/instore.json`. A example Instore se
``` ```
Note: No payment is actually processed. The order will move to the `orderStatus` set and the payment is completed instore. Note: No payment is actually processed. The order will move to the `orderStatus` set and the payment is completed instore.
## Modules
It's possible to extend the basic functionality of `expressCart` using modules. All modules are loaded from `/lib/modules` at startup and added to the `config` for use throughout the app. There is an example module `shipping-basic` to calculate the flat shipping rate. One way to extend this basic module is to call a Postage service like [easypost](https://www.easypost.com/) to get an accurate rate for your location, package size etc.
## Email settings ## Email settings
You will need to configure your SMTP details for expressCart to send email receipts to your customers. You will need to configure your SMTP details for expressCart to send email receipts to your customers.

View File

@ -42,14 +42,6 @@
"type": "boolean", "type": "boolean",
"default": true "default": true
}, },
"flatShipping": {
"type": "number",
"default": 10
},
"freeShippingAmount": {
"type": "number",
"default": 100
},
"productsPerRow": { "productsPerRow": {
"type": "number", "type": "number",
"default": 3 "default": 3
@ -114,6 +106,26 @@
"enableLanguages": { "enableLanguages": {
"type": "boolean", "type": "boolean",
"default": true "default": true
},
"modules": {
"type": "object",
"properties": {
"enabled": {
"type": "object",
"properties": {
"shipping": {
"type": "string"
}
},
"required": ["shipping"]
}
},
"required": ["enabled"],
"default": {
"enabled": {
"shipping": "shipping-basic"
}
}
} }
}, },
"required": [ "required": [
@ -125,7 +137,8 @@
"emailPassword", "emailPassword",
"emailAddress", "emailAddress",
"paymentGateway", "paymentGateway",
"databaseConnectionString" "databaseConnectionString",
"modules"
], ],
"additionalProperties": false "additionalProperties": false
} }

View File

@ -10,8 +10,6 @@
"emailPassword": "this_is_the_smtp_password", "emailPassword": "this_is_the_smtp_password",
"emailAddress": "hi@markmoffat.com", "emailAddress": "hi@markmoffat.com",
"menuEnabled": true, "menuEnabled": true,
"flatShipping": 10,
"freeShippingAmount": 100,
"productsPerRow": 3, "productsPerRow": 3,
"productsPerPage": 6, "productsPerPage": 6,
"menuTitle": "Menu", "menuTitle": "Menu",
@ -25,5 +23,10 @@
"trackStock": false, "trackStock": false,
"orderHook": "", "orderHook": "",
"availableLanguages": ["en", "it"], "availableLanguages": ["en", "it"],
"defaultLocale": "en" "defaultLocale": "en",
"modules": {
"enabled": {
"shipping": "shipping-basic"
}
}
} }

View File

@ -131,9 +131,11 @@ const updateTotalCart = (req, res) => {
// Update the total items in cart for the badge // Update the total items in cart for the badge
req.session.totalCartItems = Object.keys(req.session.cart).length; req.session.totalCartItems = Object.keys(req.session.cart).length;
// under the free shipping threshold // Calculate shipping using the loaded module
if(req.session.totalCartAmount < config.freeShippingAmount){ const shippingCost = config.modules.loaded.shipping.calculateShipping(req.session.totalCartAmount);
req.session.totalCartAmount = req.session.totalCartAmount + parseInt(config.flatShipping); if(shippingCost > 0){
req.session.totalCartShipping = parseInt(shippingCost);
req.session.totalCartAmount = req.session.totalCartAmount + parseInt(shippingCost);
req.session.shippingCostApplied = true; req.session.shippingCostApplied = true;
}else{ }else{
req.session.shippingCostApplied = false; req.session.shippingCostApplied = false;
@ -297,6 +299,19 @@ const getConfig = () => {
config.env = ''; config.env = '';
} }
// load modules
try{
config.modules.loaded = {};
Object.keys(config.modules.enabled).forEach((mod) => {
config.modules.loaded[mod] = require(`./modules/${config.modules.enabled[mod]}`);
});
}catch(ex){
console.log('Could not load modules, check your config.', ex);
process.exit(1);
}
console.log('config', config);
return config; return config;
}; };
@ -369,10 +384,6 @@ const updateConfig = (fields) => {
settingsFile.flatShipping = parseInt(fields.flatShipping); settingsFile.flatShipping = parseInt(fields.flatShipping);
} }
if(fields.freeShippingAmount){
settingsFile.freeShippingAmount = parseInt(fields.freeShippingAmount);
}
if(fields.productsPerRow){ if(fields.productsPerRow){
settingsFile.productsPerRow = parseInt(fields.productsPerRow); settingsFile.productsPerRow = parseInt(fields.productsPerRow);
} }

View File

@ -0,0 +1,13 @@
const shippingAmount = 10;
const freeThreshold = 100;
const calculateShipping = (amount) => {
if(amount >= freeThreshold){
return 0;
}
return shippingAmount;
};
module.exports = {
calculateShipping
};

View File

@ -107,9 +107,6 @@
"Cart URL": "Cart URL", "Cart URL": "Cart URL",
"This URL is used in sitemaps and when your customer returns from completing their payment.": "This URL is used in sitemaps and when your customer returns from completing their payment.", "This URL is used in sitemaps and when your customer returns from completing their payment.": "This URL is used in sitemaps and when your customer returns from completing their payment.",
"This is used as the \"from\" email when sending receipts to your customers.": "This is used as the \"from\" email when sending receipts to your customers.", "This is used as the \"from\" email when sending receipts to your customers.": "This is used as the \"from\" email when sending receipts to your customers.",
"Flat shipping rate": "Flat shipping rate",
"A flat shipping rate applied to all orders.": "A flat shipping rate applied to all orders.",
"Free shipping threshold": "Free shipping threshold",
"Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.": "Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.", "Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.": "Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.",
"Payment gateway": "Payment gateway", "Payment gateway": "Payment gateway",
"Payment_Gateway_Info": "You will also need to configure your payment gateway credentials in the `/config/&lt;gateway_name&gt;.json` file.", "Payment_Gateway_Info": "You will also need to configure your payment gateway credentials in the `/config/&lt;gateway_name&gt;.json` file.",

View File

@ -109,9 +109,6 @@
"This URL is used in sitemaps and when your customer returns from completing their payment.": "Questo URL è usato nelle sitemaps e quando il tuo cliente ritorna per completare il suo pagamento", "This URL is used in sitemaps and when your customer returns from completing their payment.": "Questo URL è usato nelle sitemaps e quando il tuo cliente ritorna per completare il suo pagamento",
"This is used as the \"from\" email when sending receipts to your customers.": "Questo è usato come \"from\" nelle email inviate ai clienti", "This is used as the \"from\" email when sending receipts to your customers.": "Questo è usato come \"from\" nelle email inviate ai clienti",
"Cart Email": "Cart Email", "Cart Email": "Cart Email",
"Flat shipping rate": "Tariffa di spedizione fissa",
"A flat shipping rate applied to all orders.": "Una tariffa di spedizione fissa da applicare a tutti gli ordini",
"Free shipping threshold": "Soglia di spedizione gratuita",
"Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.": "Ordini oltre questo valore avranno la spedizione GRATUITA. Configura un alto valore se vuoi sempre addebitare la spedizione.", "Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.": "Ordini oltre questo valore avranno la spedizione GRATUITA. Configura un alto valore se vuoi sempre addebitare la spedizione.",
"Payment gateway": "Gateway pagamento", "Payment gateway": "Gateway pagamento",
"Payment_Gateway_Info": "Dovrai configurare anche le tue credenziali per il gateway di pagamento nel file `/config/&lt;gateway_name&gt;.json`.", "Payment_Gateway_Info": "Dovrai configurare anche le tue credenziali per il gateway di pagamento nel file `/config/&lt;gateway_name&gt;.json`.",

View File

@ -33,16 +33,6 @@
<input type="email" class="form-control" name="emailAddress" value="{{config.emailAddress}}" required> <input type="email" class="form-control" name="emailAddress" value="{{config.emailAddress}}" required>
<p class="help-block">{{ @root.__ "This is used as the \"from\" email when sending receipts to your customers." }}</p> <p class="help-block">{{ @root.__ "This is used as the \"from\" email when sending receipts to your customers." }}</p>
</div> </div>
<div class="form-group">
<label>{{ @root.__ "Flat shipping rate" }} *</label>
<input type="text" class="form-control" name="flatShipping" value="{{config.flatShipping}}" required>
<p class="help-block">{{ @root.__ "A flat shipping rate applied to all orders." }}</p>
</div>
<div class="form-group">
<label>{{ @root.__ "Free shipping threshold" }}</label>
<input type="text" class="form-control" name="freeShippingAmount" value="{{config.freeShippingAmount}}">
<p class="help-block">{{ @root.__ "Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping." }}</p>
</div>
<div class="form-group"> <div class="form-group">
<label>{{ @root.__ "Payment gateway" }}</label> <label>{{ @root.__ "Payment gateway" }}</label>
<select class="form-control" name="paymentGateway"> <select class="form-control" name="paymentGateway">