@fabrix/spool-cart
Version:
Spool - eCommerce Spool for Fabrix
377 lines (376 loc) • 12.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const common_1 = require("@fabrix/fabrix/dist/common");
const spool_sequelize_1 = require("@fabrix/spool-sequelize");
const errors_1 = require("@fabrix/spool-sequelize/dist/errors");
const lodash_1 = require("lodash");
const shortId = require("shortid");
class AddressResolver extends spool_sequelize_1.SequelizeResolver {
cleanAddress(address) {
return lodash_1.pick(address, [
'address_1',
'address_2',
'address_3',
'company',
'city',
'prefix',
'first_name',
'last_name',
'suffix',
'phone',
'province',
'province_code',
'country',
'country_name',
'country_code',
'postal_code'
]);
}
resolveByInstance(address, options = {}) {
return Promise.resolve(address);
}
resolveById(address, options = {}) {
return this.findById(address.id, options)
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `Address ${address.id} not found`);
}
return resUser;
});
}
resolveByToken(address, options = {}) {
return this.findOne(lodash_1.defaultsDeep({
where: {
token: address.token
}
}, options))
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `Address token ${address.token} not found`);
}
return resUser;
});
}
resolveByNumber(address, options = {}) {
return this.findById(address, options)
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `Address ${address.token} not found`);
}
return resUser;
});
}
resolveByString(address, options = {}) {
return this.findOne(lodash_1.defaultsDeep({
where: {
token: address
}
}, options))
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `Address ${address} not found`);
}
return resUser;
});
}
resolve(address, options = {}) {
const resolvers = {
'instance': address instanceof this.instance,
'id': !!(address && lodash_1.isObject(address) && address.id),
'token': !!(address && lodash_1.isObject(address) && address.token),
'number': !!(address && lodash_1.isNumber(address)),
'string': !!(address && lodash_1.isString(address))
};
const type = Object.keys(resolvers).find((key) => resolvers[key]);
switch (type) {
case 'instance': {
return this.resolveByInstance(address, options);
}
case 'id': {
return this.resolveById(address, options);
}
case 'token': {
return this.resolveByToken(address, options);
}
case 'number': {
return this.resolveByNumber(address, options);
}
case 'string': {
return this.resolveByString(address, options);
}
default: {
const err = new Error(`Unable to resolve Address ${address}`);
return Promise.reject(err);
}
}
}
}
exports.AddressResolver = AddressResolver;
class Address extends common_1.FabrixModel {
static get resolver() {
return AddressResolver;
}
static config(app, Sequelize) {
return {
options: {
underscored: true,
scopes: {
live: {
where: {
live_mode: true
}
}
},
hooks: {
beforeValidate: [
(values, options) => {
try {
values = app.services.ProxyCartService.normalizeAddress(values);
}
catch (err) {
return Promise.resolve(err);
}
}
],
beforeCreate: [
(values, options) => {
if (!values.token) {
values.token = `address_${shortId.generate()}`;
}
return app.services.GeolocationGenericService.locate(values)
.then(latLng => {
values = lodash_1.defaults(values, latLng);
})
.catch(err => {
app.log.error(err);
});
}
],
beforeUpdate: [
(values, options) => {
return app.services.GeolocationGenericService.locate(values)
.then(latLng => {
values = lodash_1.defaults(values, latLng);
})
.catch(err => {
app.log.error(err);
return values;
});
}
]
}
}
};
}
static schema(app, Sequelize) {
return {
token: {
type: Sequelize.STRING,
unique: true
},
address_1: {
type: Sequelize.STRING,
allowNull: false
},
address_2: {
type: Sequelize.STRING
},
address_3: {
type: Sequelize.STRING
},
company: {
type: Sequelize.STRING
},
city: {
type: Sequelize.STRING,
allowNull: false
},
prefix: {
type: Sequelize.STRING
},
first_name: {
type: Sequelize.STRING
},
last_name: {
type: Sequelize.STRING
},
suffix: {
type: Sequelize.STRING
},
phone: {
type: Sequelize.STRING
},
province: {
type: Sequelize.STRING,
allowNull: false
},
province_code: {
type: Sequelize.STRING,
allowNull: false
},
country: {
type: Sequelize.STRING,
allowNull: false
},
country_code: {
type: Sequelize.STRING,
allowNull: false
},
country_name: {
type: Sequelize.STRING,
allowNull: false
},
postal_code: {
type: Sequelize.STRING,
allowNull: false
},
latitude: {
type: Sequelize.FLOAT,
allowNull: false,
defaultValue: 0.000000,
validate: {
min: -90,
max: 90
}
},
longitude: {
type: Sequelize.FLOAT,
allowNull: false,
defaultValue: 0.000000,
validate: {
min: -180,
max: 180
}
},
formatted_address: {
type: Sequelize.STRING
},
live_mode: {
type: Sequelize.BOOLEAN,
defaultValue: app.config.get('cart.live_mode')
}
};
}
static associate(models) {
models.Address.belongsToMany(models.Customer, {
foreignKey: 'address_id',
through: {
model: models.ItemAddress,
scope: {
model: 'customer'
},
},
constraints: false
});
models.Address.belongsToMany(models.Shop, {
foreignKey: 'address_id',
through: {
model: models.ItemAddress,
scope: {
model: 'shop'
},
},
constraints: false
});
models.Address.belongsToMany(models.Cart, {
foreignKey: 'address_id',
through: {
model: models.ItemAddress,
scope: {
model: 'cart'
},
},
constraints: false
});
models.Address.belongsToMany(models.Vendor, {
foreignKey: 'address_id',
through: {
model: models.ItemAddress,
scope: {
model: 'vendor'
},
},
constraints: false
});
}
}
exports.Address = Address;
Address.prototype.merge = function (updates) {
this.address_1 = updates.address_1 || this.address_1;
this.address_2 = updates.address_2 || this.address_2;
this.address_3 = updates.address_3 || this.address_3;
this.company = updates.company || this.company;
this.city = updates.city || this.city;
this.prefix = updates.prefix || this.prefix;
this.first_name = updates.first_name || this.first_name;
this.last_name = updates.last_name || this.last_name;
this.suffix = updates.suffix || this.suffix;
this.phone = updates.phone || this.phone;
this.province = updates.province || this.province;
this.province_code = updates.province_code || this.province_code;
this.country = updates.country || this.country;
this.country_name = updates.country_name || this.country_name;
this.country_code = updates.country_code || this.country_code;
this.postal_code = updates.postal_code || this.postal_code;
this.formatted_address = updates.formatted_address || this.formatted_address;
this.latitude = updates.latitude || this.latitude;
this.longitude = updates.longitude || this.longitude;
if (this.address_1 === '') {
this.address_1 = null;
}
if (this.address_2 === '') {
this.address_2 = null;
}
if (this.address_3 === '') {
this.address_3 = null;
}
if (this.company === '') {
this.company = null;
}
if (this.city === '') {
this.city = null;
}
if (this.prefix === '') {
this.prefix = null;
}
if (this.first_name === '') {
this.first_name = null;
}
if (this.last_name === '') {
this.last_name = null;
}
if (this.suffix === '') {
this.suffix = null;
}
if (this.phone === '') {
this.phone = null;
}
if (this.province === '') {
this.province = null;
}
if (this.province_code === '') {
this.province_code = null;
}
if (this.country === '') {
this.country = null;
}
if (this.country_code === '') {
this.country_code = null;
}
if (this.country_name === '') {
this.country_name = null;
}
if (this.postal_code === '') {
this.postal_code = null;
}
if (this.formatted_address === '') {
this.formatted_address = null;
}
if (this.latitude === '') {
this.latitude = null;
}
if (this.longitude === '') {
this.longitude = null;
}
return this;
};