# frozen_string_literal: true require 'system_helper' RSpec.describe ' As an Administrator I want to be able to manage orders in bulk ' do include AdminHelper include AuthenticationHelper include WebHelper context "listing orders" do before :each do login_as_admin end context "when no orders exist" do before :each do visit_bulk_order_management end it "displays a message when number of line items is zero" do expect(page).to have_text 'No orders found.' end end context "displaying the list of line items" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.parse('2022-05-05 15:30:45')) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.parse('2022-04-26 15:10:45')) } let!(:o21) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.parse('2022-08-04 09:10:45')) } let!(:o22) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.parse('2022-06-07 09:10:45')) } let!(:o3) { create(:order_with_distributor, state: 'address', completed_at: nil ) } let!(:o4) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:o5) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now ) } let!(:li1) { create(:line_item_with_shipment, order: o1) } let!(:li2) { create(:line_item_with_shipment, order: o2) } let!(:li21) { create(:line_item_with_shipment, order: o21) } let!(:li22) { create(:line_item_with_shipment, order: o22) } let!(:li3) { create(:line_item, order: o3 ) } let!(:li4) { create(:line_item_with_shipment, order: o4) } let!(:li5) { create(:line_item_with_shipment, order: o5) } before :each do visit_bulk_order_management end it "displays a list of line items" do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" expect(page).not_to have_selector "tr#li_#{li3.id}" end it "displays only line items that are not shipped" do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" expect(page).not_to have_selector "tr#li_#{li4.id}" expect(page).not_to have_selector "tr#li_#{li5.id}" end it "orders by completion date" do find("a", text: 'Completed at').click # sets ascending ordering expect(page).to have_content( /#{li2.product.name}.*#{li1.product.name}.*#{li22.product.name}.*#{li21.product.name}/m ) find("a", text: 'Completed at').click # sets descending ordering expect(page).to have_content( /#{li21.product.name}.*#{li22.product.name}.*#{li1.product.name}.*#{li2.product.name}/m ) end end context "pagination" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.yesterday ) } let!(:o3) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.yesterday - 1.day ) } let!(:product) { create(:simple_product) } let!(:var1) { create(:variant, product_id: product.id, display_name: "Little Fish") } let!(:var2) { create(:variant, product_id: product.id, display_name: "Big Fish") } before do 10.times { create(:line_item_with_shipment, variant: var1, order: o2) } 5.times { create(:line_item_with_shipment, variant: var2, order: o1) } 5.times { create(:line_item_with_shipment, variant: var1, order: o3) } end it "splits results according to line items from orders" do visit_bulk_order_management expect(page).to have_select2 "autogen4", selected: "15 per page" # should be default option expect(page).to have_content "20 Results found. Viewing 1 to 15." expect(page).to have_button("« First", disabled: true) expect(page).to have_button("Previous", disabled: true) expect(page).to have_button("1", disabled: true) expect(page).to have_button("2", disabled: false) expect(page).to have_button("Next", disabled: false) expect(page).to have_button("Last »", disabled: false) within "tbody" do expect(page).to have_css("tr", count: 15) # verifies the remaining 15 line items are shown end click_button "2" # switches to the second results page within "tbody" do expect(page).to have_css("tr", count: 5) # verifies the remaining 5 line items are shown end click_button "1" # switches to the first results page select2_select "50 per page", from: "autogen4" # should display all 20 line items expect(page).to have_content "20 Results found. Viewing 1 to 20." expect(page).to have_button("« First", disabled: true) expect(page).to have_button("Previous", disabled: true) expect(page).to have_button("1", disabled: true) expect(page).not_to have_button("2") expect(page).to have_button("Next", disabled: true) expect(page).to have_button("Last »", disabled: true) select2_select "100 per page", from: "autogen4" # should display all 20 line items expect(page).to have_content "20 Results found. Viewing 1 to 20." end it "clicking the product variant" do visit_bulk_order_management expect(page).to have_content "Little Fish", count: 10 expect(page).to have_content "Big Fish", count: 5 click_on("Little Fish") # opens BOM box within "#listing_orders" do expect(page).to have_content "Little Fish", count: 15 expect(page).not_to have_content "Big Fish" end click_link "Clear" # closes BOM box expect(page).to have_content "Big Fish", count: 5 expect(page).to have_content "Little Fish", count: 10 end end context "searching" do let!(:a1) { create(:address, phone: "1234567890", firstname: "Willy", lastname: "Wonka") } let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, bill_address: a1) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:s1) { create(:supplier_enterprise) } let!(:s2) { create(:supplier_enterprise) } let!(:li1) { create(:line_item_with_shipment, order: o1, variant: create(:variant, supplier: s1)) } let!(:li2) { create(:line_item_with_shipment, order: o2, variant: create(:variant, supplier: s2)) } let!(:li3) { create(:line_item_with_shipment, order: o2, variant: create(:variant, supplier: s2)) } before :each do visit_bulk_order_management end it "by product name" do fill_in "quick_filter", with: li1.product.name page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] end it "by supplier name" do fill_in "quick_filter", with: li1.variant.supplier.name page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] end it "by email" do fill_in "quick_filter", with: o1.email page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] end it "by order number" do fill_in "quick_filter", with: o1.number page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] end it "by phone number" do fill_in "quick_filter", with: o1.bill_address.phone page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] end it "by distributor name" do fill_in "quick_filter", with: o1.distributor.name page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] end it "by customer name" do # by firstname fill_in "quick_filter", with: o1.bill_address.firstname page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] # by lastname fill_in "quick_filter", with: o1.bill_address.lastname page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] # by fullname fill_in "quick_filter", with: "#{o1.bill_address.firstname} #{o1.bill_address.lastname}" page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] fill_in "quick_filter", with: "#{o2.bill_address.firstname} #{o2.bill_address.lastname}" page.find('.filter-actions .button.icon-search').click expect_line_items li2, li3, excluding: [li1] # by fullname reversed fill_in "quick_filter", with: "#{o1.bill_address.lastname} #{o1.bill_address.firstname}" page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] fill_in "quick_filter", with: "#{o2.bill_address.lastname} #{o2.bill_address.firstname}" page.find('.filter-actions .button.icon-search').click expect_line_items li2, li3, excluding: [li1] # by fullname with comma fill_in "quick_filter", with: "#{o1.bill_address.firstname}, #{o1.bill_address.lastname}" page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] fill_in "quick_filter", with: "#{o2.bill_address.firstname}, #{o2.bill_address.lastname}" page.find('.filter-actions .button.icon-search').click expect_line_items li2, li3, excluding: [li1] # by fullname with comma reversed fill_in "quick_filter", with: "#{o1.bill_address.lastname}, #{o1.bill_address.firstname}" page.find('.filter-actions .button.icon-search').click expect_line_items li1, excluding: [li2, li3] fill_in "quick_filter", with: "#{o2.bill_address.lastname}, #{o2.bill_address.firstname}" page.find('.filter-actions .button.icon-search').click expect_line_items li2, li3, excluding: [li1] end end context "displaying individual columns" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, bill_address: create(:address) ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, bill_address: nil ) } let!(:li1) { create(:line_item_with_shipment, order: o1) } let!(:li2) { create(:line_item_with_shipment, order: o2, product: create(:product) ) } # sets supplier name to contain unusual characters let!(:supplier) { li1.supplier.update_attribute(:name, "Sûppliẽr Näme") } before :each do visit_bulk_order_management end it "displays a column for user's full name" do expect(page).to have_selector "th.full_name", text: "Name" expect(page) .to have_selector "td.full_name", text: "#{o1.bill_address.last_name}, #{o1.bill_address.first_name}" expect(page).to have_selector "td.full_name", text: "" end it "displays a column for order date" do expect(page).to have_selector "th.date", text: 'Completed at' expect(page).to have_selector "td.date", text: o1.completed_at.strftime('%B %d, %Y') expect(page).to have_selector "td.date", text: o2.completed_at.strftime('%B %d, %Y') end it "displays a column for producer" do expect(page).to have_selector "th.producer", text: "Producer" expect(page).to have_selector "td.producer", text: "Sûppliẽr Näme", count: 2 end it "displays a column for variant description, which shows only product name " \ "when options text is blank" do expect(page).to have_selector "th.variant", text: "Product: Unit" expect(page).to have_selector "td.variant", text: li1.product.name expect(page).to have_selector "td.variant", text: "#{li2.product.name}: #{li2.variant.options_text}" end it "displays a field for quantity" do expect(page).to have_selector "th.quantity", text: "Quantity" expect(page).to have_field "quantity", with: li1.quantity.to_s expect(page).to have_field "quantity", with: li2.quantity.to_s end it "displays a column for max quantity" do expect(page).to have_selector "th.max", text: "Max" expect(page).to have_selector "td.max", text: li1.max_quantity.to_s expect(page).to have_selector "td.max", text: li2.max_quantity.to_s end end describe "sorting of line items" do let!(:o1) do create( :order_with_distributor, bill_address: create(:address, first_name: 'Bob', last_name: 'Taylor'), state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) end let!(:o2) do create( :order_with_distributor, bill_address: create(:address, first_name: 'Mary', last_name: 'Smith'), state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) end let!(:o3) do create( :order_with_distributor, bill_address: create(:address, first_name: 'Bill', last_name: 'Taylor'), state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) end let!(:li1) { create(:line_item_with_shipment, order: o1) } let!(:li2) { create(:line_item_with_shipment, order: o2) } let!(:li3) { create(:line_item_with_shipment, order: o3) } before :each do visit_bulk_order_management end it "sorts by customer last name when the customer name header is clicked" do within "#listing_orders thead" do click_on "Name" end expect(page).to have_selector("#listing_orders .line_item:nth-child(1) .full_name", text: "Smith, Mary") expect(page).to have_selector("#listing_orders .line_item:nth-child(2) .full_name", text: "Taylor, Bill") expect(page).to have_selector("#listing_orders .line_item:nth-child(3) .full_name", text: "Taylor, Bob") end it "sorts by customer last name in reverse when the customer name header is clicked twice" do within "#listing_orders thead" do click_on "Name" click_on "Name" end expect(page).to have_selector("#listing_orders .line_item:nth-child(1) .full_name", text: "Taylor, Bob") expect(page).to have_selector("#listing_orders .line_item:nth-child(2) .full_name", text: "Taylor, Bill") expect(page).to have_selector("#listing_orders .line_item:nth-child(3) .full_name", text: "Smith, Mary") end end end context "altering line item properties" do before :each do login_as_admin end context "tracking changes" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:li1) { create(:line_item_with_shipment, order: o1, quantity: 5 ) } before :each do visit_bulk_order_management end it "adds the class 'ng-dirty' to input elements when value is altered" do expect(page).not_to have_css "input[name='quantity'].ng-dirty" fill_in "quantity", with: 2 expect(page).to have_css "input[name='quantity'].ng-dirty" end end context "submitting data to the server" do let!(:order) { create(:completed_order_with_fees) } before :each do order.line_items.second.destroy # we keep only one line item for this test visit_bulk_order_management end context "when acceptable data is sent to the server" do it "displays an update button which submits pending changes" do expect(page).not_to have_selector "#save-bar" fill_in "quantity", with: 2 expect(page).to have_selector "input[name='quantity'].ng-dirty" expect(page).to have_selector "#save-bar", text: "You have unsaved changes" click_button "Save Changes" expect(page).to have_selector "#save-bar", text: "All changes saved" expect(page).not_to have_selector "input[name='quantity'].ng-dirty" end end context "when unacceptable data is sent to the server" do it "displays an update button which submits pending changes" do expect(page).not_to have_selector "#save-bar" line_item = order.line_items.first fill_in "quantity", with: line_item.variant.on_hand + line_item.quantity + 10 expect(page).to have_selector "input[name='quantity'].ng-dirty" expect(page).to have_selector "#save-bar", text: "You have unsaved changes" click_button "Save Changes" expect(page).to have_selector "#save-bar", text: "Fields with red borders contain errors." expect(page).to have_selector "input[name='quantity'].ng-dirty.update-error" expect(page).to have_content "is out of stock" end end end end context "using page controls" do before :each do login_as_admin end let!(:p1) { create(:product, group_buy: true, group_buy_unit_size: 5000, variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] ) } let!(:v1) { p1.variants.first } let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:li1) { create(:line_item_with_shipment, order: o1, variant: v1, quantity: 5, final_weight_volume: 1000, price: 10.00 ) } before :each do v1.update_attribute(:on_hand, 100) visit_bulk_order_management end context "modifying the weight/volume of a line item" do before do toggle_columns "Weight/Volume", "Price" end it "price is altered" do within "tr#li_#{li1.id}" do expect(page).to have_field "price", with: "50.00" fill_in "final_weight_volume", with: 2000 expect(page).to have_field "price", with: "100.00" end click_button "Save Changes" expect(page).to have_content "All changes saved" li1.reload expect(li1.final_weight_volume).to eq 2000 expect(li1.price).to eq 20.00 end end context "modifying the quantity of a line item" do before do toggle_columns "Price" end it "price is altered" do within "tr#li_#{li1.id}" do expect(page).to have_field "price", with: format('%.2f', li1.price * 5).to_s fill_in "quantity", with: 6 expect(page).to have_field "price", with: format('%.2f', li1.price * 6).to_s end end end context "modifying the quantity of a line item" do before do toggle_columns "Weight/Volume" end it "weight/volume is altered" do within "tr#li_#{li1.id}" do expect(page).to have_field "final_weight_volume", with: li1.final_weight_volume.round.to_s fill_in "quantity", with: 6 expect(page).to have_field "final_weight_volume", with: ((li1.final_weight_volume * 6) / 5).round.to_s end end end context "using column display toggle" do it "displays the default selected columns" do expect(page).to have_selector "th", text: "Name" expect(page).to have_selector "th", text: 'Completed at' expect(page).to have_selector "th", text: "Producer" expect(page).to have_selector "th", text: "Product: Unit" expect(page).to have_selector "th", text: "Quantity" expect(page).to have_selector "th", text: "Max" end context "hiding a column, by de-selecting it from the drop-down" do before do toggle_columns "Producer" end it "shows all default columns, except the de-selected column" do expect(page).not_to have_selector "th", text: "Producer" expect(page).to have_selector "th", text: "Name" expect(page).to have_selector "th", text: 'Completed at' expect(page).to have_selector "th", text: "Product: Unit" expect(page).to have_selector "th", text: "Quantity" expect(page).to have_selector "th", text: "Max" end end end context "using drop down seletors" do context "supplier filter" do let!(:s1) { create(:supplier_enterprise) } let!(:s2) { create(:supplier_enterprise) } let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, order_cycle: create(:simple_order_cycle) ) } let!(:li1) { create(:line_item_with_shipment, order: o1, variant: create(:variant, supplier: s1) ) } let!(:li2) { create(:line_item_with_shipment, order: o1, variant: create(:variant, supplier: s2) ) } before :each do visit_bulk_order_management end it "displays select box for producers, which filters line items by the selected supplier" do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" open_select2 "#s2id_supplier_filter" expect(page).to have_selector "div.select2-drop-active ul.select2-results li", text: "All" Enterprise.is_primary_producer.map(&:name).each do |sn| expect(page).to have_selector "div.select2-drop-active ul.select2-results li", text: sn end close_select2 select2_select s1.name, from: "supplier_filter" page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" end it "displays all line items when 'All' is selected from supplier filter" do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" select2_select s1.name, from: "supplier_filter" page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" select2_select "All", from: "supplier_filter" page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" end end context "distributor filter" do let!(:d1) { create(:distributor_enterprise) } let!(:d2) { create(:distributor_enterprise) } let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, distributor: d1, order_cycle: create(:simple_order_cycle) ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, distributor: d2, order_cycle: create(:simple_order_cycle) ) } let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item_with_shipment, order: o2 ) } before :each do visit_bulk_order_management end it "displays a select box for distributors, which filters line items " \ "by the selected distributor", retry: 3 do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" find("#s2id_distributor_filter .select2-chosen").click expect(page).to have_selector "div.select2-drop-active ul.select2-results li", text: "All" Enterprise.is_distributor.map(&:name).each do |dn| expect(page).to have_selector "div.select2-drop-active ul.select2-results li", text: dn end find(".select2-result-label", text: d1.name.to_s).click page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" end it "displays all line items when 'All' is selected from distributor filter", retry: 3 do # displays orders from one enterprise only expect(page).to have_selector "tr#li_#{li2.id}" find("#s2id_distributor_filter .select2-chosen").click find(".select2-result-label", text: d1.name.to_s).click page.find('.filter-actions .button.icon-search').click expect(page).not_to have_selector "tr#li_#{li2.id}" # displays orders from all enterprises find("#s2id_distributor_filter .select2-chosen").click find(".select2-result-label", text: "All").click page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" end end context "order_cycle filter selected" do let!(:distributor) { create(:distributor_enterprise) } let!(:oc1) { create(:simple_order_cycle, distributors: [distributor]) } let!(:oc2) { create(:simple_order_cycle, distributors: [distributor]) } let!(:oc3) { create(:simple_order_cycle, distributors: [distributor]) } let!(:oc4) do create( :simple_order_cycle, orders_close_at: 364.days.ago, orders_open_at: 400.days.ago, distributors: [distributor] ) end let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, order_cycle: oc1 ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, order_cycle: oc2 ) } let!(:o3) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: 1.week.from_now, order_cycle: oc3 ) } let!(:o3a) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: 2.weeks.from_now, order_cycle: oc3 ) } let!(:o4) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: 100.days.ago, order_cycle: oc4 ) } let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item_with_shipment, order: o2 ) } let!(:li3) { create(:line_item_with_shipment, order: o3 ) } let!(:li3a) { create(:line_item_with_shipment, order: o3a ) } let!(:li4) { create(:line_item_with_shipment, order: o4 ) } before do oc3.update!(orders_close_at: 2.weeks.from_now) oc3.update!(orders_open_at: 1.week.from_now) visit_bulk_order_management expect_line_items(li1, li2, li3, li3a, li4) select2_select oc1.name, from: "order_cycle_filter" page.find('.filter-actions .button.icon-search').click end it "displays a select box for order cycles, which filters line items " \ "by the selected order cycle", retry: 3 do expect(page).to have_select2 'order_cycle_filter', with_options: OrderCycle.pluck(:name).unshift("All") expect(page).not_to have_selector "#loading i" expect_line_items(li1, excluding: [li2, li3, li3a, li4]) end it "displays all line items when 'All' is selected from order_cycle filter", retry: 3 do select2_select "All", from: "order_cycle_filter" page.find('.filter-actions .button.icon-search').click expect_line_items(li1, li2, li3, li3a, li4) end end context "combination of filters" do let!(:s1) { create(:supplier_enterprise) } let!(:s2) { create(:supplier_enterprise) } let!(:d1) { create(:distributor_enterprise) } let!(:d2) { create(:distributor_enterprise) } let!(:oc1) { create(:simple_order_cycle, suppliers: [s1], distributors: [d1] ) } let!(:oc2) { create(:simple_order_cycle, suppliers: [s2], distributors: [d2] ) } let!(:v1) { create(:variant, supplier: s1) } let!(:v2) { create(:variant, supplier: s2) } let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, distributor: d1, order_cycle: oc1 ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, distributor: d2, order_cycle: oc2 ) } let!(:li1) { create(:line_item_with_shipment, order: o1, variant: v1 ) } let!(:li2) { create(:line_item_with_shipment, order: o2, variant: v2 ) } before :each do visit_bulk_order_management end it "allows filters to be used in combination", retry: 3 do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" click_on_select2 oc1.name, from: "order_cycle_filter" page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" click_on_select2 d1.name, from: "distributor_filter" click_on_select2 s1.name, from: "supplier_filter" page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" click_on_select2 d2.name, from: "distributor_filter" click_on_select2 s2.name, from: "supplier_filter" page.find('.filter-actions .button.icon-search').click expect(page).not_to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" click_on_select2 oc2.name, from: "order_cycle_filter" page.find('.filter-actions .button.icon-search').click expect(page).not_to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" end it "displays a 'Clear All' button which sets all select filters to 'All'", retry: 3 do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" click_on_select2 oc1.name, from: "order_cycle_filter" click_on_select2 d1.name, from: "distributor_filter" click_on_select2 s1.name, from: "supplier_filter" page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" page.find('.filter-actions #clear_filters_button').click expect(page).to have_selector "div#s2id_order_cycle_filter a.select2-choice", text: "All" expect(page).to have_selector "div#s2id_supplier_filter a.select2-choice", text: "All" expect(page).to have_selector "div#s2id_distributor_filter a.select2-choice", text: "All" expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" end end end context "using date restriction controls" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.today - 7.days - 1.second) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.today - 6.days) } let!(:o3) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now.end_of_day) } let!(:o4) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now.end_of_day + 1.day) } let!(:li1) { create(:line_item_with_shipment, order: o1, quantity: 1 ) } let!(:li2) { create(:line_item_with_shipment, order: o2, quantity: 2 ) } let!(:li3) { create(:line_item_with_shipment, order: o3, quantity: 3 ) } let!(:li4) { create(:line_item_with_shipment, order: o4, quantity: 4 ) } let(:today) { Time.zone.today } before :each do visit_bulk_order_management end it "loads all line items because no date restriction on first load" do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" expect(page).to have_selector "tr#li_#{li3.id}" expect(page).to have_selector "tr#li_#{li4.id}" end it "displays only line items whose orders meet the date restriction criteria, when changed", retry: 3 do from = today - 8.days to = today + 1.day find("input.datepicker").click select_dates_from_daterangepicker(from, today) page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" expect(page).to have_selector "tr#li_#{li3.id}" expect(page).not_to have_selector "tr#li_#{li4.id}" find("input.datepicker").click select_dates_from_daterangepicker(from, to) page.find('.filter-actions .button.icon-search').click expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" expect(page).to have_selector "tr#li_#{li3.id}" expect(page).to have_selector "tr#li_#{li4.id}" end context "when the form is dirty" do before do within("tr#li_#{li2.id} td.quantity") do page.fill_in "quantity", with: (li2.quantity + 1).to_s end end it "shows a dialog and ignores changes when confirm dialog is accepted" do accept_confirm "Unsaved changes exist and will be lost if you continue." do find("input.datepicker").click select_dates_from_daterangepicker(today - 9.days, today) page.find('.filter-actions .button.icon-search').click end # daterange picker should have changed expect(find("input.datepicker").value) .to eq "#{today.prev_day(9).strftime('%F')} to #{today.strftime('%F')}" expect(page).not_to have_selector "#save-bar" within("tr#li_#{li2.id} td.quantity") do expect(page).not_to have_selector "input[name=quantity].ng-dirty" end end it "shows a dialog and keeps changes when confirm dialog is rejected" do previousdaterangestring = find("input.datepicker").value dismiss_confirm "Unsaved changes exist and will be lost if you continue." do find("input.datepicker").click select_dates_from_daterangepicker(today - 9.days, today) page.find('.filter-actions .button.icon-search').click end expect(page).to have_selector "#save-bar" within("tr#li_#{li2.id} td.quantity") do expect(page).to have_selector "input[name=quantity].ng-dirty" end end end end context "bulk action controls" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li11) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item_with_shipment, order: o2 ) } before :each do visit_bulk_order_management end it "displays a checkbox for each line item in the list" do expect(page).to have_selector "tr#li_#{li1.id} input[type='checkbox'][name='bulk']" expect(page).to have_selector "tr#li_#{li2.id} input[type='checkbox'][name='bulk']" end # rubocop:disable Rails/FindEach. # These are Capybara finders it "displays a checkbox to which toggles the 'checked' state of all checkboxes" do check "toggle_bulk" page.all("input[type='checkbox'][name='bulk']").each{ |checkbox| expect(checkbox.checked?).to be true } uncheck "toggle_bulk" page.all("input[type='checkbox'][name='bulk']").each{ |checkbox| expect(checkbox.checked?).to be false } end # rubocop:enable Rails/FindEach it "displays a bulk action select box with a list of actions" do list_of_actions = ['Delete Selected'] find("div#bulk-actions-dropdown").click within("div#bulk-actions-dropdown") do list_of_actions.each { |action_name| expect(page).to have_selector "div.menu_item", text: action_name } end end context "performing actions" do context "deletes selected items" do it "displays a confirmation dialog when deleting one or more items " \ "leads to order cancelation" do expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li11.id}" within("tr#li_#{li1.id} td.bulk") do check "bulk" end within("tr#li_#{li11.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 expect(page).to have_content "This operation will result in one or more empty " \ "orders, which will be cancelled. Do you wish to proceed?" expect do within(".modal") do check("send_cancellation_email") click_on("OK") end # order 1 should be canceled expect(page).not_to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li11.id}" expect(o1.reload.state).to eq("canceled") # order 2 should not be canceled expect(page).to have_selector "tr#li_#{li2.id}" expect(o2.reload.state).to eq("complete") end.to have_enqueued_mail(Spree::OrderMailer, :cancel_email) end it "deletes one line item should show modal confirmation about this line item deletion " \ "and not about order cancelation" do expect(page).to have_selector "tr#li_#{li1.id}" within("tr#li_#{li1.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 within ".modal" do expect(page).to have_content "This will delete one line item from the order. " \ "Are you sure you want to proceed?" click_on "OK" end expect(page).not_to have_selector ".modal" expect(page).not_to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li11.id}" expect(o1.reload.state).to eq("complete") end end end end context "using action buttons" do context "using edit buttons" do let(:address) { create(:address) } let!(:o1) { create(:order_with_distributor, ship_address: address, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, ship_address: address, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item_with_shipment, order: o2 ) } before :each do o1.update_totals_and_states o2.update_totals_and_states visit_bulk_order_management end it "shows an edit button for line_items, which takes the user " \ "to the standard edit page for the order" do expect(page).to have_selector "a.edit-order", count: 2 # Shows a confirm dialog when unsaved changes exist page.driver .dismiss_modal :confirm, text: "Unsaved changes exist and will be lost if you continue." do within "tr#li_#{li1.id}" do fill_in "quantity", with: (li1.quantity + 1) find("a.edit-order").click end end # So we save the changes expect(URI.parse(current_url).path).to eq "/admin/orders/bulk_management" click_button "Save Changes" expect(page).to have_selector "#save-bar", text: "All changes saved" # And try again within "tr#li_#{li1.id}" do find("a.edit-order").click end expect(URI.parse(current_url).path).to eq "/admin/orders/#{o1.number}/edit" end end context "using delete buttons" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item_with_shipment, order: o2 ) } context "when deleting a line item of an order that have more than one line item" do let!(:li12) { create(:line_item_with_shipment, order: o1 ) } it "removes a line item when the relevant delete button is clicked" do visit_bulk_order_management expect(page).to have_selector "a.delete-line-item", count: 3 accept_alert do find("tr#li_#{li1.id} a.delete-line-item").click end expect(page).to have_selector "a.delete-line-item", count: 2 end end context "when deleting the last item of an order, " \ "it shows a modal about order cancellation" do before :each do visit_bulk_order_management expect(page).to have_selector "a.delete-line-item", count: 2 find("tr#li_#{li2.id} a.delete-line-item").click expect(page) .to have_content "This operation will result in one or more empty orders, " \ "which will be cancelled. Do you wish to proceed?" expect(page).to have_checked_field "Restock Items: return all items to stock" end it "the user can cancel : no line item is deleted" do within(".modal") do click_on("Cancel") end expect(o2.reload.line_items.length).to eq(1) expect(page).to have_selector "a.delete-line-item", count: 2 end it "the user can confirm : line item is then deleted and order is canceled" do expect_any_instance_of(Spree::Variant).to receive(:move).at_least(1).times expect do within(".modal") do uncheck("send_cancellation_email") click_on("OK") end expect(page).to have_selector "a.delete-line-item", count: 1 expect(o2.reload.state).to eq("canceled") end.not_to have_enqueued_mail(Spree::OrderMailer, :cancel_email) end it "the user can confirm + wants to send email confirmation : line item is " \ "then deleted, order is canceled and email is sent" do expect_any_instance_of(Spree::Variant).to receive(:move).at_least(1).times expect do within(".modal") do check("send_cancellation_email") click_on("OK") end expect(page).to have_selector "a.delete-line-item", count: 1 expect(o2.reload.state).to eq("canceled") end.to have_enqueued_mail(Spree::OrderMailer, :cancel_email) end it "the user can confirm + uncheck the restock option: line item is then deleted and " \ "order is canceled without retocking" do expect_any_instance_of(Spree::Variant).not_to receive(:move) expect do within(".modal") do uncheck("Restock Items: return all items to stock") click_on("OK") end expect(page).to have_selector "a.delete-line-item", count: 1 expect(o2.reload.state).to eq("canceled") end.to have_enqueued_mail(Spree::OrderMailer, :cancel_email) end end end end context "clicking the link on variant name" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:li1) { create(:line_item_with_shipment, order: o1 ) } let!(:li2) { create(:line_item_with_shipment, order: o2 ) } let!(:p3) { create(:product, group_buy: true, group_buy_unit_size: 5000, variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] ) } let!(:v3) { p3.variants.first } let!(:o3) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now ) } let!(:li3) { create(:line_item_with_shipment, order: o3, variant: v3, quantity: 3, max_quantity: 6 ) } let!(:li4) { create(:line_item_with_shipment, order: o2, variant: v3, quantity: 1, max_quantity: 3 ) } before :each do visit_bulk_order_management within "tr#li_#{li3.id}" do find("a", text: "#{li3.product.name}: #{li3.variant.options_text}").click end end shared_examples "display only group by information for selected variant" do it "displays group buy calc box" do expect(page).to have_selector "div#group_buy_calculation" within "div#group_buy_calculation" do expect(page).to have_text "Group Buy Unit Size" expect(page).to have_text "5000 g" expect(page).to have_text "Total Quantity Ordered" expect(page).to have_text "4000 g" expect(page).to have_text "Max Quantity Ordered" expect(page).to have_text "9000 g" expect(page).to have_text "Current Fulfilled Units" expect(page).to have_text "0.8" expect(page).to have_text "Max Fulfilled Units" expect(page).to have_text "1.8" expect(page).to have_selector "div.shared_resource" within "div.shared_resource" do expect(page).to have_selector "span", text: "Shared Resource?" expect(page).to have_selector "input#shared_resource" end end end it "all line items of the same variant" do expect(page).not_to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" expect(page).to have_selector "tr#li_#{li3.id}" expect(page).to have_selector "tr#li_#{li4.id}" expect(page).to have_css("table#listing_orders tbody tr", count: 2) end end it_behaves_like "display only group by information for selected variant" context "clicking 'Clear' in group buy box" do before :each do click_link "Clear" # closes BOM box end it "shows all products and clears group buy box" do expect(page).not_to have_selector "div#group_buy_calculation" expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" expect(page).to have_selector "tr#li_#{li3.id}" expect(page).to have_selector "tr#li_#{li4.id}" end end context "when filtering" do before do fill_in "quick_filter", with: li3.order.email page.find('.filter-actions .button.icon-search').click end it "shows only variant filtering by email" do expect(page).not_to have_selector "tr#li_#{li1.id}" expect(page).not_to have_selector "tr#li_#{li2.id}" expect(page).to have_selector "tr#li_#{li3.id}" expect(page).not_to have_selector "tr#li_#{li4.id}" end context "clicking 'Clear Filters' button" do before :each do page.find('.filter-actions #clear_filters_button').click end it_behaves_like "display only group by information for selected variant" it "but actually clears the filters" do expect(page.find("input[name='quick_filter']").value).to eq("") end end end end end context "as an enterprise manager" do let(:s1) { create(:supplier_enterprise, name: 'First Supplier') } let(:d1) { create(:distributor_enterprise, name: 'First Distributor') } let(:d2) { create(:distributor_enterprise, name: 'Another Distributor') } let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, distributor: d1 ) } let!(:o2) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, distributor: d2 ) } let!(:line_item_distributed) { create(:line_item_with_shipment, order: o1, variant: create(:variant, supplier: s1) ) } let!(:line_item_not_distributed) { create(:line_item_with_shipment, order: o2, variant: create(:variant, supplier: s1) ) } before(:each) do enterprise_user = create(:user) enterprise_user.enterprise_roles.build(enterprise: s1).save enterprise_user.enterprise_roles.build(enterprise: d1).save login_as enterprise_user end it "displays a Bulk Management Tab under the Orders item" do visit '/admin/orders' expect(page).to have_link "Bulk order management" click_link "Bulk order management" expect(page).to have_selector "h1.page-title", text: "Bulk Order Management" end it "shows only line item from orders that I distribute, and not those that I supply" do visit_bulk_order_management expect(page).to have_selector "tr#li_#{line_item_distributed.id}" expect(page).not_to have_selector "tr#li_#{line_item_not_distributed.id}" end end def visit_bulk_order_management visit spree.admin_bulk_order_management_path expect(page).not_to have_text 'Loading orders' end def expect_line_items(*line_items, excluding: []) line_items.each do |line_item| expect(page).to have_selector "tr#li_#{line_item.id}" end excluding.each do |line_item| expect(page).not_to have_selector "tr#li_#{line_item.id}" end end end