Merge pull request #5099 from Matt-Yorkley/ticking-time-bom

Improve BOM
This commit is contained in:
Pau Pérez Fabregat
2020-04-02 16:01:48 +02:00
committed by GitHub
9 changed files with 183 additions and 114 deletions

View File

@@ -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()

View File

@@ -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) =>

View File

@@ -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)

View File

@@ -4,18 +4,17 @@ module Admin
#
def index
order_params = params[:q].andand.delete :order
orders = order_permissions.editable_orders.ransack(order_params).result
order_permissions = ::Permissions::Order.new(spree_current_user)
orders = order_permissions.
editable_orders.ransack(order_params).result
line_items = order_permissions.
@line_items = order_permissions.
editable_line_items.where(order_id: orders).
includes(variant: { option_values: :option_type }).
ransack(params[:q]).result.
reorder('spree_line_items.order_id ASC, spree_line_items.id ASC')
render_as_json line_items
@line_items = @line_items.page(page).per(params[:per_page]) if using_pagination?
render json: { line_items: serialized_line_items, pagination: pagination_data }
end
# PUT /admin/bulk_line_items/:id.json
@@ -65,6 +64,12 @@ module Admin
Api::Admin::LineItemSerializer
end
def serialized_line_items
ActiveModel::ArraySerializer.new(
@line_items, each_serializer: serializer(nil)
)
end
def authorize_update!
authorize! :update, order
authorize! :read, order
@@ -73,5 +78,28 @@ module Admin
def order
@line_item.order
end
def order_permissions
::Permissions::Order.new(spree_current_user)
end
def using_pagination?
params[:per_page]
end
def pagination_data
return unless using_pagination?
{
results: @line_items.total_count,
pages: @line_items.num_pages,
page: page.to_i,
per_page: params[:per_page].to_i
}
end
def page
params[:page] || 1
end
end
end

View File

@@ -20,28 +20,28 @@
%label{ :for => 'start_date_filter' }
= t("admin.start_date")
%br
%input{ :class => "two columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()' }
%input{ :class => "two columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
.date_filter{ :class => "two columns" }
%label{ :for => 'end_date_filter' }
= t("admin.end_date")
%br
%input{ :class => "two columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()' }
%input{ :class => "two columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
.one.column  
.filter_select{ :class => "three columns" }
%label{ :for => 'supplier_filter' }
= t("admin.producer")
%br
%input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', blank: "{ id: 0, name: '#{t(:all)}' }", ng: { model: 'supplierFilter' } }
%input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'supplierFilter', change: 'refreshData()' } }
.filter_select{ :class => "three columns" }
%label{ :for => 'distributor_filter' }
= t("admin.shop")
%br
%input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', blank: "{ id: 0, name: '#{t(:all)}' }", ng: { model: 'distributorFilter' } }
%input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'distributorFilter', change: 'refreshData()' } }
.filter_select{ :class => "three columns" }
%label{ :for => 'order_cycle_filter' }
= t("admin.order_cycle")
%br
%input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', blank: "{ id: 0, name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: 'refreshData()' } }
%input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: 'refreshData()' } }
.filter_clear{ :class => "two columns omega" }
%label{ :for => 'clear_all_filters' }
%br
@@ -94,7 +94,7 @@
%hr.divider.sixteen.columns.alpha.omega
.controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || lineItems.length == 0' } }
.controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' } }
%div.three.columns.alpha
%input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' }
= render 'admin/shared/bulk_actions_dropdown'
@@ -157,7 +157,7 @@
= t("admin.orders.bulk_management.ask")
%input{ :type => 'checkbox', 'ng-model' => "confirmDelete" }
%tr.line_item{ ng: { repeat: "line_item in filteredLineItems = ( lineItems | filter:quickSearch | selectFilter:supplierFilter:distributorFilter:orderCycleFilter | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:sorting.predicate:sorting.reverse )", 'class-even' => "'even'", 'class-odd' => "'odd'", attr: { id: "li_{{line_item.id}}" } } }
%tr.line_item{ ng: { repeat: "line_item in filteredLineItems = ( line_items | filter:quickSearch | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:sorting.predicate:sorting.reverse )", 'class-even' => "'even'", 'class-odd' => "'odd'", attr: { id: "li_{{line_item.id}}" } } }
%td.bulk
%input{ :type => "checkbox", :name => 'bulk', 'ng-model' => 'line_item.checked', 'ignore-dirty' => true }
%td.order_no{ 'ng-show' => 'columns.order_no.visible' } {{ line_item.order.number }}
@@ -175,7 +175,7 @@
%span.error{ ng: { bind: 'line_item.errors.quantity' } }
%td.max{ 'ng-show' => 'columns.max.visible' } {{ line_item.max_quantity }}
%td.final_weight_volume{ 'ng-show' => 'columns.final_weight_volume.visible' }
%input.show-dirty{ :type => 'number', :name => 'final_weight_volume', :id => 'final_weight_volume', ng: { model: "line_item.final_weight_volume", readonly: "unitValueLessThanZero(line_item)", change: "weightAdjustedPrice(line_item)", required: "true", class: '{"update-error": line_item.errors.final_weight_volume}' }, min: 0, 'ng-pattern' => '/[1-9]+/' }
%input.show-dirty{ type: 'number', step: 'any', :name => 'final_weight_volume', :id => 'final_weight_volume', ng: { model: "line_item.final_weight_volume", readonly: "unitValueLessThanZero(line_item)", change: "weightAdjustedPrice(line_item)", required: "true", class: '{"update-error": line_item.errors.final_weight_volume}' }, min: 0, 'ng-pattern' => '/[0-9]*[.]?[0-9]+/' }
%span.error{ ng: { bind: 'line_item.errors.final_weight_volume' } }
%td.price{ 'ng-show' => 'columns.price.visible' }
%input.show-dirty{ :type => 'text', :name => 'price', :id => 'price', :ng => { value: 'line_item.price * line_item.quantity | currency:""', readonly: "true", class: '{"update-error": line_item.errors.price}' } }

View File

@@ -36,22 +36,21 @@ describe Admin::BulkLineItemsController, type: :controller do
end
it "retrieves a list of line_items with appropriate attributes, including line items with appropriate attributes" do
keys = json_response.first.keys.map(&:to_sym)
keys = json_response['line_items'].first.keys.map(&:to_sym)
expect(line_item_attributes.all?{ |attr| keys.include? attr }).to eq(true)
end
it "sorts line_items in ascending id line_item" do
ids = json_response.map{ |line_item| line_item['id'] }
expect(ids[0]).to be < ids[1]
expect(ids[1]).to be < ids[2]
expect(line_item_ids[0]).to be < line_item_ids[1]
expect(line_item_ids[1]).to be < line_item_ids[2]
end
it "formats final_weight_volume as a float" do
expect(json_response.map{ |line_item| line_item['final_weight_volume'] }.all?{ |fwv| fwv.is_a?(Float) }).to eq(true)
expect(json_response['line_items'].map{ |line_item| line_item['final_weight_volume'] }.all?{ |fwv| fwv.is_a?(Float) }).to eq(true)
end
it "returns distributor object with id key" do
expect(json_response.map{ |line_item| line_item['supplier'] }.all?{ |d| d.key?('id') }).to eq(true)
expect(json_response['line_items'].map{ |line_item| line_item['supplier'] }.all?{ |d| d.key?('id') }).to eq(true)
end
end
@@ -61,7 +60,7 @@ describe Admin::BulkLineItemsController, type: :controller do
end
it "retrives a list of line items which match the criteria" do
expect(json_response.map{ |line_item| line_item['id'] }).to eq [line_item2.id, line_item3.id]
expect(line_item_ids).to eq [line_item2.id, line_item3.id]
end
end
@@ -71,7 +70,7 @@ describe Admin::BulkLineItemsController, type: :controller do
end
it "retrives a list of line items whose orders match the criteria" do
expect(json_response.map{ |line_item| line_item['id'] }).to eq [line_item2.id, line_item3.id, line_item4.id]
expect(line_item_ids).to eq [line_item2.id, line_item3.id, line_item4.id]
end
end
end
@@ -106,7 +105,7 @@ describe Admin::BulkLineItemsController, type: :controller do
end
it "retrieves a list of line_items" do
keys = json_response.first.keys.map(&:to_sym)
keys = json_response['line_items'].first.keys.map(&:to_sym)
expect(line_item_attributes.all?{ |attr| keys.include? attr }).to eq(true)
end
end
@@ -118,11 +117,37 @@ describe Admin::BulkLineItemsController, type: :controller do
end
it "retrieves a list of line_items" do
keys = json_response.first.keys.map(&:to_sym)
keys = json_response['line_items'].first.keys.map(&:to_sym)
expect(line_item_attributes.all?{ |attr| keys.include? attr }).to eq(true)
end
end
end
context "paginating" do
before do
allow(controller).to receive_messages spree_current_user: create(:admin_user)
end
context "with pagination args" do
it "returns paginated results" do
spree_get :index, { page: 1, per_page: 2 }, format: :json
expect(line_item_ids).to eq [line_item1.id, line_item2.id]
expect(json_response['pagination']).to eq(
{ 'page' => 1, 'per_page' => 2, 'pages' => 2, 'results' => 4 }
)
end
it "returns paginated results for a second page" do
spree_get :index, { page: 2, per_page: 2 }, format: :json
expect(line_item_ids).to eq [line_item3.id, line_item4.id]
expect(json_response['pagination']).to eq(
{ 'page' => 2, 'per_page' => 2, 'pages' => 2, 'results' => 4 }
)
end
end
end
end
describe '#update' do
@@ -259,4 +284,10 @@ describe Admin::BulkLineItemsController, type: :controller do
end
end
end
private
def line_item_ids
json_response['line_items'].map{ |line_item| line_item['id'] }
end
end

View File

@@ -494,7 +494,7 @@ feature '
it "shows a dialog and ignores changes when confirm dialog is accepted" do
page.driver.accept_modal :confirm, text: "Unsaved changes exist and will be lost if you continue." do
fill_in "start_date_filter", with: (Date.current - 9).strftime("%F %T")
fill_in "start_date_filter", with: (Date.current - 9).strftime('%Y-%m-%d')
end
expect(page).to have_no_selector "#save-bar"
within("tr#li_#{li2.id} td.quantity") do
@@ -577,6 +577,7 @@ feature '
find("div#bulk-actions-dropdown").click
find("div#bulk-actions-dropdown div.menu_item", text: "Delete Selected" ).click
expect(page).to have_no_selector "tr#li_#{li1.id}"
expect(page).to have_selector "#quick_search"
fill_in "quick_search", with: ''
wait_until { request_monitor_finished 'LineItemsCtrl' }
expect(page).to have_selector "tr#li_#{li2.id}"

View File

@@ -13,23 +13,23 @@ describe "LineItemsCtrl", ->
compare: (actual, expected) ->
{ pass: angular.equals(actual, expected) }
beforeEach inject(($controller, $rootScope, $httpBackend, _$timeout_, _VariantUnitManager_, _Enterprises_, _Orders_, _LineItems_, _OrderCycles_) ->
beforeEach inject(($controller, $rootScope, $httpBackend, _$timeout_, _VariantUnitManager_, _Enterprises_, _Orders_, _OrderCycles_) ->
scope = $rootScope.$new()
ctrl = $controller
$timeout = _$timeout_
httpBackend = $httpBackend
Enterprises = _Enterprises_
Orders = _Orders_
LineItems = _LineItems_
OrderCycles = _OrderCycles_
VariantUnitManager = _VariantUnitManager_
momentMock = jasmine.createSpyObj('moment', ['format', 'startOf', 'endOf', 'subtract', 'add'])
momentMock = jasmine.createSpyObj('moment', ['format', 'startOf', 'endOf', 'subtract', 'add', 'isValid'])
spyOn(window,"moment").and.returnValue momentMock
momentMock.startOf.and.returnValue momentMock
momentMock.endOf.and.returnValue momentMock
momentMock.subtract.and.returnValue momentMock
momentMock.add.and.returnValue momentMock
momentMock.format.and.returnValue "SomeDate"
momentMock.isValid.and.returnValue true
supplier = { id: 1, name: "Supplier" }
distributor = { id: 5, name: "Distributor" }
@@ -37,8 +37,11 @@ describe "LineItemsCtrl", ->
order = { id: 9, order_cycle: { id: 4 }, distributor: { id: 5 }, number: "R123456" }
lineItem = { id: 7, quantity: 3, order: { id: 9 }, supplier: { id: 1 } }
httpBackend.expectGET("/api/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}}
httpBackend.expectGET("/admin/bulk_line_items.json?q%5Border%5D%5Bcompleted_at_gteq%5D=SomeDate&q%5Border%5D%5Bcompleted_at_lt%5D=SomeDate&q%5Border%5D%5Bcompleted_at_not_null%5D=true&q%5Border%5D%5Bstate_not_eq%5D=canceled").respond [lineItem]
LineItems =
index: jasmine.createSpy('index').and.returnValue(lineItem)
all: [lineItem]
httpBackend.expectGET("/api/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}}
httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bsells_in%5D%5B%5D=own&q%5Bsells_in%5D%5B%5D=any").respond [distributor]
httpBackend.expectGET("/admin/order_cycles.json?ams_prefix=basic&as=distributor&q%5Borders_close_at_gt%5D=SomeDate").respond [orderCycle]
httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bis_primary_producer_eq%5D=true").respond [supplier]
@@ -52,12 +55,6 @@ describe "LineItemsCtrl", ->
it "the RequestMonitor will have a state of loading", ->
expect(scope.RequestMonitor.loading).toBe true
it "will not have reset the select filters", ->
expect(scope.distributorFilter).toBeUndefined()
expect(scope.supplierFilter).toBeUndefined()
expect(scope.orderCycleFilter).toBeUndefined()
expect(scope.quickSearch).toBeUndefined()
it "will not have reset the form state to pristine", ->
expect(scope.bulk_order_form.$setPristine.calls.count()).toBe 0
@@ -83,49 +80,20 @@ describe "LineItemsCtrl", ->
expect(scope.orders).toDeepEqual [ { id: 9, order_cycle: orderCycle, distributor: distributor, number: "R123456" } ]
it "gets line_items, with dereferenced orders and suppliers", ->
expect(scope.lineItems).toDeepEqual [ { id: 7, quantity: 3, order: scope.orders[0], supplier: supplier } ]
expect(scope.line_items).toDeepEqual [ { id: 7, quantity: 3, order: scope.orders[0], supplier: supplier } ]
it "the RequestMonitor will have a state of loaded", ->
expect(scope.RequestMonitor.loading).toBe false
it "resets the select filters", ->
expect(scope.distributorFilter).toBe 0
expect(scope.supplierFilter).toBe 0
expect(scope.orderCycleFilter).toBe 0
expect(scope.distributorFilter).toBe ''
expect(scope.supplierFilter).toBe ''
expect(scope.orderCycleFilter).toBe ''
expect(scope.quickSearch).toBe = ""
it "resets the form state to pristine", ->
expect(scope.bulk_order_form.$setPristine.calls.count()).toBe 1
describe "deleting a line item", ->
order = line_item1 = line_item2 = null
beforeEach inject((LineItemResource) ->
spyOn(window,"confirm").and.returnValue true
order = { number: "R12345678" }
line_item1 = new LineItemResource({ id: 1, order: order })
line_item2 = new LineItemResource({ id: 2, order: order })
scope.lineItems= [ line_item1, line_item2 ]
)
describe "where the request is successful", ->
beforeEach ->
httpBackend.expectDELETE("/admin/bulk_line_items/1.json").respond "nothing"
scope.deleteLineItem line_item1
httpBackend.flush()
it "removes the deleted item from the line_items array", ->
expect(scope.lineItems).toEqual [line_item2]
describe "where the request is unsuccessful", ->
beforeEach ->
httpBackend.expectDELETE("/admin/bulk_line_items/1.json").respond 404, "NO CONTENT"
scope.deleteLineItem line_item1
httpBackend.flush()
it "does not remove line_item from the line_items array", ->
expect(scope.lineItems).toEqual [line_item1, line_item2]
describe "deleting 'checked' line items", ->
line_item1 = line_item2 = line_item3 = line_item4 = null
@@ -134,11 +102,11 @@ describe "LineItemsCtrl", ->
line_item2 = { name: "line item 2", checked: true }
line_item3 = { name: "line item 3", checked: false }
line_item4 = { name: "line item 4", checked: true }
scope.lineItems = [ line_item1, line_item2, line_item3, line_item4 ]
scope.line_items = [ line_item1, line_item2, line_item3, line_item4 ]
it "calls deletedLineItem for each 'checked' line item", ->
spyOn(scope, "deleteLineItem")
scope.deleteLineItems(scope.lineItems)
scope.deleteLineItems(scope.line_items)
expect(scope.deleteLineItem).toHaveBeenCalledWith(line_item2)
expect(scope.deleteLineItem).toHaveBeenCalledWith(line_item4)
expect(scope.deleteLineItem).not.toHaveBeenCalledWith(line_item1)

View File

@@ -1,5 +1,5 @@
describe "LineItems service", ->
LineItems = LineItemResource = lineItems = $httpBackend = null
LineItems = LineItemResource = lineItems = $httpBackend = $rootScope = $timeout = null
beforeEach ->
module 'admin.lineItems'
@@ -15,24 +15,27 @@ describe "LineItems service", ->
$httpBackend = _$httpBackend_
describe "#index", ->
result = response = null
result = response = line_item = null
beforeEach ->
response = [{ id: 5, name: 'LineItem 1'}]
line_item = { id: 5, name: 'LineItem 1'}
response = { line_items: [line_item] }
$httpBackend.expectGET('/admin/bulk_line_items.json').respond 200, response
result = LineItems.index()
$httpBackend.flush()
it "stores returned data in @byID, with ids as keys", ->
# LineItemResource returns instances of Resource rather than raw objects
expect(LineItems.byID).toDeepEqual { 5: response[0] }
expect(LineItems.byID).toDeepEqual { 5: response['line_items'][0] }
it "stores returned data in @pristineByID, with ids as keys", ->
expect(LineItems.pristineByID).toDeepEqual { 5: response[0] }
expect(LineItems.pristineByID).toDeepEqual { 5: response['line_items'][0] }
it "stores returned data in @all, as an array", ->
expect(LineItems.all).toDeepEqual [line_item]
it "returns an array of line items", ->
expect(result).toDeepEqual response
expect(result).toDeepEqual [line_item]
describe "#save", ->
describe "success", ->
@@ -115,6 +118,7 @@ describe "LineItems service", ->
lineItem = new LineItemResource({ id: 15, order: { number: '12345678'} })
LineItems.pristineByID[15] = lineItem
LineItems.byID[15] = lineItem
LineItems.all = [lineItem]
$httpBackend.expectDELETE('/admin/bulk_line_items/15.json').respond 200, { id: 15, name: 'LineItem 1'}
LineItems.delete(lineItem, callback).then( -> resolved = true).catch( -> rejected = true)
$httpBackend.flush()
@@ -122,6 +126,7 @@ describe "LineItems service", ->
it "updates the pristine copy of the lineItem", ->
expect(LineItems.pristineByID[15]).toBeUndefined()
expect(LineItems.byID[15]).toBeUndefined()
expect(LineItems.all).toEqual([])
it "runs the callback", ->
expect(callback).toHaveBeenCalled()