mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-13 04:00:21 +00:00
Merge branch 'simple-order-cycles'
Conflicts: app/views/admin/order_cycles/_row.html.haml
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
angular.module('order_cycle', ['ngResource'])
|
angular.module('admin.order_cycles', ['ngResource'])
|
||||||
.controller('AdminCreateOrderCycleCtrl', ['$scope', 'OrderCycle', 'Enterprise', 'EnterpriseFee', ($scope, OrderCycle, Enterprise, EnterpriseFee) ->
|
.controller('AdminCreateOrderCycleCtrl', ['$scope', 'OrderCycle', 'Enterprise', 'EnterpriseFee', ($scope, OrderCycle, Enterprise, EnterpriseFee) ->
|
||||||
$scope.enterprises = Enterprise.index()
|
$scope.enterprises = Enterprise.index()
|
||||||
$scope.supplied_products = Enterprise.supplied_products
|
$scope.supplied_products = Enterprise.supplied_products
|
||||||
@@ -162,235 +162,6 @@ angular.module('order_cycle', ['ngResource'])
|
|||||||
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
||||||
])
|
])
|
||||||
|
|
||||||
.factory('OrderCycle', ['$resource', '$window', ($resource, $window) ->
|
|
||||||
OrderCycle = $resource '/admin/order_cycles/:order_cycle_id.json', {}, {
|
|
||||||
'index': { method: 'GET', isArray: true}
|
|
||||||
'create': { method: 'POST'}
|
|
||||||
'update': { method: 'PUT'}}
|
|
||||||
|
|
||||||
{
|
|
||||||
order_cycle:
|
|
||||||
incoming_exchanges: []
|
|
||||||
outgoing_exchanges: []
|
|
||||||
coordinator_fees: []
|
|
||||||
|
|
||||||
loaded: false
|
|
||||||
|
|
||||||
exchangeSelectedVariants: (exchange) ->
|
|
||||||
numActiveVariants = 0
|
|
||||||
numActiveVariants++ for id, active of exchange.variants when active
|
|
||||||
numActiveVariants
|
|
||||||
|
|
||||||
exchangeDirection: (exchange) ->
|
|
||||||
if this.order_cycle.incoming_exchanges.indexOf(exchange) == -1 then 'outgoing' else 'incoming'
|
|
||||||
|
|
||||||
toggleProducts: (exchange) ->
|
|
||||||
exchange.showProducts = !exchange.showProducts
|
|
||||||
|
|
||||||
setExchangeVariants: (exchange, variants, selected) ->
|
|
||||||
exchange.variants[variant] = selected for variant in variants
|
|
||||||
|
|
||||||
addSupplier: (new_supplier_id) ->
|
|
||||||
this.order_cycle.incoming_exchanges.push({enterprise_id: new_supplier_id, incoming: true, active: true, variants: {}, enterprise_fees: []})
|
|
||||||
|
|
||||||
addDistributor: (new_distributor_id) ->
|
|
||||||
this.order_cycle.outgoing_exchanges.push({enterprise_id: new_distributor_id, incoming: false, active: true, variants: {}, enterprise_fees: []})
|
|
||||||
|
|
||||||
removeExchange: (exchange) ->
|
|
||||||
if exchange.incoming
|
|
||||||
incoming_index = this.order_cycle.incoming_exchanges.indexOf exchange
|
|
||||||
this.order_cycle.incoming_exchanges.splice(incoming_index, 1)
|
|
||||||
this.removeDistributionOfVariant(variant_id) for variant_id, active of exchange.variants when active
|
|
||||||
else
|
|
||||||
outgoing_index = this.order_cycle.outgoing_exchanges.indexOf exchange
|
|
||||||
this.order_cycle.outgoing_exchanges.splice(outgoing_index, 1) if outgoing_index > -1
|
|
||||||
|
|
||||||
addCoordinatorFee: ->
|
|
||||||
this.order_cycle.coordinator_fees.push({})
|
|
||||||
|
|
||||||
removeCoordinatorFee: (index) ->
|
|
||||||
this.order_cycle.coordinator_fees.splice(index, 1)
|
|
||||||
|
|
||||||
addExchangeFee: (exchange) ->
|
|
||||||
exchange.enterprise_fees.push({})
|
|
||||||
|
|
||||||
removeExchangeFee: (exchange, index) ->
|
|
||||||
exchange.enterprise_fees.splice(index, 1)
|
|
||||||
|
|
||||||
productSuppliedToOrderCycle: (product) ->
|
|
||||||
product_variant_ids = (variant.id for variant in product.variants)
|
|
||||||
variant_ids = [product.master_id].concat(product_variant_ids)
|
|
||||||
incomingExchangesVariants = this.incomingExchangesVariants()
|
|
||||||
|
|
||||||
# TODO: This is an O(n^2) implementation of set intersection and thus is slooow.
|
|
||||||
# Use a better algorithm if needed.
|
|
||||||
# Also, incomingExchangesVariants is called every time, when it only needs to be
|
|
||||||
# called once per change to incoming variants. Some sort of caching?
|
|
||||||
ids = (variant_id for variant_id in variant_ids when incomingExchangesVariants.indexOf(variant_id) != -1)
|
|
||||||
ids.length > 0
|
|
||||||
|
|
||||||
variantSuppliedToOrderCycle: (variant) ->
|
|
||||||
this.incomingExchangesVariants().indexOf(variant.id) != -1
|
|
||||||
|
|
||||||
incomingExchangesVariants: ->
|
|
||||||
variant_ids = []
|
|
||||||
|
|
||||||
for exchange in this.order_cycle.incoming_exchanges
|
|
||||||
variant_ids.push(parseInt(id)) for id, active of exchange.variants when active
|
|
||||||
variant_ids
|
|
||||||
|
|
||||||
participatingEnterpriseIds: ->
|
|
||||||
suppliers = (exchange.enterprise_id for exchange in this.order_cycle.incoming_exchanges)
|
|
||||||
distributors = (exchange.enterprise_id for exchange in this.order_cycle.outgoing_exchanges)
|
|
||||||
jQuery.unique(suppliers.concat(distributors)).sort()
|
|
||||||
|
|
||||||
removeDistributionOfVariant: (variant_id) ->
|
|
||||||
for exchange in this.order_cycle.outgoing_exchanges
|
|
||||||
exchange.variants[variant_id] = false
|
|
||||||
|
|
||||||
load: (order_cycle_id) ->
|
|
||||||
service = this
|
|
||||||
OrderCycle.get {order_cycle_id: order_cycle_id}, (oc) ->
|
|
||||||
angular.extend(service.order_cycle, oc)
|
|
||||||
service.order_cycle.incoming_exchanges = []
|
|
||||||
service.order_cycle.outgoing_exchanges = []
|
|
||||||
for exchange in service.order_cycle.exchanges
|
|
||||||
if exchange.incoming
|
|
||||||
angular.extend(exchange, {enterprise_id: exchange.sender_id, active: true})
|
|
||||||
delete(exchange.receiver_id)
|
|
||||||
service.order_cycle.incoming_exchanges.push(exchange)
|
|
||||||
|
|
||||||
else
|
|
||||||
angular.extend(exchange, {enterprise_id: exchange.receiver_id, active: true})
|
|
||||||
delete(exchange.sender_id)
|
|
||||||
service.order_cycle.outgoing_exchanges.push(exchange)
|
|
||||||
|
|
||||||
delete(service.order_cycle.exchanges)
|
|
||||||
service.loaded = true
|
|
||||||
|
|
||||||
this.order_cycle
|
|
||||||
|
|
||||||
create: ->
|
|
||||||
oc = new OrderCycle({order_cycle: this.dataForSubmit()})
|
|
||||||
oc.$create (data) ->
|
|
||||||
if data['success']
|
|
||||||
$window.location = '/admin/order_cycles'
|
|
||||||
else
|
|
||||||
console.log('Failed to create order cycle')
|
|
||||||
|
|
||||||
update: ->
|
|
||||||
oc = new OrderCycle({order_cycle: this.dataForSubmit()})
|
|
||||||
oc.$update {order_cycle_id: this.order_cycle.id}, (data) ->
|
|
||||||
if data['success']
|
|
||||||
$window.location = '/admin/order_cycles'
|
|
||||||
else
|
|
||||||
console.log('Failed to update order cycle')
|
|
||||||
|
|
||||||
dataForSubmit: ->
|
|
||||||
data = this.deepCopy()
|
|
||||||
data = this.removeInactiveExchanges(data)
|
|
||||||
data = this.translateCoordinatorFees(data)
|
|
||||||
data = this.translateExchangeFees(data)
|
|
||||||
data
|
|
||||||
|
|
||||||
deepCopy: ->
|
|
||||||
data = angular.extend({}, this.order_cycle)
|
|
||||||
|
|
||||||
# Copy exchanges
|
|
||||||
data.incoming_exchanges = (angular.extend {}, exchange for exchange in this.order_cycle.incoming_exchanges) if this.order_cycle.incoming_exchanges?
|
|
||||||
data.outgoing_exchanges = (angular.extend {}, exchange for exchange in this.order_cycle.outgoing_exchanges) if this.order_cycle.outgoing_exchanges?
|
|
||||||
|
|
||||||
# Copy exchange fees
|
|
||||||
all_exchanges = (data.incoming_exchanges || []) + (data.outgoing_exchanges || [])
|
|
||||||
for exchange in all_exchanges
|
|
||||||
if exchange.enterprise_fees?
|
|
||||||
exchange.enterprise_fees = (angular.extend {}, fee for fee in exchange.enterprise_fees)
|
|
||||||
|
|
||||||
data
|
|
||||||
|
|
||||||
removeInactiveExchanges: (order_cycle) ->
|
|
||||||
order_cycle.incoming_exchanges =
|
|
||||||
(exchange for exchange in order_cycle.incoming_exchanges when exchange.active)
|
|
||||||
order_cycle.outgoing_exchanges =
|
|
||||||
(exchange for exchange in order_cycle.outgoing_exchanges when exchange.active)
|
|
||||||
order_cycle
|
|
||||||
|
|
||||||
translateCoordinatorFees: (order_cycle) ->
|
|
||||||
order_cycle.coordinator_fee_ids = (fee.id for fee in order_cycle.coordinator_fees)
|
|
||||||
delete order_cycle.coordinator_fees
|
|
||||||
order_cycle
|
|
||||||
|
|
||||||
translateExchangeFees: (order_cycle) ->
|
|
||||||
for exchange in order_cycle.incoming_exchanges
|
|
||||||
exchange.enterprise_fee_ids = (fee.id for fee in exchange.enterprise_fees)
|
|
||||||
delete exchange.enterprise_fees
|
|
||||||
for exchange in order_cycle.outgoing_exchanges
|
|
||||||
exchange.enterprise_fee_ids = (fee.id for fee in exchange.enterprise_fees)
|
|
||||||
delete exchange.enterprise_fees
|
|
||||||
order_cycle
|
|
||||||
}])
|
|
||||||
|
|
||||||
.factory('Enterprise', ['$resource', ($resource) ->
|
|
||||||
Enterprise = $resource('/admin/enterprises/for_order_cycle/:enterprise_id.json', {}, {'index': {method: 'GET', isArray: true}})
|
|
||||||
|
|
||||||
{
|
|
||||||
Enterprise: Enterprise
|
|
||||||
enterprises: {}
|
|
||||||
supplied_products: []
|
|
||||||
loaded: false
|
|
||||||
|
|
||||||
index: ->
|
|
||||||
service = this
|
|
||||||
|
|
||||||
Enterprise.index (data) ->
|
|
||||||
for enterprise in data
|
|
||||||
service.enterprises[enterprise.id] = enterprise
|
|
||||||
|
|
||||||
for product in enterprise.supplied_products
|
|
||||||
service.supplied_products.push(product)
|
|
||||||
|
|
||||||
service.loaded = true
|
|
||||||
|
|
||||||
this.enterprises
|
|
||||||
|
|
||||||
suppliedVariants: (enterprise_id) ->
|
|
||||||
vs = (this.variantsOf(product) for product in this.enterprises[enterprise_id].supplied_products)
|
|
||||||
[].concat vs...
|
|
||||||
|
|
||||||
variantsOf: (product) ->
|
|
||||||
if product.variants.length > 0
|
|
||||||
variant.id for variant in product.variants
|
|
||||||
else
|
|
||||||
[product.master_id]
|
|
||||||
|
|
||||||
totalVariants: (enterprise) ->
|
|
||||||
numVariants = 0
|
|
||||||
|
|
||||||
if enterprise
|
|
||||||
counts = for product in enterprise.supplied_products
|
|
||||||
numVariants += if product.variants.length == 0 then 1 else product.variants.length
|
|
||||||
|
|
||||||
numVariants
|
|
||||||
}])
|
|
||||||
|
|
||||||
.factory('EnterpriseFee', ['$resource', ($resource) ->
|
|
||||||
EnterpriseFee = $resource('/admin/enterprise_fees/:enterprise_fee_id.json', {}, {'index': {method: 'GET', isArray: true}})
|
|
||||||
|
|
||||||
{
|
|
||||||
EnterpriseFee: EnterpriseFee
|
|
||||||
enterprise_fees: {}
|
|
||||||
loaded: false
|
|
||||||
|
|
||||||
index: ->
|
|
||||||
service = this
|
|
||||||
EnterpriseFee.index (data) ->
|
|
||||||
service.enterprise_fees = data
|
|
||||||
service.loaded = true
|
|
||||||
|
|
||||||
forEnterprise: (enterprise_id) ->
|
|
||||||
enterprise_fee for enterprise_fee in this.enterprise_fees when enterprise_fee.enterprise_id == enterprise_id
|
|
||||||
}])
|
|
||||||
|
|
||||||
.directive('datetimepicker', ['$parse', ($parse) ->
|
.directive('datetimepicker', ['$parse', ($parse) ->
|
||||||
(scope, element, attrs) ->
|
(scope, element, attrs) ->
|
||||||
# using $parse instead of scope[attrs.datetimepicker] for cases
|
# using $parse instead of scope[attrs.datetimepicker] for cases
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
angular.module('admin.order_cycles').controller "AdminSimpleCreateOrderCycleCtrl", ($scope, OrderCycle, Enterprise, EnterpriseFee) ->
|
||||||
|
$scope.enterprises = Enterprise.index (enterprises) =>
|
||||||
|
$scope.init(enterprises)
|
||||||
|
$scope.enterprise_fees = EnterpriseFee.index()
|
||||||
|
$scope.order_cycle = OrderCycle.order_cycle
|
||||||
|
|
||||||
|
$scope.init = (enterprises) ->
|
||||||
|
enterprise = enterprises[Object.keys(enterprises)[0]]
|
||||||
|
OrderCycle.addSupplier enterprise.id
|
||||||
|
OrderCycle.addDistributor enterprise.id
|
||||||
|
$scope.outgoing_exchange = OrderCycle.order_cycle.outgoing_exchanges[0]
|
||||||
|
|
||||||
|
# All variants start as checked
|
||||||
|
OrderCycle.setExchangeVariants(OrderCycle.order_cycle.incoming_exchanges[0],
|
||||||
|
Enterprise.suppliedVariants(enterprise.id), true)
|
||||||
|
|
||||||
|
OrderCycle.order_cycle.coordinator_id = enterprise.id
|
||||||
|
|
||||||
|
$scope.loaded = ->
|
||||||
|
Enterprise.loaded && EnterpriseFee.loaded
|
||||||
|
|
||||||
|
$scope.removeDistributionOfVariant = angular.noop
|
||||||
|
|
||||||
|
$scope.setExchangeVariants = (exchange, variants, selected) ->
|
||||||
|
OrderCycle.setExchangeVariants(exchange, variants, selected)
|
||||||
|
|
||||||
|
$scope.suppliedVariants = (enterprise_id) ->
|
||||||
|
Enterprise.suppliedVariants(enterprise_id)
|
||||||
|
|
||||||
|
$scope.addCoordinatorFee = ($event) ->
|
||||||
|
$event.preventDefault()
|
||||||
|
OrderCycle.addCoordinatorFee()
|
||||||
|
|
||||||
|
$scope.removeCoordinatorFee = ($event, index) ->
|
||||||
|
$event.preventDefault()
|
||||||
|
OrderCycle.removeCoordinatorFee(index)
|
||||||
|
|
||||||
|
$scope.enterpriseFeesForEnterprise = (enterprise_id) ->
|
||||||
|
EnterpriseFee.forEnterprise(parseInt(enterprise_id))
|
||||||
|
|
||||||
|
$scope.submit = ->
|
||||||
|
OrderCycle.mirrorIncomingToOutgoingProducts()
|
||||||
|
OrderCycle.create()
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
angular.module('admin.order_cycles').controller "AdminSimpleEditOrderCycleCtrl", ($scope, $location, OrderCycle, Enterprise, EnterpriseFee) ->
|
||||||
|
$scope.orderCycleId = ->
|
||||||
|
$location.absUrl().match(/\/admin\/order_cycles\/(\d+)/)[1]
|
||||||
|
|
||||||
|
$scope.enterprises = Enterprise.index()
|
||||||
|
$scope.enterprise_fees = EnterpriseFee.index()
|
||||||
|
$scope.order_cycle = OrderCycle.load $scope.orderCycleId(), (order_cycle) =>
|
||||||
|
$scope.init()
|
||||||
|
|
||||||
|
$scope.loaded = ->
|
||||||
|
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||||
|
|
||||||
|
$scope.init = ->
|
||||||
|
$scope.outgoing_exchange = OrderCycle.order_cycle.outgoing_exchanges[0]
|
||||||
|
|
||||||
|
$scope.enterpriseFeesForEnterprise = (enterprise_id) ->
|
||||||
|
EnterpriseFee.forEnterprise(parseInt(enterprise_id))
|
||||||
|
|
||||||
|
$scope.removeDistributionOfVariant = angular.noop
|
||||||
|
|
||||||
|
$scope.addCoordinatorFee = ($event) ->
|
||||||
|
$event.preventDefault()
|
||||||
|
OrderCycle.addCoordinatorFee()
|
||||||
|
|
||||||
|
$scope.removeCoordinatorFee = ($event, index) ->
|
||||||
|
$event.preventDefault()
|
||||||
|
OrderCycle.removeCoordinatorFee(index)
|
||||||
|
|
||||||
|
$scope.submit = ->
|
||||||
|
OrderCycle.mirrorIncomingToOutgoingProducts()
|
||||||
|
OrderCycle.update()
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
angular.module('admin.order_cycles').factory('Enterprise', ($resource) ->
|
||||||
|
Enterprise = $resource('/admin/enterprises/for_order_cycle/:enterprise_id.json', {}, {'index': {method: 'GET', isArray: true}})
|
||||||
|
|
||||||
|
{
|
||||||
|
Enterprise: Enterprise
|
||||||
|
enterprises: {}
|
||||||
|
supplied_products: []
|
||||||
|
loaded: false
|
||||||
|
|
||||||
|
index: (callback=null) ->
|
||||||
|
service = this
|
||||||
|
|
||||||
|
Enterprise.index (data) ->
|
||||||
|
for enterprise in data
|
||||||
|
service.enterprises[enterprise.id] = enterprise
|
||||||
|
|
||||||
|
for product in enterprise.supplied_products
|
||||||
|
service.supplied_products.push(product)
|
||||||
|
|
||||||
|
service.loaded = true
|
||||||
|
(callback || angular.noop)(service.enterprises)
|
||||||
|
|
||||||
|
this.enterprises
|
||||||
|
|
||||||
|
suppliedVariants: (enterprise_id) ->
|
||||||
|
vs = (this.variantsOf(product) for product in this.enterprises[enterprise_id].supplied_products)
|
||||||
|
[].concat vs...
|
||||||
|
|
||||||
|
variantsOf: (product) ->
|
||||||
|
if product.variants.length > 0
|
||||||
|
variant.id for variant in product.variants
|
||||||
|
else
|
||||||
|
[product.master_id]
|
||||||
|
|
||||||
|
totalVariants: (enterprise) ->
|
||||||
|
numVariants = 0
|
||||||
|
|
||||||
|
if enterprise
|
||||||
|
counts = for product in enterprise.supplied_products
|
||||||
|
numVariants += if product.variants.length == 0 then 1 else product.variants.length
|
||||||
|
|
||||||
|
numVariants
|
||||||
|
})
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
angular.module('admin.order_cycles').factory('EnterpriseFee', ($resource) ->
|
||||||
|
EnterpriseFee = $resource('/admin/enterprise_fees/:enterprise_fee_id.json', {}, {'index': {method: 'GET', isArray: true}})
|
||||||
|
|
||||||
|
{
|
||||||
|
EnterpriseFee: EnterpriseFee
|
||||||
|
enterprise_fees: {}
|
||||||
|
loaded: false
|
||||||
|
|
||||||
|
index: ->
|
||||||
|
service = this
|
||||||
|
EnterpriseFee.index (data) ->
|
||||||
|
service.enterprise_fees = data
|
||||||
|
service.loaded = true
|
||||||
|
|
||||||
|
forEnterprise: (enterprise_id) ->
|
||||||
|
enterprise_fee for enterprise_fee in this.enterprise_fees when enterprise_fee.enterprise_id == enterprise_id
|
||||||
|
})
|
||||||
|
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
angular.module('admin.order_cycles').factory('OrderCycle', ($resource, $window) ->
|
||||||
|
OrderCycle = $resource '/admin/order_cycles/:order_cycle_id.json', {}, {
|
||||||
|
'index': { method: 'GET', isArray: true}
|
||||||
|
'create': { method: 'POST'}
|
||||||
|
'update': { method: 'PUT'}}
|
||||||
|
|
||||||
|
{
|
||||||
|
order_cycle:
|
||||||
|
incoming_exchanges: []
|
||||||
|
outgoing_exchanges: []
|
||||||
|
coordinator_fees: []
|
||||||
|
|
||||||
|
loaded: false
|
||||||
|
|
||||||
|
exchangeSelectedVariants: (exchange) ->
|
||||||
|
numActiveVariants = 0
|
||||||
|
numActiveVariants++ for id, active of exchange.variants when active
|
||||||
|
numActiveVariants
|
||||||
|
|
||||||
|
exchangeDirection: (exchange) ->
|
||||||
|
if this.order_cycle.incoming_exchanges.indexOf(exchange) == -1 then 'outgoing' else 'incoming'
|
||||||
|
|
||||||
|
toggleProducts: (exchange) ->
|
||||||
|
exchange.showProducts = !exchange.showProducts
|
||||||
|
|
||||||
|
setExchangeVariants: (exchange, variants, selected) ->
|
||||||
|
exchange.variants[variant] = selected for variant in variants
|
||||||
|
|
||||||
|
addSupplier: (new_supplier_id) ->
|
||||||
|
this.order_cycle.incoming_exchanges.push({enterprise_id: new_supplier_id, incoming: true, active: true, variants: {}, enterprise_fees: []})
|
||||||
|
|
||||||
|
addDistributor: (new_distributor_id) ->
|
||||||
|
this.order_cycle.outgoing_exchanges.push({enterprise_id: new_distributor_id, incoming: false, active: true, variants: {}, enterprise_fees: []})
|
||||||
|
|
||||||
|
removeExchange: (exchange) ->
|
||||||
|
if exchange.incoming
|
||||||
|
incoming_index = this.order_cycle.incoming_exchanges.indexOf exchange
|
||||||
|
this.order_cycle.incoming_exchanges.splice(incoming_index, 1)
|
||||||
|
this.removeDistributionOfVariant(variant_id) for variant_id, active of exchange.variants when active
|
||||||
|
else
|
||||||
|
outgoing_index = this.order_cycle.outgoing_exchanges.indexOf exchange
|
||||||
|
this.order_cycle.outgoing_exchanges.splice(outgoing_index, 1) if outgoing_index > -1
|
||||||
|
|
||||||
|
addCoordinatorFee: ->
|
||||||
|
this.order_cycle.coordinator_fees.push({})
|
||||||
|
|
||||||
|
removeCoordinatorFee: (index) ->
|
||||||
|
this.order_cycle.coordinator_fees.splice(index, 1)
|
||||||
|
|
||||||
|
addExchangeFee: (exchange) ->
|
||||||
|
exchange.enterprise_fees.push({})
|
||||||
|
|
||||||
|
removeExchangeFee: (exchange, index) ->
|
||||||
|
exchange.enterprise_fees.splice(index, 1)
|
||||||
|
|
||||||
|
productSuppliedToOrderCycle: (product) ->
|
||||||
|
product_variant_ids = (variant.id for variant in product.variants)
|
||||||
|
variant_ids = [product.master_id].concat(product_variant_ids)
|
||||||
|
incomingExchangesVariants = this.incomingExchangesVariants()
|
||||||
|
|
||||||
|
# TODO: This is an O(n^2) implementation of set intersection and thus is slooow.
|
||||||
|
# Use a better algorithm if needed.
|
||||||
|
# Also, incomingExchangesVariants is called every time, when it only needs to be
|
||||||
|
# called once per change to incoming variants. Some sort of caching?
|
||||||
|
ids = (variant_id for variant_id in variant_ids when incomingExchangesVariants.indexOf(variant_id) != -1)
|
||||||
|
ids.length > 0
|
||||||
|
|
||||||
|
variantSuppliedToOrderCycle: (variant) ->
|
||||||
|
this.incomingExchangesVariants().indexOf(variant.id) != -1
|
||||||
|
|
||||||
|
incomingExchangesVariants: ->
|
||||||
|
variant_ids = []
|
||||||
|
|
||||||
|
for exchange in this.order_cycle.incoming_exchanges
|
||||||
|
variant_ids.push(parseInt(id)) for id, active of exchange.variants when active
|
||||||
|
variant_ids
|
||||||
|
|
||||||
|
participatingEnterpriseIds: ->
|
||||||
|
suppliers = (exchange.enterprise_id for exchange in this.order_cycle.incoming_exchanges)
|
||||||
|
distributors = (exchange.enterprise_id for exchange in this.order_cycle.outgoing_exchanges)
|
||||||
|
jQuery.unique(suppliers.concat(distributors)).sort()
|
||||||
|
|
||||||
|
removeDistributionOfVariant: (variant_id) ->
|
||||||
|
for exchange in this.order_cycle.outgoing_exchanges
|
||||||
|
exchange.variants[variant_id] = false
|
||||||
|
|
||||||
|
load: (order_cycle_id, callback=null) ->
|
||||||
|
service = this
|
||||||
|
OrderCycle.get {order_cycle_id: order_cycle_id}, (oc) ->
|
||||||
|
angular.extend(service.order_cycle, oc)
|
||||||
|
service.order_cycle.incoming_exchanges = []
|
||||||
|
service.order_cycle.outgoing_exchanges = []
|
||||||
|
for exchange in service.order_cycle.exchanges
|
||||||
|
if exchange.incoming
|
||||||
|
angular.extend(exchange, {enterprise_id: exchange.sender_id, active: true})
|
||||||
|
delete(exchange.receiver_id)
|
||||||
|
service.order_cycle.incoming_exchanges.push(exchange)
|
||||||
|
|
||||||
|
else
|
||||||
|
angular.extend(exchange, {enterprise_id: exchange.receiver_id, active: true})
|
||||||
|
delete(exchange.sender_id)
|
||||||
|
service.order_cycle.outgoing_exchanges.push(exchange)
|
||||||
|
|
||||||
|
delete(service.order_cycle.exchanges)
|
||||||
|
service.loaded = true
|
||||||
|
|
||||||
|
(callback || angular.noop)(service.order_cycle)
|
||||||
|
|
||||||
|
this.order_cycle
|
||||||
|
|
||||||
|
create: ->
|
||||||
|
oc = new OrderCycle({order_cycle: this.dataForSubmit()})
|
||||||
|
oc.$create (data) ->
|
||||||
|
if data['success']
|
||||||
|
$window.location = '/admin/order_cycles'
|
||||||
|
else
|
||||||
|
console.log('Failed to create order cycle')
|
||||||
|
|
||||||
|
update: ->
|
||||||
|
oc = new OrderCycle({order_cycle: this.dataForSubmit()})
|
||||||
|
oc.$update {order_cycle_id: this.order_cycle.id}, (data) ->
|
||||||
|
if data['success']
|
||||||
|
$window.location = '/admin/order_cycles'
|
||||||
|
else
|
||||||
|
console.log('Failed to update order cycle')
|
||||||
|
|
||||||
|
dataForSubmit: ->
|
||||||
|
data = this.deepCopy()
|
||||||
|
data = this.removeInactiveExchanges(data)
|
||||||
|
data = this.translateCoordinatorFees(data)
|
||||||
|
data = this.translateExchangeFees(data)
|
||||||
|
data
|
||||||
|
|
||||||
|
deepCopy: ->
|
||||||
|
data = angular.extend({}, this.order_cycle)
|
||||||
|
|
||||||
|
# Copy exchanges
|
||||||
|
data.incoming_exchanges = (angular.extend {}, exchange for exchange in this.order_cycle.incoming_exchanges) if this.order_cycle.incoming_exchanges?
|
||||||
|
data.outgoing_exchanges = (angular.extend {}, exchange for exchange in this.order_cycle.outgoing_exchanges) if this.order_cycle.outgoing_exchanges?
|
||||||
|
|
||||||
|
# Copy exchange fees
|
||||||
|
all_exchanges = (data.incoming_exchanges || []) + (data.outgoing_exchanges || [])
|
||||||
|
for exchange in all_exchanges
|
||||||
|
if exchange.enterprise_fees?
|
||||||
|
exchange.enterprise_fees = (angular.extend {}, fee for fee in exchange.enterprise_fees)
|
||||||
|
|
||||||
|
data
|
||||||
|
|
||||||
|
removeInactiveExchanges: (order_cycle) ->
|
||||||
|
order_cycle.incoming_exchanges =
|
||||||
|
(exchange for exchange in order_cycle.incoming_exchanges when exchange.active)
|
||||||
|
order_cycle.outgoing_exchanges =
|
||||||
|
(exchange for exchange in order_cycle.outgoing_exchanges when exchange.active)
|
||||||
|
order_cycle
|
||||||
|
|
||||||
|
translateCoordinatorFees: (order_cycle) ->
|
||||||
|
order_cycle.coordinator_fee_ids = (fee.id for fee in order_cycle.coordinator_fees)
|
||||||
|
delete order_cycle.coordinator_fees
|
||||||
|
order_cycle
|
||||||
|
|
||||||
|
translateExchangeFees: (order_cycle) ->
|
||||||
|
for exchange in order_cycle.incoming_exchanges
|
||||||
|
exchange.enterprise_fee_ids = (fee.id for fee in exchange.enterprise_fees)
|
||||||
|
delete exchange.enterprise_fees
|
||||||
|
for exchange in order_cycle.outgoing_exchanges
|
||||||
|
exchange.enterprise_fee_ids = (fee.id for fee in exchange.enterprise_fees)
|
||||||
|
delete exchange.enterprise_fees
|
||||||
|
order_cycle
|
||||||
|
|
||||||
|
# In the simple UI, we don't list outgoing products. Instead, all products are considered
|
||||||
|
# part of both incoming and outgoing enterprises. This method mirrors the former to the
|
||||||
|
# latter **for order cycles with a single incoming and outgoing exchange only**.
|
||||||
|
mirrorIncomingToOutgoingProducts: ->
|
||||||
|
incoming = this.order_cycle.incoming_exchanges[0]
|
||||||
|
outgoing = this.order_cycle.outgoing_exchanges[0]
|
||||||
|
|
||||||
|
for id, active of incoming.variants
|
||||||
|
outgoing.variants[id] = active
|
||||||
|
})
|
||||||
@@ -62,6 +62,10 @@ module OrderCyclesHelper
|
|||||||
OrderCycle.active.with_distributor(@distributor).present?
|
OrderCycle.active.with_distributor(@distributor).present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def order_cycles_simple_view
|
||||||
|
@order_cycles_simple_view ||= !OpenFoodNetwork::Permissions.new(spree_current_user).can_manage_complex_order_cycles?
|
||||||
|
end
|
||||||
|
|
||||||
def order_cycles_enabled?
|
def order_cycles_enabled?
|
||||||
OpenFoodNetwork::FeatureToggle.enabled? :order_cycles
|
OpenFoodNetwork::FeatureToggle.enabled? :order_cycles
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,14 +1,4 @@
|
|||||||
= f.label :name
|
= render 'name_and_timing_form', f: f
|
||||||
= f.text_field :name, 'ng-model' => 'order_cycle.name', 'required' => true
|
|
||||||
%br/
|
|
||||||
|
|
||||||
.date-field
|
|
||||||
= f.label :orders_open_at, 'Orders open'
|
|
||||||
= f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at'
|
|
||||||
.date-field
|
|
||||||
= f.label :orders_close_at, 'Orders close'
|
|
||||||
= f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at'
|
|
||||||
%br/
|
|
||||||
|
|
||||||
|
|
||||||
%h2 Incoming
|
%h2 Incoming
|
||||||
|
|||||||
15
app/views/admin/order_cycles/_name_and_timing_form.html.haml
Normal file
15
app/views/admin/order_cycles/_name_and_timing_form.html.haml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
.row
|
||||||
|
.alpha.two.columns
|
||||||
|
= f.label :name
|
||||||
|
.fourteen.columns.omega
|
||||||
|
= f.text_field :name, 'ng-model' => 'order_cycle.name', 'required' => true
|
||||||
|
|
||||||
|
.row
|
||||||
|
.alpha.two.columns
|
||||||
|
= f.label :orders_open_at, 'Orders open'
|
||||||
|
.six.columns
|
||||||
|
= f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at'
|
||||||
|
.two.columns
|
||||||
|
= f.label :orders_close_at, 'Orders close'
|
||||||
|
.six.columns.omega
|
||||||
|
= f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at'
|
||||||
@@ -4,15 +4,17 @@
|
|||||||
%td= link_to order_cycle.name, main_app.edit_admin_order_cycle_path(order_cycle)
|
%td= link_to order_cycle.name, main_app.edit_admin_order_cycle_path(order_cycle)
|
||||||
%td= order_cycle_form.text_field :orders_open_at, :class => 'datetimepicker', :value => order_cycle.orders_open_at
|
%td= order_cycle_form.text_field :orders_open_at, :class => 'datetimepicker', :value => order_cycle.orders_open_at
|
||||||
%td= order_cycle_form.text_field :orders_close_at, :class => 'datetimepicker', :value => order_cycle.orders_close_at
|
%td= order_cycle_form.text_field :orders_close_at, :class => 'datetimepicker', :value => order_cycle.orders_close_at
|
||||||
%td.suppliers
|
|
||||||
- order_cycle.suppliers.merge(OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises).each do |s|
|
- unless order_cycles_simple_view
|
||||||
= s.name
|
%td.suppliers
|
||||||
%br/
|
- order_cycle.suppliers.merge(OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises).each do |s|
|
||||||
%td= order_cycle.coordinator.name
|
= s.name
|
||||||
%td.distributors
|
%br/
|
||||||
- order_cycle.distributors.merge(OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises).each do |d|
|
%td= order_cycle.coordinator.name
|
||||||
= d.name
|
%td.distributors
|
||||||
%br/
|
- order_cycle.distributors.merge(OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises).each do |d|
|
||||||
|
= d.name
|
||||||
|
%br/
|
||||||
|
|
||||||
%td.products
|
%td.products
|
||||||
- variant_images = capture do
|
- variant_images = capture do
|
||||||
|
|||||||
26
app/views/admin/order_cycles/_simple_form.html.haml
Normal file
26
app/views/admin/order_cycles/_simple_form.html.haml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
= render 'name_and_timing_form', f: f
|
||||||
|
|
||||||
|
.row
|
||||||
|
.alpha.two.columns
|
||||||
|
= label_tag 'Pickup time'
|
||||||
|
.six.columns
|
||||||
|
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'placeholder' => 'Ready for (ie. Date / Time)', 'ng-model' => 'outgoing_exchange.pickup_time'
|
||||||
|
.two.columns
|
||||||
|
= label_tag 'Pickup instructions'
|
||||||
|
.six.columns.omega
|
||||||
|
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_instructions', 'placeholder' => 'Pick-up instructions', 'ng-model' => 'outgoing_exchange.pickup_instructions'
|
||||||
|
|
||||||
|
%table.exchanges
|
||||||
|
%tbody{ng: {repeat: "exchange in order_cycle.incoming_exchanges"}}
|
||||||
|
%tr.products
|
||||||
|
= render 'exchange_supplied_products_form'
|
||||||
|
|
||||||
|
= render 'coordinator_fees', f: f
|
||||||
|
|
||||||
|
.actions
|
||||||
|
= f.submit @order_cycle.new_record? ? 'Create' : 'Update', 'ng-disabled' => '!loaded()'
|
||||||
|
%span{'ng-show' => 'loaded()'}
|
||||||
|
or
|
||||||
|
= link_to 'Cancel', main_app.admin_order_cycles_path
|
||||||
|
%span{'ng-hide' => 'loaded()'} Loading...
|
||||||
|
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
%h1 Edit Order Cycle
|
%h1 Edit Order Cycle
|
||||||
|
|
||||||
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'order_cycle', 'ng-controller' => 'AdminEditOrderCycleCtrl', 'ng-submit' => 'submit()'} do |f|
|
- ng_controller = order_cycles_simple_view ? 'AdminSimpleEditOrderCycleCtrl' : 'AdminEditOrderCycleCtrl'
|
||||||
= render 'form', :f => f
|
|
||||||
|
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.order_cycles', 'ng-controller' => ng_controller, 'ng-submit' => 'submit()'} do |f|
|
||||||
|
- if order_cycles_simple_view
|
||||||
|
= render 'simple_form', f: f
|
||||||
|
- else
|
||||||
|
= render 'form', f: f
|
||||||
|
|||||||
@@ -11,9 +11,10 @@
|
|||||||
%col
|
%col
|
||||||
%col{'style' => 'width: 20%;'}
|
%col{'style' => 'width: 20%;'}
|
||||||
%col{'style' => 'width: 20%;'}
|
%col{'style' => 'width: 20%;'}
|
||||||
%col
|
- unless order_cycles_simple_view
|
||||||
%col
|
%col
|
||||||
%col
|
%col
|
||||||
|
%col
|
||||||
%col
|
%col
|
||||||
%col
|
%col
|
||||||
%col
|
%col
|
||||||
@@ -23,9 +24,10 @@
|
|||||||
%th Name
|
%th Name
|
||||||
%th Open
|
%th Open
|
||||||
%th Close
|
%th Close
|
||||||
%th Suppliers
|
- unless order_cycles_simple_view
|
||||||
%th Coordinator
|
%th Suppliers
|
||||||
%th Distributors
|
%th Coordinator
|
||||||
|
%th Distributors
|
||||||
%th Products
|
%th Products
|
||||||
%th.actions
|
%th.actions
|
||||||
%th.actions
|
%th.actions
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
%h1 New Order Cycle
|
%h1 New Order Cycle
|
||||||
|
|
||||||
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'order_cycle', 'ng-controller' => 'AdminCreateOrderCycleCtrl', 'ng-submit' => 'submit()'} do |f|
|
- ng_controller = order_cycles_simple_view ? 'AdminSimpleCreateOrderCycleCtrl' : 'AdminCreateOrderCycleCtrl'
|
||||||
= render 'form', :f => f
|
|
||||||
|
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.order_cycles', 'ng-controller' => ng_controller, 'ng-submit' => 'submit()'} do |f|
|
||||||
|
- if order_cycles_simple_view
|
||||||
|
= render 'simple_form', f: f
|
||||||
|
- else
|
||||||
|
= render 'form', f: f
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ module OpenFoodNetwork
|
|||||||
@user = user
|
@user = user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_manage_complex_order_cycles?
|
||||||
|
managed_and_related_enterprises_with(:add_to_order_cycle).any? do |e|
|
||||||
|
e.sells == 'any'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Find enterprises that an admin is allowed to add to an order cycle
|
# Find enterprises that an admin is allowed to add to an order cycle
|
||||||
def order_cycle_enterprises
|
def order_cycle_enterprises
|
||||||
managed_and_related_enterprises_with :add_to_order_cycle
|
managed_and_related_enterprises_with :add_to_order_cycle
|
||||||
|
|||||||
@@ -131,16 +131,16 @@ feature %q{
|
|||||||
page.should have_selector 'td.distributors', text: 'My distributor'
|
page.should have_selector 'td.distributors', text: 'My distributor'
|
||||||
|
|
||||||
# And it should have some fees
|
# And it should have some fees
|
||||||
OrderCycle.last.exchanges.incoming.first.enterprise_fees.should == [supplier_fee]
|
oc = OrderCycle.last
|
||||||
OrderCycle.last.coordinator_fees.should == [coordinator_fee]
|
oc.exchanges.incoming.first.enterprise_fees.should == [supplier_fee]
|
||||||
OrderCycle.last.exchanges.outgoing.first.enterprise_fees.should == [distributor_fee]
|
oc.coordinator_fees.should == [coordinator_fee]
|
||||||
|
oc.exchanges.outgoing.first.enterprise_fees.should == [distributor_fee]
|
||||||
|
|
||||||
# And it should have some variants selected
|
# And it should have some variants selected
|
||||||
OrderCycle.last.exchanges.first.variants.count.should == 2
|
oc.exchanges.first.variants.count.should == 2
|
||||||
OrderCycle.last.exchanges.last.variants.count.should == 2
|
oc.exchanges.last.variants.count.should == 2
|
||||||
|
|
||||||
# And my pickup time and instructions should have been saved
|
# And my pickup time and instructions should have been saved
|
||||||
oc = OrderCycle.last
|
|
||||||
exchange = oc.exchanges.where(:sender_id => oc.coordinator_id).first
|
exchange = oc.exchanges.where(:sender_id => oc.coordinator_id).first
|
||||||
exchange.pickup_time.should == 'pickup time'
|
exchange.pickup_time.should == 'pickup time'
|
||||||
exchange.pickup_instructions.should == 'pickup instructions'
|
exchange.pickup_instructions.should == 'pickup instructions'
|
||||||
@@ -576,7 +576,165 @@ feature %q{
|
|||||||
occ = OrderCycle.last
|
occ = OrderCycle.last
|
||||||
occ.name.should == "COPY OF #{oc.name}"
|
occ.name.should == "COPY OF #{oc.name}"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
describe "simplified interface for enterprise users selling only their own produce" do
|
||||||
|
let(:user) { create_enterprise_user }
|
||||||
|
let(:enterprise) { create(:enterprise, is_primary_producer: true, sells: 'own') }
|
||||||
|
let!(:p1) { create(:simple_product, supplier: enterprise) }
|
||||||
|
let!(:p2) { create(:simple_product, supplier: enterprise) }
|
||||||
|
let!(:p3) { create(:simple_product, supplier: enterprise) }
|
||||||
|
let!(:v) { create(:variant, product: p3) }
|
||||||
|
let!(:fee) { create(:enterprise_fee, enterprise: enterprise, name: 'Coord fee') }
|
||||||
|
|
||||||
|
use_short_wait
|
||||||
|
|
||||||
|
before do
|
||||||
|
user.enterprise_roles.create! enterprise: enterprise
|
||||||
|
login_to_admin_as user
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows me an index of order cycles without enterprise columns" do
|
||||||
|
create(:order_cycle, coordinator: enterprise)
|
||||||
|
visit admin_order_cycles_path
|
||||||
|
page.should_not have_selector 'th', text: 'SUPPLIERS'
|
||||||
|
page.should_not have_selector 'th', text: 'COORDINATOR'
|
||||||
|
page.should_not have_selector 'th', text: 'DISTRIBUTORS'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates order cycles", js: true do
|
||||||
|
# When I go to the new order cycle page
|
||||||
|
visit admin_order_cycles_path
|
||||||
|
click_link 'New Order Cycle'
|
||||||
|
|
||||||
|
# And I fill in the basic fields
|
||||||
|
fill_in 'order_cycle_name', with: 'Plums & Avos'
|
||||||
|
fill_in 'order_cycle_orders_open_at', with: '2014-10-17 06:00:00'
|
||||||
|
fill_in 'order_cycle_orders_close_at', with: '2014-10-24 17:00:00'
|
||||||
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time'
|
||||||
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions'
|
||||||
|
|
||||||
|
# Then my products / variants should already be selected
|
||||||
|
page.should have_checked_field "order_cycle_incoming_exchange_0_variants_#{p1.master.id}"
|
||||||
|
page.should have_checked_field "order_cycle_incoming_exchange_0_variants_#{p2.master.id}"
|
||||||
|
page.should have_checked_field "order_cycle_incoming_exchange_0_variants_#{v.id}"
|
||||||
|
|
||||||
|
# When I unselect a product
|
||||||
|
uncheck "order_cycle_incoming_exchange_0_variants_#{p2.master.id}"
|
||||||
|
|
||||||
|
# And I add a fee and save
|
||||||
|
click_button 'Add coordinator fee'
|
||||||
|
click_button 'Add coordinator fee'
|
||||||
|
click_link 'order_cycle_coordinator_fee_1_remove'
|
||||||
|
page.should have_select 'order_cycle_coordinator_fee_0_id'
|
||||||
|
page.should_not have_select 'order_cycle_coordinator_fee_1_id'
|
||||||
|
|
||||||
|
select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id'
|
||||||
|
click_button 'Create'
|
||||||
|
|
||||||
|
# Then my order cycle should have been created
|
||||||
|
page.should have_content 'Your order cycle has been created.'
|
||||||
|
page.should have_selector 'a', text: 'Plums & Avos'
|
||||||
|
page.should have_selector "input[value='2014-10-17 06:00:00 +1100']"
|
||||||
|
page.should have_selector "input[value='2014-10-24 17:00:00 +1100']"
|
||||||
|
|
||||||
|
# And it should have some variants selected
|
||||||
|
oc = OrderCycle.last
|
||||||
|
oc.exchanges.incoming.first.variants.count.should == 2
|
||||||
|
oc.exchanges.outgoing.first.variants.count.should == 2
|
||||||
|
|
||||||
|
# And it should have the fee
|
||||||
|
oc.coordinator_fees.should == [fee]
|
||||||
|
|
||||||
|
# And my pickup time and instructions should have been saved
|
||||||
|
ex = oc.exchanges.outgoing.first
|
||||||
|
ex.pickup_time.should == 'pickup time'
|
||||||
|
ex.pickup_instructions.should == 'pickup instructions'
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "editing an order cycle" do
|
||||||
|
# Given an order cycle with pickup time and instructions
|
||||||
|
fee = create(:enterprise_fee, name: 'my fee', enterprise: enterprise)
|
||||||
|
oc = create(:simple_order_cycle, suppliers: [enterprise], coordinator: enterprise, distributors: [enterprise], variants: [p1.master], coordinator_fees: [fee])
|
||||||
|
ex = oc.exchanges.outgoing.first
|
||||||
|
ex.update_attributes! pickup_time: 'pickup time', pickup_instructions: 'pickup instructions'
|
||||||
|
|
||||||
|
# When I edit it
|
||||||
|
login_to_admin_section
|
||||||
|
click_link 'Order Cycles'
|
||||||
|
click_link oc.name
|
||||||
|
wait_until { page.find('#order_cycle_name').value.present? }
|
||||||
|
|
||||||
|
# Then I should see the basic settings
|
||||||
|
page.should have_field 'order_cycle_name', with: oc.name
|
||||||
|
page.should have_field 'order_cycle_orders_open_at', with: oc.orders_open_at.to_s
|
||||||
|
page.should have_field 'order_cycle_orders_close_at', with: oc.orders_close_at.to_s
|
||||||
|
page.should have_field 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time'
|
||||||
|
page.should have_field 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions'
|
||||||
|
|
||||||
|
# And I should see the products
|
||||||
|
page.should have_checked_field "order_cycle_incoming_exchange_0_variants_#{p1.master.id}"
|
||||||
|
page.should have_unchecked_field "order_cycle_incoming_exchange_0_variants_#{p2.master.id}"
|
||||||
|
page.should have_unchecked_field "order_cycle_incoming_exchange_0_variants_#{v.id}"
|
||||||
|
|
||||||
|
# And I should see the coordinator fees
|
||||||
|
page.should have_select 'order_cycle_coordinator_fee_0_id', selected: 'my fee'
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "updating an order cycle" do
|
||||||
|
# Given an order cycle with pickup time and instructions
|
||||||
|
fee1 = create(:enterprise_fee, name: 'my fee', enterprise: enterprise)
|
||||||
|
fee2 = create(:enterprise_fee, name: 'that fee', enterprise: enterprise)
|
||||||
|
oc = create(:simple_order_cycle, suppliers: [enterprise], coordinator: enterprise, distributors: [enterprise], variants: [p1.master], coordinator_fees: [fee1])
|
||||||
|
ex = oc.exchanges.outgoing.first
|
||||||
|
ex.update_attributes! pickup_time: 'pickup time', pickup_instructions: 'pickup instructions'
|
||||||
|
|
||||||
|
# When I edit it
|
||||||
|
login_to_admin_section
|
||||||
|
visit edit_admin_order_cycle_path oc
|
||||||
|
wait_until { page.find('#order_cycle_name').value.present? }
|
||||||
|
|
||||||
|
# And I fill in the basic fields
|
||||||
|
fill_in 'order_cycle_name', with: 'Plums & Avos'
|
||||||
|
fill_in 'order_cycle_orders_open_at', with: '2014-10-17 06:00:00'
|
||||||
|
fill_in 'order_cycle_orders_close_at', with: '2014-10-24 17:00:00'
|
||||||
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'xy'
|
||||||
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'zzy'
|
||||||
|
|
||||||
|
# And I make some product selections
|
||||||
|
uncheck "order_cycle_incoming_exchange_0_variants_#{p1.master.id}"
|
||||||
|
check "order_cycle_incoming_exchange_0_variants_#{p2.master.id}"
|
||||||
|
check "order_cycle_incoming_exchange_0_variants_#{v.id}"
|
||||||
|
uncheck "order_cycle_incoming_exchange_0_variants_#{v.id}"
|
||||||
|
|
||||||
|
# And I select some fees and update
|
||||||
|
click_link 'order_cycle_coordinator_fee_0_remove'
|
||||||
|
page.should_not have_select 'order_cycle_coordinator_fee_0_id'
|
||||||
|
click_button 'Add coordinator fee'
|
||||||
|
select 'that fee', from: 'order_cycle_coordinator_fee_0_id'
|
||||||
|
|
||||||
|
click_button 'Update'
|
||||||
|
|
||||||
|
# Then my order cycle should have been updated
|
||||||
|
page.should have_content 'Your order cycle has been updated.'
|
||||||
|
page.should have_selector 'a', text: 'Plums & Avos'
|
||||||
|
page.should have_selector "input[value='2014-10-17 06:00:00 +1100']"
|
||||||
|
page.should have_selector "input[value='2014-10-24 17:00:00 +1100']"
|
||||||
|
|
||||||
|
# And it should have a variant selected
|
||||||
|
oc = OrderCycle.last
|
||||||
|
oc.exchanges.incoming.first.variants.should == [p2.master]
|
||||||
|
oc.exchanges.outgoing.first.variants.should == [p2.master]
|
||||||
|
|
||||||
|
# And it should have the fee
|
||||||
|
oc.coordinator_fees.should == [fee2]
|
||||||
|
|
||||||
|
# And my pickup time and instructions should have been saved
|
||||||
|
ex = oc.exchanges.outgoing.first
|
||||||
|
ex.pickup_time.should == 'xy'
|
||||||
|
ex.pickup_instructions.should == 'zzy'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
describe "AdminSimpleCreateOrderCycleCtrl", ->
|
||||||
|
ctrl = null
|
||||||
|
scope = {}
|
||||||
|
OrderCycle = {}
|
||||||
|
Enterprise = {}
|
||||||
|
EnterpriseFee = {}
|
||||||
|
incoming_exchange = {}
|
||||||
|
outgoing_exchange = {}
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
scope = {}
|
||||||
|
OrderCycle =
|
||||||
|
order_cycle:
|
||||||
|
incoming_exchanges: [incoming_exchange]
|
||||||
|
outgoing_exchanges: [outgoing_exchange]
|
||||||
|
addSupplier: jasmine.createSpy()
|
||||||
|
addDistributor: jasmine.createSpy()
|
||||||
|
setExchangeVariants: jasmine.createSpy()
|
||||||
|
Enterprise =
|
||||||
|
index: jasmine.createSpy()
|
||||||
|
suppliedVariants: jasmine.createSpy().andReturn('supplied variants')
|
||||||
|
EnterpriseFee =
|
||||||
|
index: jasmine.createSpy()
|
||||||
|
|
||||||
|
module('admin.order_cycles')
|
||||||
|
inject ($controller) ->
|
||||||
|
ctrl = $controller 'AdminSimpleCreateOrderCycleCtrl', {$scope: scope, OrderCycle: OrderCycle, Enterprise: Enterprise, EnterpriseFee: EnterpriseFee}
|
||||||
|
|
||||||
|
describe "initialisation", ->
|
||||||
|
enterprise = {id: 123}
|
||||||
|
enterprises = {123: enterprise}
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
scope.init(enterprises)
|
||||||
|
|
||||||
|
it "sets up an incoming and outgoing exchange", ->
|
||||||
|
expect(OrderCycle.addSupplier).toHaveBeenCalledWith(enterprise.id)
|
||||||
|
expect(OrderCycle.addDistributor).toHaveBeenCalledWith(enterprise.id)
|
||||||
|
expect(scope.outgoing_exchange).toEqual outgoing_exchange
|
||||||
|
|
||||||
|
it "selects all variants", ->
|
||||||
|
expect(Enterprise.suppliedVariants).
|
||||||
|
toHaveBeenCalledWith(enterprise.id)
|
||||||
|
|
||||||
|
expect(OrderCycle.setExchangeVariants).
|
||||||
|
toHaveBeenCalledWith(incoming_exchange, 'supplied variants', true)
|
||||||
|
|
||||||
|
it "sets the coordinator", ->
|
||||||
|
expect(OrderCycle.order_cycle.coordinator_id).toEqual enterprise.id
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
describe "AdminSimpleEditOrderCycleCtrl", ->
|
||||||
|
ctrl = null
|
||||||
|
scope = {}
|
||||||
|
location = {}
|
||||||
|
OrderCycle = {}
|
||||||
|
Enterprise = {}
|
||||||
|
EnterpriseFee = {}
|
||||||
|
incoming_exchange = {}
|
||||||
|
outgoing_exchange = {}
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
scope = {}
|
||||||
|
location =
|
||||||
|
absUrl: ->
|
||||||
|
'example.com/admin/order_cycles/27/edit'
|
||||||
|
OrderCycle =
|
||||||
|
order_cycle:
|
||||||
|
incoming_exchanges: [incoming_exchange]
|
||||||
|
outgoing_exchanges: [outgoing_exchange]
|
||||||
|
load: jasmine.createSpy()
|
||||||
|
Enterprise =
|
||||||
|
index: jasmine.createSpy()
|
||||||
|
EnterpriseFee =
|
||||||
|
index: jasmine.createSpy()
|
||||||
|
|
||||||
|
module('admin.order_cycles')
|
||||||
|
inject ($controller) ->
|
||||||
|
ctrl = $controller 'AdminSimpleEditOrderCycleCtrl', {$scope: scope, $location: location, OrderCycle: OrderCycle, Enterprise: Enterprise, EnterpriseFee: EnterpriseFee}
|
||||||
|
|
||||||
|
describe "initialisation", ->
|
||||||
|
enterprise = {id: 123}
|
||||||
|
enterprises = {123: enterprise}
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
scope.init(enterprises)
|
||||||
|
|
||||||
|
it "sets the outgoing exchange", ->
|
||||||
|
expect(scope.outgoing_exchange).toEqual outgoing_exchange
|
||||||
@@ -38,7 +38,7 @@ describe 'OrderCycle controllers', ->
|
|||||||
index: jasmine.createSpy('index').andReturn('enterprise fees list')
|
index: jasmine.createSpy('index').andReturn('enterprise fees list')
|
||||||
forEnterprise: jasmine.createSpy('forEnterprise').andReturn('enterprise fees for enterprise')
|
forEnterprise: jasmine.createSpy('forEnterprise').andReturn('enterprise fees for enterprise')
|
||||||
|
|
||||||
module('order_cycle')
|
module('admin.order_cycles')
|
||||||
inject ($controller) ->
|
inject ($controller) ->
|
||||||
ctrl = $controller 'AdminCreateOrderCycleCtrl', {$scope: scope, OrderCycle: OrderCycle, Enterprise: Enterprise, EnterpriseFee: EnterpriseFee}
|
ctrl = $controller 'AdminCreateOrderCycleCtrl', {$scope: scope, OrderCycle: OrderCycle, Enterprise: Enterprise, EnterpriseFee: EnterpriseFee}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ describe 'OrderCycle controllers', ->
|
|||||||
index: jasmine.createSpy('index').andReturn('enterprise fees list')
|
index: jasmine.createSpy('index').andReturn('enterprise fees list')
|
||||||
forEnterprise: jasmine.createSpy('forEnterprise').andReturn('enterprise fees for enterprise')
|
forEnterprise: jasmine.createSpy('forEnterprise').andReturn('enterprise fees for enterprise')
|
||||||
|
|
||||||
module('order_cycle')
|
module('admin.order_cycles')
|
||||||
inject ($controller) ->
|
inject ($controller) ->
|
||||||
ctrl = $controller 'AdminEditOrderCycleCtrl', {$scope: scope, $location: location, OrderCycle: OrderCycle, Enterprise: Enterprise, EnterpriseFee: EnterpriseFee}
|
ctrl = $controller 'AdminEditOrderCycleCtrl', {$scope: scope, $location: location, OrderCycle: OrderCycle, Enterprise: Enterprise, EnterpriseFee: EnterpriseFee}
|
||||||
|
|
||||||
@@ -323,7 +323,7 @@ describe 'OrderCycle services', ->
|
|||||||
Enterprise = null
|
Enterprise = null
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
module 'order_cycle'
|
module 'admin.order_cycles'
|
||||||
inject ($injector, _$httpBackend_)->
|
inject ($injector, _$httpBackend_)->
|
||||||
Enterprise = $injector.get('Enterprise')
|
Enterprise = $injector.get('Enterprise')
|
||||||
$httpBackend = _$httpBackend_
|
$httpBackend = _$httpBackend_
|
||||||
@@ -389,7 +389,7 @@ describe 'OrderCycle services', ->
|
|||||||
EnterpriseFee = null
|
EnterpriseFee = null
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
module 'order_cycle'
|
module 'admin.order_cycles'
|
||||||
inject ($injector, _$httpBackend_)->
|
inject ($injector, _$httpBackend_)->
|
||||||
EnterpriseFee = $injector.get('EnterpriseFee')
|
EnterpriseFee = $injector.get('EnterpriseFee')
|
||||||
$httpBackend = _$httpBackend_
|
$httpBackend = _$httpBackend_
|
||||||
@@ -431,7 +431,7 @@ describe 'OrderCycle services', ->
|
|||||||
beforeEach ->
|
beforeEach ->
|
||||||
$window = {navigator: {userAgent: 'foo'}}
|
$window = {navigator: {userAgent: 'foo'}}
|
||||||
|
|
||||||
module 'order_cycle', ($provide)->
|
module 'admin.order_cycles', ($provide)->
|
||||||
$provide.value('$window', $window)
|
$provide.value('$window', $window)
|
||||||
null
|
null
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user