Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
@NataliaTepluhina - please add this to the docs as well:

Starting with Vue Storefront v1.6 we changed the default order-placing behaviour. Currently the `config.orders.directBackendSync` is set to `true` be default. With this option enabled - if the user is online, Vue Storefront tries to pass the order immediately and synchronously (waiting for result) to the eCommerce backend. This option gives immediate and direct feedback to the user. If there is an app-level error (for example validation error on Magento side) user will be notified immediately. If there is transmission issue (no connection, servers are down etc) the order is being put into queue (as it was prior to 1.6). If `config.orders.directBackendSync` is set to false - then the legacy behaviour with queuing all the orders is being used. With `directBackendSync` set to true we do have access to the server confirmation (with backend orderId) in `store.state.order.last_order_confirmation`
  • Loading branch information
pkarw committed Nov 21, 2018
1 parent 878c656 commit e73f2ca
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 20 deletions.
1 change: 1 addition & 0 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@
}
},
"orders": {
"directBackendSync": true,
"endpoint": "http://localhost:8080/api/order",
"payment_methods_mapping": {
},
Expand Down
2 changes: 1 addition & 1 deletion core/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function createApp (ssrContext, config): { app: Vue, router: any, store:
store.state.config = config
store.state.__DEMO_MODE__ = (config.demomode === true) ? true : false
if(ssrContext) Vue.prototype.$ssrRequestContext = ssrContext

Vue.prototype.$coreRouter = router
if (!store.state.config) store.state.config = buildTimeConfig // if provided from SSR, don't replace it

// depreciated
Expand Down
1 change: 1 addition & 0 deletions core/i18n/resource/i18n/en-US.csv
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@
"to account","to account"
"Are you sure you would like to remove this item from the shopping cart?","Are you sure you would like to remove this item from the shopping cart?"
"The product or category is not available in Offline mode. Redirecting to Home.","The product or category is not available in Offline mode. Redirecting to Home."
"Processing order...","Processing order..."
9 changes: 4 additions & 5 deletions core/modules/cart/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import Vue from 'vue'
import { ActionTree } from 'vuex'
import * as types from './mutation-types'
import rootStore from '@vue-storefront/store'
// import router from '@vue-storefront/core/router'
import i18n from '@vue-storefront/i18n'
import { sha3_224 } from 'js-sha3'
import { currentStoreView } from '@vue-storefront/store/lib/multistore'
import { currentStoreView, localizedRoute} from '@vue-storefront/store/lib/multistore'
import omit from 'lodash-es/omit'
import RootState from '@vue-storefront/store/types/RootState'
import CartState from '../types/CartState'
Expand Down Expand Up @@ -179,11 +178,11 @@ const actions: ActionTree<CartState, RootState> = {
const commit = context.commit
const state = context.state

if (!state.shipping.method_code) {
if (!state.shipping || !state.shipping.method_code) {
let shippingMethod = context.rootGetters['shipping/shippingMethods'].find(item => item.default)
commit(types.CART_UPD_SHIPPING, shippingMethod)
}
if (!state.payment.code) {
if (!state.payment || !state.payment.code) {
let paymentMethod = context.rootGetters['payment/paymentMethods'].find(item => item.default)
commit(types.CART_UPD_PAYMENT, paymentMethod)
}
Expand Down Expand Up @@ -214,7 +213,7 @@ const actions: ActionTree<CartState, RootState> = {
return state.cartItems.find(p => p.sku === sku)
},
goToCheckout (context) {
// router.push(localizedRoute('/checkout', currentStoreView().storeCode))
Vue.prototype.$coreRouter.push(localizedRoute('/checkout', currentStoreView().storeCode))
},
addItem ({ commit, dispatch, state }, { productToAdd, forceServerSilence = false }) {
let productsToAdd = []
Expand Down
12 changes: 7 additions & 5 deletions core/modules/checkout/store/checkout/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ const actions: ActionTree<CheckoutState, RootState> = {
*/
placeOrder (context, { order }) {
try {
context.dispatch('order/placeOrder', order, {root: true}).then(result => {
Vue.prototype.$db.usersCollection.setItem('last-cart-bypass-ts', new Date().getTime())
context.dispatch('cart/clear', {}, {root: true})
if (context.state.personalDetails.createAccount) {
context.commit(types.CHECKOUT_DROP_PASSWORD)
return context.dispatch('order/placeOrder', order, {root: true}).then(result => {
if (!result.resultCode || result.resultCode === 200) {
Vue.prototype.$db.usersCollection.setItem('last-cart-bypass-ts', new Date().getTime())
context.dispatch('cart/clear', {}, {root: true})
if (context.state.personalDetails.createAccount) {
context.commit(types.CHECKOUT_DROP_PASSWORD)
}
}
})
} catch (e) {
Expand Down
42 changes: 38 additions & 4 deletions core/modules/order/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { ActionTree } from 'vuex'
import RootState from '@vue-storefront/store/types/RootState'
import OrderState from '../types/OrderState'
const Ajv = require('ajv') // json validator
import rootStore from '@vue-storefront/store'
import { isOnline } from '@vue-storefront/store/lib/search'
import i18n from '@vue-storefront/i18n'

const actions: ActionTree<OrderState, RootState> = {
/**
Expand All @@ -28,10 +31,41 @@ const actions: ActionTree<OrderState, RootState> = {
throw new ValidationError(validate.errors)
} else {
Vue.prototype.$bus.$emit('order-before-placed', { order: order })
commit(types.ORDER_PLACE_ORDER, order)
Vue.prototype.$bus.$emit('order-after-placed', { order: order })

return true
if (!rootStore.state.config.orders.directBackendSync || !isOnline())
{
commit(types.ORDER_PLACE_ORDER, order)
Vue.prototype.$bus.$emit('order-after-placed', { order: order })
return Promise.resolve(true)
} else {
Vue.prototype.$bus.$emit('notification-progress-start', i18n.t('Processing order...'))
return rootStore.dispatch('sync/execute', { url: rootStore.state.config.orders.endpoint, // sync the order
payload: {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
mode: 'cors',
body: JSON.stringify(order)
},
}, { root: true }).then(task => {
Vue.prototype.$bus.$emit('notification-progress-stop')
if (task.resultCode !== 500) {
order.transmited = true
commit(types.ORDER_PLACE_ORDER, order) // archive this order but not trasmit it second time
commit(types.ORDER_LAST_ORDER_WITH_CONFIRMATION, { order: order, confirmation: task.result })
Vue.prototype.$bus.$emit('order-after-placed', { order: order, confirmation: task.result })
}
return task.result
}).catch(e => {
rootStore.dispatch('notification/spawnNotification', {
type: 'error',
message: i18n.t('The order can not be transfered because of server error. Order has been queued'),
action1: { label: i18n.t('OK') }
})
order.transmited = false // queue order
commit(types.ORDER_PLACE_ORDER, order) // archive this order but not trasmit it second time
Vue.prototype.$bus.$emit('notification-progress-stop')
throw (e)
})
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions core/modules/order/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import OrderState from '../types/OrderState'
export const module: Module<OrderState, RootState> = {
namespaced: true,
state: {
last_order_confirmation: null
},
actions,
mutations
Expand Down
3 changes: 2 additions & 1 deletion core/modules/order/store/mutation-types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const SN_ORDER = 'order'
export const ORDER_PLACE_ORDER = SN_ORDER + '/PLACE_ORDER'
export const ORDER_PROCESS_QUEUE = SN_ORDER + '/PROCESS_QUEUE'
export const ORDER_PROCESS_QUEUE = SN_ORDER + '/PROCESS_QUEUE'
export const ORDER_LAST_ORDER_WITH_CONFIRMATION = SN_ORDER + '/LAST_ORDER_CONFIRMATION'
8 changes: 6 additions & 2 deletions core/modules/order/store/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@ const mutations: MutationTree<OrderState> = {
const ordersCollection = Vue.prototype.$db.ordersCollection
const orderId = entities.uniqueEntityId(order) // timestamp as a order id is not the best we can do but it's enough
order.order_id = orderId.toString()
order.transmited = false
order.created_at = new Date()
order.updated_at = new Date()

ordersCollection.setItem(orderId.toString(), order, (err, resp) => {
if (err) console.error(err)
Vue.prototype.$bus.$emit('order/PROCESS_QUEUE', { config: rootStore.state.config }) // process checkout queue
if (!order.transmited) {
Vue.prototype.$bus.$emit('order/PROCESS_QUEUE', { config: rootStore.state.config }) // process checkout queue
}
console.info('Order placed, orderId = ' + orderId)
}).catch((reason) => {
console.error(reason) // it doesn't work on SSR
}) // populate cache
},
[types.ORDER_LAST_ORDER_WITH_CONFIRMATION] (state, payload) {
state.last_order_confirmation = payload
}
}

Expand Down
1 change: 1 addition & 0 deletions core/modules/order/types/OrderState.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export default interface OrderState {
last_order_confirmation: any
}
6 changes: 4 additions & 2 deletions core/pages/Checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default {
stockCheckCompleted: false,
stockCheckOK: false,
orderPlaced: false,
confirmation: null, // order confirmation from server
activeSection: {
personalDetails: true,
shipping: false,
Expand Down Expand Up @@ -132,10 +133,11 @@ export default {
this.$forceUpdate()
})
},
onAfterPlaceOrder (order) {
onAfterPlaceOrder (payload) {
this.confirmation = payload.confirmation
this.orderPlaced = true
this.$store.dispatch('checkout/setThankYouPage', true)
console.debug(this.order)
console.debug(payload.order)
},
onBeforeEdit (section) {
this.activateSection(section)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
{{ $t('Your purchase') }}
</h3>
<p v-if="OnlineOnly" v-html="this.$t('You have successfuly placed the order. You can check status of your order by using our <b>delivery status</b> feature. You will receive an order confirmation e-mail with details of your order and a link to track its progress.')" />
<p v-if="OnlineOnly && lastOrderConfirmation" v-html="this.$t('The server order id has been set to ') + lastOrderConfirmation.backendOrderId"/>
<p v-if="OnlineOnly" v-html="this.$t('E-mail us at <b>demo@vuestorefront.io</b> with any questions, suggestions how we could improve products or shopping experience')"/>

<h4 v-if="OfflineOnly">
Expand Down Expand Up @@ -89,6 +90,9 @@ export default {
}
},
computed: {
lastOrderConfirmation () {
return this.$store.state.order.last_order_confirmation.confirmation
},
isNotificationSupported () {
if (Vue.prototype.$isServer || !('Notification' in window)) return false
return 'Notification' in window
Expand Down
1 change: 1 addition & 0 deletions src/themes/default/resource/i18n/en-US.csv
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,4 @@
"DPD Courier","DPD Courier"
"My Recently viewed products","My Recently viewed products"
"No products yet","No products yet"
"The server order id has been set to ","The server order id has been set to "

0 comments on commit e73f2ca

Please sign in to comment.