From 8e54eebdcda1362834607d4f4a28c5c0fe0757cc Mon Sep 17 00:00:00 2001 From: Mike Murray Date: Thu, 20 Oct 2016 17:04:40 -0700 Subject: [PATCH 001/256] Register template (#1362) * added email templates package Added ability to register html and react templates with new helper Reaction.registerTemplate. * Schema updates and render render functions Added handlebars render functions, as well as the ability to register a custom template renderer. Added caching for handlebars templates. Updated templates schema with more properties. * Updated tests and template registration functionality * add handlebars --- .../email-templates/lib/templates/standard.js | 12 ++ .../included/email-templates/register.js | 0 .../included/email-templates/server/index.js | 9 + lib/collections/schemas/templates.js | 41 ++++ lib/core/templates.js | 5 + package.json | 1 + server/api/core/core.js | 18 ++ server/api/core/import.js | 18 ++ server/api/core/templates.app-test.js | 97 +++++++++ server/api/core/templates.js | 184 ++++++++++++++++++ 10 files changed, 385 insertions(+) create mode 100644 imports/plugins/included/email-templates/lib/templates/standard.js create mode 100644 imports/plugins/included/email-templates/register.js create mode 100644 imports/plugins/included/email-templates/server/index.js create mode 100644 lib/core/templates.js create mode 100644 server/api/core/templates.app-test.js create mode 100644 server/api/core/templates.js diff --git a/imports/plugins/included/email-templates/lib/templates/standard.js b/imports/plugins/included/email-templates/lib/templates/standard.js new file mode 100644 index 00000000000..c1b5b1f6ea9 --- /dev/null +++ b/imports/plugins/included/email-templates/lib/templates/standard.js @@ -0,0 +1,12 @@ +import { html } from "/lib/core/templates"; + +// Standard HTML Email templste to be processed by Handlebars +const StandardTemplate = html` + + + "Great!!!" {{title}} + + +`; + +export default StandardTemplate; diff --git a/imports/plugins/included/email-templates/register.js b/imports/plugins/included/email-templates/register.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/imports/plugins/included/email-templates/server/index.js b/imports/plugins/included/email-templates/server/index.js new file mode 100644 index 00000000000..ea06c9ad494 --- /dev/null +++ b/imports/plugins/included/email-templates/server/index.js @@ -0,0 +1,9 @@ +import { Reaction } from "/server/api"; +import StandardTemplate from "../lib/templates/standard"; + +Reaction.registerTemplate({ + title: "Standard Email", + name: "standard-email", + type: "email", + template: StandardTemplate +}); diff --git a/lib/collections/schemas/templates.js b/lib/collections/schemas/templates.js index 567031b65c6..47ea3f69e9e 100644 --- a/lib/collections/schemas/templates.js +++ b/lib/collections/schemas/templates.js @@ -1,7 +1,48 @@ import { SimpleSchema } from "meteor/aldeed:simple-schema"; +import { Audience } from "./layouts"; export const Templates = new SimpleSchema({ + name: { + type: String, + index: true + }, + priority: { + type: Number, + optional: true, + defaultValue: 1 + }, + enabled: { + type: Boolean, + defaultValue: true + }, + route: { + type: String, + optional: true + }, + audience: { + type: [Audience], + optional: true + }, + type: { + type: String + }, + provides: { + type: String, + defaultValue: "template" + }, + block: { + type: String, + optional: true + }, + defaultData: { + type: Object, + blackbox: true + }, template: { + type: String, + optional: true + }, + parser: { type: String }, language: { diff --git a/lib/core/templates.js b/lib/core/templates.js new file mode 100644 index 00000000000..2db1de4af69 --- /dev/null +++ b/lib/core/templates.js @@ -0,0 +1,5 @@ + +// Template literal for html strings. +export function html(strings, ...values) { + return strings.raw[0]; +} diff --git a/package.json b/package.json index a50f397436e..1e3536c459b 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "fibers": "^1.0.14", "font-awesome": "^4.6.3", "griddle-react": "^0.6.1", + "handlebars": "^4.0.5", "i18next": "^3.4.3", "i18next-browser-languagedetector": "^1.0.0", "i18next-localstorage-cache": "^0.3.0", diff --git a/server/api/core/core.js b/server/api/core/core.js index b3966081f9e..043df9f0f1a 100644 --- a/server/api/core/core.js +++ b/server/api/core/core.js @@ -6,6 +6,7 @@ import { Jobs, Packages, Shops } from "/lib/collections"; import { Hooks, Logger } from "/server/api"; import ProcessJobs from "/server/jobs"; import { getRegistryDomain } from "./setDomain"; +import { registerTemplate } from "./templates"; import { sendVerificationEmail } from "./accounts"; import { getMailUrl } from "./email/config"; @@ -46,6 +47,23 @@ export default { return registeredPackage; }, + registerTemplate(templateInfo, shopIds) { + if (typeof shopIds === "string") { + // Register template with supplied, single shopId + registerTemplate(templateInfo, shopIds); + } else if (Array.isArray(shopIds)) { + // Register template for all supplied shopIds + for (const shopId of shopIds) { + registerTemplate(templateInfo, shopId); + } + } + + // Otherwise template for all available shops + return Shops.find().forEach((shop) => { + registerTemplate(templateInfo, shop._id); + }); + }, + /** * hasPermission - server * server permissions checks diff --git a/server/api/core/import.js b/server/api/core/import.js index a75a0ce66b5..6e7a31425c3 100644 --- a/server/api/core/import.js +++ b/server/api/core/import.js @@ -250,6 +250,24 @@ Import.package = function (pkg, shopId) { // server/startup/i18n.js // +/** + * @summary Store a template in the import buffer. + * @param {Object} tempalteInfo The template data to be updated + * @param {String} shopId The package data to be updated + * @returns {undefined} + */ +Import.template = function (templateInfo, shopId) { + check(templateInfo, Object); + check(shopId, String); + + const key = { + name: templateInfo.name, + shopId: shopId + }; + + return this.object(Collections.Templates, key, templateInfo); +}; + /** * @summary Store a translation in the import buffer. * @param {Object} key A key to look up the translation diff --git a/server/api/core/templates.app-test.js b/server/api/core/templates.app-test.js new file mode 100644 index 00000000000..4e7b2a17004 --- /dev/null +++ b/server/api/core/templates.app-test.js @@ -0,0 +1,97 @@ +import React from "react"; +import { expect } from "meteor/practicalmeteor:chai"; +import Reaction from "./"; +import { + registerTemplate, + getTemplateByName, + renderTemplate, + resetRegisteredTemplates, + processTemplateInfoForMemoryCache, + TEMPLATE_PARSER_REACT, + TEMPLATE_PARSER_HANDLEBARS +} from "./templates"; +import { Templates } from "/lib/collections"; + + +function sampleReactComponent() { + return ( +
{"Test"}
+ ); +} + +describe("Templates:", function () { + beforeEach(function () { + Templates.direct.remove(); + resetRegisteredTemplates(); + }); + + it("It should process a handlebars template for memory cache", function () { + const expectedTemplate = processTemplateInfoForMemoryCache({ + name: "test-template", + template: "
Test
" + }); + + expect(expectedTemplate.name).to.be.equal("test-template"); + expect(expectedTemplate.parser).to.be.equal(TEMPLATE_PARSER_HANDLEBARS); + }); + + it("It should process a react component for memory cache", function () { + const expectedTemplate = processTemplateInfoForMemoryCache({ + name: "test-template", + template: sampleReactComponent + }); + + expect(expectedTemplate.name).to.be.equal("test-template"); + expect(expectedTemplate.parser).to.be.equal(TEMPLATE_PARSER_REACT); + expect(expectedTemplate.template).to.be.a("function"); + }); + + it("It should register Handlebars template", function () { + const shopId = Reaction.getShopId(); + // Register template + const sampleTemplate = { + name: "test-template", + template: "
Test
" + }; + registerTemplate(sampleTemplate, shopId); + + const actualTemplate = getTemplateByName("test-template", shopId); + expect(sampleTemplate.name).to.be.equal(actualTemplate.name); + expect(actualTemplate.parser).to.be.equal(TEMPLATE_PARSER_HANDLEBARS); + }); + + it("It should register Handlebars template and render to a string", function () { + const shopId = Reaction.getShopId(); + // Register template + const sampleTemplate = { + name: "test-template", + template: "
Test
" + }; + + registerTemplate(sampleTemplate, shopId); + + const actualTemplate = getTemplateByName("test-template", shopId); + expect(sampleTemplate.name).to.be.equal(actualTemplate.name); + expect(actualTemplate.parser).to.be.equal(TEMPLATE_PARSER_HANDLEBARS); + + // Compile template to string + const renderedHtmlString = renderTemplate(actualTemplate); + expect(renderedHtmlString).to.be.a("string"); + }); + + it("It should register a React component", function () { + const shopId = Reaction.getShopId(); + const sampleTemplate = { + name: "test-template-react", + template: sampleReactComponent + }; + + registerTemplate(sampleTemplate, shopId); + + const actualTemplate = getTemplateByName("test-template-react", shopId); + + expect(sampleTemplate.name).to.be.equal(actualTemplate.name); + expect(actualTemplate.parser).to.be.equal(TEMPLATE_PARSER_REACT); + expect(actualTemplate.template).to.be.a("function"); + }); +}); diff --git a/server/api/core/templates.js b/server/api/core/templates.js new file mode 100644 index 00000000000..abfffc1d850 --- /dev/null +++ b/server/api/core/templates.js @@ -0,0 +1,184 @@ +import React from "react"; +import ReactDOMServer from "react-dom/server"; +import Handlebars from "handlebars"; +import Import from "./import"; +import Immutable from "immutable"; +import { Templates } from "/lib/collections"; + +let registeredTemplates = Immutable.OrderedMap(); +let templateCache = Immutable.Map(); +let templateParsers = Immutable.Map(); + +// var ReactComponentPrototype = React.Component.prototype +// var ReactClassComponentPrototype = (Object.getPrototypeOf(Object.getPrototypeOf(new (React.createClass({ render () {} }))()))) + +export const TEMPLATE_PARSER_REACT = "react"; +export const TEMPLATE_PARSER_HANDLEBARS = "handlebars"; + +export function registerTemplate(templateInfo, shopId, insertImmediately = false) { + const literal = registerTemplateForMemoryCache(templateInfo, shopId); + const reference = registerTemplateForDatabase(templateInfo, shopId, insertImmediately); + + return { + templateLiteral: literal, + templateReference: reference + }; +} + +export function registerTemplateForMemoryCache(templateInfo, shopId) { + // Process template info and cache in memory. + // This allows us to have function and class references for the templates for + // React and other custom parsers + const templateInfoForMemoryCache = processTemplateInfoForMemoryCache(templateInfo); + + + let shopTemplates = registeredTemplates.get(shopId); + + if (!shopTemplates) { + shopTemplates = {}; + } + + shopTemplates[templateInfo.name] = templateInfoForMemoryCache; + registeredTemplates = registeredTemplates.set(shopId, shopTemplates); + + return templateInfoForMemoryCache; +} + +export function registerTemplateForDatabase(templateInfo, shopId, insertImmediately = false) { + // Process template info for use in a database + // Namely, any literals like functions are stripped as they cannot be safetly, + // and should not stored in the database + const templateInfoForDatabase = processTemplateInfoForDatabase(templateInfo); + + Import.template(templateInfoForDatabase, shopId); + + if (insertImmediately) { + Import.flush(); + } + + // Return template data crafted for entry into a database + return templateInfoForDatabase; +} + +export function getTemplateByName(templateName, shopId) { + const registeredTemplate = registeredTemplates.get(shopId)[templateName]; + + if (registeredTemplate) { + return registeredTemplate; + } + + const templateInfo = Templates.findOne({ + name: templateName, + shopId + }); + + return registerTemplateForMemoryCache(templateInfo); +} + +export function processTemplateInfoForMemoryCache(templateInfo) { + // Avoid mutating the original passed in param + const info = Immutable.Map(templateInfo); + + if (typeof templateInfo.template === "string") { + // Set the template parser to Handlebars for string based templates + return info.set("parser", TEMPLATE_PARSER_HANDLEBARS).toObject(); + } else if (typeof templateInfo.template === "function") { + // Set the parser to react for React components + return info.set("parser", TEMPLATE_PARSER_REACT).toObject(); + } + + return null; +} + +export function processTemplateInfoForDatabase(templateInfo) { + const templateData = { + name: templateInfo.name, + title: templateInfo.title, + type: templateInfo.type, + templateData: templateInfo.template + }; + + + if (typeof templateInfo.template === "string") { + templateData.template = templateInfo.template; + templateData.parser = TEMPLATE_PARSER_HANDLEBARS; + } else if (typeof templateInfo.template === "function") { + templateData.parser = TEMPLATE_PARSER_REACT; + } + + return templateData; +} + + +export function registerTemplateParser(name, renderFunction) { + templateParsers = templateParsers.set(name, renderFunction); +} + +export function renderTemplate(templateInfo, data = {}) { + if (templateInfo.parser === TEMPLATE_PARSER_REACT) { + return null; + } else if (templateInfo.parser === TEMPLATE_PARSER_HANDLEBARS) { + return renderHandlebarsTemplate(templateInfo, data); + } + + if (typeof templateParsers.get(name) === "function") { + return templateParsers.get(name)(templateInfo, data); + } + + return false; +} + +/** + * Compile and cache Handlebars template + * @param {String} name Name of template to register amd save to cache + * @param {String} template markup + * @return {Function} Compiled handlebars template. + */ +export function compileHandlebarsTemplate(name, template) { + const compiledTemplate = Handlebars.compile(template); + templateCache = templateCache.set(name, compiledTemplate); + return compiledTemplate; +} + +export function renderHandlebarsTemplate(templateInfo, data) { + if (templateCache[templateInfo.name] === undefined) { + compileHandlebarsTemplate(templateInfo.name, templateInfo.template); + } + + const compiledTemplate = templateCache.get(templateInfo.name); + return compiledTemplate(data); +} + +export function renderTemplateToStaticMarkup(template, props) { + return ReactDOMServer.renderToStaticMarkup( + React.createElement(template, props) + ); +} + +/** + * Reset regestered templates + * This is mostly useful for aiding in unit testing + * @return {Immutable.OrderedMap} immultable.js OrderedMap + */ +export function resetRegisteredTemplates() { + registeredTemplates = Immutable.OrderedMap(); +} + +export default { + get registeredTemplates() { + return registeredTemplates; + }, + get templateCache() { + return templateCache; + }, + get templateParsers() { + return templateParsers; + }, + registerTemplate, + getTemplateByName, + processTemplateInfoForDatabase, + processTemplateInfoForMemoryCache, + compileHandlebarsTemplate, + renderHandlebarsTemplate, + renderTemplateToStaticMarkup +}; From e48f46632d6856d5d268f04ef28bdfcf00883e20 Mon Sep 17 00:00:00 2001 From: Mike Murray Date: Fri, 21 Oct 2016 10:39:54 -0700 Subject: [PATCH 002/256] Quick fixes for template registration (#1518) Fixed import of "Import" module. Fixed type in jsDoc comments for "Import.template" function. --- server/api/core/import.js | 2 +- server/api/core/templates.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/api/core/import.js b/server/api/core/import.js index 6e7a31425c3..f0203498660 100644 --- a/server/api/core/import.js +++ b/server/api/core/import.js @@ -252,7 +252,7 @@ Import.package = function (pkg, shopId) { /** * @summary Store a template in the import buffer. - * @param {Object} tempalteInfo The template data to be updated + * @param {Object} templateInfo The template data to be updated * @param {String} shopId The package data to be updated * @returns {undefined} */ diff --git a/server/api/core/templates.js b/server/api/core/templates.js index abfffc1d850..164aa8c7e0a 100644 --- a/server/api/core/templates.js +++ b/server/api/core/templates.js @@ -1,8 +1,8 @@ import React from "react"; import ReactDOMServer from "react-dom/server"; import Handlebars from "handlebars"; -import Import from "./import"; import Immutable from "immutable"; +import { Import } from "./import"; import { Templates } from "/lib/collections"; let registeredTemplates = Immutable.OrderedMap(); From 665432d59d384101b963d30299e8bf1b11e8f5b0 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Sun, 23 Oct 2016 10:52:33 +0800 Subject: [PATCH 003/256] Remove unused imports --- .../client/templates/searchModal/searchModal.html | 10 ---------- .../client/templates/searchModal/searchModal.js | 5 +---- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/imports/plugins/included/ui-search/client/templates/searchModal/searchModal.html b/imports/plugins/included/ui-search/client/templates/searchModal/searchModal.html index 263502ba5e6..836b9dbf98f 100644 --- a/imports/plugins/included/ui-search/client/templates/searchModal/searchModal.html +++ b/imports/plugins/included/ui-search/client/templates/searchModal/searchModal.html @@ -1,21 +1,11 @@ diff --git a/imports/plugins/included/ui-search/client/templates/searchModal/searchModal.js b/imports/plugins/included/ui-search/client/templates/searchModal/searchModal.js index cb48d2be165..cb0c6ca0566 100644 --- a/imports/plugins/included/ui-search/client/templates/searchModal/searchModal.js +++ b/imports/plugins/included/ui-search/client/templates/searchModal/searchModal.js @@ -1,10 +1,7 @@ import _ from "lodash"; -import React from "react"; -import { DataType } from "react-taco-table"; import { Template } from "meteor/templating"; -import { i18next } from "/client/api"; import { ProductSearch, Tags, OrderSearch, AccountSearch } from "/lib/collections"; -import { IconButton, SortableTable } from "/imports/plugins/core/ui/client/components"; +import { IconButton } from "/imports/plugins/core/ui/client/components"; /* * searchModal extra functions From 3789059664ede076deb4cd0b1b5767d35e9a82b3 Mon Sep 17 00:00:00 2001 From: Mike Murray Date: Mon, 24 Oct 2016 16:01:20 -0700 Subject: [PATCH 004/256] Add templates to database (#1522) * Register all email templates * Fetch email templates from database * Add helper to get email template file without any extra dependencies * Update method for fetching email template file * Fix template paths * Re-added missing comment * Fixed path to core order "new" email template --- .../included/email-templates/lib/paths.js | 16 ++++ .../included/email-templates/server/index.js | 89 ++++++++++++++++++- server/api/core/email/email.js | 23 +++-- 3 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 imports/plugins/included/email-templates/lib/paths.js diff --git a/imports/plugins/included/email-templates/lib/paths.js b/imports/plugins/included/email-templates/lib/paths.js new file mode 100644 index 00000000000..b2e53fec1b2 --- /dev/null +++ b/imports/plugins/included/email-templates/lib/paths.js @@ -0,0 +1,16 @@ +// Tempalte paths relative to private/email/templates +export const coreDefaultTemplate = "coreDefault"; + +export const resetPaswordTemplate = "accounts/reset_password"; +export const inviteShopMemberTemplate = "accounts/inviteShopMember"; +export const welcomeEmailTemplate = "accounts/sendWelcomeEmail"; +export const verifyEmailTemplate = "accounts/verify_email"; + +export const checkoutLoginTemplate = "checkout/checkoutLogin"; + +export const coreOrderCompletedTemplate = "orders/coreOrderCompleted"; +export const coreOrderCreatedTemplate = "orders/coreOrderCreated"; +export const coreOrderShippingInvoiceTemplate = "orders/coreOrderShippingInvoice"; +export const coreOrderShippingSummaryTemplate = "orders/coreOrderShippingSummary"; +export const coreOrderShippingTrackingTemplate = "orders/coreOrderShippingTracking"; +export const coreOrderNewTemplate = "orders/new"; diff --git a/imports/plugins/included/email-templates/server/index.js b/imports/plugins/included/email-templates/server/index.js index ea06c9ad494..80072c5da37 100644 --- a/imports/plugins/included/email-templates/server/index.js +++ b/imports/plugins/included/email-templates/server/index.js @@ -1,9 +1,90 @@ import { Reaction } from "/server/api"; -import StandardTemplate from "../lib/templates/standard"; +import * as TemplatePaths from "../lib/paths.js"; +// Default Reaction.registerTemplate({ - title: "Standard Email", - name: "standard-email", + title: "Default", + name: TemplatePaths.coreDefaultTemplate, type: "email", - template: StandardTemplate + template: Reaction.Email.getTemplateFile(TemplatePaths.coreDefaultTemplate) +}); + +// Accounts +Reaction.registerTemplate({ + title: "Reset Password", + name: TemplatePaths.resetPaswordTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.resetPaswordTemplate) +}); + +Reaction.registerTemplate({ + title: "Invite Shop Member", + name: TemplatePaths.inviteShopMemberTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.inviteShopMemberTemplate) +}); + +Reaction.registerTemplate({ + title: "Welcome Email", + name: TemplatePaths.welcomeEmailTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.welcomeEmailTemplate) +}); + +Reaction.registerTemplate({ + title: "Verify Account", + name: TemplatePaths.verifyEmailTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.verifyEmailTemplate) +}); + +// Checkout +Reaction.registerTemplate({ + title: "Checkout Login", + name: TemplatePaths.checkoutLoginTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.checkoutLoginTemplate) +}); + +// Order workflow +Reaction.registerTemplate({ + title: "Order Completed", + name: TemplatePaths.coreOrderCompletedTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.coreOrderCompletedTemplate) +}); + +Reaction.registerTemplate({ + title: "Order Created", + name: TemplatePaths.coreOrderCreatedTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.coreOrderCreatedTemplate) +}); + +Reaction.registerTemplate({ + title: "Shipping Invoice", + name: TemplatePaths.coreOrderShippingInvoiceTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.coreOrderShippingInvoiceTemplate) +}); + +Reaction.registerTemplate({ + title: "Shipping Summary", + name: TemplatePaths.coreOrderShippingSummaryTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.coreOrderShippingSummaryTemplate) +}); + +Reaction.registerTemplate({ + title: "Shipping Tracking", + name: TemplatePaths.coreOrderShippingTrackingTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.coreOrderShippingTrackingTemplate) +}); + +Reaction.registerTemplate({ + title: "New Order Started Processing", + name: TemplatePaths.coreOrderNewTemplate, + type: "email", + template: Reaction.Email.getTemplateFile(TemplatePaths.coreOrderNewTemplate) }); diff --git a/server/api/core/email/email.js b/server/api/core/email/email.js index b931bfb3779..4ef485b4481 100644 --- a/server/api/core/email/email.js +++ b/server/api/core/email/email.js @@ -43,18 +43,31 @@ export function getTemplate(template) { } // check database for a matching template - const tmpl = Templates.findOne({ template, language }); + const tmpl = Templates.findOne({ name: template, language }); // use that template if found - if (tmpl && tmpl.source) { - return tmpl.source; + if (tmpl && tmpl.template) { + return tmpl.template; } // otherwise, use the default template from the filesystem - const file = `email/templates/${template}.html`; + return getTemplateFile(template); +} + +/** + * Reaction.Email.getTemplateFile + * @param {String} file name of the template on file system + * @return {String} returns source + */ +export function getTemplateFile(file) { + if (typeof file !== "string") { + const msg = "Reaction.Email.getTemplateFile() requires a template name"; + Logger.error(msg); + throw new Meteor.Error("no-template-name", msg); + } try { - return Assets.getText(file); + return Assets.getText(`email/templates/${file}.html`); } catch (e) { Logger.warn(`Template not found: ${file}. Falling back to coreDefault.html`); return Assets.getText("email/templates/coreDefault.html"); From 1cb8eb867eef8ca6417c71c2342ef2dea4306f16 Mon Sep 17 00:00:00 2001 From: Erik Kieckhafer Date: Mon, 24 Oct 2016 16:21:28 -0700 Subject: [PATCH 005/256] Admin Invite & Password reset emails (#1523) * added some comments to break up html table * reorganized data for email template removed all [0]. type variables from new.html email template, so all variables are set in orders.js for easy manipulation * welcome to the shop email template * extract social from template, add on/off switch * invite shop member email * shopName variable updates * update reaction address This was driving me crazy seeing the wrong address in all these emails being tested. * add Collections imports for Accounts, Cart, Shopts * password reset emails * update subject of order confirmation email * lint fix * renamed file for email template * removed test text --- private/data/Shops.json | 6 +- .../templates/accounts/inviteShopMember.html | 1028 +++------------- .../templates/accounts/resetPassword.html | 172 +++ .../templates/accounts/reset_password.html | 7 - .../templates/accounts/sendWelcomeEmail.html | 1030 +++-------------- private/email/templates/orders/new.html | 53 +- server/api/core/accounts/password.js | 61 +- server/methods/accounts/accounts.js | 135 ++- server/methods/core/orders.js | 59 +- 9 files changed, 736 insertions(+), 1815 deletions(-) create mode 100644 private/email/templates/accounts/resetPassword.html delete mode 100644 private/email/templates/accounts/reset_password.html diff --git a/private/data/Shops.json b/private/data/Shops.json index 5db4b311c98..dcb382afa51 100755 --- a/private/data/Shops.json +++ b/private/data/Shops.json @@ -3064,11 +3064,11 @@ "addressBook": [{ "company": "Reaction Commerce", "fullName": "Ongo Works", - "address1": "1119 Colorado Ave", - "address2": "Ste. 7", + "address1": "2110 Main Street", + "address2": "Suite 207", "city": "Santa Monica", "region": "CA", - "postal": "90401", + "postal": "90405", "country": "US", "phone": "8885551212", "isCommercial": true, diff --git a/private/email/templates/accounts/inviteShopMember.html b/private/email/templates/accounts/inviteShopMember.html index 6104df3c3e0..39335b147bc 100644 --- a/private/email/templates/accounts/inviteShopMember.html +++ b/private/email/templates/accounts/inviteShopMember.html @@ -1,900 +1,172 @@ - - - - + + + +Basic Email + + + - - - - + +
-
- - - - - -
-
- - - - -
- - - - - - -
- {{shop.name}} -
- -
-
-
-
+ + + + + +
+ + +
+ + + + + - -
 
+ + - -
+ + + + + + + + + + + + -
 
logo
 
- - + + + + + + + + + + + + + + + - -
+ +
Hi, {{invitedUserName}}.
 
{{currentUserName}} has invited you to join {{shopName}}.
 
+ + + + +
Get Started 
+ - - -
- + + + + + + + + + + + + + {{#if socialLinks.display}} + + + + + -
 
 
 
You received this email because a user of {{shopName}} invited you to create an account. Questions or suggestions? Email us at {{contactEmail}}
 
+ - - - -
-

Hi, {{invitedUserName}}

+ {{#if socialLinks.twitter.display}} +
+ twt_icon
- - - + {{/if}} + {{#if socialLinks.facebook.display}} + + + {{/if}} + {{#if socialLinks.googlePlus.display}} + - + {{/if}}
  + fb_icon +   -

{{currentUserName}} invited you to join {{shop.name}}.

+ g_plus_icon
-
- - - + -
- - - - - - -
-

You're invited!

-

If you don't want to accept this invitation or think you were mistaken for someone else please let us know!

-
-
 
- + {{else}} - + - -


- + {{/if}} + - + + + + + + + + + + + + + + + + + -
+  
 
© {{copyrightDate}} {{legalName}}. All rights reserved
 
{{physicalAddress.address}}, {{physicalAddress.city}}, {{physicalAddress.region}} {{physicalAddress.postal}}
 
- - - - -
-
-

Sent by {{shop.name}}

-
-
-
- -
- -
+
+ + + + + + diff --git a/private/email/templates/accounts/resetPassword.html b/private/email/templates/accounts/resetPassword.html new file mode 100644 index 00000000000..a8a675fa41d --- /dev/null +++ b/private/email/templates/accounts/resetPassword.html @@ -0,0 +1,172 @@ + + + + +Basic Email + + + + + + + + + + +
+ + + + +
+ + + + + + +
 
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{#if socialLinks.display}} + + + + + + + + + + {{else}} + + + + {{/if}} + + + + + + + + + + + + + + + + + + + + + + +
 
logo
 
Reset Your Password
 
We've received a request to reset your password. If you didn't make the request, you can just ignore this email.
 
+ + + + +
Reset Password 
 
 
 
You received this email because you have an account with {{shopName}}. Questions or suggestions? Email us at {{contactEmail}}
 
+ + + {{#if socialLinks.twitter.display}} + + {{/if}} + {{#if socialLinks.facebook.display}} + + + {{/if}} + {{#if socialLinks.googlePlus.display}} + + + {{/if}} + +
+ twt_icon +   + fb_icon +   + g_plus_icon +
+
 
 
 
 
© {{copyrightDate}} {{legalName}}. All rights reserved
 
{{physicalAddress.address}}, {{physicalAddress.city}}, {{physicalAddress.region}} {{physicalAddress.postal}}
 
+
+ + diff --git a/private/email/templates/accounts/reset_password.html b/private/email/templates/accounts/reset_password.html deleted file mode 100644 index d756b426325..00000000000 --- a/private/email/templates/accounts/reset_password.html +++ /dev/null @@ -1,7 +0,0 @@ - -

Hello,

- -

To reset your password at {{shopName}}, click the link below:

- -

{{url}}

- diff --git a/private/email/templates/accounts/sendWelcomeEmail.html b/private/email/templates/accounts/sendWelcomeEmail.html index 1818477285d..716b912648a 100644 --- a/private/email/templates/accounts/sendWelcomeEmail.html +++ b/private/email/templates/accounts/sendWelcomeEmail.html @@ -1,902 +1,172 @@ - - - - + + + +Basic Email + + + - - - - + +
-
- - - - - -
-
- - - - -
- - - - - - - -
- {{shop.name}} -
-
-
-
-
+ + + + + +
+ + +
+ + + + + - -
 
+ + - -
+ + + + + + + + + + + + -
 
logo
 
- - + + + + + + + + + + + + + + + - -
+ +
Hello!
 
Welcome to {{shopName}}.
 
+ + + + +
Get Started 
+ + + + + + + + + + - - -
 
 
 
- + + + + {{#if socialLinks.display}} + + + + + -
You received this email because you have an account with {{shopName}}. Questions or suggestions? Email us at {{contactEmail}}
 
+ - - - -
-

Hi, {{user.username}}

+ {{#if socialLinks.twitter.display}} +
+ twt_icon
- - - + {{/if}} + {{#if socialLinks.facebook.display}} + + + {{/if}} + {{#if socialLinks.googlePlus.display}} + - + {{/if}}
  + fb_icon +   -

Welcome to {{shop.name}}.

+ g_plus_icon
-
- - - + -
- - - - - - -
- -

We're excited to have you at {{shop.name}}!

-

Thank you for taking the time to register at {{shop.name}}.

-

We'll keep this introduction simple. Welcome aboard!

-
-
 
- + {{else}} - + - -


- + {{/if}} + - + + + + + + + + + + + + + + + + + -
+  
 
© {{copyrightDate}} {{legalName}}. All rights reserved
 
{{physicalAddress.address}}, {{physicalAddress.city}}, {{physicalAddress.region}} {{physicalAddress.postal}}
 
- - - - -
-
-

Sent by {{shop.name}}

-
-
-
- -
- -
+
+ + + + + + diff --git a/private/email/templates/orders/new.html b/private/email/templates/orders/new.html index 2626eb78b96..2fc82149cd3 100644 --- a/private/email/templates/orders/new.html +++ b/private/email/templates/orders/new.html @@ -127,6 +127,8 @@ + + @@ -142,6 +144,9 @@ + + + + + - + - + + + + + + + + + {{#if socialLinks.display}} @@ -354,20 +368,26 @@ @@ -375,6 +395,12 @@ + {{else}} + + + + {{/if}} + @@ -382,15 +408,16 @@ - + - + + +
 
Order Confirmation
@@ -220,11 +225,11 @@
- - - + + @@ -339,14 +344,23 @@
{{shipping.address.address1}},
{{shipping.address.city}}, +
{{shipping.address.address}},
{{shipping.address.city}}, {{shipping.address.region}} {{shipping.address.postal}}
{{order.billing.[0].address.address1}},
{{order.billing.[0].address.city}}, - {{order.billing.[0].address.region}} {{order.billing.[0].address.postal}}
{{order.billing.[0].paymentMethod.storedCard}}{{billing.address.address}},
{{billing.address.city}}, + {{billing.address.region}} {{billing.address.postal}}
{{billing.paymentMethod}}
 
  
You received this email because you created an order with {{shop.addressBook.[0].company}}. If you have any questions, concerns, or suggestions please email us: - {{shop.emails.[0].address}} 
 
You received this email because you created an order with {{shopName}}. Questions or suggestions? Email us at {{contactEmail}}
 
+ {{#if socialLinks.twitter.display}} + {{/if}} + {{#if socialLinks.facebook.display}} + {{/if}} + {{#if socialLinks.googlePlus.display}} + {{/if}}
- twt_icon   - fb_icon   - g_plus_icon
 
 
 
 
© {{copyrightDate}} {{shop.addressBook.[0].company}}. All rights reserved© {{copyrightDate}} {{legalName}}. All rights reserved
 
{{shop.addressBook.[0].address1}} {{shop.addressBook.[0].address2}}, {{shop.addressBook.[0].city}}, - {{shop.addressBook.[0].region}} {{shop.addressBook.[0].postal}}{{physicalAddress.address}}, {{physicalAddress.city}}, {{physicalAddress.region}} {{physicalAddress.postal}}
diff --git a/server/api/core/accounts/password.js b/server/api/core/accounts/password.js index 50d1e76c8fe..c806a635131 100644 --- a/server/api/core/accounts/password.js +++ b/server/api/core/accounts/password.js @@ -2,6 +2,7 @@ import _ from "lodash"; import { Meteor } from "meteor/meteor"; import { Accounts } from "meteor/accounts-base"; import { SSR } from "meteor/meteorhacks:ssr"; +import { Media, Shops } from "/lib/collections"; import { Reaction, Logger } from "/server/api"; @@ -35,6 +36,7 @@ export function sendResetPasswordEmail(userId, optionalEmail) { throw new Meteor.Error("email-not-found", "Email not found"); } + // Create token for password reset const token = Random.secret(); const when = new Date(); const tokenObj = { token, email, when }; @@ -47,16 +49,65 @@ export function sendResetPasswordEmail(userId, optionalEmail) { Meteor._ensure(user, "services", "password").reset = tokenObj; - SSR.compileTemplate("resetPassword", Reaction.Email.getTemplate("accounts/reset_password")); + const tpl = "accounts/resetPassword"; + SSR.compileTemplate(tpl, Reaction.Email.getTemplate(tpl)); - const shopName = Reaction.getShopName(); - const url = Accounts.urls.resetPassword(token); + // Get shop data for email display + const shop = Shops.findOne(Reaction.getShopId()); + + // Get shop logo, if available. If not, use default logo from file-system + let emailLogo; + if (Array.isArray(shop.brandAssets)) { + const brandAsset = _.find(shop.brandAssets, (asset) => asset.type === "navbarBrandImage"); + const mediaId = Media.findOne(brandAsset.mediaId); + emailLogo = path.join(Meteor.absoluteUrl(), mediaId.url()); + } else { + emailLogo = Meteor.absoluteUrl() + "resources/email-templates/shop-logo.png"; + } + + const dataForEmail = { + // Shop Data + shop: shop, + contactEmail: shop.emails[0].address, + homepage: Meteor.absoluteUrl(), + emailLogo: emailLogo, + copyrightDate: moment().format("YYYY"), + legalName: shop.addressBook[0].company, + physicalAddress: { + address: shop.addressBook[0].address1 + " " + shop.addressBook[0].address2, + city: shop.addressBook[0].city, + region: shop.addressBook[0].region, + postal: shop.addressBook[0].postal + }, + shopName: shop.name, + socialLinks: { + display: true, + facebook: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/facebook-icon.png", + link: "https://www.facebook.com" + }, + googlePlus: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/google-plus-icon.png", + link: "https://plus.google.com" + }, + twitter: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/twitter-icon.png", + link: "https://www.twitter.com" + } + }, + // Account Data + passwordResetUrl: Accounts.urls.resetPassword(token), + user: user + }; return Reaction.Email.send({ to: email, from: Reaction.getShopEmail(), - subject: `${shopName} - Reset your password`, - html: SSR.render("resetPassword", { shopName, user, url }) + subject: `${dataForEmail.shopName}: Here's your password reset link`, + html: SSR.render(tpl, dataForEmail) }); } diff --git a/server/methods/accounts/accounts.js b/server/methods/accounts/accounts.js index da9140c9a55..a3dee38f226 100644 --- a/server/methods/accounts/accounts.js +++ b/server/methods/accounts/accounts.js @@ -1,4 +1,9 @@ +import _ from "lodash"; +import moment from "moment"; +import path from "path"; import * as Collections from "/lib/collections"; +// TODO: Change all imports from collections to only pull in needed? +// import { Accounts, Cart, Media, Shops } from "/lib/collections"; import * as Schemas from "/lib/collections/schemas"; import { Logger, Reaction } from "/server/api"; @@ -274,8 +279,8 @@ Meteor.methods({ "emails.address": email }); - const tmpl = "accounts/inviteShopMember"; - SSR.compileTemplate("accounts/inviteShopMember", Reaction.Email.getTemplate(tmpl)); + const tpl = "accounts/inviteShopMember"; + SSR.compileTemplate(tpl, Reaction.Email.getTemplate(tpl)); if (!user) { const userId = Accounts.createUser({ @@ -297,24 +302,71 @@ Meteor.methods({ } }); + // Get shop logo, if available. If not, use default logo from file-system + let emailLogo; + if (Array.isArray(shop.brandAssets)) { + const brandAsset = _.find(shop.brandAssets, (asset) => asset.type === "navbarBrandImage"); + const mediaId = Collections.Media.findOne(brandAsset.mediaId); + emailLogo = path.join(Meteor.absoluteUrl(), mediaId.url()); + } else { + emailLogo = Meteor.absoluteUrl() + "resources/email-templates/shop-logo.png"; + } + + const dataForEmail = { + // Shop Data + shop: shop, + contactEmail: shop.emails[0].address, + homepage: Meteor.absoluteUrl(), + emailLogo: emailLogo, + copyrightDate: moment().format("YYYY"), + legalName: shop.addressBook[0].company, + physicalAddress: { + address: shop.addressBook[0].address1 + " " + shop.addressBook[0].address2, + city: shop.addressBook[0].city, + region: shop.addressBook[0].region, + postal: shop.addressBook[0].postal + }, + shopName: shop.name, + socialLinks: { + display: true, + facebook: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/facebook-icon.png", + link: "https://www.facebook.com" + }, + googlePlus: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/google-plus-icon.png", + link: "https://plus.google.com" + }, + twitter: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/twitter-icon.png", + link: "https://www.twitter.com" + } + }, + // Account Data + user: Meteor.user(), + + + + currentUserName, + invitedUserName: name, + url: Accounts.urls.enrollAccount(token) + }; + Reaction.Email.send({ to: email, from: `${shop.name} <${shop.emails[0].address}>`, - subject: `You have been invited to join ${shop.name}`, - html: SSR.render("accounts/inviteShopMember", { - homepage: Meteor.absoluteUrl(), - shop, - currentUserName, - invitedUserName: name, - url: Accounts.urls.enrollAccount(token) - }) + subject: `You've been invited to join ${shop.name}`, + html: SSR.render(tpl, dataForEmail) }); } else { Reaction.Email.send({ to: email, from: `${shop.name} <${shop.emails[0].address}>`, - subject: `You have been invited to join ${shop.name}`, - html: SSR.render("accounts/inviteShopMember", { + subject: `You've been invited to join ${shop.name}`, + html: SSR.render(tpl, { homepage: Meteor.absoluteUrl(), shop, currentUserName, @@ -342,6 +394,53 @@ Meteor.methods({ const user = Collections.Accounts.findOne(userId); const shop = Collections.Shops.findOne(shopId); + // Get shop logo, if available. If not, use default logo from file-system + let emailLogo; + if (Array.isArray(shop.brandAssets)) { + const brandAsset = _.find(shop.brandAssets, (asset) => asset.type === "navbarBrandImage"); + const mediaId = Collections.Media.findOne(brandAsset.mediaId); + emailLogo = path.join(Meteor.absoluteUrl(), mediaId.url()); + } else { + emailLogo = Meteor.absoluteUrl() + "resources/email-templates/shop-logo.png"; + } + + const dataForEmail = { + // Shop Data + shop: shop, + contactEmail: shop.emails[0].address, + homepage: Meteor.absoluteUrl(), + emailLogo: emailLogo, + copyrightDate: moment().format("YYYY"), + legalName: shop.addressBook[0].company, + physicalAddress: { + address: shop.addressBook[0].address1 + " " + shop.addressBook[0].address2, + city: shop.addressBook[0].city, + region: shop.addressBook[0].region, + postal: shop.addressBook[0].postal + }, + shopName: shop.name, + socialLinks: { + display: true, + facebook: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/facebook-icon.png", + link: "https://www.facebook.com" + }, + googlePlus: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/google-plus-icon.png", + link: "https://plus.google.com" + }, + twitter: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/twitter-icon.png", + link: "https://www.twitter.com" + } + }, + // Account Data + user: Meteor.user() + }; + // anonymous users arent welcome here if (!user.emails || !user.emails.length > 0) { return true; @@ -358,18 +457,14 @@ Meteor.methods({ shopEmail = shop.emails[0].address; } - const tmpl = "accounts/sendWelcomeEmail"; - SSR.compileTemplate("accounts/sendWelcomeEmail", Reaction.Email.getTemplate(tmpl)); + const tpl = "accounts/sendWelcomeEmail"; + SSR.compileTemplate(tpl, Reaction.Email.getTemplate(tpl)); Reaction.Email.send({ to: userEmail, from: `${shop.name} <${shopEmail}>`, - subject: `Welcome to ${shop.name}!`, - html: SSR.render("accounts/sendWelcomeEmail", { - homepage: Meteor.absoluteUrl(), - shop: shop, - user: Meteor.user() - }) + subject: `You're In. Welcome to ${shop.name}!`, + html: SSR.render(tpl, dataForEmail) }); return true; diff --git a/server/methods/core/orders.js b/server/methods/core/orders.js index c1124488eab..e99ae9b3db3 100644 --- a/server/methods/core/orders.js +++ b/server/methods/core/orders.js @@ -334,7 +334,6 @@ Meteor.methods({ // Get Shop information const shop = Shops.findOne(order.shopId); - const shopContact = shop.addressBook[0]; // Get shop logo, if available let emailLogo; @@ -391,24 +390,66 @@ Meteor.methods({ } // Merge data into single object to pass to email template - const dataForOrderEmail = { + const dataForEmail = { + // Shop Data + shop: shop, + contactEmail: shop.emails[0].address, homepage: Meteor.absoluteUrl(), emailLogo: emailLogo, copyrightDate: moment().format("YYYY"), - shop: shop, - shopContact: shopContact, + legalName: shop.addressBook[0].company, + physicalAddress: { + address: shop.addressBook[0].address1 + " " + shop.addressBook[0].address2, + city: shop.addressBook[0].city, + region: shop.addressBook[0].region, + postal: shop.addressBook[0].postal + }, + shopName: shop.name, + socialLinks: { + display: true, + facebook: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/facebook-icon.png", + link: "https://www.facebook.com" + }, + googlePlus: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/google-plus-icon.png", + link: "https://plus.google.com" + }, + twitter: { + display: true, + icon: Meteor.absoluteUrl() + "resources/email-templates/twitter-icon.png", + link: "https://www.twitter.com" + } + }, + // Order Data order: order, - orderDate: moment(order.createdAt).format("MM/DD/YYYY"), billing: { + address: { + address: order.billing[0].address.address1, + city: order.billing[0].address.city, + region: order.billing[0].address.region, + postal: order.billing[0].address.postal + }, + paymentMethod: order.billing[0].paymentMethod.storedCard, subtotal: accounting.toFixed(order.billing[0].invoice.subtotal, 2), shipping: accounting.toFixed(order.billing[0].invoice.shipping, 2), taxes: accounting.toFixed(order.billing[0].invoice.taxes, 2), discounts: accounting.toFixed(order.billing[0].invoice.discounts, 2), total: accounting.toFixed(order.billing[0].invoice.total, 2) }, - shipping: order.shipping[0], + combinedItems: combinedItems, + orderDate: moment(order.createdAt).format("MM/DD/YYYY"), orderUrl: getSlug(shop.name) + "/cart/completed?_id=" + order.cartId, - combinedItems: combinedItems + shipping: { + address: { + address: order.shipping[0].address.address1, + city: order.shipping[0].address.city, + region: order.shipping[0].address.region, + postal: order.shipping[0].address.postal + } + } }; Logger.info(`orders/sendNotification status: ${order.workflow.status}`); @@ -434,9 +475,9 @@ Meteor.methods({ Reaction.Email.send({ to: order.email, from: `${shop.name} <${shop.emails[0].address}>`, - subject: `Your order is confirmed`, + subject: `${shop.name}: Your order is confirmed`, // subject: `Order update from ${shop.name}`, - html: SSR.render(tpl, dataForOrderEmail) + html: SSR.render(tpl, dataForEmail) }); return true; From 9e7fdca8b9a1da56ef4d3593b7937a3fb013acd8 Mon Sep 17 00:00:00 2001 From: Erik Kieckhafer Date: Tue, 25 Oct 2016 13:21:27 -0700 Subject: [PATCH 006/256] update const to conform to new file name (#1528) Will take care of `WARN Reaction: Template not found: accounts/reset_password. Falling back to coreDefault.html` error --- imports/plugins/included/email-templates/lib/paths.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imports/plugins/included/email-templates/lib/paths.js b/imports/plugins/included/email-templates/lib/paths.js index b2e53fec1b2..6b637ca7db7 100644 --- a/imports/plugins/included/email-templates/lib/paths.js +++ b/imports/plugins/included/email-templates/lib/paths.js @@ -1,7 +1,7 @@ // Tempalte paths relative to private/email/templates export const coreDefaultTemplate = "coreDefault"; -export const resetPaswordTemplate = "accounts/reset_password"; +export const resetPaswordTemplate = "accounts/resetPassword"; export const inviteShopMemberTemplate = "accounts/inviteShopMember"; export const welcomeEmailTemplate = "accounts/sendWelcomeEmail"; export const verifyEmailTemplate = "accounts/verify_email"; From c575fb53533d281671e28e2e950ebe77ce49bdf5 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 08:56:51 +0800 Subject: [PATCH 007/256] Add registry settings to package --- imports/plugins/included/ui-search/register.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/imports/plugins/included/ui-search/register.js b/imports/plugins/included/ui-search/register.js index 82d8b0d3e20..a83d2c615b4 100644 --- a/imports/plugins/included/ui-search/register.js +++ b/imports/plugins/included/ui-search/register.js @@ -4,5 +4,11 @@ Reaction.registerPackage({ label: "Search UI", name: "reaction-ui-search", icon: "fa fa-search", - autoEnable: true + autoEnable: true, + registry: [ + { + provides: "search-ui", + template: "searchModal" + } + ] }); From a2460a55b87f9706ecc9afc0ef0c85926e122000 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 08:57:27 +0800 Subject: [PATCH 008/256] Conditionally show search --- .../core/ui-navbar/client/components/navbar/navbar.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.html b/imports/plugins/core/ui-navbar/client/components/navbar/navbar.html index 0cd53e5ec97..c6e119282ad 100644 --- a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.html +++ b/imports/plugins/core/ui-navbar/client/components/navbar/navbar.html @@ -6,8 +6,9 @@ - - + {{#if isSearchEnabled}} + + {{/if}}
{{> accounts tpl="loginDropdown"}}
{{> cartIcon}}
From 9c8a0af6ff49318e4771d57129d165ef7bce46df Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 08:58:26 +0800 Subject: [PATCH 009/256] Make naming consistent --- imports/plugins/included/ui-search/register.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imports/plugins/included/ui-search/register.js b/imports/plugins/included/ui-search/register.js index a83d2c615b4..ebf9a0b304e 100644 --- a/imports/plugins/included/ui-search/register.js +++ b/imports/plugins/included/ui-search/register.js @@ -7,7 +7,7 @@ Reaction.registerPackage({ autoEnable: true, registry: [ { - provides: "search-ui", + provides: "ui-search", template: "searchModal" } ] From ceb5395bdd2f5c4a45f48eec227cedb8a34b6c3a Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 08:59:51 +0800 Subject: [PATCH 010/256] Look up in registry to determine whether to show search, and if so which template --- .../client/components/navbar/navbar.js | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js b/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js index ae94de7ab93..df26092062a 100644 --- a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js +++ b/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js @@ -1,9 +1,26 @@ import { FlatButton } from "/imports/plugins/core/ui/client/components"; import { Reaction } from "/client/api"; -import { Tags } from "/lib/collections"; +import { Tags, Packages } from "/lib/collections"; + +function getSearchPackage() { + const searchPackage = Packages.findOne({ + shopId: Reaction.getShopId(), + "registry.provides": "ui-search", + enabled: true + }); + return searchPackage; +} + Template.CoreNavigationBar.onCreated(function () { this.state = new ReactiveDict(); + const searchPackage = getSearchPackage(); + if (searchPackage) { + this.state.set("searchEnabled", true); + this.state.set("searchTemplate", searchPackage.registry[0].template); + } else { + this.state.set("searchEnabled", false); + } }); /** @@ -19,7 +36,10 @@ Template.CoreNavigationBar.events({ return $(".dashboard-navbar-packages ul li").removeClass("active"); }, "click .search": function () { - Blaze.renderWithData(Template.searchModal, { + const instance = Template.instance(); + const searchTemplateName = instance.state.get("searchTemplate"); + const searchTemplate = Template[searchTemplateName]; + Blaze.renderWithData(searchTemplate, { }, $("body").get(0)); $("body").css("overflow", "hidden"); $("#search-input").focus(); @@ -27,17 +47,23 @@ Template.CoreNavigationBar.events({ }); Template.CoreNavigationBar.helpers({ + isSearchEnabled() { + const instance = Template.instance(); + return instance.state.get("searchEnabled"); + }, + + searchTemplate() { + const instance = Template.instance(); + if (instance.state.get("searchEnabled")) { + return instance.state.get("searchTemplate"); + } + }, + IconButtonComponent() { return { component: FlatButton, icon: "fa fa-search", kind: "flat" - // onClick() { - // Blaze.renderWithData(Template.searchModal, { - // }, $("body").get(0)); - // $("body").css("overflow-y", "hidden"); - // $("#search-input").focus(); - // } }; }, onMenuButtonClick() { @@ -51,9 +77,7 @@ Template.CoreNavigationBar.helpers({ tagNavProps() { const instance = Template.instance(); - let tags = []; - - tags = Tags.find({ + const tags = Tags.find({ isTopLevel: true }, { sort: { From ac2e3139f5a467cea776c0977c226a04396cc797 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 09:56:14 +0800 Subject: [PATCH 011/256] Add migration to update existing registries --- .../migrations/2_add_key_to_search_ui.js | 24 +++++++++++++++++++ .../core/versions/server/migrations/index.js | 1 + 2 files changed, 25 insertions(+) create mode 100644 imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js new file mode 100644 index 00000000000..ca3cd328d99 --- /dev/null +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -0,0 +1,24 @@ +import { Migrations } from "/imports/plugins/core/versions"; +import { Packages } from "/lib/collections"; + + +// Add keys to search so that stock search is enabled by default +Migrations.add({ + version: 2, + up() { + while (!Packages.find({Name: "reaction-ui-search"})) { + Packages.update({name: "reaction-ui-search"}, + { + $set: { + registry: [{ + provides: "ui-search", + template: "searchModal" + } + + ] + } + } + ); + } + } +}); diff --git a/imports/plugins/core/versions/server/migrations/index.js b/imports/plugins/core/versions/server/migrations/index.js index 238d8131c02..333be6112bc 100644 --- a/imports/plugins/core/versions/server/migrations/index.js +++ b/imports/plugins/core/versions/server/migrations/index.js @@ -1 +1,2 @@ import "./1_rebuild_account_and_order_search_collections"; +import "./2_add_key_to_search_ui"; From c9a56b2ec3f48e2731c25f8f0d3f2253da8a5103 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 10:15:45 +0800 Subject: [PATCH 012/256] Modify all search-ui record --- .../core/versions/server/migrations/2_add_key_to_search_ui.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js index ca3cd328d99..32a1f611798 100644 --- a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -17,7 +17,8 @@ Migrations.add({ ] } - } + }, + { multi: true} ); } } From 2a40c577bdc70e80677046fa0acaa217c15bc2c5 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 10:23:36 +0800 Subject: [PATCH 013/256] Loop until missing record is available to modify --- .../core/versions/server/migrations/2_add_key_to_search_ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js index 32a1f611798..9a87a3560cd 100644 --- a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -6,7 +6,7 @@ import { Packages } from "/lib/collections"; Migrations.add({ version: 2, up() { - while (!Packages.find({Name: "reaction-ui-search"})) { + while (!Packages.find({Name: "reaction-ui-search", "registry.provides": "ui-search"})) { Packages.update({name: "reaction-ui-search"}, { $set: { From 19621010d7740864bc37d946c7478eae7b4c4151 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 10:33:53 +0800 Subject: [PATCH 014/256] Logging --- .../versions/server/migrations/2_add_key_to_search_ui.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js index 9a87a3560cd..27fc6711006 100644 --- a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -1,12 +1,13 @@ import { Migrations } from "/imports/plugins/core/versions"; import { Packages } from "/lib/collections"; - +import { Hooks, Logger } from "/server/api"; // Add keys to search so that stock search is enabled by default Migrations.add({ version: 2, up() { - while (!Packages.find({Name: "reaction-ui-search", "registry.provides": "ui-search"})) { + Hooks.Events.add("afterCoreInit", () => { + Logger.info("Running search package update"); Packages.update({name: "reaction-ui-search"}, { $set: { @@ -20,6 +21,6 @@ Migrations.add({ }, { multi: true} ); - } + }); } }); From 164a02425b5d68ee487e697efaedbbb2ee6a6376 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 11:08:21 +0800 Subject: [PATCH 015/256] No hook, no conditional --- .../migrations/2_add_key_to_search_ui.js | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js index 27fc6711006..f25937b78fc 100644 --- a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -6,21 +6,19 @@ import { Hooks, Logger } from "/server/api"; Migrations.add({ version: 2, up() { - Hooks.Events.add("afterCoreInit", () => { - Logger.info("Running search package update"); - Packages.update({name: "reaction-ui-search"}, - { - $set: { - registry: [{ - provides: "ui-search", - template: "searchModal" - } - - ] + Logger.info("Running search package update"); + Packages.update({name: "reaction-ui-search"}, + { + $set: { + registry: [{ + provides: "ui-search", + template: "searchModal" } - }, - { multi: true} - ); - }); + + ] + } + }, + { multi: true} + ); } }); From 13fe738cf1c44daf43ed6ebee503cad96d048c87 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 11:26:35 +0800 Subject: [PATCH 016/256] Make field label more explicit --- lib/collections/schemas/registry.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/collections/schemas/registry.js b/lib/collections/schemas/registry.js index 9ca5086344c..2e9cde80b73 100644 --- a/lib/collections/schemas/registry.js +++ b/lib/collections/schemas/registry.js @@ -31,6 +31,7 @@ export const Registry = new SimpleSchema({ }, name: { type: String, + label: "Registry Name", index: true }, template: { From 41d1afff73d1a47232cdbd8efbe54a599dac4ef0 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 11:26:50 +0800 Subject: [PATCH 017/256] Set name which is required for some reason --- .../versions/server/migrations/2_add_key_to_search_ui.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js index f25937b78fc..df5d1b3759c 100644 --- a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -1,6 +1,6 @@ import { Migrations } from "/imports/plugins/core/versions"; import { Packages } from "/lib/collections"; -import { Hooks, Logger } from "/server/api"; +import { Logger } from "/server/api"; // Add keys to search so that stock search is enabled by default Migrations.add({ @@ -11,11 +11,10 @@ Migrations.add({ { $set: { registry: [{ + name: "Search Modal", provides: "ui-search", template: "searchModal" - } - - ] + }] } }, { multi: true} From a504444406c0177d780e8f483b0e1e8dbc87d02c Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 11:33:52 +0800 Subject: [PATCH 018/256] Make registry consistent with migration. I guess schema is not validated here either? --- imports/plugins/included/ui-search/register.js | 1 + 1 file changed, 1 insertion(+) diff --git a/imports/plugins/included/ui-search/register.js b/imports/plugins/included/ui-search/register.js index ebf9a0b304e..92c9f6e0683 100644 --- a/imports/plugins/included/ui-search/register.js +++ b/imports/plugins/included/ui-search/register.js @@ -7,6 +7,7 @@ Reaction.registerPackage({ autoEnable: true, registry: [ { + name: "Search Modal", provides: "ui-search", template: "searchModal" } From 0473ffd83d2d15248ba2dfef35db29283743f072 Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 11:40:31 +0800 Subject: [PATCH 019/256] Remove logging --- .../core/versions/server/migrations/2_add_key_to_search_ui.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js index df5d1b3759c..8c22682e39a 100644 --- a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -1,12 +1,10 @@ import { Migrations } from "/imports/plugins/core/versions"; import { Packages } from "/lib/collections"; -import { Logger } from "/server/api"; // Add keys to search so that stock search is enabled by default Migrations.add({ version: 2, up() { - Logger.info("Running search package update"); Packages.update({name: "reaction-ui-search"}, { $set: { From d8078af5d5aaad5c4d34ced455bcfb9e8c04c30a Mon Sep 17 00:00:00 2001 From: Brent Hoover Date: Thu, 10 Nov 2016 13:02:52 +0800 Subject: [PATCH 020/256] Update package.json to reflect release number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1b0d1600db4..7c0d603fd8f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "reaction", "description": "Reaction is a modern reactive, real-time event driven ecommerce platform.", - "version": "0.17.1", + "version": "0.18.0", "main": "main.js", "directories": { "test": "tests" From 8e5eb79991cc8dfd2f8a35a4a0fc6c98078a6469 Mon Sep 17 00:00:00 2001 From: Aaron Judd Date: Thu, 10 Nov 2016 13:36:10 -0800 Subject: [PATCH 021/256] Discounts (#1556) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * discount skeleton - remove from core - add core/discounts - add discounts-rates - add discount-codes - new discount schemas [WIP] * local module import of translations - adds `loadTranslations` and `loadTranslation` methods - removes necessity to add translations to core - `import { loadTranslations } from "/server/startup/i18n”;` - multiple file import illustrated in reaction-taxes - single import illustrated in reaction-discounts - introduces mergeDeep helper in i18n/startup and updates to translation resource structure to accommodate additional namespaces for package (uses package name). * updated i18n namespace and handling - add i18n handling for griddle column headers - add local i18n imports to discounts - updated i18n taxSettings namespace (into packages + admin) * change info logging to debug * schemas, forms, ui, i18n for discount modules * updated Discount schemas - implement client collections for DiscountCodes, DiscountRates - implement multi-schema on server Discounts collection * updated discounts pub - split security out * Meteor 1.4.2.1 updated to Meteor 1.4.2.1. * group payments packages - resolves #1408 - consolidates all payment packages into a single admin group - rename include payment package folders `payment-` - add initial local i18n, moved from en.json (TODO, other lang). - move “default method” setting from shop to new `core/payments` package. - move checkout/payment templates from core to `core/payments` package. - expose icon in public registry --- .meteor/packages | 4 +- .meteor/release | 2 +- .meteor/versions | 6 +- client/modules/core/helpers/apps.js | 3 +- client/modules/i18n/main.js | 2 +- client/modules/i18n/startup.js | 55 +++-- imports/plugins/core/catalog/register.js | 2 +- imports/plugins/core/checkout/client/index.js | 3 - .../templates/shop/settings/settings.html | 22 -- .../templates/shop/settings/settings.js | 31 --- .../plugins/core/discounts/client/index.js | 2 + .../discounts/client/settings/settings.html | 22 ++ .../discounts/client/settings/settings.js | 118 ++++++++++ .../discounts/lib/collections/collections.js | 13 ++ .../core/discounts/lib/collections/index.js | 1 + .../lib/collections/schemas/config.js | 25 ++ .../lib/collections/schemas/discounts.js | 87 +++++++ .../lib/collections/schemas/index.js | 2 + imports/plugins/core/discounts/register.js | 38 +++ .../core/discounts/server/api/import.js | 20 ++ .../core/discounts/server/api/index.js | 3 + .../discounts/server/hooks/collections.js | 47 ++++ .../core/discounts/server/hooks/index.js | 1 + .../core/discounts/server/i18n/en.json | 22 ++ .../core/discounts/server/i18n/index.js | 7 + .../plugins/core/discounts/server/index.js | 6 + .../core/discounts/server/methods/index.js | 1 + .../server/methods/methods.app-test.js | 30 +++ .../core/discounts/server/methods/methods.js | 82 +++++++ .../server/publications/discounts.js | 41 ++++ .../discounts/server/security/discounts.js | 13 ++ .../core/payments/client/checkout/index.js | 1 + .../payments/client/checkout/payment/index.js | 3 + .../checkout/payment/methods/cards.html | 2 - .../client}/checkout/payment/methods/cards.js | 18 +- .../client}/checkout/payment/payment.html | 0 imports/plugins/core/payments/client/index.js | 2 + .../core/payments/client/settings/index.js | 2 + .../payments/client/settings/settings.html | 44 ++++ .../core/payments/client/settings/settings.js | 97 ++++++++ imports/plugins/core/payments/register.js | 26 +++ .../plugins/core/payments/server/i18n/en.json | 34 +++ .../core/payments/server/i18n/index.js | 19 ++ imports/plugins/core/payments/server/index.js | 1 + .../core/taxes/client/settings/custom.js | 32 ++- imports/plugins/core/taxes/register.js | 2 +- .../plugins/core/taxes/server/i18n/ar.json | 37 +++ .../plugins/core/taxes/server/i18n/de.json | 37 +++ .../plugins/core/taxes/server/i18n/en.json | 45 ++++ .../plugins/core/taxes/server/i18n/es.json | 37 +++ .../plugins/core/taxes/server/i18n/fr.json | 37 +++ .../plugins/core/taxes/server/i18n/he.json | 37 +++ .../core/taxes/server/i18n/i18n/en.json | 15 ++ .../core/taxes/server/i18n/i18n/index.js | 7 + .../plugins/core/taxes/server/i18n/index.js | 19 ++ .../plugins/core/taxes/server/i18n/pt.json | 36 +++ .../plugins/core/taxes/server/i18n/ro.json | 37 +++ .../plugins/core/taxes/server/i18n/ru.json | 37 +++ .../plugins/core/taxes/server/i18n/zh.json | 37 +++ imports/plugins/core/taxes/server/index.js | 1 + .../plugins/included/braintree/register.js | 50 ---- .../client/collections/codes.js | 10 + .../included/discount-codes/client/index.js | 3 + .../discount-codes/client/settings/codes.html | 72 ++++++ .../discount-codes/client/settings/codes.js | 215 +++++++++++++++++ .../discount-codes/lib/collections/index.js | 3 + .../lib/collections/schemas/codes.js | 33 +++ .../lib/collections/schemas/config.js | 22 ++ .../lib/collections/schemas/index.js | 2 + .../included/discount-codes/register.js | 21 ++ .../discount-codes/server/hooks/hooks.js | 20 ++ .../discount-codes/server/hooks/index.js | 1 + .../discount-codes/server/i18n/en.json | 27 +++ .../discount-codes/server/i18n/index.js | 7 + .../included/discount-codes/server/index.js | 5 + .../discount-codes/server/methods/index.js | 1 + .../server/methods/methods.app-test.js | 30 +++ .../discount-codes/server/methods/methods.js | 39 ++++ .../server/publications/discounts.js | 43 ++++ .../server/security/discounts.js | 13 ++ .../client/collections/rates.js | 9 + .../included/discount-rates/client/index.js | 3 + .../discount-rates/client/settings/rates.html | 66 ++++++ .../discount-rates/client/settings/rates.js | 216 ++++++++++++++++++ .../discount-rates/lib/collections/index.js | 3 + .../lib/collections/schemas/config.js | 22 ++ .../lib/collections/schemas/index.js | 2 + .../lib/collections/schemas/rates.js | 18 ++ .../included/discount-rates/register.js | 21 ++ .../discount-rates/server/hooks/hooks.js | 19 ++ .../discount-rates/server/hooks/index.js | 1 + .../discount-rates/server/i18n/en.json | 23 ++ .../discount-rates/server/i18n/index.js | 7 + .../included/discount-rates/server/index.js | 5 + .../discount-rates/server/methods/index.js | 1 + .../server/methods/methods.app-test.js | 30 +++ .../discount-rates/server/methods/methods.js | 38 +++ .../server/publications/discounts.js | 43 ++++ .../server/security/discounts.js | 13 ++ .../inventory/server/methods/inventory.js | 2 +- .../jobcontrol/server/jobs/exchangerates.js | 2 +- .../client/api/authnet.js | 0 .../client/api/index.js | 0 .../client/checkout/authnet.html | 0 .../client/checkout/authnet.js | 0 .../client/dashboard/authnet.html | 0 .../client/dashboard/authnet.js | 0 .../client/index.js | 0 .../client/settings/authnet.html | 0 .../client/settings/authnet.js | 0 .../lib/collections/schemas/index.js | 0 .../lib/collections/schemas/package.js | 0 .../{authnet => payments-authnet}/register.js | 22 +- .../payments-authnet/server/i18n/en.json | 24 ++ .../payments-authnet/server/i18n/index.js | 19 ++ .../server/index.js | 1 + .../server/methods/authnet.js | 0 .../client/api/braintree.js | 0 .../client/checkout/braintree.html | 0 .../client/checkout/braintree.js | 0 .../client/index.js | 0 .../client/settings/braintree.html | 0 .../client/settings/braintree.js | 0 .../lib/collections/schemas/braintree.js | 0 .../lib/collections/schemas/index.js | 0 .../included/payments-braintree/register.js | 31 +++ .../payments-braintree/server/i18n/en.json | 31 +++ .../payments-braintree/server/i18n/index.js | 19 ++ .../server/index.js | 1 + .../server/methods/braintree.js | 0 .../server/methods/braintreeApi.js | 0 .../server/methods/braintreeMethods.js | 0 .../braintreeapi-methods-refund.app-test.js | 0 .../client/checkout/example.html | 0 .../client/checkout/example.js | 0 .../client/index.js | 0 .../client/settings/example.html | 8 +- .../client/settings/example.js | 0 .../lib/api/example.js | 0 .../lib/api/index.js | 0 .../lib/collections/schemas/example.js | 0 .../lib/collections/schemas/index.js | 0 .../register.js | 19 +- .../payments-example/server/i18n/en.json | 26 +++ .../payments-example/server/i18n/index.js | 19 ++ .../server/index.js | 1 + .../example-payment-methods.app-test.js | 0 .../server/methods/example.js | 0 .../server/methods/exampleapi.js | 0 .../client/index.js | 0 .../client/lib/paypalRestApi.js | 0 .../client/paypal.less | 0 .../templates/checkout/checkoutButton.html | 0 .../templates/checkout/checkoutButton.js | 0 .../templates/checkout/payflowForm.html | 0 .../client/templates/checkout/payflowForm.js | 0 .../templates/checkout/paymentForm.html | 0 .../client/templates/checkout/paymentForm.js | 0 .../templates/checkout/return/cancel.html | 0 .../templates/checkout/return/cancel.js | 0 .../templates/checkout/return/done.html | 0 .../client/templates/checkout/return/done.js | 0 .../client/templates/dashboard/dashboard.html | 0 .../client/templates/dashboard/dashboard.js | 0 .../client/templates/settings/settings.html | 0 .../client/templates/settings/settings.js | 0 .../lib/api/index.js | 0 .../lib/api/paypal.js | 0 .../lib/collections/schemas/index.js | 0 .../lib/collections/schemas/paypal.js | 0 .../{paypal => payments-paypal}/register.js | 19 +- .../payments-paypal/server/i18n/en.json | 23 ++ .../payments-paypal/server/i18n/index.js | 19 ++ .../server/index.js | 1 + .../server/methods/express.js | 0 .../server/methods/payflow.js | 0 .../payflowpro-methods-refund.app-test.js | 0 .../server/methods/payflowproApi.js | 0 .../server/methods/payflowproMethods.js | 0 .../server/security/paypal.js | 0 .../client/checkout/stripe.html | 0 .../client/checkout/stripe.js | 0 .../client/index.js | 0 .../client/settings/stripe.html | 0 .../client/settings/stripe.js | 0 .../lib/api/index.js | 0 .../lib/api/stripe.js | 0 .../lib/collections/schemas/index.js | 0 .../lib/collections/schemas/stripe.js | 0 .../{stripe => payments-stripe}/register.js | 20 +- .../payments-stripe/server/i18n/en.json | 22 ++ .../payments-stripe/server/i18n/index.js | 19 ++ .../server/index.js | 1 + .../server/methods/stripe.js | 0 .../stripeapi-integrationtest.app-test.js | 0 .../stripeapi-methods-capture.app-test.js | 0 .../stripeapi-methods-charge.app-test.js | 0 .../stripeapi-methods-refund.app-test.js | 0 .../stripeapi-methods-refundlist.app-test.js | 0 .../server/methods/stripeapi.js | 0 .../taxes-avalara/client/settings/avalara.js | 4 +- .../client/settings/taxcloud.js | 4 +- .../taxes-taxjar/client/settings/taxjar.js | 4 +- lib/collections/collections.js | 8 - lib/collections/schemas/discounts.js | 81 ------- lib/collections/schemas/index.js | 1 - private/data/i18n/ar.json | 21 +- private/data/i18n/de.json | 21 +- private/data/i18n/en.json | 50 ---- private/data/i18n/es.json | 21 +- private/data/i18n/fr.json | 21 +- private/data/i18n/he.json | 21 +- private/data/i18n/pt.json | 21 +- private/data/i18n/ro.json | 21 +- private/data/i18n/ru.json | 21 +- private/data/i18n/zh.json | 21 +- server/methods/core/cart.js | 2 +- server/publications/collections/discounts.js | 16 -- server/publications/collections/packages.js | 3 +- server/security/collections.js | 1 - server/startup/i18n.js | 59 ++++- 221 files changed, 2768 insertions(+), 573 deletions(-) create mode 100644 imports/plugins/core/discounts/client/index.js create mode 100644 imports/plugins/core/discounts/client/settings/settings.html create mode 100644 imports/plugins/core/discounts/client/settings/settings.js create mode 100644 imports/plugins/core/discounts/lib/collections/collections.js create mode 100644 imports/plugins/core/discounts/lib/collections/index.js create mode 100644 imports/plugins/core/discounts/lib/collections/schemas/config.js create mode 100644 imports/plugins/core/discounts/lib/collections/schemas/discounts.js create mode 100644 imports/plugins/core/discounts/lib/collections/schemas/index.js create mode 100644 imports/plugins/core/discounts/register.js create mode 100644 imports/plugins/core/discounts/server/api/import.js create mode 100644 imports/plugins/core/discounts/server/api/index.js create mode 100644 imports/plugins/core/discounts/server/hooks/collections.js create mode 100644 imports/plugins/core/discounts/server/hooks/index.js create mode 100644 imports/plugins/core/discounts/server/i18n/en.json create mode 100644 imports/plugins/core/discounts/server/i18n/index.js create mode 100644 imports/plugins/core/discounts/server/index.js create mode 100644 imports/plugins/core/discounts/server/methods/index.js create mode 100644 imports/plugins/core/discounts/server/methods/methods.app-test.js create mode 100644 imports/plugins/core/discounts/server/methods/methods.js create mode 100644 imports/plugins/core/discounts/server/publications/discounts.js create mode 100644 imports/plugins/core/discounts/server/security/discounts.js create mode 100644 imports/plugins/core/payments/client/checkout/index.js create mode 100644 imports/plugins/core/payments/client/checkout/payment/index.js rename imports/plugins/core/{checkout/client/templates => payments/client}/checkout/payment/methods/cards.html (96%) rename imports/plugins/core/{checkout/client/templates => payments/client}/checkout/payment/methods/cards.js (62%) rename imports/plugins/core/{checkout/client/templates => payments/client}/checkout/payment/payment.html (100%) create mode 100644 imports/plugins/core/payments/client/index.js create mode 100644 imports/plugins/core/payments/client/settings/index.js create mode 100644 imports/plugins/core/payments/client/settings/settings.html create mode 100644 imports/plugins/core/payments/client/settings/settings.js create mode 100644 imports/plugins/core/payments/register.js create mode 100644 imports/plugins/core/payments/server/i18n/en.json create mode 100644 imports/plugins/core/payments/server/i18n/index.js create mode 100644 imports/plugins/core/payments/server/index.js create mode 100644 imports/plugins/core/taxes/server/i18n/ar.json create mode 100644 imports/plugins/core/taxes/server/i18n/de.json create mode 100644 imports/plugins/core/taxes/server/i18n/en.json create mode 100644 imports/plugins/core/taxes/server/i18n/es.json create mode 100644 imports/plugins/core/taxes/server/i18n/fr.json create mode 100644 imports/plugins/core/taxes/server/i18n/he.json create mode 100644 imports/plugins/core/taxes/server/i18n/i18n/en.json create mode 100644 imports/plugins/core/taxes/server/i18n/i18n/index.js create mode 100644 imports/plugins/core/taxes/server/i18n/index.js create mode 100644 imports/plugins/core/taxes/server/i18n/pt.json create mode 100644 imports/plugins/core/taxes/server/i18n/ro.json create mode 100644 imports/plugins/core/taxes/server/i18n/ru.json create mode 100644 imports/plugins/core/taxes/server/i18n/zh.json delete mode 100644 imports/plugins/included/braintree/register.js create mode 100644 imports/plugins/included/discount-codes/client/collections/codes.js create mode 100644 imports/plugins/included/discount-codes/client/index.js create mode 100644 imports/plugins/included/discount-codes/client/settings/codes.html create mode 100644 imports/plugins/included/discount-codes/client/settings/codes.js create mode 100644 imports/plugins/included/discount-codes/lib/collections/index.js create mode 100644 imports/plugins/included/discount-codes/lib/collections/schemas/codes.js create mode 100644 imports/plugins/included/discount-codes/lib/collections/schemas/config.js create mode 100644 imports/plugins/included/discount-codes/lib/collections/schemas/index.js create mode 100644 imports/plugins/included/discount-codes/register.js create mode 100644 imports/plugins/included/discount-codes/server/hooks/hooks.js create mode 100644 imports/plugins/included/discount-codes/server/hooks/index.js create mode 100644 imports/plugins/included/discount-codes/server/i18n/en.json create mode 100644 imports/plugins/included/discount-codes/server/i18n/index.js create mode 100644 imports/plugins/included/discount-codes/server/index.js create mode 100644 imports/plugins/included/discount-codes/server/methods/index.js create mode 100644 imports/plugins/included/discount-codes/server/methods/methods.app-test.js create mode 100644 imports/plugins/included/discount-codes/server/methods/methods.js create mode 100644 imports/plugins/included/discount-codes/server/publications/discounts.js create mode 100644 imports/plugins/included/discount-codes/server/security/discounts.js create mode 100644 imports/plugins/included/discount-rates/client/collections/rates.js create mode 100644 imports/plugins/included/discount-rates/client/index.js create mode 100644 imports/plugins/included/discount-rates/client/settings/rates.html create mode 100644 imports/plugins/included/discount-rates/client/settings/rates.js create mode 100644 imports/plugins/included/discount-rates/lib/collections/index.js create mode 100644 imports/plugins/included/discount-rates/lib/collections/schemas/config.js create mode 100644 imports/plugins/included/discount-rates/lib/collections/schemas/index.js create mode 100644 imports/plugins/included/discount-rates/lib/collections/schemas/rates.js create mode 100644 imports/plugins/included/discount-rates/register.js create mode 100644 imports/plugins/included/discount-rates/server/hooks/hooks.js create mode 100644 imports/plugins/included/discount-rates/server/hooks/index.js create mode 100644 imports/plugins/included/discount-rates/server/i18n/en.json create mode 100644 imports/plugins/included/discount-rates/server/i18n/index.js create mode 100644 imports/plugins/included/discount-rates/server/index.js create mode 100644 imports/plugins/included/discount-rates/server/methods/index.js create mode 100644 imports/plugins/included/discount-rates/server/methods/methods.app-test.js create mode 100644 imports/plugins/included/discount-rates/server/methods/methods.js create mode 100644 imports/plugins/included/discount-rates/server/publications/discounts.js create mode 100644 imports/plugins/included/discount-rates/server/security/discounts.js rename imports/plugins/included/{authnet => payments-authnet}/client/api/authnet.js (100%) rename imports/plugins/included/{authnet => payments-authnet}/client/api/index.js (100%) rename imports/plugins/included/{authnet => payments-authnet}/client/checkout/authnet.html (100%) rename imports/plugins/included/{authnet => payments-authnet}/client/checkout/authnet.js (100%) rename imports/plugins/included/{authnet => payments-authnet}/client/dashboard/authnet.html (100%) rename imports/plugins/included/{authnet => payments-authnet}/client/dashboard/authnet.js (100%) rename imports/plugins/included/{authnet => payments-authnet}/client/index.js (100%) rename imports/plugins/included/{authnet => payments-authnet}/client/settings/authnet.html (100%) rename imports/plugins/included/{authnet => payments-authnet}/client/settings/authnet.js (100%) rename imports/plugins/included/{authnet => payments-authnet}/lib/collections/schemas/index.js (100%) rename imports/plugins/included/{authnet => payments-authnet}/lib/collections/schemas/package.js (100%) rename imports/plugins/included/{authnet => payments-authnet}/register.js (53%) create mode 100644 imports/plugins/included/payments-authnet/server/i18n/en.json create mode 100644 imports/plugins/included/payments-authnet/server/i18n/index.js rename imports/plugins/included/{authnet => payments-authnet}/server/index.js (62%) rename imports/plugins/included/{authnet => payments-authnet}/server/methods/authnet.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/client/api/braintree.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/client/checkout/braintree.html (100%) rename imports/plugins/included/{braintree => payments-braintree}/client/checkout/braintree.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/client/index.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/client/settings/braintree.html (100%) rename imports/plugins/included/{braintree => payments-braintree}/client/settings/braintree.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/lib/collections/schemas/braintree.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/lib/collections/schemas/index.js (100%) create mode 100644 imports/plugins/included/payments-braintree/register.js create mode 100644 imports/plugins/included/payments-braintree/server/i18n/en.json create mode 100644 imports/plugins/included/payments-braintree/server/i18n/index.js rename imports/plugins/included/{braintree => payments-braintree}/server/index.js (80%) rename imports/plugins/included/{braintree => payments-braintree}/server/methods/braintree.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/server/methods/braintreeApi.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/server/methods/braintreeMethods.js (100%) rename imports/plugins/included/{braintree => payments-braintree}/server/methods/braintreeapi-methods-refund.app-test.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/client/checkout/example.html (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/client/checkout/example.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/client/index.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/client/settings/example.html (70%) rename imports/plugins/included/{example-paymentmethod => payments-example}/client/settings/example.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/lib/api/example.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/lib/api/index.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/lib/collections/schemas/example.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/lib/collections/schemas/index.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/register.js (51%) create mode 100644 imports/plugins/included/payments-example/server/i18n/en.json create mode 100644 imports/plugins/included/payments-example/server/i18n/index.js rename imports/plugins/included/{example-paymentmethod => payments-example}/server/index.js (79%) rename imports/plugins/included/{example-paymentmethod => payments-example}/server/methods/example-payment-methods.app-test.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/server/methods/example.js (100%) rename imports/plugins/included/{example-paymentmethod => payments-example}/server/methods/exampleapi.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/index.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/lib/paypalRestApi.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/paypal.less (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/checkoutButton.html (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/checkoutButton.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/payflowForm.html (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/payflowForm.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/paymentForm.html (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/paymentForm.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/return/cancel.html (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/return/cancel.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/return/done.html (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/checkout/return/done.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/dashboard/dashboard.html (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/dashboard/dashboard.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/settings/settings.html (100%) rename imports/plugins/included/{paypal => payments-paypal}/client/templates/settings/settings.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/lib/api/index.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/lib/api/paypal.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/lib/collections/schemas/index.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/lib/collections/schemas/paypal.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/register.js (58%) create mode 100644 imports/plugins/included/payments-paypal/server/i18n/en.json create mode 100644 imports/plugins/included/payments-paypal/server/i18n/index.js rename imports/plugins/included/{paypal => payments-paypal}/server/index.js (83%) rename imports/plugins/included/{paypal => payments-paypal}/server/methods/express.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/server/methods/payflow.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/server/methods/payflowpro-methods-refund.app-test.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/server/methods/payflowproApi.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/server/methods/payflowproMethods.js (100%) rename imports/plugins/included/{paypal => payments-paypal}/server/security/paypal.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/client/checkout/stripe.html (100%) rename imports/plugins/included/{stripe => payments-stripe}/client/checkout/stripe.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/client/index.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/client/settings/stripe.html (100%) rename imports/plugins/included/{stripe => payments-stripe}/client/settings/stripe.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/lib/api/index.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/lib/api/stripe.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/lib/collections/schemas/index.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/lib/collections/schemas/stripe.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/register.js (57%) create mode 100644 imports/plugins/included/payments-stripe/server/i18n/en.json create mode 100644 imports/plugins/included/payments-stripe/server/i18n/index.js rename imports/plugins/included/{stripe => payments-stripe}/server/index.js (79%) rename imports/plugins/included/{stripe => payments-stripe}/server/methods/stripe.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/server/methods/stripeapi-integrationtest.app-test.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/server/methods/stripeapi-methods-capture.app-test.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/server/methods/stripeapi-methods-charge.app-test.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/server/methods/stripeapi-methods-refund.app-test.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/server/methods/stripeapi-methods-refundlist.app-test.js (100%) rename imports/plugins/included/{stripe => payments-stripe}/server/methods/stripeapi.js (100%) delete mode 100644 lib/collections/schemas/discounts.js delete mode 100644 server/publications/collections/discounts.js diff --git a/.meteor/packages b/.meteor/packages index fff98875a3a..ac55fe93463 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -29,7 +29,7 @@ underscore@1.0.10 logging@1.1.16 reload@1.1.11 ejson@1.0.13 -less@2.7.6 +less@2.7.7 service-configuration@1.0.11 amplify mdg:validated-method @@ -37,7 +37,7 @@ shell-server@0.2.1 # Meteor Auth Packages accounts-base@1.2.14 -accounts-password@1.3.1 +accounts-password@1.3.2 accounts-facebook@1.0.11 accounts-google@1.0.11 accounts-twitter@1.1.12 diff --git a/.meteor/release b/.meteor/release index c26084673d3..65e8c3928f8 100644 --- a/.meteor/release +++ b/.meteor/release @@ -1 +1 @@ -METEOR@1.4.2 +METEOR@1.4.2.1 diff --git a/.meteor/versions b/.meteor/versions index e43518af313..3055a7e4bfb 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -2,7 +2,7 @@ accounts-base@1.2.14 accounts-facebook@1.0.11 accounts-google@1.0.11 accounts-oauth@1.1.14 -accounts-password@1.3.1 +accounts-password@1.3.2 accounts-twitter@1.1.12 alanning:roles@1.2.15 aldeed:autoform@5.8.1 @@ -28,7 +28,7 @@ browser-policy@1.0.9 browser-policy-common@1.0.11 browser-policy-content@1.0.12 browser-policy-framing@1.0.12 -caching-compiler@1.1.8 +caching-compiler@1.1.9 caching-html-compiler@1.0.7 callback-hook@1.0.10 cfs:access-point@0.1.49 @@ -90,7 +90,7 @@ kadira:blaze-layout@2.3.0 kadira:dochead@1.5.0 kadira:flow-router-ssr@3.13.0 launch-screen@1.1.0 -less@2.7.6 +less@2.7.7 livedata@1.0.18 localstorage@1.0.12 logging@1.1.16 diff --git a/client/modules/core/helpers/apps.js b/client/modules/core/helpers/apps.js index 6b98758fcbd..f158ff241fe 100644 --- a/client/modules/core/helpers/apps.js +++ b/client/modules/core/helpers/apps.js @@ -93,7 +93,8 @@ export function Apps(optionHash) { enabled: 1, registry: 1, name: 1, - provides: 1 + provides: 1, + icon: 1 }; // fetch the packages diff --git a/client/modules/i18n/main.js b/client/modules/i18n/main.js index 4c743558c50..806faf0eb28 100644 --- a/client/modules/i18n/main.js +++ b/client/modules/i18n/main.js @@ -3,7 +3,7 @@ import { Meteor } from "meteor/meteor"; import { Tracker } from "meteor/tracker"; import { SimpleSchema } from "meteor/aldeed:simple-schema"; import { Reaction } from "/client/api"; -import { Packages, Translations } from "/lib/collections"; +import { Packages } from "/lib/collections"; // // Reaction i18n Translations, RTL and Currency Exchange Support diff --git a/client/modules/i18n/startup.js b/client/modules/i18n/startup.js index 8be073e69e8..d1f230e07bb 100644 --- a/client/modules/i18n/startup.js +++ b/client/modules/i18n/startup.js @@ -32,6 +32,34 @@ const options = { htmlTag: document.documentElement }; +/** + * Simple is object check. + * @param {Object} item item to check if is an object + * @returns {boolean} return true if object + */ +function isObject(item) { + return (item && typeof item === "object" && !Array.isArray(item) && item !== null); +} + +/** + * Helper for Deep merge two objects. + * @param {Object} target deep merge into this object + * @param {Object} source merge this object + * @returns {Object} return deep merged object + */ +function mergeDeep(target, source) { + if (isObject(target) && isObject(source)) { + Object.keys(source).forEach(key => { + if (isObject(source[key])) { + if (!target[key]) Object.assign(target, { [key]: {} }); + mergeDeep(target[key], source[key]); + } else { + Object.assign(target, { [key]: source[key] }); + } + }); + } + return target; +} Meteor.startup(() => { // use tracker autorun to detect language changes @@ -55,18 +83,16 @@ Meteor.startup(() => { } }).fetch(); - - // map reduce translations into i18next formatting - const resources = translations.reduce(function (x, y) { - const ns = Object.keys(y.translation)[0]; - // first creating the structure, when add additional namespaces - if (x[y.i18n]) { - x[y.i18n][ns] = y.translation[ns]; - } else { - x[y.i18n] = y.translation; - } - return x; - }, {}); + // + // reduce and merge translations + // into i18next resource format + // + let resources = {}; + translations.forEach(function (translation) { + const resource = {}; + resource[translation.i18n] = translation.translation; + resources = mergeDeep(resources, resource); + }); // // initialize i18next @@ -81,13 +107,10 @@ Meteor.startup(() => { debug: false, ns: packageNamespaces, // translation namespace for every package defaultNS: "core", // reaction "core" is the default namespace + fallbackNS: packageNamespaces, lng: language, // user session language fallbackLng: shop ? shop.language : null, // Shop language resources: resources - // saveMissing: true, - // missingKeyHandler: function (lng, ns, key, fallbackValue) { - // Meteor.call("i18n/addTranslation", lng, ns, key, fallbackValue); - // } }, () => { // someday this should work // see: https://github.com/aldeed/meteor-simple-schema/issues/494 diff --git a/imports/plugins/core/catalog/register.js b/imports/plugins/core/catalog/register.js index 65610c8a905..a7cf808b6a1 100644 --- a/imports/plugins/core/catalog/register.js +++ b/imports/plugins/core/catalog/register.js @@ -14,7 +14,7 @@ Reaction.registerPackage({ label: "Catalog", description: "Product catalog", icon: "fa fa-archive", - priority: 2, + priority: 1, container: "core" }, { diff --git a/imports/plugins/core/checkout/client/index.js b/imports/plugins/core/checkout/client/index.js index 342a17e2d97..e476dfa118a 100644 --- a/imports/plugins/core/checkout/client/index.js +++ b/imports/plugins/core/checkout/client/index.js @@ -20,9 +20,6 @@ import "./templates/checkout/completed/completed.js"; import "./templates/checkout/header/header.html"; import "./templates/checkout/login/login.html"; import "./templates/checkout/login/login.js"; -import "./templates/checkout/payment/methods/cards.html"; -import "./templates/checkout/payment/methods/cards.js"; -import "./templates/checkout/payment/payment.html"; import "./templates/checkout/progressBar/progressBar.html"; import "./templates/checkout/progressBar/progressBar.js"; import "./templates/checkout/review/review.html"; diff --git a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.html b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.html index 4c33ffa52db..afb07a20296 100644 --- a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.html +++ b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.html @@ -82,28 +82,6 @@ -
-
- -
-
-
- {{#autoForm collection=Collections.Shops doc=shop id="shopEditPaymentMethodsForm" type="update" - autosave=true}} - {{> afQuickField name='defaultPaymentMethod' options=paymentMethodOptions}} - {{/autoForm}} -
-
-
-
diff --git a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js index e784e177db2..7d1ee80584c 100644 --- a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js +++ b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js @@ -133,23 +133,6 @@ Template.shopSettings.helpers({ addressBook: function () { const address = Shops.findOne().addressBook; return address[0]; - }, - paymentMethodOptions() { - const paymentMethods = Reaction.Apps({provides: "paymentMethod"}); - const options = [{ - label: i18next.t("app.auto"), - value: "none" - }]; - - if (paymentMethods && _.isArray(paymentMethods)) { - for (const method of paymentMethods) { - options.push({ - label: i18next.t(method.i18nKeyLabel), - value: method.packageName - }); - } - } - return options; } }); @@ -214,17 +197,3 @@ AutoForm.hooks({ } } }); - -AutoForm.hooks({ - shopEditPaymentMethodsForm: { - onSuccess: function () { - return Alerts.toast(i18next.t("shopSettings.shopPaymentMethodsSaved"), - "success"); - }, - onError: function (operation, error) { - return Alerts.toast( - `${i18next.t("shopSettings.shopPaymentMethodsFailed")} ${error}`, "error" - ); - } - } -}); diff --git a/imports/plugins/core/discounts/client/index.js b/imports/plugins/core/discounts/client/index.js new file mode 100644 index 00000000000..c244a3fc8e5 --- /dev/null +++ b/imports/plugins/core/discounts/client/index.js @@ -0,0 +1,2 @@ +import "./settings/settings.html"; +import "./settings/settings.js"; diff --git a/imports/plugins/core/discounts/client/settings/settings.html b/imports/plugins/core/discounts/client/settings/settings.html new file mode 100644 index 00000000000..b717351a464 --- /dev/null +++ b/imports/plugins/core/discounts/client/settings/settings.html @@ -0,0 +1,22 @@ + diff --git a/imports/plugins/core/discounts/client/settings/settings.js b/imports/plugins/core/discounts/client/settings/settings.js new file mode 100644 index 00000000000..5ccf54eac00 --- /dev/null +++ b/imports/plugins/core/discounts/client/settings/settings.js @@ -0,0 +1,118 @@ +import { Template } from "meteor/templating"; +import { Packages } from "/lib/collections"; +// import { DiscountCodes } from "../../lib/collections"; +// import { i18next } from "/client/api"; +import { DiscountPackageConfig } from "../../lib/collections/schemas"; + +// /* +// * Template discountses Helpers +// */ +// Template.discountSettings.onCreated(function () { +// this.autorun(() => { +// this.subscribe("DiscountCodes"); +// }); +// }); + +Template.discountSettings.helpers({ + packageConfigSchema() { + return DiscountPackageConfig; + }, + // + // check if this package setting is enabled + // + checked(pkg) { + let enabled; + const pkgData = Packages.findOne(pkg.packageId); + const setting = pkg.name.split("/").splice(-1); + + if (pkgData && pkgData.settings) { + if (pkgData.settings[setting]) { + enabled = pkgData.settings[setting].enabled; + } + } + return enabled === true ? "checked" : ""; + }, + // + // get current packages settings data + // + packageData() { + return Packages.findOne({ + name: "reaction-discounts" + }); + }, + // + // prepare and return discountsCodes + // for default shop value + // + // taxCodes() { + // const instance = Template.instance(); + // if (instance.subscriptionsReady()) { + // const discountsCodes = DiscountCodes.find().fetch(); + // const options = [{ + // label: i18next.t("app.auto"), + // value: "none" + // }]; + // + // for (const discountsCode of discountsCodes) { + // options.push({ + // label: i18next.t(discountsCode.label), + // value: discountsCode.id + // }); + // } + // return options; + // } + // return undefined; + // }, + // + // Template helper to add a hidden class if the condition is false + // + shown(pkg) { + let enabled; + const pkgData = Packages.findOne(pkg.packageId); + const setting = pkg.name.split("/").splice(-1); + + if (pkgData && pkgData.settings) { + if (pkgData.settings[setting]) { + enabled = pkgData.settings[setting].enabled; + } + } + + return enabled !== true ? "hidden" : ""; + } +}); + +Template.discountSettings.events({ + /** + * discountSettings settings update enabled status for discounts service on change + * @param {event} event jQuery Event + * @return {void} + */ + "change input[name=enabled]": (event) => { + const name = event.target.value; + const packageId = event.target.getAttribute("data-id"); + const fields = [{ + property: "enabled", + value: event.target.checked + }]; + + Meteor.call("registry/update", packageId, name, fields); + }, + + /** + * discountSettings settings show/hide secret key for a discounts service + * @param {event} event jQuery Event + * @return {void} + */ + "click [data-event-action=showSecret]": (event) => { + const button = $(event.currentTarget); + const input = button.closest(".form-group").find("input[name=secret]"); + + if (input.attr("type") === "password") { + input.attr("type", "text"); + button.html("Hide"); + } else { + input.attr("type", "password"); + button.html("Show"); + } + } +}); diff --git a/imports/plugins/core/discounts/lib/collections/collections.js b/imports/plugins/core/discounts/lib/collections/collections.js new file mode 100644 index 00000000000..82b32e8cac1 --- /dev/null +++ b/imports/plugins/core/discounts/lib/collections/collections.js @@ -0,0 +1,13 @@ +import { Mongo } from "meteor/mongo"; +import * as Schemas from "./schemas"; + +/** +* Discounts Collection +* @type {Object} +* @desc Collection for custom discount rates +* for dollar, percentage, and shipping +* discount rates. +*/ +export const Discounts = new Mongo.Collection("Discounts"); + +Discounts.attachSchema(Schemas.Discounts); diff --git a/imports/plugins/core/discounts/lib/collections/index.js b/imports/plugins/core/discounts/lib/collections/index.js new file mode 100644 index 00000000000..45e94450ebd --- /dev/null +++ b/imports/plugins/core/discounts/lib/collections/index.js @@ -0,0 +1 @@ +export * from "./collections"; diff --git a/imports/plugins/core/discounts/lib/collections/schemas/config.js b/imports/plugins/core/discounts/lib/collections/schemas/config.js new file mode 100644 index 00000000000..d9368dcb2ad --- /dev/null +++ b/imports/plugins/core/discounts/lib/collections/schemas/config.js @@ -0,0 +1,25 @@ +import { SimpleSchema } from "meteor/aldeed:simple-schema"; +import { PackageConfig } from "/lib/collections/schemas/registry"; +import { Discounts } from "./discounts"; + +/** +* DiscountsPackageConfig Schema +*/ + +export const DiscountsPackageConfig = new SimpleSchema([ + PackageConfig, { + "settings.rates": { + type: Object, + optional: true + }, + "settings.rates.enabled": { + type: Boolean, + optional: true, + defaultValue: false + }, + "settings.rates.discounts": { + type: [Discounts], + optional: true + } + } +]); diff --git a/imports/plugins/core/discounts/lib/collections/schemas/discounts.js b/imports/plugins/core/discounts/lib/collections/schemas/discounts.js new file mode 100644 index 00000000000..692a81ed397 --- /dev/null +++ b/imports/plugins/core/discounts/lib/collections/schemas/discounts.js @@ -0,0 +1,87 @@ +import { SimpleSchema } from "meteor/aldeed:simple-schema"; +import { shopIdAutoValue } from "/lib/collections/schemas/helpers"; + +/* +* Discounts Schema +*/ + +export const Discounts = new SimpleSchema({ + "shopId": { + type: String, + autoValue: shopIdAutoValue, + index: 1, + label: "Discounts shopId" + }, + "label": { + type: String + }, + "description": { + type: String, + optional: true + }, + "discountMethod": { + label: "Calculation Method", + type: String, + index: 1 + }, + "discount": { + type: String, + optional: true + }, + "conditions": { + type: Object, + optional: true, + label: "Conditions" + }, + "conditions.order": { + type: Object + }, + "conditions.order.min": { + type: Number, + label: "Mininum", + decimal: true, + defaultValue: 0.00 + }, + "conditions.order.max": { + type: Number, + label: "Maximum", + decimal: true, + optional: true + }, + "conditions.order.startDate": { + type: Date, + label: "Start", + optional: true + }, + "conditions.order.endDate": { + type: Date, + label: "End", + optional: true + }, + "conditions.enabled": { + type: Boolean, + label: "Enabled", + defaultValue: true, + optional: true + }, + "conditions.audience": { + type: [String], + optional: true, + label: "Audience" + }, + "conditions.permissions": { + type: [String], + optional: true, + label: "Permissions" + }, + "conditions.products": { + type: [String], + optional: true, + label: "Products" + }, + "conditions.tags": { + type: [String], + optional: true, + label: "Tags" + } +}); diff --git a/imports/plugins/core/discounts/lib/collections/schemas/index.js b/imports/plugins/core/discounts/lib/collections/schemas/index.js new file mode 100644 index 00000000000..9534ec432ce --- /dev/null +++ b/imports/plugins/core/discounts/lib/collections/schemas/index.js @@ -0,0 +1,2 @@ +export * from "./discounts"; +export * from "./config"; diff --git a/imports/plugins/core/discounts/register.js b/imports/plugins/core/discounts/register.js new file mode 100644 index 00000000000..be327b9d763 --- /dev/null +++ b/imports/plugins/core/discounts/register.js @@ -0,0 +1,38 @@ +import { Reaction } from "/server/api"; + +Reaction.registerPackage({ + label: "Discounts", + name: "reaction-discounts", + icon: "fa fa-gift", + autoEnable: true, + settings: { + custom: { + enabled: true + }, + rates: { + enabled: false + } + }, + registry: [ + { + provides: "dashboard", + name: "discounts", + label: "Discounts", + description: "Provide discount rates", + icon: "fa fa-gift", + priority: 1, + container: "core", + workflow: "coreDashboardWorkflow" + }, + { + label: "DiscountSettings", + name: "discounts/settings", + provides: "settings", + template: "discountSettings" + }, + { + template: "flatRateCheckoutDiscounts", + provides: "discountMethod" + } + ] +}); diff --git a/imports/plugins/core/discounts/server/api/import.js b/imports/plugins/core/discounts/server/api/import.js new file mode 100644 index 00000000000..f0bf04e19e2 --- /dev/null +++ b/imports/plugins/core/discounts/server/api/import.js @@ -0,0 +1,20 @@ +import { Reaction } from "/server/api"; +import { Import } from "/server/api/core/import"; +import * as Collections from "../../lib/collections"; + +// plugin Import helpers +const DiscountImport = Import; + +// Import helper to store a discountRate in the import buffer. +DiscountImport.discountRate = function (key, discountRate) { + return this.object(Collections.Discounts, key, discountRate); +}; + +// configure Import key detection +DiscountImport.indication("discount", Collections.Discounts, 0.5); + +// should assign to global +Object.assign(Reaction.Import, DiscountImport); + +// exports Reaction.Import with new discount helper +export default Reaction; diff --git a/imports/plugins/core/discounts/server/api/index.js b/imports/plugins/core/discounts/server/api/index.js new file mode 100644 index 00000000000..4b7505b122f --- /dev/null +++ b/imports/plugins/core/discounts/server/api/index.js @@ -0,0 +1,3 @@ +import Reaction from "./import"; + +export default Reaction; diff --git a/imports/plugins/core/discounts/server/hooks/collections.js b/imports/plugins/core/discounts/server/hooks/collections.js new file mode 100644 index 00000000000..658bd8088ed --- /dev/null +++ b/imports/plugins/core/discounts/server/hooks/collections.js @@ -0,0 +1,47 @@ +import { Cart } from "/lib/collections"; +import { Logger } from "/server/api"; + +/** +* Discounts Collection Hooks +* @type {Object} +* @desc After cart update apply discounts. +* if items are changed, recalculating discounts +* we could have done this in the core/cart transform +* but this way this file controls the events from +* the core/discounts plugin. +* @todo just move so a single Hook.event and move all the +* cart hooks to a single location. +*/ +Cart.after.update((userId, cart, fieldNames, modifier) => { + // adding quantity + if (modifier.$inc) { + Logger.debug("incrementing cart - recalculating discounts"); + Meteor.call("discounts/calculate", cart._id); + } + + // adding new items + if (modifier.$addToSet) { + if (modifier.$addToSet.items) { + Logger.debug("adding to cart - recalculating discounts"); + Meteor.call("discounts/calculate", cart._id); + } + } + + // altering the cart shipping + // or billing address we'll update discounts + // ie: shipping/getShippingRates + if (modifier.$set) { + if (modifier.$set["shipping.$.shipmentMethod"] || modifier.$set["shipping.$.address"]) { + Logger.debug("updated shipping info - recalculating discounts"); + Meteor.call("discounts/calculate", cart._id); + } + } + + // removing items + if (modifier.$pull) { + if (modifier.$pull.items) { + Logger.debug("removing from cart - recalculating discounts"); + Meteor.call("discounts/calculate", cart._id); + } + } +}); diff --git a/imports/plugins/core/discounts/server/hooks/index.js b/imports/plugins/core/discounts/server/hooks/index.js new file mode 100644 index 00000000000..0c4003816c7 --- /dev/null +++ b/imports/plugins/core/discounts/server/hooks/index.js @@ -0,0 +1 @@ +import "./collections"; diff --git a/imports/plugins/core/discounts/server/i18n/en.json b/imports/plugins/core/discounts/server/i18n/en.json new file mode 100644 index 00000000000..52d1c4eb1f6 --- /dev/null +++ b/imports/plugins/core/discounts/server/i18n/en.json @@ -0,0 +1,22 @@ +[{ + "language": "English", + "i18n": "en", + "ns": "reaction-discounts", + "translation": { + "reaction-discounts": { + "admin": { + "settings": { + "discountsettingsLabel": "Discount Settings" + }, + "shortcut": { + "discountsLabel": "Discounts", + "discountsDescription": "Provide promotions and discounts." + }, + "dashboard": { + "discountsLabel": "Discounts", + "discountsDescription": "Provide promotions and discounts." + } + } + } + } +}] diff --git a/imports/plugins/core/discounts/server/i18n/index.js b/imports/plugins/core/discounts/server/i18n/index.js new file mode 100644 index 00000000000..02d738aa5bc --- /dev/null +++ b/imports/plugins/core/discounts/server/i18n/index.js @@ -0,0 +1,7 @@ +import { loadTranslation } from "/server/startup/i18n"; +import json from "./en.json"; + +// +// import local translations +// +loadTranslation(json); diff --git a/imports/plugins/core/discounts/server/index.js b/imports/plugins/core/discounts/server/index.js new file mode 100644 index 00000000000..943926f070a --- /dev/null +++ b/imports/plugins/core/discounts/server/index.js @@ -0,0 +1,6 @@ +// assemble server api +import "./i18n"; +import "./hooks/collections"; +import "./security/discounts"; +import "./publications/discounts"; +import "./methods"; diff --git a/imports/plugins/core/discounts/server/methods/index.js b/imports/plugins/core/discounts/server/methods/index.js new file mode 100644 index 00000000000..c8abe684b3c --- /dev/null +++ b/imports/plugins/core/discounts/server/methods/index.js @@ -0,0 +1 @@ +import "./methods"; diff --git a/imports/plugins/core/discounts/server/methods/methods.app-test.js b/imports/plugins/core/discounts/server/methods/methods.app-test.js new file mode 100644 index 00000000000..161d2bcd237 --- /dev/null +++ b/imports/plugins/core/discounts/server/methods/methods.app-test.js @@ -0,0 +1,30 @@ +import { Meteor } from "meteor/meteor"; +import { Roles } from "meteor/alanning:roles"; +import { expect } from "meteor/practicalmeteor:chai"; +import { sinon } from "meteor/practicalmeteor:sinon"; + +before(function () { + this.timeout(10000); + Meteor._sleepForMs(7000); +}); + +describe("discounts methods", function () { + let sandbox; + + beforeEach(function () { + sandbox = sinon.sandbox.create(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + describe("discounts/deleteRate", function () { + it("should throw 403 error with discounts permission", function (done) { + sandbox.stub(Roles, "userIsInRole", () => false); + // this should actually trigger a whole lot of things + expect(() => Meteor.call("discounts/deleteRate", "dummystring")).to.throw(Meteor.Error, /Access Denied/); + return done(); + }); + }); +}); diff --git a/imports/plugins/core/discounts/server/methods/methods.js b/imports/plugins/core/discounts/server/methods/methods.js new file mode 100644 index 00000000000..e87e6a9afcf --- /dev/null +++ b/imports/plugins/core/discounts/server/methods/methods.js @@ -0,0 +1,82 @@ +import { Meteor } from "meteor/meteor"; +import { Match, check } from "meteor/check"; +import { Cart, Packages } from "/lib/collections"; +import { Discounts } from "../../lib/collections"; +import Reaction from "../api"; +import { Logger } from "/server/api"; + +// +// make all discount methods available +// +export const methods = { + /** + * discounts/deleteRate + * @param {String} discountId discount id to delete + * @return {String} returns update/insert result + */ + "discounts/deleteRate": function (discountId) { + check(discountId, String); + + // check permissions to delete + if (!Reaction.hasPermission("discounts")) { + throw new Meteor.Error(403, "Access Denied"); + } + + return Discounts.remove(discountId); + }, + + /** + * discounts/setRate + * @param {String} cartId cartId + * @param {Number} discountRate discountRate + * @param {Object} discounts discounts + * @return {Number} returns update result + */ + "discounts/setRate": function (cartId, discountRate, discounts) { + check(cartId, String); + check(discountRate, Number); + check(discounts, Match.Optional(Array)); + + return Cart.update(cartId, { + $set: { + discounts: discounts, + discount: discountRate + } + }); + }, + + /** + * discounts/calculate + * @param {String} cartId cartId + * @return {Object} returns discount object + */ + "discounts/calculate": function (cartId) { + check(cartId, String); + const cartToCalc = Cart.findOne(cartId); + const shopId = cartToCalc.shopId; + const discountRate = 0; + + // get all discount packages + const pkg = Packages.findOne({ + shopId: shopId, + name: "reaction-discounts" + }); + + // + // custom rates + // check if plugin is enabled and this calculation method is enabled + if (pkg && pkg.enabled === true && pkg.settings.rates.enabled === true) { + Logger.info("Calculating custom discount rates"); + Meteor.call("discounts/setRate", cartToCalc._id, discountRate); + } else { + // we are here because the custom rate package is disabled. + // we're going to set an inital rate of 0 + // all methods that trigger when discounts/calculate will + // recalculate this rate as needed. + // Meteor.call("discounts/setRate", cartToCalc._id, discountRate); + } + } // end discounts/calculate +}; + +// export methods to Meteor +Meteor.methods(methods); diff --git a/imports/plugins/core/discounts/server/publications/discounts.js b/imports/plugins/core/discounts/server/publications/discounts.js new file mode 100644 index 00000000000..f334c585f4e --- /dev/null +++ b/imports/plugins/core/discounts/server/publications/discounts.js @@ -0,0 +1,41 @@ +import { Meteor } from "meteor/meteor"; +import { Match, check} from "meteor/check"; +import { Counts } from "meteor/tmeasday:publish-counts"; +import { Discounts} from "../../lib/collections"; +import { Reaction } from "/server/api"; + +/** + * Discounts + * @type {Publication} + * @param {Object} query + * @param {Object} options + */ +Meteor.publish("Discounts", function (query, options) { + check(query, Match.Optional(Object)); + check(options, Match.Optional(Object)); + + // check shopId + const shopId = Reaction.getShopId(); + if (!shopId && query) { + return this.ready(); + } + + const select = query || {}; + // append shopId to query + // applicable discounts are published + // for this users cartId; + select.shopId = shopId; + // select.cartId = cartId; + + // appends a count to the collection + // we're doing this for use with griddleTable + Counts.publish(this, "discounts-count", Discounts.find( + select, + options + )); + + return Discounts.find( + select, + options + ); +}); diff --git a/imports/plugins/core/discounts/server/security/discounts.js b/imports/plugins/core/discounts/server/security/discounts.js new file mode 100644 index 00000000000..d142c5a6b7e --- /dev/null +++ b/imports/plugins/core/discounts/server/security/discounts.js @@ -0,0 +1,13 @@ +import { Security } from "meteor/ongoworks:security"; +import { Discounts } from "../../lib/collections"; +import { Reaction } from "/server/api"; + +// +// Security definitions +// +Security.permit(["read", "insert", "update", "remove"]).collections([ + Discounts +]).ifHasRole({ + role: "discounts", + group: Reaction.getShopId() +}); diff --git a/imports/plugins/core/payments/client/checkout/index.js b/imports/plugins/core/payments/client/checkout/index.js new file mode 100644 index 00000000000..90aef2610a5 --- /dev/null +++ b/imports/plugins/core/payments/client/checkout/index.js @@ -0,0 +1 @@ +import "./payment"; diff --git a/imports/plugins/core/payments/client/checkout/payment/index.js b/imports/plugins/core/payments/client/checkout/payment/index.js new file mode 100644 index 00000000000..c985fe13913 --- /dev/null +++ b/imports/plugins/core/payments/client/checkout/payment/index.js @@ -0,0 +1,3 @@ +import "./methods/cards.html"; +import "./methods/cards.js"; +import "./payment.html"; diff --git a/imports/plugins/core/checkout/client/templates/checkout/payment/methods/cards.html b/imports/plugins/core/payments/client/checkout/payment/methods/cards.html similarity index 96% rename from imports/plugins/core/checkout/client/templates/checkout/payment/methods/cards.html rename to imports/plugins/core/payments/client/checkout/payment/methods/cards.html index 4e4adbcffac..de79539a3a0 100644 --- a/imports/plugins/core/checkout/client/templates/checkout/payment/methods/cards.html +++ b/imports/plugins/core/payments/client/checkout/payment/methods/cards.html @@ -1,7 +1,6 @@ + + diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index 7b2b4a11a68..6b445d48b51 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -42,3 +42,12 @@ AutoForm.hooks({ } } }); + +Template.stripeConnectRedirect.onCreated( function() { + //grabs values stripe passes back in the url as the params + this.autorun(() => { + FlowRouter.watchPathChange(); + let url = FlowRouter.current(); + Meteor.call('stripeConnect/saveSellerParams', Reaction.getShopId(), url); + }); +}); diff --git a/imports/plugins/included/payments-stripe-connect/register.js b/imports/plugins/included/payments-stripe-connect/register.js index 2b5eb97cd13..c2f441dc110 100644 --- a/imports/plugins/included/payments-stripe-connect/register.js +++ b/imports/plugins/included/payments-stripe-connect/register.js @@ -11,7 +11,8 @@ Reaction.registerPackage({ "api_key": "", "reaction-stripe-connect": { enabled: false - } + }, + "redirect_stripe_connect": "stripe-connect-redirect" }, registry: [ // Settings panel @@ -27,6 +28,12 @@ Reaction.registerPackage({ template: "stripePaymentForm", provides: "paymentMethod", icon: "fa fa-cc-stripe" + }, + + // Redirect for Stripe Connect Sign-In + { + template: "stripeConnectRedirect", + route: "/dashboard/connect", //not sure about this route } ] }); diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js new file mode 100644 index 00000000000..5f8a04eca29 --- /dev/null +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -0,0 +1,50 @@ +import { Meteor } from "meteor/meteor"; +import { check } from "meteor/check"; +import { Logger } from "/server/api"; + +Meteor.methods({ + /** + * separate url into params + * save params into sellerShop collection + **/ + "stripeConnect/saveSellerParams": function(shopId, url) { + Logger.warn(url); + check(url, String); + let result; + try { + let token_type_index = url.indexOf("token_type="); + let stripe_publishable_key_index = url.indexOf("stripe_publishable_key="); + let scope_index = url.indexOf("scope="); + let livemode_index = url.indexOf("livemode="); + let stripe_user_id_index = url.indexOf("stripe_user_id="); + let refresh_token_index = url.indexOf("refresh_token="); + let access_token_index = url.indexOf("access_token="); + let token_type = url.split(token_type_index, url.indexOf('&', token_type_index)); + let stripe_publishable_key = url.split(stripe_publishable_key_index, url.indexOf('&', stripe_publishable_key_index)); + let scope = url.split(scope_index, url.indexOf('&', scope_index)); + let livemode = url.split(livemode_index, url.indexOf('&', livemode_index)); + let stripe_user_id = url.split(stripe_user_id_index, url.indexOf('&', stripe_user_id_index)); + let refresh_token = url.split(refresh_token_index, url.indexOf('&', refresh_token_index)); + let access_token = url.split(access_token_index, url.indexOf('&', access_token_index)); + //TODO: Add new schema to shop collection or expand current one for these fields? + db.Shops.save ( { _id: shopId, + token_type: token_type, + stripe_publishable_key: stripe_publishable_key, + scope: scope, + livemode: livemode, + stripe_user_id: stripe_user_id, + refresh_token: refresh_token, + access_token: access_token } ); + result = { + saved: true + }; + } catch (error) { + Logger.warn(error); + result = { + saved: false, + error: error + }; + } + return result; + } +}); diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/en.json b/imports/plugins/included/payments-stripe-connect/server/i18n/en.json index 48d300f5dd6..3e8eeb8c397 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/en.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/en.json @@ -6,17 +6,21 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectConnectLabel": "Stripe Connect" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectConnectLabel": "Stripe Connect", - "stripeConnectConnectDescription": "Stripe Connect payments" + "stripeConnectLabel": "Stripe Connect", + "stripeConnectDescription": "Stripe Connect payments" }, "paymentSettings": { - "stripeConnectConnectLabel": "Stripe Connect", - "stripeConnectConnectSettingsLabel": "Stripe Connect", - "stripeConnectConnectSettingsDescription": "Don't have a Stripe Connect API Client ID?", - "stripeConnectConnectSettingsGetItHere": "Get it here" + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", + "stripeConnectSettingsDescription": "Don't have a Stripe Connect API Client ID?", + "stripeConnectSettingsGetItHere": "Get it here" + }, + //TODO: Add to other languages + "redirect": { + "stripeConnectWaitingNote": "Will auto redirect in a couple seconds or click here." } } } diff --git a/imports/plugins/included/payments-stripe-connect/server/index.js b/imports/plugins/included/payments-stripe-connect/server/index.js index 3979f964b5a..931b4521238 100644 --- a/imports/plugins/included/payments-stripe-connect/server/index.js +++ b/imports/plugins/included/payments-stripe-connect/server/index.js @@ -1 +1,2 @@ import "./i18n"; +import "./Methods"; From bddf1f1552834b52e75c64ff6265f0d90542b8d3 Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Sat, 4 Mar 2017 19:43:30 -0600 Subject: [PATCH 230/256] sellerShop(s) changes --- .../lib/collections/collections.js | 2 +- .../server/Methods/methods.js | 2 +- lib/collections/schemas/shops.js | 35 +++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/imports/plugins/included/marketplace/lib/collections/collections.js b/imports/plugins/included/marketplace/lib/collections/collections.js index 1847d2a791b..31d13a71990 100644 --- a/imports/plugins/included/marketplace/lib/collections/collections.js +++ b/imports/plugins/included/marketplace/lib/collections/collections.js @@ -5,4 +5,4 @@ import * as Schemas from "/lib/collections/schemas"; */ export const SellerShops = new Mongo.Collection("SellerShops"); -SellerShops.attachSchema(Schemas.Shop); +SellerShops.attachSchema(Schemas.SellerShop); diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js index 5f8a04eca29..d921bb176f2 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -27,7 +27,7 @@ Meteor.methods({ let refresh_token = url.split(refresh_token_index, url.indexOf('&', refresh_token_index)); let access_token = url.split(access_token_index, url.indexOf('&', access_token_index)); //TODO: Add new schema to shop collection or expand current one for these fields? - db.Shops.save ( { _id: shopId, + db.SellerShops.save ( { _id: shopId, token_type: token_type, stripe_publishable_key: stripe_publishable_key, scope: scope, diff --git a/lib/collections/schemas/shops.js b/lib/collections/schemas/shops.js index 8fa817bd306..59247ebf57c 100644 --- a/lib/collections/schemas/shops.js +++ b/lib/collections/schemas/shops.js @@ -267,3 +267,38 @@ export const Shop = new SimpleSchema({ optional: true } }); + +/** + * Seller Shop Schema + */ +export const SellerShop = new SimpleSchema({ + token_type: { + type: String, + optional: true + }, + stripe_publishable_key: { + type: String, + optional: true + }, + scope: { + type: String, + optional: true + }, + livemode: { + type: Boolean, + optional: true + }, + stripe_user_id: { + type: String, + optional: true + }, + refresh_token: { + type: String, + optional: true + }, + access_token: { + type: String, + optional: true + } +}); +SellerShop.extend(Shop); From 97778bb153b05260a640abd79ffab085eecf02bc Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Sat, 4 Mar 2017 22:56:20 -0600 Subject: [PATCH 231/256] sellerShop(s) changes --- .../client/settings/settings.html | 2 +- .../client/settings/settings.js | 16 ++++++------- .../server/Methods/methods.js | 23 +++++++++++-------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.html b/imports/plugins/included/payments-stripe-connect/client/settings/settings.html index 4953e1c1870..18093a81d34 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.html +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.html @@ -59,5 +59,5 @@ diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index 6b445d48b51..533b30c6b91 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -43,11 +43,11 @@ AutoForm.hooks({ } }); -Template.stripeConnectRedirect.onCreated( function() { - //grabs values stripe passes back in the url as the params - this.autorun(() => { - FlowRouter.watchPathChange(); - let url = FlowRouter.current(); - Meteor.call('stripeConnect/saveSellerParams', Reaction.getShopId(), url); - }); -}); + Template.stripeConnectRedirect.onCreated( function() { + //grabs values stripe passes back in the url as the params + this.autorun(() => { + FlowRouter.watchPathChange(); + let url = FlowRouter.current(); + Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), url); + }); + }); diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js index d921bb176f2..2c39320c6cc 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -1,6 +1,7 @@ import { Meteor } from "meteor/meteor"; import { check } from "meteor/check"; import { Logger } from "/server/api"; +import { SellerShops } from "/imports/plugins/included/marketplace/lib/collections"; Meteor.methods({ /** @@ -8,8 +9,9 @@ Meteor.methods({ * save params into sellerShop collection **/ "stripeConnect/saveSellerParams": function(shopId, url) { - Logger.warn(url); + check(shopId, String); check(url, String); + Logger.warn(url); let result; try { let token_type_index = url.indexOf("token_type="); @@ -26,15 +28,16 @@ Meteor.methods({ let stripe_user_id = url.split(stripe_user_id_index, url.indexOf('&', stripe_user_id_index)); let refresh_token = url.split(refresh_token_index, url.indexOf('&', refresh_token_index)); let access_token = url.split(access_token_index, url.indexOf('&', access_token_index)); - //TODO: Add new schema to shop collection or expand current one for these fields? - db.SellerShops.save ( { _id: shopId, - token_type: token_type, - stripe_publishable_key: stripe_publishable_key, - scope: scope, - livemode: livemode, - stripe_user_id: stripe_user_id, - refresh_token: refresh_token, - access_token: access_token } ); + db.SellerShops.save({ _ + "id" : shopId, + "token_type" : token_type, + "stripe_publishable_key" : stripe_publishable_key, + "scope" : scope, + "livemode" : livemode, + "stripe_user_id" : stripe_user_id, + "refresh_token" : refresh_token, + "access_token" : access_token + }); result = { saved: true }; From bc0383a2356877c9628d7db2877424acbf2601ff Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Sat, 4 Mar 2017 23:09:42 -0600 Subject: [PATCH 232/256] sellerShop(s) changes --- .../server/Methods/methods.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js index 2c39320c6cc..c27383ec7a2 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -28,15 +28,15 @@ Meteor.methods({ let stripe_user_id = url.split(stripe_user_id_index, url.indexOf('&', stripe_user_id_index)); let refresh_token = url.split(refresh_token_index, url.indexOf('&', refresh_token_index)); let access_token = url.split(access_token_index, url.indexOf('&', access_token_index)); - db.SellerShops.save({ _ - "id" : shopId, - "token_type" : token_type, - "stripe_publishable_key" : stripe_publishable_key, - "scope" : scope, - "livemode" : livemode, - "stripe_user_id" : stripe_user_id, - "refresh_token" : refresh_token, - "access_token" : access_token + db.SellerShops.save({ + "id" : shopId, + "token_type" : token_type, + "stripe_publishable_key" : stripe_publishable_key, + "scope" : scope, + "livemode" : livemode, + "stripe_user_id" : stripe_user_id, + "refresh_token" : refresh_token, + "access_token" : access_token }); result = { saved: true From debfa7b59dcaa36e2e79414abee8e2970bb64751 Mon Sep 17 00:00:00 2001 From: DylanRichardPearson Date: Sat, 4 Mar 2017 23:22:38 -0600 Subject: [PATCH 233/256] Prefill stripe connect form with seller shop data --- .../stripeConnectSignupButton.html | 4 +-- .../stripeConnectSignupButton.js | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.html b/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.html index b988ec92466..03e75e0ef6b 100644 --- a/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.html +++ b/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.html @@ -2,8 +2,8 @@ + data-i18n="marketplace.stripeConnectSignup">Start Accepting Payments diff --git a/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js b/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js index a1d4e6aa723..23262a22dde 100644 --- a/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js +++ b/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js @@ -1,3 +1,14 @@ +import { Meteor } from "meteor/meteor"; +import { i18next } from "/client/api"; +import { Reaction } from "/lib/api"; +import { SellerShops } from "../../../lib/collections"; + +Template.stripeConnectSignupButton.onCreated(function () { + this.autorun(() => { + Meteor.subscribe("SellerShops"); + }); +}); + // Button Template.stripeConnectSignupButton.helpers({ /** @@ -13,3 +24,22 @@ Template.stripeConnectSignupButton.helpers({ return classes.join(" "); } }); + +Template.stripeConnectSignupButton.events({ + "click [data-event-action='button-click-stripe-signup']": function () { + + const sellerShop = Reaction.getSellerShop(); + + const email = sellerShop.emails[0].address; + const country = sellerShop.addressBook[0].country; + const phoneNumber = sellerShop.addressBook[0].phone; + const businessName = sellerShop.addressBook[0].company; + const streetAddress = sellerShop.addressBook[0].address1; + const city = sellerShop.addressBook[0].city; + const state = sellerShop.addressBook[0].state; + const zip = sellerShop.addressBook[0].postal; + + const autofillParams = `&stripe_user[email]=${email}&stripe_user[country]=${country}&stripe_user[phone_number]=${phoneNumber}&stripe_user[business_name]=${businessName}&stripe_user[street_address]=${streetAddress}&stripe_user[city]=${city}&stripe_user[state]=${state}&stripe_user[zip]=${zip}`; + window.location.href = "https://connect.stripe.com/oauth/authorize?response_type=code&client_id=ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7&scope=read_write" + autofillParams; + } +}); From b5a2101d2fe67b109f8d4a6b8e8eec07db0ecbca Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Sun, 5 Mar 2017 15:03:52 -0600 Subject: [PATCH 234/256] [tm 799] adding the stripe connect fees and destination to the stripe charge stuff --- .../payments-stripe/client/checkout/stripe.js | 3 +- .../payments-stripe/server/methods/stripe.js | 35 +++++++++++++++---- .../server/methods/stripeapi.js | 5 +-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/imports/plugins/included/payments-stripe/client/checkout/stripe.js b/imports/plugins/included/payments-stripe/client/checkout/stripe.js index 06bbea18d8a..2d24c4bdac2 100644 --- a/imports/plugins/included/payments-stripe/client/checkout/stripe.js +++ b/imports/plugins/included/payments-stripe/client/checkout/stripe.js @@ -66,7 +66,8 @@ AutoForm.addHooks("stripe-payment-form", { const storedCard = cardData.type.charAt(0).toUpperCase() + cardData.type.slice(1) + " " + doc.cardNumber.slice(-4); Stripe.authorize(cardData, { total: Cart.findOne().cartTotal(), - currency: Shops.findOne().currency + currency: Shops.findOne().currency, + shopId: Shops.findOne()._id }, function (error, transaction) { submitting = false; if (error) { diff --git a/imports/plugins/included/payments-stripe/server/methods/stripe.js b/imports/plugins/included/payments-stripe/server/methods/stripe.js index 104c72b2077..21b783bfcc7 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripe.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripe.js @@ -97,15 +97,32 @@ Meteor.methods({ }); check(paymentData, { total: String, - currency: String + currency: String, + shopId: String }); - const chargeObj = { - amount: "", - currency: "", - card: {}, - capture: true - }; + // check if this is a seller shop for destination and transaction fee logic + const sellerShop = sellerShops.findOne(paymentData.shopId); + + if (sellerShop && sellerShop.stripeConnectSettings) { + const chargeObj = { + chargeData: { + amount: "", + currency: "", + transactionFee: 0, + card: {}, + capture: true + }, + stripe_account: sellerShop.stripeConnectSettings.stripe_user_id + }; + } else { + const chargeObj = { + amount: "", + currency: "", + card: {}, + capture: true + }; + } if (transactionType === "authorize") { chargeObj.capture = false; @@ -113,6 +130,10 @@ Meteor.methods({ chargeObj.card = parseCardData(cardData); chargeObj.amount = formatForStripe(paymentData.total); chargeObj.currency = paymentData.currency; + const stripeConnectSettings = Packages.findOne({ name: "reaction-stripe-connect" }).settings; + if (stripeConnectSettings.transactionFee.enabled && sellerShop.stripeConnectSettings) { + chargeObj.transactionFee = Number(paymentData.total) * stripeConnectSettings.transactionFee.percentage; + } let result; let chargeResult; diff --git a/imports/plugins/included/payments-stripe/server/methods/stripeapi.js b/imports/plugins/included/payments-stripe/server/methods/stripeapi.js index a606f98425a..f8af6d80de2 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripeapi.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripeapi.js @@ -49,10 +49,11 @@ StripeApi.methods.getApiKey = new ValidatedMethod({ validate: null, run() { const settings = Packages.findOne({ name: "reaction-stripe" }).settings; - if (!settings.api_key) { + const stripeConnectSettings = Packages.findOne({ name: "reaction-stripe-connect" }).settings; + if (!settings.api_key && !stripeConnectSettings.api_key) { throw new Meteor.Error("403", "Invalid Stripe Credentials"); } - return settings.api_key; + return (stripeConnectSettings.api_key) ? stripeConnectSettings.api_key : settings.api_key; } }); From d3a19fa137ea07311c9e7d8c133e76dda6cf6022 Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Sun, 5 Mar 2017 16:03:25 -0600 Subject: [PATCH 235/256] spelling --- server/api/core/core.js | 2 +- server/api/core/templates.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/api/core/core.js b/server/api/core/core.js index 0869536a8ee..2e323a987ca 100644 --- a/server/api/core/core.js +++ b/server/api/core/core.js @@ -47,7 +47,7 @@ export default { /** * registerTemplate - * registers Templates into the Tempaltes Collection + * registers Templates into the Templates Collection * @return {function} Registers template */ registerTemplate: registerTemplate, diff --git a/server/api/core/templates.js b/server/api/core/templates.js index 33eb7e0277e..c78a0b7e4a4 100644 --- a/server/api/core/templates.js +++ b/server/api/core/templates.js @@ -74,7 +74,7 @@ export function getTemplateByName(templateName, shopId) { const templateInfo = Templates.findOne({ name: templateName, $or: [ - // Attemt to find user editable / edited templated first + // Attemt to find user editable / edited template first { isOriginalTemplate: false }, From 4a1f2413d8e5d7b7ffc77810b66ec62b35d670d9 Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Sun, 5 Mar 2017 16:26:17 -0600 Subject: [PATCH 236/256] changing router params --- .../client/settings/settings.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index 533b30c6b91..fc0b058cbd2 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -46,8 +46,13 @@ AutoForm.hooks({ Template.stripeConnectRedirect.onCreated( function() { //grabs values stripe passes back in the url as the params this.autorun(() => { - FlowRouter.watchPathChange(); - let url = FlowRouter.current(); - Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), url); + FlowRouter.route("/dashboard/connect", { + name: "StripeConnect.url", + action(params, queryParams) { + console.log("Gathering Stripe Connect URL parameters."); + + Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), params, queryParams); + } + }); }); }); From 10107e0d79a26fdd9b6532b5bcb460a50e596702 Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Sun, 5 Mar 2017 17:38:53 -0600 Subject: [PATCH 237/256] [tm 799] fixes for the shop url stuff --- .../lib/collections/collections.js | 2 +- .../lib/collections/schemas/marketplace.js | 13 +++++++ .../server/i18n/en.json | 1 - .../payments-stripe-connect/server/index.js | 1 - lib/collections/schemas/shops.js | 35 ------------------- 5 files changed, 14 insertions(+), 38 deletions(-) diff --git a/imports/plugins/included/marketplace/lib/collections/collections.js b/imports/plugins/included/marketplace/lib/collections/collections.js index 31d13a71990..ce1f5a9f546 100644 --- a/imports/plugins/included/marketplace/lib/collections/collections.js +++ b/imports/plugins/included/marketplace/lib/collections/collections.js @@ -1,4 +1,4 @@ -import * as Schemas from "/lib/collections/schemas"; +import * as Schemas from "./schemas"; /** * SellerShops Collection diff --git a/imports/plugins/included/marketplace/lib/collections/schemas/marketplace.js b/imports/plugins/included/marketplace/lib/collections/schemas/marketplace.js index 3049459131a..925db6daa3f 100644 --- a/imports/plugins/included/marketplace/lib/collections/schemas/marketplace.js +++ b/imports/plugins/included/marketplace/lib/collections/schemas/marketplace.js @@ -1,5 +1,6 @@ import { SimpleSchema } from "meteor/aldeed:simple-schema"; import { PackageConfig } from "/lib/collections/schemas/registry"; +import { Shop } from "/lib/collections/schemas/shops.js"; export const MarketplacePackageConfig = new SimpleSchema([ PackageConfig, { @@ -15,3 +16,15 @@ export const MarketplacePackageConfig = new SimpleSchema([ } } ]); + +/** + * Seller Shop Schema + */ +export const SellerShop = new SimpleSchema([ + Shop, { + stripeConnectSettings: { + type: Object, + optional: true + } + } +]); diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/en.json b/imports/plugins/included/payments-stripe-connect/server/i18n/en.json index 3e8eeb8c397..a8fa2e7708d 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/en.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/en.json @@ -18,7 +18,6 @@ "stripeConnectSettingsDescription": "Don't have a Stripe Connect API Client ID?", "stripeConnectSettingsGetItHere": "Get it here" }, - //TODO: Add to other languages "redirect": { "stripeConnectWaitingNote": "Will auto redirect in a couple seconds or click here." } diff --git a/imports/plugins/included/payments-stripe-connect/server/index.js b/imports/plugins/included/payments-stripe-connect/server/index.js index 931b4521238..3979f964b5a 100644 --- a/imports/plugins/included/payments-stripe-connect/server/index.js +++ b/imports/plugins/included/payments-stripe-connect/server/index.js @@ -1,2 +1 @@ import "./i18n"; -import "./Methods"; diff --git a/lib/collections/schemas/shops.js b/lib/collections/schemas/shops.js index 59247ebf57c..8fa817bd306 100644 --- a/lib/collections/schemas/shops.js +++ b/lib/collections/schemas/shops.js @@ -267,38 +267,3 @@ export const Shop = new SimpleSchema({ optional: true } }); - -/** - * Seller Shop Schema - */ -export const SellerShop = new SimpleSchema({ - token_type: { - type: String, - optional: true - }, - stripe_publishable_key: { - type: String, - optional: true - }, - scope: { - type: String, - optional: true - }, - livemode: { - type: Boolean, - optional: true - }, - stripe_user_id: { - type: String, - optional: true - }, - refresh_token: { - type: String, - optional: true - }, - access_token: { - type: String, - optional: true - } -}); -SellerShop.extend(Shop); From 2eae27b43135652bcec33a91c94305e5161532cb Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Sun, 5 Mar 2017 17:39:54 -0600 Subject: [PATCH 238/256] more fixes --- imports/plugins/included/payments-stripe-connect/register.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/register.js b/imports/plugins/included/payments-stripe-connect/register.js index c2f441dc110..673e90ce384 100644 --- a/imports/plugins/included/payments-stripe-connect/register.js +++ b/imports/plugins/included/payments-stripe-connect/register.js @@ -12,7 +12,7 @@ Reaction.registerPackage({ "reaction-stripe-connect": { enabled: false }, - "redirect_stripe_connect": "stripe-connect-redirect" + "stripe-redirect-url": "stripe-connect-redirect" }, registry: [ // Settings panel @@ -33,7 +33,7 @@ Reaction.registerPackage({ // Redirect for Stripe Connect Sign-In { template: "stripeConnectRedirect", - route: "/dashboard/connect", //not sure about this route + route: "/stripe-connect-redirect" } ] }); From 6f84d9c9c5d3795fee6e8db3ee9f7e587caf1342 Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Sun, 5 Mar 2017 17:41:11 -0600 Subject: [PATCH 239/256] work in progress --- .../lib/collections/collections.js | 2 +- .../client/settings/settings.html | 3 + .../client/settings/settings.js | 4 +- .../payments-stripe-connect/register.js | 2 +- .../server/Methods/methods.js | 1 - lib/collections/schemas/shops.js | 70 ++++++++++--------- 6 files changed, 44 insertions(+), 38 deletions(-) diff --git a/imports/plugins/included/marketplace/lib/collections/collections.js b/imports/plugins/included/marketplace/lib/collections/collections.js index 31d13a71990..1847d2a791b 100644 --- a/imports/plugins/included/marketplace/lib/collections/collections.js +++ b/imports/plugins/included/marketplace/lib/collections/collections.js @@ -5,4 +5,4 @@ import * as Schemas from "/lib/collections/schemas"; */ export const SellerShops = new Mongo.Collection("SellerShops"); -SellerShops.attachSchema(Schemas.SellerShop); +SellerShops.attachSchema(Schemas.Shop); diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.html b/imports/plugins/included/payments-stripe-connect/client/settings/settings.html index 18093a81d34..568b9e5f9e7 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.html +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.html @@ -60,4 +60,7 @@ diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index fc0b058cbd2..98e49e238f3 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -46,11 +46,11 @@ AutoForm.hooks({ Template.stripeConnectRedirect.onCreated( function() { //grabs values stripe passes back in the url as the params this.autorun(() => { - FlowRouter.route("/dashboard/connect", { + FlowRouter.route("https://connect.stripe.com/oauth/authorize", { name: "StripeConnect.url", action(params, queryParams) { console.log("Gathering Stripe Connect URL parameters."); - + Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), params, queryParams); } }); diff --git a/imports/plugins/included/payments-stripe-connect/register.js b/imports/plugins/included/payments-stripe-connect/register.js index c2f441dc110..91e3ef24427 100644 --- a/imports/plugins/included/payments-stripe-connect/register.js +++ b/imports/plugins/included/payments-stripe-connect/register.js @@ -33,7 +33,7 @@ Reaction.registerPackage({ // Redirect for Stripe Connect Sign-In { template: "stripeConnectRedirect", - route: "/dashboard/connect", //not sure about this route + route: "https://connect.stripe.com/oauth/authorize" } ] }); diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js index c27383ec7a2..f47c16147b8 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -1,7 +1,6 @@ import { Meteor } from "meteor/meteor"; import { check } from "meteor/check"; import { Logger } from "/server/api"; -import { SellerShops } from "/imports/plugins/included/marketplace/lib/collections"; Meteor.methods({ /** diff --git a/lib/collections/schemas/shops.js b/lib/collections/schemas/shops.js index 59247ebf57c..fd05417fa4b 100644 --- a/lib/collections/schemas/shops.js +++ b/lib/collections/schemas/shops.js @@ -121,6 +121,41 @@ export const BrandAsset = new SimpleSchema({ } }); + +/** + * Stripe Connect Schema + */ +export const StripeConnectSettings = new SimpleSchema({ + "tokenType": { + type: String, + optional: true + }, + "stripePublishableKey": { + type: String, + optional: true + }, + "scope": { + type: String, + optional: true + }, + "livemode": { + type: Boolean, + optional: true + }, + "stripeUserId": { + type: String, + optional: true + }, + "refreshToken": { + type: String, + optional: true + }, + "accessToken": { + type: String, + optional: true + } +}); + /** * Shop Schema */ @@ -265,40 +300,9 @@ export const Shop = new SimpleSchema({ } }, optional: true - } -}); - -/** - * Seller Shop Schema - */ -export const SellerShop = new SimpleSchema({ - token_type: { - type: String, - optional: true - }, - stripe_publishable_key: { - type: String, - optional: true - }, - scope: { - type: String, - optional: true - }, - livemode: { - type: Boolean, - optional: true - }, - stripe_user_id: { - type: String, - optional: true - }, - refresh_token: { - type: String, - optional: true }, - access_token: { - type: String, + "stripeConnectSettings": { + type: [StripeConnectSettings], optional: true } }); -SellerShop.extend(Shop); From df63e463d21983f5244e31b82ec5a73ef1252ac7 Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Sun, 5 Mar 2017 18:13:02 -0600 Subject: [PATCH 240/256] changed shop schema and stripe connect saving --- .../client/settings/settings.js | 10 ++++-- .../server/Methods/methods.js | 36 ++++++------------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index 98e49e238f3..42b58e6c8a0 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -50,8 +50,14 @@ AutoForm.hooks({ name: "StripeConnect.url", action(params, queryParams) { console.log("Gathering Stripe Connect URL parameters."); - - Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), params, queryParams); + let tokenType = FlowRouter.getQueryParam("token_type"); + let stripePublishableKey = FlowRouter.getQueryParams("stripe_publishable_key"); + let scope = FlowRouter.getQueryParams("scope"); + let livemode = FlowRouter.getQueryParams("livemode"); + let stripeUserId = FlowRouter.getQueryParams("stripe_user_id"); + let refreshToken = FlowRouter.getQueryParams("refresh_token"); + let accessToken = FlowRouter.getQueryParams("access_token"); + Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), tokenType, stripePublishableKey, scope, livemode, stripeUserId, refreshToken, accessToken); } }); }); diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js index f47c16147b8..772b5a7a4f6 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -7,35 +7,21 @@ Meteor.methods({ * separate url into params * save params into sellerShop collection **/ - "stripeConnect/saveSellerParams": function(shopId, url) { - check(shopId, String); - check(url, String); + "stripeConnect/saveSellerParams": function(shopId, tokenType, stripePublishableKey, scope, livemode, stripeUserId, refreshToken, accessToken) { Logger.warn(url); let result; try { - let token_type_index = url.indexOf("token_type="); - let stripe_publishable_key_index = url.indexOf("stripe_publishable_key="); - let scope_index = url.indexOf("scope="); - let livemode_index = url.indexOf("livemode="); - let stripe_user_id_index = url.indexOf("stripe_user_id="); - let refresh_token_index = url.indexOf("refresh_token="); - let access_token_index = url.indexOf("access_token="); - let token_type = url.split(token_type_index, url.indexOf('&', token_type_index)); - let stripe_publishable_key = url.split(stripe_publishable_key_index, url.indexOf('&', stripe_publishable_key_index)); - let scope = url.split(scope_index, url.indexOf('&', scope_index)); - let livemode = url.split(livemode_index, url.indexOf('&', livemode_index)); - let stripe_user_id = url.split(stripe_user_id_index, url.indexOf('&', stripe_user_id_index)); - let refresh_token = url.split(refresh_token_index, url.indexOf('&', refresh_token_index)); - let access_token = url.split(access_token_index, url.indexOf('&', access_token_index)); db.SellerShops.save({ - "id" : shopId, - "token_type" : token_type, - "stripe_publishable_key" : stripe_publishable_key, - "scope" : scope, - "livemode" : livemode, - "stripe_user_id" : stripe_user_id, - "refresh_token" : refresh_token, - "access_token" : access_token + "stripeConnectSettings": { + "id": shopId, + "tokenType": token_type, + "stripePublishableKey": stripe_publishable_key, + "scope": scope, + "livemode": livemode, + "stripeUserId": stripe_user_id, + "refreshToken": refresh_token, + "accessToken": access_token + } }); result = { saved: true From f3ab2cbe8fa729b73dd531da95fbf7c30208a71e Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Sun, 5 Mar 2017 18:41:01 -0600 Subject: [PATCH 241/256] [tm 799] fixing some stuff for the methods and schema --- .../lib/collections/collections.js | 5 +- .../client/settings/settings.js | 57 ++++++++----------- .../server/Methods/methods.js | 39 ++++--------- lib/collections/schemas/shops.js | 39 ------------- 4 files changed, 35 insertions(+), 105 deletions(-) diff --git a/imports/plugins/included/marketplace/lib/collections/collections.js b/imports/plugins/included/marketplace/lib/collections/collections.js index 2179ece853f..0e1ac382915 100644 --- a/imports/plugins/included/marketplace/lib/collections/collections.js +++ b/imports/plugins/included/marketplace/lib/collections/collections.js @@ -1,8 +1,7 @@ -import * as Schemas from "./schemas"; - +import { SellerShop } from "./schemas"; /** * SellerShops Collection */ export const SellerShops = new Mongo.Collection("SellerShops"); -SellerShops.attachSchema(Schemas.Shop); +SellerShops.attachSchema(SellerShop); diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index 42b58e6c8a0..52bac6aa52d 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -17,21 +17,6 @@ Template.stripeConnectSettings.helpers({ } }); - Template.stripeConnect.helpers({ - packageData() { - return Packages.findOne({ - name: "reaction-stripe-connect", - shopId: Reaction.getShopId() - }); - } - }); - - Template.stripeConnect.events({ - "click [data-event-action=showStripeConnectSettings]"() { - Reaction.showActionView(); - } - }); - AutoForm.hooks({ "stripe-connect-update-form": { onSuccess: function () { @@ -43,22 +28,26 @@ AutoForm.hooks({ } }); - Template.stripeConnectRedirect.onCreated( function() { - //grabs values stripe passes back in the url as the params - this.autorun(() => { - FlowRouter.route("https://connect.stripe.com/oauth/authorize", { - name: "StripeConnect.url", - action(params, queryParams) { - console.log("Gathering Stripe Connect URL parameters."); - let tokenType = FlowRouter.getQueryParam("token_type"); - let stripePublishableKey = FlowRouter.getQueryParams("stripe_publishable_key"); - let scope = FlowRouter.getQueryParams("scope"); - let livemode = FlowRouter.getQueryParams("livemode"); - let stripeUserId = FlowRouter.getQueryParams("stripe_user_id"); - let refreshToken = FlowRouter.getQueryParams("refresh_token"); - let accessToken = FlowRouter.getQueryParams("access_token"); - Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), tokenType, stripePublishableKey, scope, livemode, stripeUserId, refreshToken, accessToken); - } - }); - }); - }); +Template.stripeConnectRedirect.onCreated(function () { + // grab stripe connects oauth values and redirect the user + const stripeConnectSettings = { + tokenType: FlowRouter.getQueryParam("token_type"), + stripePublishableKey: FlowRouter.getQueryParam("stripePublishableKey"), + scope: FlowRouter.getQueryParam("scope"), + liveMode: FlowRouter.getQueryParam("livemode"), + stripeUserId: FlowRouter.getQueryParam("stripe_user_id"), + refreshToken: FlowRouter.getQueryParam("refresh_token"), + accessToken: FlowRouter.getQueryParam("access_token") + }; + + /* + * work in progress!! need to figure out way to get correct shop id for seller. for redirection + * and saving params correctly. + */ + Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), stripeConnectSettings, function (err) { + if (err) { + Alerts.toast("There was an error with saving your seller params from stripe."); + } + Reaction.Router.go("/"); + }); +}); diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js index 772b5a7a4f6..bc517e04d68 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -1,38 +1,19 @@ import { Meteor } from "meteor/meteor"; import { check } from "meteor/check"; -import { Logger } from "/server/api"; +import { SellerShops } from "/imports/plugins/included/marketplace/lib/collections"; Meteor.methods({ /** * separate url into params * save params into sellerShop collection **/ - "stripeConnect/saveSellerParams": function(shopId, tokenType, stripePublishableKey, scope, livemode, stripeUserId, refreshToken, accessToken) { - Logger.warn(url); - let result; - try { - db.SellerShops.save({ - "stripeConnectSettings": { - "id": shopId, - "tokenType": token_type, - "stripePublishableKey": stripe_publishable_key, - "scope": scope, - "livemode": livemode, - "stripeUserId": stripe_user_id, - "refreshToken": refresh_token, - "accessToken": access_token - } - }); - result = { - saved: true - }; - } catch (error) { - Logger.warn(error); - result = { - saved: false, - error: error - }; - } - return result; - } + "stripeConnect/saveSellerParams": function (shopId, stripeConnectSettings) { + // add a robust check for stripe connect settings. + check(stripeConnectSettings, Object); + let result; + result = SellerShops.update({ shopId }, { + $set: { stripeConnectSettings: stripeConnectSettings } + }); + return result; + } }); diff --git a/lib/collections/schemas/shops.js b/lib/collections/schemas/shops.js index fd05417fa4b..8fa817bd306 100644 --- a/lib/collections/schemas/shops.js +++ b/lib/collections/schemas/shops.js @@ -121,41 +121,6 @@ export const BrandAsset = new SimpleSchema({ } }); - -/** - * Stripe Connect Schema - */ -export const StripeConnectSettings = new SimpleSchema({ - "tokenType": { - type: String, - optional: true - }, - "stripePublishableKey": { - type: String, - optional: true - }, - "scope": { - type: String, - optional: true - }, - "livemode": { - type: Boolean, - optional: true - }, - "stripeUserId": { - type: String, - optional: true - }, - "refreshToken": { - type: String, - optional: true - }, - "accessToken": { - type: String, - optional: true - } -}); - /** * Shop Schema */ @@ -300,9 +265,5 @@ export const Shop = new SimpleSchema({ } }, optional: true - }, - "stripeConnectSettings": { - type: [StripeConnectSettings], - optional: true } }); From 8f13516b9053d3a5bf4f31f5501b0a36d0b915ac Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Sun, 5 Mar 2017 18:48:43 -0600 Subject: [PATCH 242/256] remove this --- settings/dev.settings.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/settings/dev.settings.json b/settings/dev.settings.json index 75abb837e87..e54e3b5e2ca 100644 --- a/settings/dev.settings.json +++ b/settings/dev.settings.json @@ -2,9 +2,9 @@ "ROOT_URL": "", "MAIL_URL": "", "reaction": { - "REACTION_USER": "dpearson", - "REACTION_AUTH": "dylanpearson", - "REACTION_EMAIL": "dylanrichardpearson@gmail.com" + "REACTION_USER": "", + "REACTION_AUTH": "", + "REACTION_EMAIL": "" }, "REACTION_LOG_LEVEL": "info", "public": {} From 494c1eaa7d472cb6582b0093847709341ec2108a Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Sun, 5 Mar 2017 19:16:34 -0600 Subject: [PATCH 243/256] fixes --- .../client/settings/settings.js | 12 ++---------- .../server/Methods/methods.js | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index 52bac6aa52d..f86002647ef 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -30,21 +30,13 @@ AutoForm.hooks({ Template.stripeConnectRedirect.onCreated(function () { // grab stripe connects oauth values and redirect the user - const stripeConnectSettings = { - tokenType: FlowRouter.getQueryParam("token_type"), - stripePublishableKey: FlowRouter.getQueryParam("stripePublishableKey"), - scope: FlowRouter.getQueryParam("scope"), - liveMode: FlowRouter.getQueryParam("livemode"), - stripeUserId: FlowRouter.getQueryParam("stripe_user_id"), - refreshToken: FlowRouter.getQueryParam("refresh_token"), - accessToken: FlowRouter.getQueryParam("access_token") - }; + const authCode = FlowRouter.getQueryParam("code"); /* * work in progress!! need to figure out way to get correct shop id for seller. for redirection * and saving params correctly. */ - Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), stripeConnectSettings, function (err) { + Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), authCode, function (err) { if (err) { Alerts.toast("There was an error with saving your seller params from stripe."); } diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js index bc517e04d68..d1b0c146939 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -1,4 +1,5 @@ import { Meteor } from "meteor/meteor"; +import { HTTP } from 'meteor/http'; import { check } from "meteor/check"; import { SellerShops } from "/imports/plugins/included/marketplace/lib/collections"; @@ -7,13 +8,20 @@ Meteor.methods({ * separate url into params * save params into sellerShop collection **/ - "stripeConnect/saveSellerParams": function (shopId, stripeConnectSettings) { + "stripeConnect/saveSellerParams": function (shopId, authCode) { // add a robust check for stripe connect settings. - check(stripeConnectSettings, Object); + check(authCode, String); let result; - result = SellerShops.update({ shopId }, { - $set: { stripeConnectSettings: stripeConnectSettings } - }); + const api_key = Packages.findOne({ name: "reaction-stripe-connect" }).settings.api_key; + const stripeUrl = "https://connect.stripe.com/oauth/token"; + try { + const result = HTTP.call("POST", stripeUrl, {params: + { client_secret: api_key, code: authCode, grant_type: "authorization_code" } + }); + // check result for correct data + SellerShops.update({ shopId }, { + $set: { stripeConnectSettings: result } + }); return result; } }); From 91e8c8db877fe24008c667229e660819e3a757c9 Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Mon, 6 Mar 2017 09:45:27 -0600 Subject: [PATCH 244/256] fixes from merge --- .meteor/packages | 3 -- ...ld_account_and_order_search_collections.js | 22 +++++++++ .../migrations/2_add_key_to_search_ui.js | 21 +++++++++ .../plugins/core/versions/server/startup.js | 20 ++++++++ .../client/styles/dashboard/console.less | 5 +- .../products/productGrid/controls.js | 1 - .../included/shippo/server/methods/shippo.js | 47 ------------------- .../shippo/server/methods/shippoapi.js | 18 ------- 8 files changed, 64 insertions(+), 73 deletions(-) create mode 100644 imports/plugins/core/versions/server/migrations/1_rebuild_account_and_order_search_collections.js create mode 100644 imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js create mode 100644 imports/plugins/core/versions/server/startup.js diff --git a/.meteor/packages b/.meteor/packages index c047e45b9de..1645c86d19f 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -94,6 +94,3 @@ johanbrook:publication-collector # spiderable # adds phantomjs SEO rendering, use ongoworks:spiderable with Docker # meteorhacks:sikka # additional ddp, login security - -# Custom Packages -gadicc:blaze-react-component diff --git a/imports/plugins/core/versions/server/migrations/1_rebuild_account_and_order_search_collections.js b/imports/plugins/core/versions/server/migrations/1_rebuild_account_and_order_search_collections.js new file mode 100644 index 00000000000..52e707778e8 --- /dev/null +++ b/imports/plugins/core/versions/server/migrations/1_rebuild_account_and_order_search_collections.js @@ -0,0 +1,22 @@ +import { Migrations } from "/imports/plugins/core/versions"; +import { OrderSearch, AccountSearch } from "/lib/collections"; +import { buildOrderSearch, + buildAccountSearch } from "/imports/plugins/included/search-mongo/server/methods/searchcollections"; + +Migrations.add({ + version: 1, + up: function () { + OrderSearch.remove({}); + AccountSearch.remove(); + buildOrderSearch(); + buildAccountSearch(); + }, + down: function () { + // whether we are going up or down we just want to update the search collections + // to match whatever the current code in the build methods are. + OrderSearch.remove({}); + AccountSearch.remove(); + buildOrderSearch(); + buildAccountSearch(); + } +}); diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js new file mode 100644 index 00000000000..04aafe8dc33 --- /dev/null +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -0,0 +1,21 @@ +import { Migrations } from "/imports/plugins/core/versions"; +import { Packages } from "/lib/collections"; + +// Add keys to search so that stock search is enabled by default +Migrations.add({ + version: 2, + up() { + Packages.update({ name: "reaction-ui-search" }, + { + $set: { + registry: [{ + name: "Search Modal", + provides: "ui-search", + template: "searchModal" + }] + } + }, + { multi: true } + ); + } +}); \ No newline at end of file diff --git a/imports/plugins/core/versions/server/startup.js b/imports/plugins/core/versions/server/startup.js new file mode 100644 index 00000000000..a6f588e1c54 --- /dev/null +++ b/imports/plugins/core/versions/server/startup.js @@ -0,0 +1,20 @@ +import _ from "lodash"; +import { Hooks, Logger } from "/server/api"; +import { Migrations } from "/imports/plugins/core/versions"; + +function reactionLogger(opts) { + if (_.includes(["warn", "info", "error"], opts.level)) { + Logger[opts.level](opts.message); + } +} + +Migrations.config({ + logger: reactionLogger, + log: true, + logIfLatest: false, + collectionName: "Migrations" +}); + +Hooks.Events.add("afterCoreInit", () => { + Migrations.migrateTo("latest"); +}); \ No newline at end of file diff --git a/imports/plugins/included/default-theme/client/styles/dashboard/console.less b/imports/plugins/included/default-theme/client/styles/dashboard/console.less index a12f8e9d2f6..6cbd8c99c3b 100644 --- a/imports/plugins/included/default-theme/client/styles/dashboard/console.less +++ b/imports/plugins/included/default-theme/client/styles/dashboard/console.less @@ -228,8 +228,6 @@ body.admin-vertical .admin-controls { // .form-control; // } -<<<<<<< HEAD -======= .rui.admin.action-view { @@ -246,7 +244,6 @@ body.admin-vertical .admin-controls { } ->>>>>>> upstream/marketplace-my-shops .rui.admin.action-view .panel { border: 0; border-radius: 0; @@ -287,4 +284,4 @@ body.admin-vertical .admin-controls { .rui.admin.action-view-pane .panel-group > .panel:last-child { border-bottom: 1px solid @list-group-border; -} +} \ No newline at end of file diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/controls.js b/imports/plugins/included/product-variant/client/templates/products/productGrid/controls.js index 86eb686ff05..d1347958344 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/controls.js +++ b/imports/plugins/included/product-variant/client/templates/products/productGrid/controls.js @@ -2,7 +2,6 @@ import { Reaction } from "/lib/api"; import { Session } from "meteor/session"; import { Template } from "meteor/templating"; import { ReactiveDict } from "meteor/reactive-dict"; -import { Reaction } from "/lib/api"; import { IconButton } from "/imports/plugins/core/ui/client/components"; Template.gridControls.onCreated(function () { diff --git a/imports/plugins/included/shippo/server/methods/shippo.js b/imports/plugins/included/shippo/server/methods/shippo.js index e084ffe631e..d41d54d19f2 100644 --- a/imports/plugins/included/shippo/server/methods/shippo.js +++ b/imports/plugins/included/shippo/server/methods/shippo.js @@ -187,17 +187,10 @@ export const methods = { * activated Carriers of the Shippo account. * This method is intended to be used mainly by Autoform. * @param {Object} modifier - The Autoform's modifier string -<<<<<<< HEAD - * @param {_id} string - The id of the Shippo package that gets updated - * @return {Object} result - The object returned. - * @return {string("update"|"delete")} result.type - The type of updating happened. - * */ -======= * @param {String} _id - The id of the Shippo package that gets updated * @return {Object} result - The object returned. * @return {String} {string("update"|"delete")} result.type - The type of updating happened. */ ->>>>>>> upstream/marketplace-my-shops "shippo/updateApiKey"(modifier, _id) { // Important server-side check for security and data integrity check(modifier, ShippoPackageConfig); @@ -263,14 +256,6 @@ export const methods = { /** * Fetches the tracking status of shipped orders from Shippo and updates the * relevant orders' properties -<<<<<<< HEAD - * @return {Boolean} result - if the updating happened successfully or not. - * */ - - "shippo/fetchTrackingStatusForOrders"() { - const shopId = Reaction.getShopId(); - -======= * @param {String} orderId - optional orderId to get status of just one order. * @return {Boolean} result - if the updating happened successfully or not. * */ @@ -278,24 +263,11 @@ export const methods = { check(orderId, Match.Optional(String)); const shopId = Reaction.getShopId(); let shippoOrders; ->>>>>>> upstream/marketplace-my-shops const apiKey = getApiKey(shopId); if (!apiKey) { return false; } -<<<<<<< HEAD - // Find the orders of the shop that have shippo provider, tracking number, that are shipped - // but they are not yet delivered; - const shippoOrders = Orders.find({ - shopId, - "shipping.0.shippo.transactionId": { $exists: true }, - "shipping.0.tracking": { $exists: true }, - "shipping.0.shipped": true, - "shipping.0.delivered": { $ne: true } - // For now we don' t have logic for returned products - }); -======= if (orderId) { // return a specific order shippoOrders = Orders.find({ @@ -315,7 +287,6 @@ export const methods = { }); } ->>>>>>> upstream/marketplace-my-shops // no orders to update if (!shippoOrders.count()) { @@ -469,23 +440,6 @@ export const methods = { const rateId = orderShipment.shipmentMethod.settings.rateId; // make the actual purchase const transaction = ShippoApi.methods.createTransaction.call({ rateId, apiKey }); -<<<<<<< HEAD - - return Orders.update({ - _id: orderId - }, { - $set: { - "shipping.0.shippingLabelUrl": transaction.label_url, - "shipping.0.tracking": transaction.tracking_number, - "shipping.0.shippo.transactionId": transaction.object_id, - "shipping.0.shippo.trackingStatusDate": null, - "shipping.0.shippo.trackingStatusStatus": null - } - }); - } - } - -======= if (transaction) { return Orders.update({ _id: orderId @@ -501,7 +455,6 @@ export const methods = { } } } ->>>>>>> upstream/marketplace-my-shops return false; } }; diff --git a/imports/plugins/included/shippo/server/methods/shippoapi.js b/imports/plugins/included/shippo/server/methods/shippoapi.js index 7381b488dd2..d927963bdb5 100644 --- a/imports/plugins/included/shippo/server/methods/shippoapi.js +++ b/imports/plugins/included/shippo/server/methods/shippoapi.js @@ -1,13 +1,8 @@ /* eslint camelcase: 0 */ import Shippo from "shippo"; import { Meteor } from "meteor/meteor"; -<<<<<<< HEAD -import { Logger } from "/server/api"; -import { SimpleSchema } from "meteor/aldeed:simple-schema"; -======= import { SimpleSchema } from "meteor/aldeed:simple-schema"; import { Logger } from "/server/api"; ->>>>>>> upstream/marketplace-my-shops import { purchaseAddressSchema, parcelSchema } from "../lib/shippoApiSchema"; export const ShippoApi = { @@ -153,23 +148,14 @@ ShippoApi.methods.createTransaction = new ValidatedMethod({ }); if (transaction.object_status !== "SUCCESS") { -<<<<<<< HEAD - Logger.error(transaction.messages); - throw new Meteor.Error(transaction.messages); -======= const error = transaction.messages[0].text; Logger.error(error); throw new Meteor.Error(error); ->>>>>>> upstream/marketplace-my-shops } return transaction; } catch (error) { -<<<<<<< HEAD - Logger.error(error.message); -======= Logger.debug(error.message); ->>>>>>> upstream/marketplace-my-shops throw new Meteor.Error(error.message); } } @@ -196,10 +182,6 @@ ShippoApi.methods.getTransaction = new ValidatedMethod({ const retrieveTransactionFiber = Meteor.wrapAsync(shippoObj.transaction.retrieve, shippoObj.transaction); try { const transaction = retrieveTransactionFiber(transactionId); -<<<<<<< HEAD - -======= ->>>>>>> upstream/marketplace-my-shops return transaction; } catch (error) { Logger.error(error.message); From b9477aaee4e5385207df9572b009b19549c5f624 Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Mon, 6 Mar 2017 15:13:03 -0600 Subject: [PATCH 245/256] some fixes for merge --- imports/plugins/core/layout/client/templates/theme/theme.js | 3 --- lib/api/core.js | 3 --- 2 files changed, 6 deletions(-) diff --git a/imports/plugins/core/layout/client/templates/theme/theme.js b/imports/plugins/core/layout/client/templates/theme/theme.js index 24e22d40fad..91590969e91 100644 --- a/imports/plugins/core/layout/client/templates/theme/theme.js +++ b/imports/plugins/core/layout/client/templates/theme/theme.js @@ -41,10 +41,7 @@ function getRouteLayout(context) { * addBodyClasses * Adds body classes to help themes distinguish pages and components based on the current route name and layout theme * @param {Object} context - route context -<<<<<<< HEAD -======= * @returns {undefined} ->>>>>>> upstream/marketplace-my-shops */ function addBodyClasses(context) { let classes; diff --git a/lib/api/core.js b/lib/api/core.js index c39393f610b..4009aa36baf 100644 --- a/lib/api/core.js +++ b/lib/api/core.js @@ -12,8 +12,6 @@ if (Meteor.isServer) { } /** -<<<<<<< HEAD -======= * Check if package is enabled * @param {String} name - Package name * @return {Boolean} True if the package is enabled @@ -25,7 +23,6 @@ function isPackageEnabled(name) { } /** ->>>>>>> upstream/marketplace-my-shops * getSellerShopId * @summary Get a seller's shopId or default to parent shopId * @param {userId} userId - An optional userId to find a shop for From cf3c0027b494a5bf05960ce4b3ab60f986aa136b Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Tue, 7 Mar 2017 12:48:05 -0600 Subject: [PATCH 246/256] some of the suggested changes for pr --- .meteor/packages | 2 ++ imports/plugins/core/dashboard/register.js | 2 +- .../server/migrations/2_add_key_to_search_ui.js | 2 +- imports/plugins/core/versions/server/startup.js | 2 +- .../client/styles/dashboard/console.less | 2 +- .../included/default-theme/client/styles/navbar.less | 1 - .../server/{Methods => methods}/methods.js | 12 ++++++++---- 7 files changed, 14 insertions(+), 9 deletions(-) rename imports/plugins/included/payments-stripe-connect/server/{Methods => methods}/methods.js (69%) diff --git a/.meteor/packages b/.meteor/packages index 1645c86d19f..630632dac08 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -94,3 +94,5 @@ johanbrook:publication-collector # spiderable # adds phantomjs SEO rendering, use ongoworks:spiderable with Docker # meteorhacks:sikka # additional ddp, login security + +# Custom Packages diff --git a/imports/plugins/core/dashboard/register.js b/imports/plugins/core/dashboard/register.js index da4c5cac547..0dd9a8a4a6b 100644 --- a/imports/plugins/core/dashboard/register.js +++ b/imports/plugins/core/dashboard/register.js @@ -59,4 +59,4 @@ Reaction.registerPackage({ adminControlsFooter: "adminControlsFooter" } }] -}); \ No newline at end of file +}); diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js index 04aafe8dc33..d291a3805e0 100644 --- a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -18,4 +18,4 @@ Migrations.add({ { multi: true } ); } -}); \ No newline at end of file +}); diff --git a/imports/plugins/core/versions/server/startup.js b/imports/plugins/core/versions/server/startup.js index a6f588e1c54..d0177b2e477 100644 --- a/imports/plugins/core/versions/server/startup.js +++ b/imports/plugins/core/versions/server/startup.js @@ -17,4 +17,4 @@ Migrations.config({ Hooks.Events.add("afterCoreInit", () => { Migrations.migrateTo("latest"); -}); \ No newline at end of file +}); diff --git a/imports/plugins/included/default-theme/client/styles/dashboard/console.less b/imports/plugins/included/default-theme/client/styles/dashboard/console.less index 6cbd8c99c3b..3ac4575193a 100644 --- a/imports/plugins/included/default-theme/client/styles/dashboard/console.less +++ b/imports/plugins/included/default-theme/client/styles/dashboard/console.less @@ -284,4 +284,4 @@ body.admin-vertical .admin-controls { .rui.admin.action-view-pane .panel-group > .panel:last-child { border-bottom: 1px solid @list-group-border; -} \ No newline at end of file +} diff --git a/imports/plugins/included/default-theme/client/styles/navbar.less b/imports/plugins/included/default-theme/client/styles/navbar.less index db7795730ed..ab6d158f570 100644 --- a/imports/plugins/included/default-theme/client/styles/navbar.less +++ b/imports/plugins/included/default-theme/client/styles/navbar.less @@ -110,7 +110,6 @@ } .rui.navbar .languages .dropdown-menu { - margin-top: 0px; min-width: 250px !important; } diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/methods/methods.js similarity index 69% rename from imports/plugins/included/payments-stripe-connect/server/Methods/methods.js rename to imports/plugins/included/payments-stripe-connect/server/methods/methods.js index d1b0c146939..e5c99ed5206 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/methods/methods.js @@ -15,13 +15,17 @@ Meteor.methods({ const api_key = Packages.findOne({ name: "reaction-stripe-connect" }).settings.api_key; const stripeUrl = "https://connect.stripe.com/oauth/token"; try { - const result = HTTP.call("POST", stripeUrl, {params: - { client_secret: api_key, code: authCode, grant_type: "authorization_code" } + const result = HTTP.call("POST", stripeUrl, { + params: {client_secret: api_key, code: authCode, grant_type: "authorization_code"} }); // check result for correct data - SellerShops.update({ shopId }, { - $set: { stripeConnectSettings: result } + SellerShops.update({shopId}, { + $set: {stripeConnectSettings: result} }); + } catch (error) { + Logger.error(error); + result = { error }; + } return result; } }); From a45239bec5fc9673bd28929f0b693ec3caf28bb5 Mon Sep 17 00:00:00 2001 From: lorenzo Date: Tue, 7 Mar 2017 22:57:37 +0200 Subject: [PATCH 247/256] fixed merge issues --- .../included/marketplace/client/index.js | 3 ++ .../stripeConnectSignupButton.js | 2 +- .../included/marketplace/lib/api/index.js | 1 - .../marketplace/lib/api/marketplace.js | 32 ------------------- .../lib/collections/collections.js | 7 ---- .../marketplace/lib/collections/index.js | 1 - 6 files changed, 4 insertions(+), 42 deletions(-) delete mode 100644 imports/plugins/included/marketplace/lib/api/index.js delete mode 100644 imports/plugins/included/marketplace/lib/api/marketplace.js delete mode 100644 imports/plugins/included/marketplace/lib/collections/collections.js delete mode 100644 imports/plugins/included/marketplace/lib/collections/index.js diff --git a/imports/plugins/included/marketplace/client/index.js b/imports/plugins/included/marketplace/client/index.js index cd501f39dab..cfb77506e09 100644 --- a/imports/plugins/included/marketplace/client/index.js +++ b/imports/plugins/included/marketplace/client/index.js @@ -9,3 +9,6 @@ import "./templates/settings/sellerShopSettings.js"; import "./templates/shops/shopSelect.html"; import "./templates/shops/shopSelect.js"; + +import "./templates/stripeConnectSignupButton/stripeConnectSignupButton.html"; +import "./templates/stripeConnectSignupButton/stripeConnectSignupButton.js"; diff --git a/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js b/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js index 23262a22dde..45f3f6a83f7 100644 --- a/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js +++ b/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js @@ -1,7 +1,7 @@ import { Meteor } from "meteor/meteor"; import { i18next } from "/client/api"; import { Reaction } from "/lib/api"; -import { SellerShops } from "../../../lib/collections"; +import { SellerShops } from "/lib/collections"; Template.stripeConnectSignupButton.onCreated(function () { this.autorun(() => { diff --git a/imports/plugins/included/marketplace/lib/api/index.js b/imports/plugins/included/marketplace/lib/api/index.js deleted file mode 100644 index 21a5b786946..00000000000 --- a/imports/plugins/included/marketplace/lib/api/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from "./marketplace"; diff --git a/imports/plugins/included/marketplace/lib/api/marketplace.js b/imports/plugins/included/marketplace/lib/api/marketplace.js deleted file mode 100644 index 8f3339281f7..00000000000 --- a/imports/plugins/included/marketplace/lib/api/marketplace.js +++ /dev/null @@ -1,32 +0,0 @@ -import { Meteor } from "meteor/meteor"; -import { Reaction } from "/lib/api"; - -/** - * hasMarketplaceGuestAccess - * @summary Checks if the current user is a guest in the marketplace and not a seller - * Owners always have full access - * @returns {Boolean} True if current user is a guest and not a seller, or the owner - */ -function hasMarketplaceGuestAccess() { - const currentUser = Meteor.user(); - - // parent shop owners have full access - if (Roles.getGroupsForUser(currentUser, "owner").length) { - return true; - } - - const packageSettings = Reaction.getPackageSettings("reaction-marketplace"); - - // if marketplace is on - // allow only guests, who aren't sellers already - // to become sellers for their shop group - return ( - packageSettings.enabled && - packageSettings.settings.public.allowGuestSellers && - Roles.getGroupsForUser(currentUser, "admin").length < 1 - ); -} - -export const Marketplace = { - hasMarketplaceGuestAccess -}; diff --git a/imports/plugins/included/marketplace/lib/collections/collections.js b/imports/plugins/included/marketplace/lib/collections/collections.js deleted file mode 100644 index 0e1ac382915..00000000000 --- a/imports/plugins/included/marketplace/lib/collections/collections.js +++ /dev/null @@ -1,7 +0,0 @@ -import { SellerShop } from "./schemas"; -/** - * SellerShops Collection - */ -export const SellerShops = new Mongo.Collection("SellerShops"); - -SellerShops.attachSchema(SellerShop); diff --git a/imports/plugins/included/marketplace/lib/collections/index.js b/imports/plugins/included/marketplace/lib/collections/index.js deleted file mode 100644 index 45e94450ebd..00000000000 --- a/imports/plugins/included/marketplace/lib/collections/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from "./collections"; From fa5fd17d2c786104fa62a9aa1e251dfeace954f8 Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Tue, 7 Mar 2017 15:22:09 -0600 Subject: [PATCH 248/256] [tm 799] fixes for PR --- .meteor/packages | 1 + imports/plugins/core/dashboard/register.js | 2 +- imports/plugins/core/revisions/server/hooks.js | 7 ------- .../versions/server/migrations/2_add_key_to_search_ui.js | 2 +- imports/plugins/core/versions/server/startup.js | 2 +- .../default-theme/client/styles/dashboard/console.less | 2 +- .../included/default-theme/client/styles/navbar.less | 2 +- .../payments-stripe-connect/client/settings/settings.js | 6 +----- .../included/payments-stripe/client/checkout/stripe.js | 6 +++--- .../included/payments-stripe/server/methods/stripe.js | 2 +- .../included/payments-stripe/server/methods/stripeapi.js | 4 ++-- 11 files changed, 13 insertions(+), 23 deletions(-) diff --git a/.meteor/packages b/.meteor/packages index 1645c86d19f..a0a974948f6 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -94,3 +94,4 @@ johanbrook:publication-collector # spiderable # adds phantomjs SEO rendering, use ongoworks:spiderable with Docker # meteorhacks:sikka # additional ddp, login security +# Custom Packages diff --git a/imports/plugins/core/dashboard/register.js b/imports/plugins/core/dashboard/register.js index da4c5cac547..0dd9a8a4a6b 100644 --- a/imports/plugins/core/dashboard/register.js +++ b/imports/plugins/core/dashboard/register.js @@ -59,4 +59,4 @@ Reaction.registerPackage({ adminControlsFooter: "adminControlsFooter" } }] -}); \ No newline at end of file +}); diff --git a/imports/plugins/core/revisions/server/hooks.js b/imports/plugins/core/revisions/server/hooks.js index 365db36dd88..6723a767fee 100644 --- a/imports/plugins/core/revisions/server/hooks.js +++ b/imports/plugins/core/revisions/server/hooks.js @@ -518,13 +518,6 @@ Products.before.update(function (userId, product, fieldNames, modifier, options) modifier.$set = newSet; modifier.$inc = newInc; - - // if (isEmpty(newSet) === false) { - // Products.update(originalSelector, modifier, { - // publish: true, - // selector: options.selector - // }); - // } } // prevent the underlying document from being modified as it is in draft mode diff --git a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js index 04aafe8dc33..d291a3805e0 100644 --- a/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js +++ b/imports/plugins/core/versions/server/migrations/2_add_key_to_search_ui.js @@ -18,4 +18,4 @@ Migrations.add({ { multi: true } ); } -}); \ No newline at end of file +}); diff --git a/imports/plugins/core/versions/server/startup.js b/imports/plugins/core/versions/server/startup.js index a6f588e1c54..d0177b2e477 100644 --- a/imports/plugins/core/versions/server/startup.js +++ b/imports/plugins/core/versions/server/startup.js @@ -17,4 +17,4 @@ Migrations.config({ Hooks.Events.add("afterCoreInit", () => { Migrations.migrateTo("latest"); -}); \ No newline at end of file +}); diff --git a/imports/plugins/included/default-theme/client/styles/dashboard/console.less b/imports/plugins/included/default-theme/client/styles/dashboard/console.less index 6cbd8c99c3b..3ac4575193a 100644 --- a/imports/plugins/included/default-theme/client/styles/dashboard/console.less +++ b/imports/plugins/included/default-theme/client/styles/dashboard/console.less @@ -284,4 +284,4 @@ body.admin-vertical .admin-controls { .rui.admin.action-view-pane .panel-group > .panel:last-child { border-bottom: 1px solid @list-group-border; -} \ No newline at end of file +} diff --git a/imports/plugins/included/default-theme/client/styles/navbar.less b/imports/plugins/included/default-theme/client/styles/navbar.less index db7795730ed..2b87b679a7a 100644 --- a/imports/plugins/included/default-theme/client/styles/navbar.less +++ b/imports/plugins/included/default-theme/client/styles/navbar.less @@ -110,7 +110,7 @@ } .rui.navbar .languages .dropdown-menu { - margin-top: 0px; + margin-top: 0; min-width: 250px !important; } diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index f86002647ef..a40ccd43a68 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -32,11 +32,7 @@ Template.stripeConnectRedirect.onCreated(function () { // grab stripe connects oauth values and redirect the user const authCode = FlowRouter.getQueryParam("code"); - /* - * work in progress!! need to figure out way to get correct shop id for seller. for redirection - * and saving params correctly. - */ - Meteor.call("stripeConnect/saveSellerParams", Reaction.getShopId(), authCode, function (err) { + Meteor.call("stripeConnect/saveSellerParams", Reaction.getSellerShopId(), authCode, function (err) { if (err) { Alerts.toast("There was an error with saving your seller params from stripe."); } diff --git a/imports/plugins/included/payments-stripe/client/checkout/stripe.js b/imports/plugins/included/payments-stripe/client/checkout/stripe.js index 2d24c4bdac2..63ed214c7a8 100644 --- a/imports/plugins/included/payments-stripe/client/checkout/stripe.js +++ b/imports/plugins/included/payments-stripe/client/checkout/stripe.js @@ -3,7 +3,7 @@ import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; import { AutoForm } from "meteor/aldeed:autoform"; import { getCardType } from "/client/modules/core/helpers/globals"; -import { Cart, Shops } from "/lib/collections"; +import { Cart, SellerShops } from "/lib/collections"; import { Stripe } from "../../lib/api"; import { StripePayment } from "../../lib/collections/schemas"; @@ -66,8 +66,8 @@ AutoForm.addHooks("stripe-payment-form", { const storedCard = cardData.type.charAt(0).toUpperCase() + cardData.type.slice(1) + " " + doc.cardNumber.slice(-4); Stripe.authorize(cardData, { total: Cart.findOne().cartTotal(), - currency: Shops.findOne().currency, - shopId: Shops.findOne()._id + currency: SellerShops.findOne().currency, + shopId: SellerShops.findOne()._id }, function (error, transaction) { submitting = false; if (error) { diff --git a/imports/plugins/included/payments-stripe/server/methods/stripe.js b/imports/plugins/included/payments-stripe/server/methods/stripe.js index 21b783bfcc7..1b4cb5aeead 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripe.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripe.js @@ -130,7 +130,7 @@ Meteor.methods({ chargeObj.card = parseCardData(cardData); chargeObj.amount = formatForStripe(paymentData.total); chargeObj.currency = paymentData.currency; - const stripeConnectSettings = Packages.findOne({ name: "reaction-stripe-connect" }).settings; + const stripeConnectSettings = Reaction.getPackageSettings("reaction-stripe-connect").settings; if (stripeConnectSettings.transactionFee.enabled && sellerShop.stripeConnectSettings) { chargeObj.transactionFee = Number(paymentData.total) * stripeConnectSettings.transactionFee.percentage; } diff --git a/imports/plugins/included/payments-stripe/server/methods/stripeapi.js b/imports/plugins/included/payments-stripe/server/methods/stripeapi.js index f8af6d80de2..bf1f5a09779 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripeapi.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripeapi.js @@ -48,8 +48,8 @@ StripeApi.methods.getApiKey = new ValidatedMethod({ name: "StripeApi.methods.getApiKey", validate: null, run() { - const settings = Packages.findOne({ name: "reaction-stripe" }).settings; - const stripeConnectSettings = Packages.findOne({ name: "reaction-stripe-connect" }).settings; + const settings = Reaction.getPackageSettings("reaction-stripe").settings; + const stripeConnectSettings = Reaction.getPackageSettings("reaction-stripe-connect").settings; if (!settings.api_key && !stripeConnectSettings.api_key) { throw new Meteor.Error("403", "Invalid Stripe Credentials"); } From d70f3b0b581fe54dd3081b6e6f9acef95f408308 Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Tue, 7 Mar 2017 15:37:21 -0600 Subject: [PATCH 249/256] [tm 799] more fixes --- .../payments-stripe-connect/server/Methods/methods.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js index d1b0c146939..9cfbc478ace 100644 --- a/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/Methods/methods.js @@ -1,7 +1,7 @@ import { Meteor } from "meteor/meteor"; -import { HTTP } from 'meteor/http'; +import { HTTP } from "meteor/http"; import { check } from "meteor/check"; -import { SellerShops } from "/imports/plugins/included/marketplace/lib/collections"; +import { Shops } from "/lib/collections"; Meteor.methods({ /** @@ -15,13 +15,15 @@ Meteor.methods({ const api_key = Packages.findOne({ name: "reaction-stripe-connect" }).settings.api_key; const stripeUrl = "https://connect.stripe.com/oauth/token"; try { - const result = HTTP.call("POST", stripeUrl, {params: + result = HTTP.call("POST", stripeUrl, {params: { client_secret: api_key, code: authCode, grant_type: "authorization_code" } }); // check result for correct data - SellerShops.update({ shopId }, { + Shops.update({ shopId }, { $set: { stripeConnectSettings: result } }); + } catch (error) { + } return result; } }); From 478b6036108d6d8e82239ac1d85a516239c5f537 Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Tue, 7 Mar 2017 20:01:09 -0600 Subject: [PATCH 250/256] changed stripe(connect) labels --- .../included/payments-stripe-connect/server/i18n/ar.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/bg.json | 2 +- .../included/payments-stripe-connect/server/i18n/el.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/es.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/my.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/ro.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/ru.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/zh.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/ar.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/bg.json | 2 +- .../plugins/included/payments-stripe/server/i18n/el.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/es.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/my.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/ro.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/ru.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/zh.json | 8 ++++---- 16 files changed, 58 insertions(+), 58 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/ar.json b/imports/plugins/included/payments-stripe-connect/server/i18n/ar.json index 940aa0a6466..8c7ea514aca 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/ar.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/ar.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "شريط" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "شريط", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "المدفوعات شريط" }, "paymentSettings": { - "stripeConnectLabel": "شريط", - "stripeConnectSettingsLabel": "شريط", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "لم يكن لديك معرف العميل الشريط API؟", "stripeConnectSettingsGetItHere": "أحضره هنا" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/bg.json b/imports/plugins/included/payments-stripe-connect/server/i18n/bg.json index 4bf434802bd..09b3eaa0ab1 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/bg.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/bg.json @@ -9,7 +9,7 @@ "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "райе", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "плащания Stripe Connect" }, "paymentSettings": { diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/el.json b/imports/plugins/included/payments-stripe-connect/server/i18n/el.json index 9b6e985f8ab..ac9f94fb6ab 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/el.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/el.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "Ταινία" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "Ταινία", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "πληρωμές stripeConnect" }, "paymentSettings": { - "stripeConnectLabel": "Ταινία", - "stripeConnectSettingsLabel": "Ταινία", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "Δεν έχετε Stripe Connect API αναγνωριστικό πελάτη;", "stripeConnectSettingsGetItHere": "Αποκτήστε το εδώ" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/es.json b/imports/plugins/included/payments-stripe-connect/server/i18n/es.json index a81e86ebc2d..18176bfdc86 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/es.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/es.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "Raya" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "Raya", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "pagos de la raya" }, "paymentSettings": { - "stripeConnectLabel": "Raya", - "stripeConnectSettingsLabel": "Raya", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "No tener un ID de cliente de API de la raya?", "stripeConnectSettingsGetItHere": "Consiguelo aqui" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/my.json b/imports/plugins/included/payments-stripe-connect/server/i18n/my.json index c8268bd18f2..0b85e1e9915 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/my.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/my.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "အစင်း" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "အစင်း", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "အစင်းငွေပေးချေမှု" }, "paymentSettings": { - "stripeConnectLabel": "အစင်း", - "stripeConnectSettingsLabel": "အစင်း", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "တစ်ဦး Stripe Connect ဟာ API ကိုလိုင်း ID ကိုရှိသည်မဟုတ်သလား?", "stripeConnectSettingsGetItHere": "ဒီမှာရယူပါ" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/ro.json b/imports/plugins/included/payments-stripe-connect/server/i18n/ro.json index c0af4009e87..475a1b37d88 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/ro.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/ro.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "Dunga" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "Dunga", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "plăţile Stripe Connect" }, "paymentSettings": { - "stripeConnectLabel": "Dunga", - "stripeConnectSettingsLabel": "Dunga", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "Nu aveți un ID client Stripe Connect API?", "stripeConnectSettingsGetItHere": "Adu-o aici" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/ru.json b/imports/plugins/included/payments-stripe-connect/server/i18n/ru.json index efaedd1b6fc..dc8fa651e5f 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/ru.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/ru.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "нашивка" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "нашивка", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "нашивки платежи" }, "paymentSettings": { - "stripeConnectLabel": "нашивка", - "stripeConnectSettingsLabel": "нашивка", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "Не имеют нашивки API идентификатор клиента?", "stripeConnectSettingsGetItHere": "Получи это здесь" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/zh.json b/imports/plugins/included/payments-stripe-connect/server/i18n/zh.json index d6c087d019a..0e31d4dc779 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/zh.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/zh.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "条纹" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "条纹", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "条纹支付" }, "paymentSettings": { - "stripeConnectLabel": "条纹", - "stripeConnectSettingsLabel": "条纹", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "不要有条纹API客户端ID?", "stripeConnectSettingsGetItHere": "在这里获得" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/ar.json b/imports/plugins/included/payments-stripe/server/i18n/ar.json index c8604f7bf5c..2ad4845ca4e 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ar.json +++ b/imports/plugins/included/payments-stripe/server/i18n/ar.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "شريط" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "شريط", + "stripeLabel": "Stripe", "stripeDescription": "المدفوعات شريط" }, "paymentSettings": { - "stripeLabel": "شريط", - "stripeSettingsLabel": "شريط", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "لم يكن لديك معرف العميل الشريط API؟", "stripeSettingsGetItHere": "أحضره هنا" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/bg.json b/imports/plugins/included/payments-stripe/server/i18n/bg.json index ef08220fd0f..69c1493d686 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/bg.json +++ b/imports/plugins/included/payments-stripe/server/i18n/bg.json @@ -9,7 +9,7 @@ "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "райе", + "stripeLabel": "Stripe", "stripeDescription": "плащания Stripe" }, "paymentSettings": { diff --git a/imports/plugins/included/payments-stripe/server/i18n/el.json b/imports/plugins/included/payments-stripe/server/i18n/el.json index c41a222c8d9..259b76ccdac 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/el.json +++ b/imports/plugins/included/payments-stripe/server/i18n/el.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "Ταινία" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "Ταινία", + "stripeLabel": "Stripe", "stripeDescription": "πληρωμές stripe" }, "paymentSettings": { - "stripeLabel": "Ταινία", - "stripeSettingsLabel": "Ταινία", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "Δεν έχετε Stripe API αναγνωριστικό πελάτη;", "stripeSettingsGetItHere": "Αποκτήστε το εδώ" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/es.json b/imports/plugins/included/payments-stripe/server/i18n/es.json index 9c21c048856..f475ea883c8 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/es.json +++ b/imports/plugins/included/payments-stripe/server/i18n/es.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "Raya" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "Raya", + "stripeLabel": "Stripe", "stripeDescription": "pagos de la raya" }, "paymentSettings": { - "stripeLabel": "Raya", - "stripeSettingsLabel": "Raya", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "No tener un ID de cliente de API de la raya?", "stripeSettingsGetItHere": "Consiguelo aqui" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/my.json b/imports/plugins/included/payments-stripe/server/i18n/my.json index 88f41536ce8..2434d396d50 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/my.json +++ b/imports/plugins/included/payments-stripe/server/i18n/my.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "အစင်း" + "stripeLabel": "Stripe", }, "dashboard": { - "stripeLabel": "အစင်း", + "stripeLabel": "Stripe", "stripeDescription": "အစင်းငွေပေးချေမှု" }, "paymentSettings": { - "stripeLabel": "အစင်း", - "stripeSettingsLabel": "အစင်း", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "တစ်ဦး Stripe ဟာ API ကိုလိုင်း ID ကိုရှိသည်မဟုတ်သလား?", "stripeSettingsGetItHere": "ဒီမှာရယူပါ" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/ro.json b/imports/plugins/included/payments-stripe/server/i18n/ro.json index 74933a52bc1..4aa3073b676 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ro.json +++ b/imports/plugins/included/payments-stripe/server/i18n/ro.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "Dunga" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "Dunga", + "stripeLabel": "Stripe", "stripeDescription": "plăţile Stripe" }, "paymentSettings": { - "stripeLabel": "Dunga", - "stripeSettingsLabel": "Dunga", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "Nu aveți un ID client Stripe API?", "stripeSettingsGetItHere": "Adu-o aici" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/ru.json b/imports/plugins/included/payments-stripe/server/i18n/ru.json index 5a9de66b971..431bf733375 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ru.json +++ b/imports/plugins/included/payments-stripe/server/i18n/ru.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "нашивка" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "нашивка", + "stripeLabel": "Stripe", "stripeDescription": "нашивки платежи" }, "paymentSettings": { - "stripeLabel": "нашивка", - "stripeSettingsLabel": "нашивка", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "Не имеют нашивки API идентификатор клиента?", "stripeSettingsGetItHere": "Получи это здесь" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/zh.json b/imports/plugins/included/payments-stripe/server/i18n/zh.json index 420c41cb839..96e0816ed7f 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/zh.json +++ b/imports/plugins/included/payments-stripe/server/i18n/zh.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "条纹" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "条纹", + "stripeLabel": "Stripe", "stripeDescription": "条纹支付" }, "paymentSettings": { - "stripeLabel": "条纹", - "stripeSettingsLabel": "条纹", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "不要有条纹API客户端ID?", "stripeSettingsGetItHere": "在这里获得" } From fae113690808898712edd1de92ebe45a28a8a064 Mon Sep 17 00:00:00 2001 From: Nathaniel Schmeling Date: Thu, 9 Mar 2017 11:02:41 -0600 Subject: [PATCH 251/256] changed to working commit and readded the i18n labels --- .../included/payments-stripe-connect/server/i18n/ar.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/bg.json | 2 +- .../included/payments-stripe-connect/server/i18n/el.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/es.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/my.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/ro.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/ru.json | 8 ++++---- .../included/payments-stripe-connect/server/i18n/zh.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/ar.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/bg.json | 2 +- .../plugins/included/payments-stripe/server/i18n/el.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/es.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/my.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/ro.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/ru.json | 8 ++++---- .../plugins/included/payments-stripe/server/i18n/zh.json | 8 ++++---- 16 files changed, 58 insertions(+), 58 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/ar.json b/imports/plugins/included/payments-stripe-connect/server/i18n/ar.json index 940aa0a6466..8c7ea514aca 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/ar.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/ar.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "شريط" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "شريط", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "المدفوعات شريط" }, "paymentSettings": { - "stripeConnectLabel": "شريط", - "stripeConnectSettingsLabel": "شريط", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "لم يكن لديك معرف العميل الشريط API؟", "stripeConnectSettingsGetItHere": "أحضره هنا" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/bg.json b/imports/plugins/included/payments-stripe-connect/server/i18n/bg.json index 4bf434802bd..09b3eaa0ab1 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/bg.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/bg.json @@ -9,7 +9,7 @@ "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "райе", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "плащания Stripe Connect" }, "paymentSettings": { diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/el.json b/imports/plugins/included/payments-stripe-connect/server/i18n/el.json index 9b6e985f8ab..ac9f94fb6ab 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/el.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/el.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "Ταινία" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "Ταινία", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "πληρωμές stripeConnect" }, "paymentSettings": { - "stripeConnectLabel": "Ταινία", - "stripeConnectSettingsLabel": "Ταινία", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "Δεν έχετε Stripe Connect API αναγνωριστικό πελάτη;", "stripeConnectSettingsGetItHere": "Αποκτήστε το εδώ" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/es.json b/imports/plugins/included/payments-stripe-connect/server/i18n/es.json index a81e86ebc2d..18176bfdc86 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/es.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/es.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "Raya" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "Raya", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "pagos de la raya" }, "paymentSettings": { - "stripeConnectLabel": "Raya", - "stripeConnectSettingsLabel": "Raya", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "No tener un ID de cliente de API de la raya?", "stripeConnectSettingsGetItHere": "Consiguelo aqui" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/my.json b/imports/plugins/included/payments-stripe-connect/server/i18n/my.json index c8268bd18f2..0b85e1e9915 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/my.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/my.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "အစင်း" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "အစင်း", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "အစင်းငွေပေးချေမှု" }, "paymentSettings": { - "stripeConnectLabel": "အစင်း", - "stripeConnectSettingsLabel": "အစင်း", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "တစ်ဦး Stripe Connect ဟာ API ကိုလိုင်း ID ကိုရှိသည်မဟုတ်သလား?", "stripeConnectSettingsGetItHere": "ဒီမှာရယူပါ" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/ro.json b/imports/plugins/included/payments-stripe-connect/server/i18n/ro.json index c0af4009e87..475a1b37d88 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/ro.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/ro.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "Dunga" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "Dunga", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "plăţile Stripe Connect" }, "paymentSettings": { - "stripeConnectLabel": "Dunga", - "stripeConnectSettingsLabel": "Dunga", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "Nu aveți un ID client Stripe Connect API?", "stripeConnectSettingsGetItHere": "Adu-o aici" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/ru.json b/imports/plugins/included/payments-stripe-connect/server/i18n/ru.json index efaedd1b6fc..dc8fa651e5f 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/ru.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/ru.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "нашивка" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "нашивка", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "нашивки платежи" }, "paymentSettings": { - "stripeConnectLabel": "нашивка", - "stripeConnectSettingsLabel": "нашивка", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "Не имеют нашивки API идентификатор клиента?", "stripeConnectSettingsGetItHere": "Получи это здесь" } diff --git a/imports/plugins/included/payments-stripe-connect/server/i18n/zh.json b/imports/plugins/included/payments-stripe-connect/server/i18n/zh.json index d6c087d019a..0e31d4dc779 100644 --- a/imports/plugins/included/payments-stripe-connect/server/i18n/zh.json +++ b/imports/plugins/included/payments-stripe-connect/server/i18n/zh.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeConnectLabel": "条纹" + "stripeConnectLabel": "Stripe Connect" }, "dashboard": { - "stripeConnectLabel": "条纹", + "stripeConnectLabel": "Stripe Connect", "stripeConnectDescription": "条纹支付" }, "paymentSettings": { - "stripeConnectLabel": "条纹", - "stripeConnectSettingsLabel": "条纹", + "stripeConnectLabel": "Stripe Connect", + "stripeConnectSettingsLabel": "Stripe Connect", "stripeConnectSettingsDescription": "不要有条纹API客户端ID?", "stripeConnectSettingsGetItHere": "在这里获得" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/ar.json b/imports/plugins/included/payments-stripe/server/i18n/ar.json index c8604f7bf5c..2ad4845ca4e 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ar.json +++ b/imports/plugins/included/payments-stripe/server/i18n/ar.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "شريط" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "شريط", + "stripeLabel": "Stripe", "stripeDescription": "المدفوعات شريط" }, "paymentSettings": { - "stripeLabel": "شريط", - "stripeSettingsLabel": "شريط", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "لم يكن لديك معرف العميل الشريط API؟", "stripeSettingsGetItHere": "أحضره هنا" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/bg.json b/imports/plugins/included/payments-stripe/server/i18n/bg.json index ef08220fd0f..69c1493d686 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/bg.json +++ b/imports/plugins/included/payments-stripe/server/i18n/bg.json @@ -9,7 +9,7 @@ "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "райе", + "stripeLabel": "Stripe", "stripeDescription": "плащания Stripe" }, "paymentSettings": { diff --git a/imports/plugins/included/payments-stripe/server/i18n/el.json b/imports/plugins/included/payments-stripe/server/i18n/el.json index c41a222c8d9..259b76ccdac 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/el.json +++ b/imports/plugins/included/payments-stripe/server/i18n/el.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "Ταινία" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "Ταινία", + "stripeLabel": "Stripe", "stripeDescription": "πληρωμές stripe" }, "paymentSettings": { - "stripeLabel": "Ταινία", - "stripeSettingsLabel": "Ταινία", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "Δεν έχετε Stripe API αναγνωριστικό πελάτη;", "stripeSettingsGetItHere": "Αποκτήστε το εδώ" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/es.json b/imports/plugins/included/payments-stripe/server/i18n/es.json index 9c21c048856..f475ea883c8 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/es.json +++ b/imports/plugins/included/payments-stripe/server/i18n/es.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "Raya" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "Raya", + "stripeLabel": "Stripe", "stripeDescription": "pagos de la raya" }, "paymentSettings": { - "stripeLabel": "Raya", - "stripeSettingsLabel": "Raya", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "No tener un ID de cliente de API de la raya?", "stripeSettingsGetItHere": "Consiguelo aqui" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/my.json b/imports/plugins/included/payments-stripe/server/i18n/my.json index 88f41536ce8..3de2ef42689 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/my.json +++ b/imports/plugins/included/payments-stripe/server/i18n/my.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "အစင်း" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "အစင်း", + "stripeLabel": "Stripe", "stripeDescription": "အစင်းငွေပေးချေမှု" }, "paymentSettings": { - "stripeLabel": "အစင်း", - "stripeSettingsLabel": "အစင်း", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "တစ်ဦး Stripe ဟာ API ကိုလိုင်း ID ကိုရှိသည်မဟုတ်သလား?", "stripeSettingsGetItHere": "ဒီမှာရယူပါ" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/ro.json b/imports/plugins/included/payments-stripe/server/i18n/ro.json index 74933a52bc1..4aa3073b676 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ro.json +++ b/imports/plugins/included/payments-stripe/server/i18n/ro.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "Dunga" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "Dunga", + "stripeLabel": "Stripe", "stripeDescription": "plăţile Stripe" }, "paymentSettings": { - "stripeLabel": "Dunga", - "stripeSettingsLabel": "Dunga", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "Nu aveți un ID client Stripe API?", "stripeSettingsGetItHere": "Adu-o aici" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/ru.json b/imports/plugins/included/payments-stripe/server/i18n/ru.json index 5a9de66b971..431bf733375 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ru.json +++ b/imports/plugins/included/payments-stripe/server/i18n/ru.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "нашивка" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "нашивка", + "stripeLabel": "Stripe", "stripeDescription": "нашивки платежи" }, "paymentSettings": { - "stripeLabel": "нашивка", - "stripeSettingsLabel": "нашивка", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "Не имеют нашивки API идентификатор клиента?", "stripeSettingsGetItHere": "Получи это здесь" } diff --git a/imports/plugins/included/payments-stripe/server/i18n/zh.json b/imports/plugins/included/payments-stripe/server/i18n/zh.json index 420c41cb839..96e0816ed7f 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/zh.json +++ b/imports/plugins/included/payments-stripe/server/i18n/zh.json @@ -6,15 +6,15 @@ "reaction-payments": { "admin": { "shortcut": { - "stripeLabel": "条纹" + "stripeLabel": "Stripe" }, "dashboard": { - "stripeLabel": "条纹", + "stripeLabel": "Stripe", "stripeDescription": "条纹支付" }, "paymentSettings": { - "stripeLabel": "条纹", - "stripeSettingsLabel": "条纹", + "stripeLabel": "Stripe", + "stripeSettingsLabel": "Stripe", "stripeSettingsDescription": "不要有条纹API客户端ID?", "stripeSettingsGetItHere": "在这里获得" } From f97c443dc8175d3fe8cfe6f04a29a0190b5644c6 Mon Sep 17 00:00:00 2001 From: Tyler Dunkel Date: Thu, 30 Mar 2017 09:24:58 -0500 Subject: [PATCH 252/256] [tm-799] change to allow stripe connect trans-fee to be a decimal number. --- .../lib/collections/schemas/stripe-connect.js | 3 ++- .../included/payments-stripe/server/methods/stripe.js | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/lib/collections/schemas/stripe-connect.js b/imports/plugins/included/payments-stripe-connect/lib/collections/schemas/stripe-connect.js index 9eb70fbb7a8..c00e1ed129c 100644 --- a/imports/plugins/included/payments-stripe-connect/lib/collections/schemas/stripe-connect.js +++ b/imports/plugins/included/payments-stripe-connect/lib/collections/schemas/stripe-connect.js @@ -17,7 +17,8 @@ export const StripeConnectPackageConfig = new SimpleSchema([ }, "settings.transactionFee.percentage": { type: Number, - label: "Fee Percentage" + label: "Fee Percentage", + decimal: true } } ]); diff --git a/imports/plugins/included/payments-stripe/server/methods/stripe.js b/imports/plugins/included/payments-stripe/server/methods/stripe.js index 1b4cb5aeead..136b0af829f 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripe.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripe.js @@ -130,9 +130,11 @@ Meteor.methods({ chargeObj.card = parseCardData(cardData); chargeObj.amount = formatForStripe(paymentData.total); chargeObj.currency = paymentData.currency; + + // check for a transaction fee and apply. const stripeConnectSettings = Reaction.getPackageSettings("reaction-stripe-connect").settings; - if (stripeConnectSettings.transactionFee.enabled && sellerShop.stripeConnectSettings) { - chargeObj.transactionFee = Number(paymentData.total) * stripeConnectSettings.transactionFee.percentage; + if (sellerShop.stripeConnectSettings && stripeConnectSettings.transactionFee.enabled) { + chargeObj.transactionFee = chargeObj.amount * stripeConnectSettings.transactionFee.percentage; } let result; let chargeResult; From cf103ccb95513cb80d54226a78f81672329e1c27 Mon Sep 17 00:00:00 2001 From: Spencer Norman Date: Tue, 25 Apr 2017 18:33:18 -0600 Subject: [PATCH 253/256] Getting this WIP code ready to merge with marketplace feature branch Tweaks, fixing linting issues, basic code cleanup and some commenting out of partial functionality. --- client/modules/core/main.js | 4 +- client/modules/i18n/helpers.js | 1 - .../containers/ordersActionContainer.js | 1 + .../client/containers/publishContainer.js | 2 +- .../stripeConnectSignupButton.js | 10 +-- .../client/settings/settings.js | 2 + .../server/methods/methods.js | 30 +++++---- .../payments-stripe/server/methods/stripe.js | 63 +++++++++++-------- .../server/methods/stripeapi.js | 6 +- .../client/components/productAdmin.js | 1 - .../templates/products/productGrid/notice.js | 1 - .../included/shippo/server/i18n/index.js | 1 + private/data/i18n/en.json | 7 --- server/methods/core/cart.js | 17 +---- server/startup/registry/accounts.js | 63 ------------------- 15 files changed, 72 insertions(+), 137 deletions(-) delete mode 100644 server/startup/registry/accounts.js diff --git a/client/modules/core/main.js b/client/modules/core/main.js index 10081c61366..e502c483cf2 100644 --- a/client/modules/core/main.js +++ b/client/modules/core/main.js @@ -231,6 +231,7 @@ export default { } return false; }, + updateUserPreferences(packageName, preference, values) { const currentPreference = this.getUserPreferences(packageName, preference, {}); return this.setUserPreferences(packageName, preference, { @@ -238,6 +239,7 @@ export default { ...values }); }, + getShopId() { return this.shopId; }, @@ -316,7 +318,6 @@ export default { return Session.equals("admin/showActionViewDetail", true); }, - setActionView(viewData) { if (viewData) { let viewStack; @@ -469,7 +470,6 @@ export default { }]); }, - getCurrentTag() { if (this.Router.getRouteName() === "tag") { return this.Router.current().params.slug; diff --git a/client/modules/i18n/helpers.js b/client/modules/i18n/helpers.js index 3cab90a4668..61761b6beb2 100644 --- a/client/modules/i18n/helpers.js +++ b/client/modules/i18n/helpers.js @@ -1,4 +1,3 @@ -import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; import { Reaction, Logger, i18next } from "/client/api"; import { Shops } from "/lib/collections"; diff --git a/imports/plugins/core/orders/client/containers/ordersActionContainer.js b/imports/plugins/core/orders/client/containers/ordersActionContainer.js index fcf18410986..baf2da32d22 100644 --- a/imports/plugins/core/orders/client/containers/ordersActionContainer.js +++ b/imports/plugins/core/orders/client/containers/ordersActionContainer.js @@ -25,6 +25,7 @@ function composer(props, onData) { if (filter.name === selectedFilterName) { selectedIndex = index; } + filter.label = i18next.t(`order.filter.${filter.name}`, { defaultValue: filter.label }); filter.i18nKeyLabel = `order.filter.${filter.name}`; diff --git a/imports/plugins/core/revisions/client/containers/publishContainer.js b/imports/plugins/core/revisions/client/containers/publishContainer.js index d4355ad9960..9578e49a920 100644 --- a/imports/plugins/core/revisions/client/containers/publishContainer.js +++ b/imports/plugins/core/revisions/client/containers/publishContainer.js @@ -1,7 +1,7 @@ import React, { Component, PropTypes } from "react"; import { composeWithTracker } from "/lib/api/compose"; import PublishControls from "../components/publishControls"; -import { Tags, Revisions } from "/lib/collections"; +import { Revisions } from "/lib/collections"; import { Meteor } from "meteor/meteor"; import TranslationProvider from "/imports/plugins/core/ui/client/providers/translationProvider"; import { isRevisionControlEnabled } from "../../lib/api"; diff --git a/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js b/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js index 45f3f6a83f7..53122ce4a8c 100644 --- a/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js +++ b/imports/plugins/included/marketplace/client/templates/stripeConnectSignupButton/stripeConnectSignupButton.js @@ -1,10 +1,12 @@ import { Meteor } from "meteor/meteor"; -import { i18next } from "/client/api"; import { Reaction } from "/lib/api"; -import { SellerShops } from "/lib/collections"; + +// TODO: This button should be a React component. Template.stripeConnectSignupButton.onCreated(function () { this.autorun(() => { + // TODO: this should probably be managed by a subscription? + // Seems inefficient to do it at the button component level Meteor.subscribe("SellerShops"); }); }); @@ -27,7 +29,6 @@ Template.stripeConnectSignupButton.helpers({ Template.stripeConnectSignupButton.events({ "click [data-event-action='button-click-stripe-signup']": function () { - const sellerShop = Reaction.getSellerShop(); const email = sellerShop.emails[0].address; @@ -39,7 +40,8 @@ Template.stripeConnectSignupButton.events({ const state = sellerShop.addressBook[0].state; const zip = sellerShop.addressBook[0].postal; - const autofillParams = `&stripe_user[email]=${email}&stripe_user[country]=${country}&stripe_user[phone_number]=${phoneNumber}&stripe_user[business_name]=${businessName}&stripe_user[street_address]=${streetAddress}&stripe_user[city]=${city}&stripe_user[state]=${state}&stripe_user[zip]=${zip}`; + const autofillParams = `&stripe_user[email]=${email}&stripe_user[country]=${country}&stripe_user[phone_number]=${phoneNumber}&stripe_user[business_name]=${businessName}&stripe_user[street_address]=${streetAddress}&stripe_user[city]=${city}&stripe_user[state]=${state}&stripe_user[zip]=${zip}`; // eslint-disable-line max-len + // TODO: Should client_id be hardcoded in here? window.location.href = "https://connect.stripe.com/oauth/authorize?response_type=code&client_id=ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7&scope=read_write" + autofillParams; } }); diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index a40ccd43a68..75f9f58649f 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -29,11 +29,13 @@ AutoForm.hooks({ }); Template.stripeConnectRedirect.onCreated(function () { + // TODO: Verify that this works and define steps to reproduce. // grab stripe connects oauth values and redirect the user const authCode = FlowRouter.getQueryParam("code"); Meteor.call("stripeConnect/saveSellerParams", Reaction.getSellerShopId(), authCode, function (err) { if (err) { + // TODO: i18n here Alerts.toast("There was an error with saving your seller params from stripe."); } Reaction.Router.go("/"); diff --git a/imports/plugins/included/payments-stripe-connect/server/methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/methods/methods.js index c1f1c12cc48..de884c41f4f 100644 --- a/imports/plugins/included/payments-stripe-connect/server/methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/methods/methods.js @@ -1,30 +1,34 @@ import { Meteor } from "meteor/meteor"; import { HTTP } from "meteor/http"; import { check } from "meteor/check"; -import { Shops } from "/lib/collections"; +import { Shops } from "/lib/collections"; // TODO: Should this be SellerShops? Meteor.methods({ - /** - * separate url into params - * save params into sellerShop collection - **/ + // TODO: Review all of this code for functionality + // separate url into params + // save params into sellerShop collection "stripeConnect/saveSellerParams": function (shopId, authCode) { // add a robust check for stripe connect settings. check(authCode, String); let result; - const api_key = Packages.findOne({ name: "reaction-stripe-connect" }).settings.api_key; + const apiKey = Packages.findOne({ name: "reaction-stripe-connect" }).settings.api_key; const stripeUrl = "https://connect.stripe.com/oauth/token"; try { - const result = HTTP.call("POST", stripeUrl, { - params: {client_secret: api_key, code: authCode, grant_type: "authorization_code"} + result = HTTP.call("POST", stripeUrl, { + params: { + client_secret: apiKey, // eslint-disable-line camelcase + code: authCode, + grant_type: "authorization_code" // eslint-disable-line camelcase + } }); - // check result for correct data - Shops.update({shopId}, { - $set: {stripeConnectSettings: result} + + // TODO: check result for correct data + Shops.update({ shopId }, { + $set: { stripeConnectSettings: result } }); } catch (error) { - Logger.error(error); - result = { error }; + Logger.error(error); + result = { error }; } return result; } diff --git a/imports/plugins/included/payments-stripe/server/methods/stripe.js b/imports/plugins/included/payments-stripe/server/methods/stripe.js index 136b0af829f..5e9483748cd 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripe.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripe.js @@ -98,31 +98,41 @@ Meteor.methods({ check(paymentData, { total: String, currency: String, - shopId: String + shopId: String // // TODO: Implement Marketplace Payment - perhaps including shopId }); + const chargeObj = { + amount: "", + currency: "", + card: {}, + capture: true + }; + // check if this is a seller shop for destination and transaction fee logic - const sellerShop = sellerShops.findOne(paymentData.shopId); + // TODO: Add transaction fee to Stripe chargeObj when stripeConnect is in use. - if (sellerShop && sellerShop.stripeConnectSettings) { - const chargeObj = { - chargeData: { - amount: "", - currency: "", - transactionFee: 0, - card: {}, - capture: true - }, - stripe_account: sellerShop.stripeConnectSettings.stripe_user_id - }; - } else { - const chargeObj = { - amount: "", - currency: "", - card: {}, - capture: true - }; - } + // Where is sellerShops coming from here? + // const sellerShop = sellerShops.findOne(paymentData.shopId); + // + // if (sellerShop && sellerShop.stripeConnectSettings) { + // const chargeObj = { + // chargeData: { + // amount: "", + // currency: "", + // transactionFee: 0, + // card: {}, + // capture: true + // }, + // stripe_account: sellerShop.stripeConnectSettings.stripe_user_id + // }; + // } else { + // const chargeObj = { + // amount: "", + // currency: "", + // card: {}, + // capture: true + // }; + // } if (transactionType === "authorize") { chargeObj.capture = false; @@ -131,11 +141,12 @@ Meteor.methods({ chargeObj.amount = formatForStripe(paymentData.total); chargeObj.currency = paymentData.currency; - // check for a transaction fee and apply. - const stripeConnectSettings = Reaction.getPackageSettings("reaction-stripe-connect").settings; - if (sellerShop.stripeConnectSettings && stripeConnectSettings.transactionFee.enabled) { - chargeObj.transactionFee = chargeObj.amount * stripeConnectSettings.transactionFee.percentage; - } + // TODO: Check for a transaction fee and apply + // const stripeConnectSettings = Reaction.getPackageSettings("reaction-stripe-connect").settings; + // if (sellerShop.stripeConnectSettings && stripeConnectSettings.transactionFee.enabled) { + // chargeObj.transactionFee = chargeObj.amount * stripeConnectSettings.transactionFee.percentage; + // } + let result; let chargeResult; diff --git a/imports/plugins/included/payments-stripe/server/methods/stripeapi.js b/imports/plugins/included/payments-stripe/server/methods/stripeapi.js index 8363717696b..e50a4d1d037 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripeapi.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripeapi.js @@ -1,7 +1,6 @@ /* eslint camelcase: 0 */ import { Meteor } from "meteor/meteor"; import { SimpleSchema } from "meteor/aldeed:simple-schema"; -import { Packages } from "/lib/collections"; import { Reaction, Logger } from "/server/api"; export const StripeApi = {}; @@ -47,11 +46,14 @@ StripeApi.methods.getApiKey = new ValidatedMethod({ validate: null, run() { const settings = Reaction.getPackageSettings("reaction-stripe").settings; + // TODO: We should merge Stripe Connect plugin with reaction-stripe + // or fully separate them, but we shouldn't be checking package settings for a package + // we don't require. const stripeConnectSettings = Reaction.getPackageSettings("reaction-stripe-connect").settings; if (!settings.api_key && !stripeConnectSettings.api_key) { throw new Meteor.Error("403", "Invalid Stripe Credentials"); } - return (stripeConnectSettings.api_key) ? stripeConnectSettings.api_key : settings.api_key; + return stripeConnectSettings.api_key || settings.api_key; } }); diff --git a/imports/plugins/included/product-admin/client/components/productAdmin.js b/imports/plugins/included/product-admin/client/components/productAdmin.js index eae7d3577fb..58676cbd2cb 100644 --- a/imports/plugins/included/product-admin/client/components/productAdmin.js +++ b/imports/plugins/included/product-admin/client/components/productAdmin.js @@ -15,7 +15,6 @@ import { import { Router } from "/client/api"; import { TagListContainer } from "/imports/plugins/core/ui/client/containers"; import update from "react/lib/update"; -import PublishContainer from "/imports/plugins/core/revisions/client/containers/publishContainer"; const fieldNames = [ "title", diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.js b/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.js index 2a05cace920..bcbceb5058d 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.js +++ b/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.js @@ -1,5 +1,4 @@ import { ReactionProduct } from "/lib/api"; -import { Catalog } from "/lib/api"; /** * gridNotice helpers diff --git a/imports/plugins/included/shippo/server/i18n/index.js b/imports/plugins/included/shippo/server/i18n/index.js index 4adc5cba346..54444fb4957 100644 --- a/imports/plugins/included/shippo/server/i18n/index.js +++ b/imports/plugins/included/shippo/server/i18n/index.js @@ -1,4 +1,5 @@ import { loadTranslations } from "/server/startup/i18n"; + import ar from "./ar.json"; import bg from "./bg.json"; import cs from "./cs.json"; diff --git a/private/data/i18n/en.json b/private/data/i18n/en.json index 6a00930848c..d3a822d7c5f 100644 --- a/private/data/i18n/en.json +++ b/private/data/i18n/en.json @@ -598,13 +598,6 @@ "orderTotal": "Total" } }, - "marketplace": { - "becomeSeller": "Become a seller", - "errorCannotCreateShop": "Could not create shop for current user {{user}}", - "yourShopIsReady": "Your shop is now ready!", - "dashboardSettingsSaved": "Marketplace settings saved successfully!", - "dashboardSettingsFailed": "Failed to save Marketplace settings" - }, "accountsUI": { "members": "Members", "manage": "Manage", diff --git a/server/methods/core/cart.js b/server/methods/core/cart.js index 0f7b20172ba..63aa137242d 100644 --- a/server/methods/core/cart.js +++ b/server/methods/core/cart.js @@ -512,22 +512,7 @@ Meteor.methods({ if (cart.userId !== this.userId) { throw new Meteor.Error(403, "Access Denied"); } - - let orders = []; - let order = Object.assign({}, cart); - delete order.items; - delete order.shopId; - const sessionId = cart.sessionId; - const itemsByShop = _.groupBy(cart.items, "shopId"); - for (var item in itemsByShop) { - if (!itemsByShop.hasOwnProperty(item)) { - continue; - } - order.items = itemsByShop[item]; - order.shopId = item; - orders.push(order); - } - Logger.info("orders array", orders); + const order = Object.assign({}, cart); Logger.debug("cart/copyCartToOrder", cartId); // reassign the id, we'll get a new orderId diff --git a/server/startup/registry/accounts.js b/server/startup/registry/accounts.js deleted file mode 100644 index 645767a34bc..00000000000 --- a/server/startup/registry/accounts.js +++ /dev/null @@ -1,63 +0,0 @@ -import { Reaction } from "/server/api"; - -export default function () { - Reaction.registerPackage({ - label: "Accounts", - name: "reaction-accounts", - icon: "fa fa-sign-in", - autoEnable: true, - settings: {}, - registry: [{ - route: "/dashboard/accounts", - name: "accounts", - provides: "dashboard", - label: "Accounts", - description: "Manage how members sign into your shop.", - icon: "fa fa-sign-in", - container: "core", - template: "accountsDashboard", - workflow: "coreAccountsWorkflow", - priority: 1 - }, { - label: "Account Settings", - icon: "fa fa-sign-in", - provides: "settings", - route: "/dashboard/account/settings", - container: "accounts", - workflow: "coreAccountsWorkflow", - template: "accountsSettings" - }, { - route: "/dashboard/accounts", - name: "dashboard/accounts", - workflow: "coreAccountsWorkflow", - provides: "shortcut", - label: "Accounts", - icon: "fa fa-users", - priority: 1 - }, { - route: "/account/profile", - template: "accountProfile", - name: "account/profile", - label: "Profile", - icon: "fa fa-user", - provides: "userAccountDropdown" - }], - layout: [{ - layout: "coreLayout", - workflow: "coreAccountsWorkflow", - collection: "Accounts", - theme: "default", - enabled: true, - structure: { - template: "accountsDashboard", - layoutHeader: "layoutHeader", - layoutFooter: "", - notFound: "notFound", - dashboardHeader: "dashboardHeader", - dashboardControls: "", - dashboardHeaderControls: "", - adminControlsFooter: "adminControlsFooter" - } - }] - }); -} From ef7feeaac9cd65d95c1e5a34184c713d46527eb6 Mon Sep 17 00:00:00 2001 From: Spencer Norman Date: Tue, 25 Apr 2017 18:51:10 -0600 Subject: [PATCH 254/256] Use Reaction Router in place of FlowRouter --- .../payments-stripe-connect/client/settings/settings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index 75f9f58649f..00ca0cc8d92 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -1,5 +1,5 @@ import { Template } from "meteor/templating"; -import { Reaction, i18next } from "/client/api"; +import { Reaction, i18next, Router } from "/client/api"; import { Packages } from "/lib/collections"; import { StripeConnectPackageConfig } from "../../lib/collections/schemas"; @@ -31,7 +31,7 @@ AutoForm.hooks({ Template.stripeConnectRedirect.onCreated(function () { // TODO: Verify that this works and define steps to reproduce. // grab stripe connects oauth values and redirect the user - const authCode = FlowRouter.getQueryParam("code"); + const authCode = Router.getQueryParam("code"); Meteor.call("stripeConnect/saveSellerParams", Reaction.getSellerShopId(), authCode, function (err) { if (err) { From bcf33bfffd4a701bd7405f0b37051bcc4f752ce7 Mon Sep 17 00:00:00 2001 From: Spencer Norman Date: Tue, 25 Apr 2017 19:05:50 -0600 Subject: [PATCH 255/256] Fix stripe tests --- .../included/payments-stripe/client/checkout/stripe.js | 5 +++-- .../included/payments-stripe/server/methods/stripe.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/imports/plugins/included/payments-stripe/client/checkout/stripe.js b/imports/plugins/included/payments-stripe/client/checkout/stripe.js index 63ed214c7a8..960f1a680e4 100644 --- a/imports/plugins/included/payments-stripe/client/checkout/stripe.js +++ b/imports/plugins/included/payments-stripe/client/checkout/stripe.js @@ -66,8 +66,9 @@ AutoForm.addHooks("stripe-payment-form", { const storedCard = cardData.type.charAt(0).toUpperCase() + cardData.type.slice(1) + " " + doc.cardNumber.slice(-4); Stripe.authorize(cardData, { total: Cart.findOne().cartTotal(), - currency: SellerShops.findOne().currency, - shopId: SellerShops.findOne()._id + currency: SellerShops.findOne().currency + // Commenting this out because it causes tests to fail and isn't fully implemented. + // shopId: SellerShops.findOne()._id // TODO: Implement Marketplace Payments }, function (error, transaction) { submitting = false; if (error) { diff --git a/imports/plugins/included/payments-stripe/server/methods/stripe.js b/imports/plugins/included/payments-stripe/server/methods/stripe.js index 5e9483748cd..0c385b48f91 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripe.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripe.js @@ -97,8 +97,9 @@ Meteor.methods({ }); check(paymentData, { total: String, - currency: String, - shopId: String // // TODO: Implement Marketplace Payment - perhaps including shopId + currency: String + // Commenting this out because it causes tests to fail and isn't fully implemented. + // shopId: String // TODO: Implement Marketplace Payment - perhaps including shopId }); const chargeObj = { From 4387e4eda7f11470a5b0b7c92f2adbb724fe29e4 Mon Sep 17 00:00:00 2001 From: Spencer Norman Date: Tue, 25 Apr 2017 19:09:43 -0600 Subject: [PATCH 256/256] Put sessionId back in, not sure why it got removed. Fixes Inventory Hook tests --- server/methods/core/cart.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server/methods/core/cart.js b/server/methods/core/cart.js index 63aa137242d..0f67fc4ed64 100644 --- a/server/methods/core/cart.js +++ b/server/methods/core/cart.js @@ -513,6 +513,7 @@ Meteor.methods({ throw new Meteor.Error(403, "Access Denied"); } const order = Object.assign({}, cart); + const sessionId = cart.sessionId; Logger.debug("cart/copyCartToOrder", cartId); // reassign the id, we'll get a new orderId