diff --git a/app/locales/en.json b/app/locales/en.json index ed876d8..babe3e5 100644 --- a/app/locales/en.json +++ b/app/locales/en.json @@ -67,6 +67,7 @@ "tasks.recipes.setupGroup": "setup group profile and members", "tasks.recipes.createProfile": "create your profile", "tasks.steps.groupProfile": "enter your group profile information", + "tasks.steps.supplierProfile": "enter your supplier profile information", "tasks.steps.memberInvites": "invite group members", "tasks.recipes.setupSupplier": "setup supplier profile and products" } diff --git a/db/migrations/20170818142530_add-agent-type-ids-to-orders.js b/db/migrations/20170818142530_add-agent-type-ids-to-orders.js new file mode 100644 index 0000000..67b8d21 --- /dev/null +++ b/db/migrations/20170818142530_add-agent-type-ids-to-orders.js @@ -0,0 +1,13 @@ +exports.up = function(knex, Promise) { + return knex.schema.table('orders', function(table){ + table.renameColumn('agentId', 'consumerAgentId') + table.integer('supplierAgentId').references('agents.id') + }) +}; + +exports.down = function(knex, Promise) { + return knex.schema.table('orders', function(table){ + table.renameColumn('consumerAgentId', 'agentId') + table.dropColumn('supplierAgentId') + }) +}; diff --git a/ordering/services/orders.js b/ordering/services/orders.js index 3d04e04..881a372 100644 --- a/ordering/services/orders.js +++ b/ordering/services/orders.js @@ -1,6 +1,6 @@ const feathersKnex = require('feathers-knex') const { iff } = require('feathers-hooks-common') -import { pipe, equals, length, isNil } from 'ramda' +import { pipe, equals, length, isNil, isEmpty } from 'ramda' import * as taskRecipes from '../../tasks/data/recipes' module.exports = function () { @@ -17,7 +17,9 @@ module.exports = function () { const hooks = { before: { create: [ - iff(hasNoGroupAgent, createGroupAgent) + iff(hasNoGroupAgent, createGroupAgent), + iff(hasNoSupplierAgent, createSupplierAgent), + iff(hasNoRelation, createRelation) ] }, after: { @@ -32,21 +34,42 @@ function createGroupAgent (hook) { const agents = hook.app.service('agents') return agents.create({ type: 'group' }) .then((agent) => { - hook.data.agentId = agent.id + hook.data.consumerAgentId = agent.id return hook }) } function hasNoGroupAgent (hook) { - return isNil(hook.data.agentId) + return isNil(hook.data.consumerAgentId) +} + +function hasNoRelation (hook) { + const relationships = hook.app.service('relationships') + const supplierAgentId = hook.data.supplierAgentId + return relationships.find({ query: { sourceId: supplierAgentId } }).then((relationship)=>{ + return isEmpty(relationship) + }) +} + +function createRelation (hook){ + const relationships = hook.app.service('relationships') + const consumerAgentId = hook.data.consumerAgentId + const supplierAgentId = hook.data.supplierAgentId + return relationships.create({ + relationshipType: 'supplier', + sourceId: consumerAgentId, + targetId: supplierAgentId +}).then(() => { + return hook +}) } const hasLengthOne = pipe(length, equals(1)) function hasOneOrder (hook) { const orders = hook.app.service('orders') - const agentId = hook.data.agentId - return orders.find({ query: { agentId } }) + const consumerAgentId = hook.data.consumerAgentId + return orders.find({ query: { consumerAgentId } }) .then(hasLengthOne) } @@ -59,10 +82,24 @@ function createPrereqTaskPlan (hook) { const assigneeId = hook.params.credential.agentId const params = { - contextAgentId: hook.data.agentId + consumerAgentId: hook.data.consumerAgentId, + supplierAgentId: hook.data.supplierAgentId } return taskPlans.create({ taskRecipeId, params, assigneeId }) .then(() => { return hook }) } + +function createSupplierAgent (hook) { + const agents = hook.app.service('agents') + return agents.create({ type: 'group' }) + .then((agent) => { + hook.data.supplierAgentId = agent.id + return hook + }) +} + +function hasNoSupplierAgent (hook) { + return isNil(hook.data.supplierAgentId) +} diff --git a/tasks/components/SetupGroupTask.js b/tasks/components/SetupGroupTask.js index 56c1a6e..4aff49b 100644 --- a/tasks/components/SetupGroupTask.js +++ b/tasks/components/SetupGroupTask.js @@ -20,10 +20,10 @@ const rolesToRelationships = (roles = {}) => { export default (props) => { const { taskPlan, actions } = props if (isNil(taskPlan)) return null - const { params: { contextAgent } } = taskPlan - if (isNil(contextAgent)) return null + const { params: { consumerAgent } } = taskPlan + if (isNil(consumerAgent)) return null - const { profile, members } = contextAgent + const { profile, members } = consumerAgent console.log('members', members) @@ -33,14 +33,14 @@ export default (props) => { content: h(Profile, { initialValues: profile, updateProfile: (nextProfile) => { - actions.profiles.update(profile.id, merge(nextProfile, { agentId: contextAgent.id })) + actions.profiles.update(profile.id, merge(nextProfile, { agentId: consumerAgent.id })) } }) }, { id: 'tasks.steps.memberInvites', content: h(MemberInvites, { - agent: contextAgent, + agent: consumerAgent, initialValues: { members }, @@ -59,7 +59,7 @@ export default (props) => { credential = {}, } = agent const relationships = rolesToRelationships(roles) - const contextAgentId = contextAgent.id + const consumerAgentId = consumerAgent.id const agentData = { id, @@ -67,7 +67,7 @@ export default (props) => { profile, credential, relationships, - contextAgentId + consumerAgentId } if (isNil(agentData.id)) { diff --git a/tasks/components/SetupSupplierTask.js b/tasks/components/SetupSupplierTask.js index ecbc1de..bd1ea0b 100644 --- a/tasks/components/SetupSupplierTask.js +++ b/tasks/components/SetupSupplierTask.js @@ -1,6 +1,31 @@ -import React from 'react' +import h from 'react-hyperscript' +import { isNil, merge, isEmpty } from 'ramda' + +import TaskStepper from './TaskStepper' +import Profile from '../../agents/components/Profile' +import MemberInvites from '../../agents/components/MemberInvites' export default (props) => { - const { taskPlan } = props - return
Setup supplier yo!
+ const { taskPlan, actions } = props + if (isNil(taskPlan)) return null + const { params: { supplierAgent } } = taskPlan + if (isNil(supplierAgent)) return null + + const { profile, members } = supplierAgent + + const steps = [ + { + id: 'tasks.steps.supplierProfile', + content: h(Profile, { + initialValues: profile, + updateProfile: (nextProfile) => { + actions.profiles.update(profile.id, merge(nextProfile, { agentId: supplierAgent.id })) + } + }) + }, + ] + + return h(TaskStepper, { + steps + }) } diff --git a/tasks/containers/SetupGroupTask.js b/tasks/containers/SetupGroupTask.js index 5f142fc..8c68a79 100644 --- a/tasks/containers/SetupGroupTask.js +++ b/tasks/containers/SetupGroupTask.js @@ -6,7 +6,7 @@ import { agents, profiles, relationships, credentials } from 'dogstack-agents/ac import getSetupGroupTaskProps from '../getters/getSetupGroupTaskProps' import SetupGroupTask from '../components/SetupGroupTask' -const getContextAgentFromTaskPlan = path(['params', 'contextAgent']) +const getConsumerAgentFromTaskPlan = path(['params', 'consumerAgent']) export default compose( connectFeathers({ @@ -21,20 +21,20 @@ export default compose( // new queries by checking if deepEqual query: (props) => { var queries = [] - // once we have the task plan, query for the context agent + // once we have the task plan, query for the consumer agent const { taskPlan } = props if (taskPlan) { - const { params: { contextAgentId, contextAgent } } = taskPlan + const { params: { consumerAgentId, consumerAgent } } = taskPlan queries.push({ service: 'agents', - id: contextAgentId + id: consumerAgentId }) queries.push({ service: 'profiles', params: { query: { - agentId: contextAgentId + agentId: consumerAgentId } } }) @@ -42,13 +42,13 @@ export default compose( service: 'relationships', params: { query: { - sourceId: contextAgentId + sourceId: consumerAgentId } } }) - if (contextAgent) { - const { members } = contextAgent + if (consumerAgent) { + const { members } = consumerAgent const queryEachMember = forEach(member => { const { agentId } = member queries.push({ @@ -86,11 +86,11 @@ export default compose( // wait for task plan before re-query if (isNil(taskPlan)) return false - // re-query when we haven't gotten back contextAgent or taskWork - const contextAgent = getContextAgentFromTaskPlan(taskPlan) + // re-query when we haven't gotten back consumerAgent or taskWork + const consumerAgent = getConsumerAgentFromTaskPlan(taskPlan) - if (isNil(contextAgent)) return true - if (anyMembersAreNil(contextAgent)) { + if (isNil(consumerAgent)) return true + if (anyMembersAreNil(consumerAgent)) { return true } diff --git a/tasks/containers/SetupSupplierTask.js b/tasks/containers/SetupSupplierTask.js new file mode 100644 index 0000000..15a6799 --- /dev/null +++ b/tasks/containers/SetupSupplierTask.js @@ -0,0 +1,60 @@ +import { isNil, path, prop, pipe, values, any, forEach, either } from 'ramda' +import { connect as connectFeathers } from 'feathers-action-react' +import { compose } from 'recompose' + +import { agents, profiles, relationships, credentials } from 'dogstack-agents/actions' +import getSetupGroupTaskProps from '../getters/getSetupGroupTaskProps' +import SetupSupplierTask from '../components/SetupSupplierTask' + +const getSupplierAgentFromTaskPlan = path(['params', 'supplierAgent']) + +export default compose( + connectFeathers({ + selector: getSetupGroupTaskProps, + actions: { + agents, + profiles, + relationships, + credentials + }, + // TODO can optimize `feathers-action-react` to de-dupe + // new queries by checking if deepEqual + query: (props) => { + var queries = [] + // once we have the task plan, query for the supplier agent + const { taskPlan } = props + + if (taskPlan) { + const { params: { supplierAgentId } } = taskPlan + queries.push({ + service: 'agents', + id: supplierAgentId + }) + queries.push({ + service: 'profiles', + params: { + query: { + agentId: supplierAgentId + } + } + }) + } + + return queries + }, + shouldQueryAgain: (props, status) => { + if (status.isPending) return false + + const { taskPlan } = props.ownProps + + // wait for task plan before re-query + if (isNil(taskPlan)) return false + + // re-query when we haven't gotten back supplierAgent or taskWork + const supplierAgent = getSupplierAgentFromTaskPlan(taskPlan) + if (isNil(supplierAgent)) return true + + return false + } + }) +)(SetupSupplierTask) diff --git a/tasks/data/recipes.js b/tasks/data/recipes.js index af78876..39a42d6 100644 --- a/tasks/data/recipes.js +++ b/tasks/data/recipes.js @@ -1,5 +1,5 @@ import SetupGroupTask from '../containers/SetupGroupTask' -import SetupSupplierTask from '../components/SetupSupplierTask' +import SetupSupplierTask from '../containers/SetupSupplierTask' import CreateProfileTask from '../containers/CreateProfileTask' export const setupGroup = { diff --git a/tasks/getters/getEnhancedTaskPlans.js b/tasks/getters/getEnhancedTaskPlans.js index 7ab79e1..bd17570 100644 --- a/tasks/getters/getEnhancedTaskPlans.js +++ b/tasks/getters/getEnhancedTaskPlans.js @@ -21,12 +21,16 @@ const getEnhancedTaskPlans = createSelector( const assignee = agents[assigneeId] const taskWork = filter(propEq('taskPlanId', id))(taskWorks) - const { contextAgentId } = params - const contextAgent = isNil(contextAgentId) + const { consumerAgentId, supplierAgentId } = params + const consumerAgent = isNil(consumerAgentId) ? null - : agents[contextAgentId] + : agents[consumerAgentId] + const supplierAgent = isNil(supplierAgentId) + ? null + : agents[supplierAgentId] const nextParams = merge(params, { - contextAgent + consumerAgent, + supplierAgent }) return merge(taskPlan, {