Merge pull request #8294 from guidoDutra/8131-cancel-empty-orders-on-BOM-page

Cancel empty orders on BOM page
This commit is contained in:
Filipe
2022-03-18 11:24:26 +00:00
committed by GitHub
5 changed files with 139 additions and 24 deletions

View File

@@ -104,15 +104,38 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
else
StatusMessage.display 'failure', t "unsaved_changes_error"
$scope.cancelOrder = (order) ->
return $http(
method: 'GET'
url: "/admin/orders/#{order.number}/fire?e=cancel")
$scope.deleteLineItem = (lineItem) ->
if ($scope.confirmDelete && confirm(t "are_you_sure")) || !$scope.confirmDelete
LineItems.delete lineItem
if lineItem.order.item_count == 1
if confirm(t('js.admin.deleting_item_will_cancel_order'))
$scope.cancelOrder(lineItem.order).then(-> $scope.refreshData())
else if ($scope.confirmDelete && confirm(t "are_you_sure")) || !$scope.confirmDelete
LineItems.delete(lineItem, () -> $scope.refreshData())
$scope.deleteLineItems = (lineItemsToDelete) ->
existingState = $scope.confirmDelete
$scope.confirmDelete = false
$scope.deleteLineItem lineItem for lineItem in lineItemsToDelete when lineItem.checked
$scope.confirmDelete = existingState
$scope.deleteLineItems = (lineItems) ->
lineItemsToDelete = lineItems.filter (item) -> item.checked
willCancelOrders = false
itemsPerOrder = new Map()
for item in lineItemsToDelete
{ order } = item
if itemsPerOrder.has(order)
itemsPerOrder.get(order).push(item)
else
itemsPerOrder.set(order, [item])
willCancelOrders = true if (order.item_count == itemsPerOrder.get(order).length)
if willCancelOrders
return unless confirm(t("js.admin.deleting_item_will_cancel_order"))
itemsPerOrder.forEach (items, order) =>
if order.item_count == items.length
$scope.cancelOrder(order).then(-> $scope.refreshData())
else
Promise.all(LineItems.delete(item) for item in items).then(-> $scope.refreshData())
$scope.allBoxesChecked = ->
checkedCount = $scope.filteredLineItems.reduce (count,lineItem) ->

View File

@@ -7,7 +7,7 @@ module Api
:edit_path, :state, :payment_state, :shipment_state,
:payments_path, :ready_to_ship, :ready_to_capture, :created_at,
:distributor_name, :special_instructions, :display_outstanding_balance,
:item_total, :adjustment_total, :payment_total, :total
:item_total, :adjustment_total, :payment_total, :total, :item_count
has_one :distributor, serializer: Api::Admin::IdSerializer
has_one :order_cycle, serializer: Api::Admin::IdSerializer
@@ -69,6 +69,10 @@ module Api
object.completed_at.blank? ? "" : I18n.l(object.completed_at, format: '%B %d, %Y')
end
def item_count
object.line_items.count
end
private
def spree_routes_helper

View File

@@ -2847,6 +2847,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
admin:
unit_price_tooltip: "The unit price increases transparency by allowing your customers to easily compare prices between different products and packaging sizes. Note, that the final unit price displayed in the shopfront might differ as it is includes taxes & fees."
enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it."
deleting_item_will_cancel_order: "This operation will result in one or more empty orders, which will be cancelled. Do you wish to proceed?"
modals:
got_it: "Got it"
close: "Close"
@@ -3345,6 +3346,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
last: "Last"
spree:
order_updated: "Order Updated"
add_country: "Add country"
add_state: "Add state"
adjustment: "Adjustment"

View File

@@ -44,6 +44,9 @@ describe "LineItemsCtrl", ->
LineItems =
index: jasmine.createSpy('index').and.returnValue(lineItem)
all: [lineItem]
delete: (lineItem, callback=null) ->
callback() if callback
return Promise.resolve()
httpBackend.expectGET("/api/v0/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%5Bshipment_state_not_eq%5D=shipped&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]
@@ -98,23 +101,102 @@ describe "LineItemsCtrl", ->
it "resets the form state to pristine", ->
expect(scope.bulk_order_form.$setPristine.calls.count()).toBe 1
describe "deleting 'checked' line items", ->
line_item1 = line_item2 = line_item3 = line_item4 = null
describe "deleting a line item", ->
line_item1 = line_item2 = null
order1 = order2 = null
beforeEach ->
line_item1 = { name: "line item 1", checked: false }
line_item2 = { name: "line item 2", checked: true }
line_item3 = { name: "line item 3", checked: false }
line_item4 = { name: "line item 4", checked: true }
order1 = { id: 1, item_count: 1 }
order2 = { id: 2, item_count: 2 }
line_item1 = {
name: "line item 1",
order: order1
}
line_item2 = {
name: "line item 2",
order: order2
}
scope.line_items = [ line_item1, line_item2 ]
it "shows a different message if order will be canceled", ->
spyOn(window, "confirm")
scope.deleteLineItem(line_item2)
expect(confirm).not.toHaveBeenCalledWith("This operation will result in one or more empty orders, which will be cancelled. Do you wish to proceed?")
scope.deleteLineItem(line_item1)
expect(confirm).toHaveBeenCalledWith("This operation will result in one or more empty orders, which will be cancelled. Do you wish to proceed?")
it "deletes the line item", ->
spyOn(window, "confirm").and.callFake(-> return true)
spyOn(LineItems, "delete")
scope.deleteLineItem(line_item2)
expect(LineItems.delete).toHaveBeenCalledWith(line_item2, jasmine.anything())
it "cancels empty order", ->
spyOn(window, "confirm").and.callFake(-> return true)
spyOn(scope, "cancelOrder").and.callFake(-> return Promise.resolve())
scope.deleteLineItem(line_item1)
expect(scope.cancelOrder).toHaveBeenCalledWith(order1)
describe "deleting 'checked' line items", ->
line_item1 = line_item2 = line_item3 = line_item4 = null
order1 = order2 = order3 = null
beforeEach ->
order1 = { id: 1, item_count: 1 }
order2 = { id: 2, item_count: 1 }
order3 = { id: 3, item_count: 2 }
line_item1 = {
name: "line item 1",
order: order1
checked: false
}
line_item2 = {
name: "line item 2",
order: order2,
checked: false
}
line_item3 = {
name: "line item 3",
order: order3,
checked: false
}
line_item4 = {
name: "line item 4",
order: order3,
checked: false
}
scope.line_items = [ line_item1, line_item2, line_item3, line_item4 ]
it "calls deletedLineItem for each 'checked' line item", ->
spyOn(scope, "deleteLineItem")
it "asks for confirmation only if orders will be canceled", ->
spyOn(window, "confirm")
line_item3.checked = true
scope.deleteLineItems(scope.line_items)
expect(scope.deleteLineItem).toHaveBeenCalledWith(line_item2)
expect(scope.deleteLineItem).toHaveBeenCalledWith(line_item4)
expect(scope.deleteLineItem).not.toHaveBeenCalledWith(line_item1)
expect(scope.deleteLineItem).not.toHaveBeenCalledWith(line_item3)
expect(confirm).not.toHaveBeenCalled()
line_item1.checked = true
scope.deleteLineItems(scope.line_items)
expect(confirm).toHaveBeenCalledWith("This operation will result in one or more empty orders, which will be cancelled. Do you wish to proceed?")
it "deletes checked line items for non-empty orders", ->
line_item1.checked = true
line_item3.checked = true
spyOn(window, "confirm").and.callFake(-> return true)
spyOn(LineItems, "delete")
scope.deleteLineItems(scope.line_items)
expect(LineItems.delete).toHaveBeenCalledWith(line_item3)
expect(LineItems.delete).not.toHaveBeenCalledWith(line_item1)
expect(LineItems.delete).not.toHaveBeenCalledWith(line_item2)
expect(LineItems.delete).not.toHaveBeenCalledWith(line_item4)
it "cancels all empty orders", ->
line_item1.checked = true
line_item3.checked = true
spyOn(window, "confirm").and.callFake(-> return true)
spyOn(scope, "cancelOrder").and.callFake(-> return Promise.resolve())
scope.deleteLineItems(scope.line_items)
expect(scope.cancelOrder).toHaveBeenCalledWith(order1)
expect(scope.cancelOrder).not.toHaveBeenCalledWith(order3)
describe "check boxes for line items", ->
line_item1 = line_item2 = null

View File

@@ -670,8 +670,10 @@ describe '
within("tr#li_#{li2.id} td.bulk") do
check "bulk"
end
find("div#bulk-actions-dropdown").click
find("div#bulk-actions-dropdown div.menu_item", text: "Delete Selected" ).click
page.driver.accept_modal :confirm do
find("div#bulk-actions-dropdown").click
find("div#bulk-actions-dropdown div.menu_item", text: "Delete Selected" ).click
end
expect(page).to have_selector "tr#li_#{li1.id}"
expect(page).to have_no_selector "tr#li_#{li2.id}"
end
@@ -693,8 +695,10 @@ describe '
check "toggle_bulk"
fill_in "quick_search", with: o1.number
expect(page).to have_no_selector "tr#li_#{li2.id}"
find("div#bulk-actions-dropdown").click
find("div#bulk-actions-dropdown div.menu_item", text: "Delete Selected" ).click
page.driver.accept_modal :confirm do
find("div#bulk-actions-dropdown").click
find("div#bulk-actions-dropdown div.menu_item", text: "Delete Selected" ).click
end
expect(page).to have_no_selector "tr#li_#{li1.id}"
expect(page).to have_selector "#quick_search"
fill_in "quick_search", with: ''