mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-06 02:51:34 +00:00
Merge branch 'master' into 3-0-stable-apr3
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, SortOptions, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, VariantUnitManager, RequestMonitor) ->
|
||||
$scope.initialized = false
|
||||
$scope.RequestMonitor = RequestMonitor
|
||||
$scope.filteredLineItems = []
|
||||
$scope.line_items = LineItems.all
|
||||
$scope.confirmDelete = true
|
||||
$scope.startDate = moment().startOf('day').subtract(7, 'days').format('YYYY-MM-DD')
|
||||
$scope.endDate = moment().startOf('day').format('YYYY-MM-DD')
|
||||
@@ -15,50 +15,77 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
$scope.confirmRefresh = ->
|
||||
LineItems.allSaved() || confirm(t("unsaved_changes_warning"))
|
||||
|
||||
$scope.resetFilters = ->
|
||||
$scope.distributorFilter = ''
|
||||
$scope.supplierFilter = ''
|
||||
$scope.orderCycleFilter = ''
|
||||
$scope.quickSearch = ''
|
||||
|
||||
$scope.resetSelectFilters = ->
|
||||
$scope.distributorFilter = 0
|
||||
$scope.supplierFilter = 0
|
||||
$scope.orderCycleFilter = 0
|
||||
$scope.quickSearch = ""
|
||||
$scope.resetFilters()
|
||||
$scope.refreshData()
|
||||
|
||||
$scope.refreshData = ->
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == 0
|
||||
$scope.startDate = moment(OrderCycles.byID[$scope.orderCycleFilter].orders_open_at).format('YYYY-MM-DD')
|
||||
$scope.endDate = moment(OrderCycles.byID[$scope.orderCycleFilter].orders_close_at).startOf('day').format('YYYY-MM-DD')
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == ''
|
||||
$scope.setOrderCycleDateRange()
|
||||
|
||||
formatted_start_date = moment($scope.startDate).format()
|
||||
formatted_end_date = moment($scope.endDate).add(1,'day').format()
|
||||
$scope.formattedStartDate = moment($scope.startDate).format()
|
||||
$scope.formattedEndDate = moment($scope.endDate).add(1,'day').format()
|
||||
|
||||
return unless moment($scope.formattedStartDate).isValid() and moment($scope.formattedEndDate).isValid()
|
||||
|
||||
$scope.loadOrders()
|
||||
$scope.loadLineItems()
|
||||
|
||||
unless $scope.initialized
|
||||
$scope.loadAssociatedData()
|
||||
|
||||
$scope.dereferenceLoadedData()
|
||||
|
||||
$scope.setOrderCycleDateRange = ->
|
||||
start_date = OrderCycles.byID[$scope.orderCycleFilter].orders_open_at
|
||||
end_date = OrderCycles.byID[$scope.orderCycleFilter].orders_close_at
|
||||
format = "YYYY-MM-DD HH:mm:ss Z"
|
||||
$scope.startDate = moment(start_date, format).format('YYYY-MM-DD')
|
||||
$scope.endDate = moment(end_date, format).startOf('day').format('YYYY-MM-DD')
|
||||
|
||||
$scope.loadOrders = ->
|
||||
RequestMonitor.load $scope.orders = Orders.index(
|
||||
"q[state_not_eq]": "canceled",
|
||||
"q[completed_at_not_null]": "true",
|
||||
"q[completed_at_gteq]": formatted_start_date,
|
||||
"q[completed_at_lt]": formatted_end_date
|
||||
"q[distributor_id_eq]": $scope.distributorFilter,
|
||||
"q[order_cycle_id_eq]": $scope.orderCycleFilter,
|
||||
"q[completed_at_gteq]": $scope.formattedStartDate,
|
||||
"q[completed_at_lt]": $scope.formattedEndDate
|
||||
)
|
||||
|
||||
RequestMonitor.load $scope.lineItems = LineItems.index(
|
||||
"q[order][state_not_eq]": "canceled",
|
||||
"q[order][completed_at_not_null]": "true",
|
||||
"q[order][completed_at_gteq]": formatted_start_date,
|
||||
"q[order][completed_at_lt]": formatted_end_date
|
||||
$scope.loadLineItems = ->
|
||||
RequestMonitor.load LineItems.index(
|
||||
"q[order_state_not_eq]": "canceled",
|
||||
"q[order_completed_at_not_null]": "true",
|
||||
"q[order_distributor_id_eq]": $scope.distributorFilter,
|
||||
"q[variant_product_supplier_id_eq]": $scope.supplierFilter,
|
||||
"q[order_order_cycle_id_eq]": $scope.orderCycleFilter,
|
||||
"q[order_completed_at_gteq]": $scope.formattedStartDate,
|
||||
"q[order_completed_at_lt]": $scope.formattedEndDate
|
||||
)
|
||||
|
||||
unless $scope.initialized
|
||||
RequestMonitor.load $scope.distributors = Enterprises.index(action: "visible", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
|
||||
RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{moment().subtract(90,'days').format()}")
|
||||
RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
|
||||
$scope.loadAssociatedData = ->
|
||||
RequestMonitor.load $scope.distributors = Enterprises.index(action: "visible", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
|
||||
RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{moment().subtract(90,'days').format()}")
|
||||
RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
|
||||
|
||||
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise, $scope.suppliers.$promise, $scope.lineItems.$promise]).then ->
|
||||
$scope.dereferenceLoadedData = ->
|
||||
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise, $scope.suppliers.$promise, $scope.line_items.$promise]).then ->
|
||||
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.byID
|
||||
Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.byID
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.byID
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.byID
|
||||
Dereferencer.dereferenceAttr $scope.line_items, "supplier", Enterprises.byID
|
||||
Dereferencer.dereferenceAttr $scope.line_items, "order", Orders.byID
|
||||
$scope.bulk_order_form.$setPristine()
|
||||
StatusMessage.clear()
|
||||
|
||||
unless $scope.initialized
|
||||
$scope.initialized = true
|
||||
$timeout ->
|
||||
$scope.resetSelectFilters()
|
||||
|
||||
$scope.$watch 'bulk_order_form.$dirty', (newVal, oldVal) ->
|
||||
if newVal == true
|
||||
@@ -77,13 +104,12 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
|
||||
$scope.deleteLineItem = (lineItem) ->
|
||||
if ($scope.confirmDelete && confirm(t "are_you_sure")) || !$scope.confirmDelete
|
||||
LineItems.delete lineItem, =>
|
||||
$scope.lineItems.splice $scope.lineItems.indexOf(lineItem), 1
|
||||
LineItems.delete lineItem
|
||||
|
||||
$scope.deleteLineItems = (lineItems) ->
|
||||
$scope.deleteLineItems = (lineItemsToDelete) ->
|
||||
existingState = $scope.confirmDelete
|
||||
$scope.confirmDelete = false
|
||||
$scope.deleteLineItem lineItem for lineItem in lineItems when lineItem.checked
|
||||
$scope.deleteLineItem lineItem for lineItem in lineItemsToDelete when lineItem.checked
|
||||
$scope.confirmDelete = existingState
|
||||
|
||||
$scope.allBoxesChecked = ->
|
||||
@@ -154,4 +180,5 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
lineItem.final_weight_volume = LineItems.pristineByID[lineItem.id].final_weight_volume * lineItem.quantity / LineItems.pristineByID[lineItem.id].quantity
|
||||
$scope.weightAdjustedPrice(lineItem)
|
||||
|
||||
$scope.resetFilters()
|
||||
$scope.refreshData()
|
||||
|
||||
@@ -14,9 +14,10 @@ angular.module("admin.payments").factory 'AdminStripeElements', ($rootScope, Sta
|
||||
@stripe.createToken(@card, cardData).then (response) =>
|
||||
if(response.error)
|
||||
StatusMessage.display 'error', response.error.message
|
||||
console.error(JSON.stringify(response.error))
|
||||
else
|
||||
secrets.token = response.token.id
|
||||
secrets.cc_type = @mapCC(response.token.card.brand)
|
||||
secrets.cc_type = @mapTokenApiCardBrand(response.token.card.brand)
|
||||
secrets.card = response.token.card
|
||||
submit()
|
||||
|
||||
@@ -29,15 +30,16 @@ angular.module("admin.payments").factory 'AdminStripeElements', ($rootScope, Sta
|
||||
@stripe.createPaymentMethod({ type: 'card', card: @card }, @card, cardData).then (response) =>
|
||||
if(response.error)
|
||||
StatusMessage.display 'error', response.error.message
|
||||
console.error(JSON.stringify(response.error))
|
||||
else
|
||||
secrets.token = response.paymentMethod.id
|
||||
secrets.cc_type = response.paymentMethod.card.brand
|
||||
secrets.cc_type = @mapPaymentMethodsApiCardBrand(response.paymentMethod.card.brand)
|
||||
secrets.card = response.paymentMethod.card
|
||||
submit()
|
||||
|
||||
# Maps the brand returned by Stripe to that required by activemerchant
|
||||
mapCC: (ccType) ->
|
||||
switch ccType
|
||||
# Maps the brand returned by Stripe's tokenAPI to that required by activemerchant
|
||||
mapTokenApiCardBrand: (cardBrand) ->
|
||||
switch cardBrand
|
||||
when 'MasterCard' then return 'master'
|
||||
when 'Visa' then return 'visa'
|
||||
when 'American Express' then return 'american_express'
|
||||
@@ -45,6 +47,14 @@ angular.module("admin.payments").factory 'AdminStripeElements', ($rootScope, Sta
|
||||
when 'JCB' then return 'jcb'
|
||||
when 'Diners Club' then return 'diners_club'
|
||||
|
||||
# Maps the brand returned by Stripe's paymentMethodsAPI to that required by activemerchant
|
||||
mapPaymentMethodsApiCardBrand: (cardBrand) ->
|
||||
switch cardBrand
|
||||
when 'mastercard' then return 'master'
|
||||
when 'amex' then return 'american_express'
|
||||
when 'diners' then return 'diners_club'
|
||||
else return cardBrand # a few brands are equal, for example, visa
|
||||
|
||||
# It doesn't matter if any of these are nil, all are optional.
|
||||
makeCardData: (secrets) ->
|
||||
{'name': secrets.name,
|
||||
|
||||
@@ -2,7 +2,6 @@ angular.module("admin.resources").factory 'LineItemResource', ($resource) ->
|
||||
$resource('/admin/bulk_line_items/:id.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
'update':
|
||||
method: 'PUT'
|
||||
transformRequest: (data, headersGetter) =>
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
new class LineItems
|
||||
all: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
pagination: {}
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
LineItemResource.index params, (data) =>
|
||||
request = LineItemResource.index params, (data) =>
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
@all.$promise = request.$promise
|
||||
@all
|
||||
|
||||
resetData: ->
|
||||
@all.length = 0
|
||||
@byID = {}
|
||||
@pristineByID = {}
|
||||
|
||||
load: (lineItems) ->
|
||||
load: (data) ->
|
||||
angular.extend(@pagination, data.pagination)
|
||||
@resetData()
|
||||
for lineItem in lineItems
|
||||
for lineItem in data.line_items
|
||||
@all.push lineItem
|
||||
@byID[lineItem.id] = lineItem
|
||||
@pristineByID[lineItem.id] = angular.copy(lineItem)
|
||||
|
||||
@@ -25,8 +32,9 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
|
||||
save: (lineItem) ->
|
||||
deferred = $q.defer()
|
||||
lineItemResource = new LineItemResource(lineItem)
|
||||
lineItem.errors = {}
|
||||
lineItem.$update({id: lineItem.id})
|
||||
lineItemResource.$update({id: lineItem.id})
|
||||
.then( (data) =>
|
||||
@pristineByID[lineItem.id] = angular.copy(lineItem)
|
||||
deferred.resolve(data)
|
||||
@@ -54,8 +62,10 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
|
||||
delete: (lineItem, callback=null) ->
|
||||
deferred = $q.defer()
|
||||
lineItem.$delete({id: lineItem.id})
|
||||
lineItemResource = new LineItemResource(lineItem)
|
||||
lineItemResource.$delete({id: lineItem.id})
|
||||
.then( (data) =>
|
||||
@all.splice(@all.indexOf(lineItem),1)
|
||||
delete @byID[lineItem.id]
|
||||
delete @pristineByID[lineItem.id]
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#= require angular-animate
|
||||
#= require angular-resource
|
||||
#= require lodash.underscore.js
|
||||
# bluebird.js is a dependency of angular-google-maps.js 2.0.0
|
||||
#= require bluebird.js
|
||||
#= require angular-scroll.min.js
|
||||
#= require angular-google-maps.min.js
|
||||
#= require ../shared/mm-foundation-tpls-0.9.0-20180826174721.min.js
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
Darkswarm.controller "PageSelectionCtrl", ($scope, $location) ->
|
||||
$scope.selectedPage = ->
|
||||
# The path looks like `/contact` for the URL `https://ofn.org/shop#/contact`.
|
||||
# We remove the slash at the beginning.
|
||||
page = $location.path()[1..]
|
||||
|
||||
return $scope.whitelist[0] unless page
|
||||
|
||||
# If the path points to an unrelated path like `/login`, stay where we were.
|
||||
return $scope.lastPage unless page in $scope.whitelist
|
||||
|
||||
$scope.lastPage = page
|
||||
page
|
||||
|
||||
$scope.whitelistPages = (pages) ->
|
||||
$scope.whitelist = pages
|
||||
$scope.lastPage = pages[0]
|
||||
@@ -7,7 +7,7 @@ window.Darkswarm = angular.module("Darkswarm", [
|
||||
'templates',
|
||||
'ngSanitize',
|
||||
'ngAnimate',
|
||||
'google-maps',
|
||||
'uiGmapgoogle-maps',
|
||||
'duScroll',
|
||||
'angularFileUpload',
|
||||
'angularSlideables'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Darkswarm.directive 'mapOsmTiles', ($timeout) ->
|
||||
restrict: 'E'
|
||||
require: '^googleMap'
|
||||
require: '^uiGmapGoogleMap'
|
||||
scope: {}
|
||||
link: (scope, elem, attrs, ctrl) ->
|
||||
$timeout =>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Darkswarm.directive 'mapSearch', ($timeout, Search) ->
|
||||
# Install a basic search field in a map
|
||||
restrict: 'E'
|
||||
require: ['^googleMap', 'ngModel']
|
||||
require: ['^uiGmapGoogleMap', 'ngModel']
|
||||
replace: true
|
||||
template: '<input id="pac-input" ng-model="query" placeholder="' + t('location_placeholder') + '"></input>'
|
||||
scope: {}
|
||||
|
||||
@@ -50,7 +50,7 @@ Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer,
|
||||
false
|
||||
|
||||
calculateDistance: (query, firstMatching) ->
|
||||
if query?.length > 0
|
||||
if query?.length > 0 and Geo.OK
|
||||
if firstMatching?
|
||||
@setDistanceFrom firstMatching
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Darkswarm.service "Geo", ->
|
||||
new class Geo
|
||||
OK: google.maps.GeocoderStatus.OK
|
||||
OK: google?.maps?.GeocoderStatus?.OK
|
||||
|
||||
# Usage:
|
||||
# Geo.geocode address, (results, status) ->
|
||||
|
||||
@@ -15,9 +15,11 @@ Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) ->
|
||||
if(response.error)
|
||||
Loading.clear()
|
||||
RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"})
|
||||
@triggerAngularDigest()
|
||||
console.error(JSON.stringify(response.error))
|
||||
else
|
||||
secrets.token = response.token.id
|
||||
secrets.cc_type = @mapCC(response.token.card.brand)
|
||||
secrets.cc_type = @mapTokenApiCardBrand(response.token.card.brand)
|
||||
secrets.card = response.token.card
|
||||
submit()
|
||||
|
||||
@@ -32,15 +34,21 @@ Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) ->
|
||||
if(response.error)
|
||||
Loading.clear()
|
||||
RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"})
|
||||
@triggerAngularDigest()
|
||||
console.error(JSON.stringify(response.error))
|
||||
else
|
||||
secrets.token = response.paymentMethod.id
|
||||
secrets.cc_type = response.paymentMethod.card.brand
|
||||
secrets.cc_type = @mapPaymentMethodsApiCardBrand(response.paymentMethod.card.brand)
|
||||
secrets.card = response.paymentMethod.card
|
||||
submit()
|
||||
|
||||
# Maps the brand returned by Stripe to that required by activemerchant
|
||||
mapCC: (ccType) ->
|
||||
switch ccType
|
||||
triggerAngularDigest: ->
|
||||
# $evalAsync is improved way of triggering a digest without calling $apply
|
||||
$rootScope.$evalAsync()
|
||||
|
||||
# Maps the brand returned by Stripe's tokenAPI to that required by activemerchant
|
||||
mapTokenApiCardBrand: (cardBrand) ->
|
||||
switch cardBrand
|
||||
when 'MasterCard' then return 'master'
|
||||
when 'Visa' then return 'visa'
|
||||
when 'American Express' then return 'american_express'
|
||||
@@ -48,6 +56,14 @@ Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) ->
|
||||
when 'JCB' then return 'jcb'
|
||||
when 'Diners Club' then return 'diners_club'
|
||||
|
||||
# Maps the brand returned by Stripe's paymentMethodsAPI to that required by activemerchant
|
||||
mapPaymentMethodsApiCardBrand: (cardBrand) ->
|
||||
switch cardBrand
|
||||
when 'mastercard' then return 'master'
|
||||
when 'amex' then return 'american_express'
|
||||
when 'diners' then return 'diners_club'
|
||||
else return cardBrand # a few brands are equal, for example, visa
|
||||
|
||||
# It doesn't matter if any of these are nil, all are optional.
|
||||
makeCardData: (secrets) ->
|
||||
{'name': secrets.name,
|
||||
|
||||
Reference in New Issue
Block a user