Merge remote-tracking branch 'origin/fix_taxonomy' into fix_taxonomy

This commit is contained in:
Neal Chambers
2023-03-06 15:09:13 +09:00
13 changed files with 345 additions and 56 deletions

View File

@@ -15,7 +15,9 @@ module CheckoutCallbacks
prepend_before_action :require_distributor_chosen
before_action :load_order, :associate_user, :load_saved_addresses, :load_saved_credit_cards
before_action :load_shipping_methods, if: -> { params[:step] == "details" }
before_action :allowed_shipping_methods, if: -> {
params[:step] == "details"
}
before_action :ensure_order_not_completed
before_action :ensure_checkout_allowed
@@ -46,8 +48,22 @@ module CheckoutCallbacks
@selected_card = nil
end
def load_shipping_methods
@shipping_methods = available_shipping_methods.sort { |a, b| a.name.casecmp(b.name) }
def allowed_shipping_methods
@allowed_shipping_methods ||= sorted_available_shipping_methods.filter(
&method(:supports_all_products_shipping_categories?)
)
end
def sorted_available_shipping_methods
available_shipping_methods.sort { |a, b| a.name.casecmp(b.name) }
end
def supports_all_products_shipping_categories?(shipping_method)
(products_shipping_categories - shipping_method.shipping_categories.pluck(:id)).empty?
end
def products_shipping_categories
@products_shipping_categories ||= @order.products.pluck(:shipping_category_id).uniq
end
def redirect_to_shop?

View File

@@ -24,7 +24,7 @@ class SplitCheckoutController < ::BaseController
check_step if params[:step]
recalculate_tax if params[:step] == "summary"
flash_error_when_no_shipping_method_available if available_shipping_methods.none?
flash_error_when_no_shipping_method_available if allowed_shipping_methods.none?
end
def update

View File

@@ -30,8 +30,10 @@ class OrderCycleForm
order_cycle.schedule_ids = schedule_ids if parameter_specified?(:schedule_ids)
order_cycle.save!
apply_exchange_changes
attach_selected_distributor_payment_methods
attach_selected_distributor_shipping_methods
if can_update_selected_payment_or_shipping_methods?
attach_selected_distributor_payment_methods
attach_selected_distributor_shipping_methods
end
sync_subscriptions
true
end
@@ -61,14 +63,33 @@ class OrderCycleForm
def attach_selected_distributor_payment_methods
return if @selected_distributor_payment_method_ids.nil?
order_cycle.selected_distributor_payment_method_ids = selected_distributor_payment_method_ids
if distributor_only?
payment_method_ids = order_cycle.selected_distributor_payment_method_ids
payment_method_ids -= user_distributor_payment_method_ids
payment_method_ids += user_only_selected_distributor_payment_method_ids
order_cycle.selected_distributor_payment_method_ids = payment_method_ids
else
order_cycle.selected_distributor_payment_method_ids = selected_distributor_payment_method_ids
end
order_cycle.save!
end
def attach_selected_distributor_shipping_methods
return if @selected_distributor_shipping_method_ids.nil?
order_cycle.selected_distributor_shipping_method_ids = selected_distributor_shipping_method_ids
if distributor_only?
# A distributor can only update methods associated with their own
# enterprise, so we load all previously selected methods, and replace
# only the distributor's methods with their selection (not touching other
# distributor's methods).
shipping_method_ids = order_cycle.selected_distributor_shipping_method_ids
shipping_method_ids -= user_distributor_shipping_method_ids
shipping_method_ids += user_only_selected_distributor_shipping_method_ids
order_cycle.selected_distributor_shipping_method_ids = shipping_method_ids
else
order_cycle.selected_distributor_shipping_method_ids = selected_distributor_shipping_method_ids
end
order_cycle.save!
end
@@ -99,6 +120,10 @@ class OrderCycleForm
@selected_distributor_payment_method_ids
end
def user_only_selected_distributor_payment_method_ids
user_distributor_payment_method_ids.intersection(selected_distributor_payment_method_ids)
end
def selected_distributor_shipping_method_ids
@selected_distributor_shipping_method_ids = (
attachable_distributor_shipping_method_ids &
@@ -112,6 +137,10 @@ class OrderCycleForm
@selected_distributor_shipping_method_ids
end
def user_only_selected_distributor_shipping_method_ids
user_distributor_shipping_method_ids.intersection(selected_distributor_shipping_method_ids)
end
def build_schedule_ids
return unless parameter_specified?(:schedule_ids)
@@ -160,4 +189,37 @@ class OrderCycleForm
def new_schedule_ids
@order_cycle.schedule_ids - existing_schedule_ids
end
def can_update_selected_payment_or_shipping_methods?
@user.admin? || coordinator? || distributor?
end
def coordinator?
@user.enterprises.include?(@order_cycle.coordinator)
end
def distributor?
!user_distributors_ids.empty?
end
def distributor_only?
distributor? && !@user.admin? && !coordinator?
end
def user_distributors_ids
@user_distributors_ids ||= @user.enterprises.pluck(:id)
.intersection(@order_cycle.distributors.pluck(:id))
end
def user_distributor_payment_method_ids
@user_distributor_payment_method_ids ||=
DistributorPaymentMethod.where(distributor_id: user_distributors_ids)
.pluck(:id)
end
def user_distributor_shipping_method_ids
@user_distributor_shipping_method_ids ||=
DistributorShippingMethod.where(distributor_id: user_distributors_ids)
.pluck(:id)
end
end

View File

@@ -76,8 +76,8 @@
- display_ship_address = false
- ship_method_description = nil
- selected_shipping_method ||= @shipping_methods[0].id if @shipping_methods.length == 1
- @shipping_methods.each do |shipping_method|
- selected_shipping_method ||= @allowed_shipping_methods[0].id if @allowed_shipping_methods.length == 1
- @allowed_shipping_methods.each do |shipping_method|
- ship_method_is_selected = shipping_method.id == selected_shipping_method.to_i
%div.checkout-input.checkout-input-radio
= fields_for shipping_method do |shipping_method_form|

View File

@@ -1335,6 +1335,7 @@ en_FR:
payment_methods: Payment Methods Report
delivery: Delivery Report
sales_tax_totals_by_producer: Sales Tax Totals By Producer
sales_tax_totals_by_order: Sales Tax Totals By Order
tax_types: Tax Types
tax_rates: Tax Rates
pack_by_customer: Pack By Customer

View File

@@ -2073,7 +2073,7 @@ en_GB:
components_filters_clearfilters: "Clear all filters"
groups_title: Groups
groups_headline: Groups / regions
groups_text: "Every producer is unique. Every business has something different to offer. Our groups are collectives of producers, hubs and distributors who share something in common like location, farmers market or philosophy. This makes your shopping experience easier. So explore our groups and have the curating done for you."
groups_text: "Every producer is unique. Every business has something different to offer. Our groups are collectives of producers, hubs and distributors who share something in common, whether that's belonging to a local farmers market, specialising in a specific product, or sharing a philosophy. Explore our curated groups below."
groups_search: "Search name or keyword"
groups_no_groups: "No groups found"
groups_about: "About Us"

View File

@@ -1336,6 +1336,7 @@ fr:
payment_methods: Rapport Méthodes de Paiement
delivery: Rapport de Livraison
sales_tax_totals_by_producer: Détail des montants de taxes par producteur
sales_tax_totals_by_order: Détail des montants de taxes par commande
tax_types: Par type de taxe
tax_rates: Par taux de taxe
pack_by_customer: Préparation des commandes par Acheteur

View File

@@ -20,7 +20,7 @@
},
"dependencies": {
"@babel/preset-env": "^7.18.2",
"@floating-ui/dom": "^1.2.1",
"@floating-ui/dom": "^1.2.3",
"@hotwired/turbo": "^7.3.0",
"@rails/webpacker": "5.4.4",
"babel-loader": "^8.2.3",

View File

@@ -0,0 +1,5 @@
Distributor,Order Cycle,Order number,Tax Category,Tax Rate Name,Tax Rate,Total excl. tax ($),Tax,Total incl. tax ($),First Name,Last Name,Code,Email
Distributor,oc1,ORDER_NUMBER_1,tax_category,State,0.015,115.0,1.73,116.73,cfname,clname,ABC123,order1@example.com
Distributor,oc1,ORDER_NUMBER_1,tax_category,Country,0.025,115.0,2.88,117.88,cfname,clname,ABC123,order1@example.com
Distributor,oc1,ORDER_NUMBER_2,tax_category,State,0.015,215.0,3.23,218.23,c2fname,c2lname,DEF456,order2@example.com
Distributor,oc1,ORDER_NUMBER_2,tax_category,Country,0.025,215.0,5.38,220.38,c2fname,c2lname,DEF456,order2@example.com
1 Distributor Order Cycle Order number Tax Category Tax Rate Name Tax Rate Total excl. tax ($) Tax Total incl. tax ($) First Name Last Name Code Email
2 Distributor oc1 ORDER_NUMBER_1 tax_category State 0.015 115.0 1.73 116.73 cfname clname ABC123 order1@example.com
3 Distributor oc1 ORDER_NUMBER_1 tax_category Country 0.025 115.0 2.88 117.88 cfname clname ABC123 order1@example.com
4 Distributor oc1 ORDER_NUMBER_2 tax_category State 0.015 215.0 3.23 218.23 c2fname c2lname DEF456 order2@example.com
5 Distributor oc1 ORDER_NUMBER_2 tax_category Country 0.025 215.0 5.38 220.38 c2fname c2lname DEF456 order2@example.com

Binary file not shown.

View File

@@ -223,22 +223,93 @@ describe OrderCycleForm do
context "updating payment methods" do
context "and it's valid" do
it "saves the changes" do
distributor = create(:distributor_enterprise)
distributor_payment_method = create(
:payment_method,
distributors: [distributor]
).distributor_payment_methods.first
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
let!(:distributor){ create(:distributor_enterprise) }
let!(:payment_method){ create(:payment_method, distributors: [distributor]) }
let!(:payment_method2){ create(:payment_method, distributors: [distributor]) }
let!(:distributor_payment_method){ distributor.distributor_payment_methods.first.id }
let!(:distributor_payment_method2){ distributor.distributor_payment_methods.second.id }
let!(:supplier){ create(:supplier_enterprise) }
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_payment_method_ids: [distributor_payment_method.id] },
order_cycle.coordinator
)
context "the submitter is a coordinator" do
it "saves the changes" do
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
expect(form.save).to be true
expect(order_cycle.distributor_payment_methods).to eq [distributor_payment_method]
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_payment_method_ids: [distributor_payment_method] },
order_cycle.coordinator.users.first
)
expect{ form.save }.to change{ order_cycle.distributor_payment_methods.pluck(:id) }
.from([distributor_payment_method, distributor_payment_method2])
.to([distributor_payment_method])
end
end
context "submitter is a supplier" do
it "doesn't save the changes" do
order_cycle = create(:distributor_order_cycle, distributors: [distributor],
suppliers: [supplier])
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_payment_method_ids: [distributor_payment_method] },
supplier.users.first
)
expect{ form.save }.to_not change{ order_cycle.distributor_payment_methods.pluck(:id) }
end
end
context "submitter is an admin" do
it "saves the changes" do
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_payment_method_ids: [distributor_payment_method2] },
create(:admin_user)
)
expect{ form.save }.to change{ order_cycle.distributor_payment_methods.pluck(:id) }
.from([distributor_payment_method, distributor_payment_method2])
.to([distributor_payment_method2])
end
end
context "submitter is a distributor" do
context "can update his own payment methods" do
it "saves the changes" do
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_payment_method_ids: [distributor_payment_method] },
distributor.users.first
)
expect{ form.save }.to change{ order_cycle.distributor_payment_methods.pluck(:id) }
.from([distributor_payment_method, distributor_payment_method2])
.to([distributor_payment_method])
end
end
context "can't update other distributors' payment methods" do
let(:distributor2){ create(:distributor_enterprise) }
it "doesn't save the changes" do
order_cycle = create(:distributor_order_cycle,
distributors: [distributor, distributor2])
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_payment_method_ids: [distributor_payment_method] },
distributor2.users.first
)
expect{ form.save }.to_not change{
order_cycle.distributor_payment_methods.pluck(:id)
}
end
end
end
end
@@ -260,33 +331,113 @@ describe OrderCycleForm do
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_payment_method_ids: [distributor_payment_method_ii.id] },
order_cycle.coordinator
order_cycle.coordinator.users.first
)
expect(form.save).to be true
expect(order_cycle.distributor_payment_methods).to eq [distributor_payment_method_i]
expect{ form.save }.not_to change{
order_cycle.distributor_payment_methods.pluck(:id)
}.from([distributor_payment_method_i.id])
end
end
end
context "updating shipping methods" do
context "and it's valid" do
it "saves the changes" do
distributor = create(:distributor_enterprise)
distributor_shipping_method = create(
:shipping_method,
distributors: [distributor]
).distributor_shipping_methods.first
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
let!(:distributor){ create(:distributor_enterprise) }
let!(:shipping_method){ create(:shipping_method, distributors: [distributor]) }
let!(:shipping_method2){ create(:shipping_method, distributors: [distributor]) }
let!(:distributor_shipping_method){ distributor.distributor_shipping_methods.first.id }
let!(:distributor_shipping_method2){ distributor.distributor_shipping_methods.second.id }
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_shipping_method_ids: [distributor_shipping_method.id] },
order_cycle.coordinator
)
let(:supplier){ create(:supplier_enterprise) }
context "the submitter is a coordinator" do
it "saves the changes" do
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
expect(form.save).to be true
expect(order_cycle.distributor_shipping_methods).to eq [distributor_shipping_method]
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_shipping_method_ids: [distributor_shipping_method] },
order_cycle.coordinator.users.first
)
expect{ form.save }.to change{ order_cycle.distributor_shipping_methods.pluck(:id) }
.from([distributor_shipping_method, distributor_shipping_method2])
.to([distributor_shipping_method])
end
end
context "submitter is a supplier" do
it "doesn't save the changes" do
order_cycle = create(:distributor_order_cycle, distributors: [distributor],
suppliers: [supplier])
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_shipping_method_ids: [distributor_shipping_method] },
supplier.users.first
)
expect{ form.save }.not_to change{
order_cycle.distributor_shipping_methods.pluck(:id)
}.from([distributor_shipping_method, distributor_shipping_method2])
end
end
context "submitter is an admin" do
it "saves the changes" do
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_shipping_method_ids: [distributor_shipping_method] },
create(:admin_user)
)
expect{ form.save }.to change{ order_cycle.distributor_shipping_methods.pluck(:id) }
.from([distributor_shipping_method, distributor_shipping_method2])
.to([distributor_shipping_method])
end
end
context "submitter is a distributor" do
context "can update his own shipping methods" do
it "saves the changes" do
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_shipping_method_ids: [distributor_shipping_method] },
distributor.users.first
)
expect{ form.save }.to change{
order_cycle.distributor_shipping_methods.pluck(:id)
}.from([
distributor_shipping_method, distributor_shipping_method2
]).to([distributor_shipping_method])
end
end
context "can't update other distributors' shipping methods" do
let!(:distributor2){ create(:distributor_enterprise) }
let!(:shipping_method3){ create(:shipping_method, distributors: [distributor2]) }
let!(:distributor_shipping_method3){
distributor2.distributor_shipping_methods.first.id
}
it "doesn't save the changes" do
order_cycle = create(:distributor_order_cycle,
distributors: [distributor, distributor2])
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_shipping_method_ids: [distributor_shipping_method] },
distributor2.users.first
)
expect{ form.save }.not_to change{
order_cycle.distributor_shipping_methods.pluck(:id)
}.from [
distributor_shipping_method, distributor_shipping_method2,
distributor_shipping_method3
]
end
end
end
end
@@ -308,7 +459,7 @@ describe OrderCycleForm do
form = OrderCycleForm.new(
order_cycle,
{ selected_distributor_shipping_method_ids: [distributor_shipping_method_ii.id] },
order_cycle.coordinator
order_cycle.coordinator.users.first
)
expect(form.save).to be true

View File

@@ -105,7 +105,7 @@ describe "Sales Tax Totals By order" do
it "generates the report" do
login_as admin
visit admin_reports_path
click_on I18n.t("admin.reports.sales_tax_totals_by_order")
click_on "Sales Tax Totals By Order"
expect(page).to have_button("Go")
click_on "Go"
@@ -167,7 +167,7 @@ describe "Sales Tax Totals By order" do
it "generates the report" do
login_as admin
visit admin_reports_path
click_on I18n.t("admin.reports.sales_tax_totals_by_order")
click_on "Sales Tax Totals By Order"
expect(page).to have_button("Go")
click_on "Go"
@@ -335,7 +335,7 @@ describe "Sales Tax Totals By order" do
login_as admin
visit admin_reports_path
click_on I18n.t("admin.reports.sales_tax_totals_by_order")
click_on "Sales Tax Totals By Order"
end
it "should load all the orders" do
@@ -423,5 +423,58 @@ describe "Sales Tax Totals By order" do
expect(page.find("table.report__table tbody").text).to have_content(customer2_summary_row)
expect(page).to have_selector(table_raw_selector, count: 6)
end
describe "downloading" do
context "csv files" do
let(:report_file_csv) do
CSV.read("spec/fixtures/reports/sales_tax_by_order/sales_tax_by_order.csv")
end
it 'downloads the file' do
expect(downloaded_filenames.length).to eq(0) # downloads folder should be empty
select "CSV", from: "report_format"
click_on "Go"
wait_for_download
expect(downloaded_filenames.length).to eq(1) # downloads folder should contain 1 file
expect(downloaded_filename).to match(/.*\.csv/)
expect(CSV.read(downloaded_filename)).to eq(report_file_csv)
end
end
context "xlsx files" do
let(:report_file_xlsx) do
File.open("spec/fixtures/reports/sales_tax_by_order/sales_tax_by_order.xlsx")
end
it 'downloads the file' do
expect(downloaded_filenames.length).to eq(0) # downloads folder should be empty
select "Spreadsheet", from: "report_format"
find("#display_summary_row").uncheck
click_on "Go"
wait_for_download
expect(downloaded_filenames.length).to eq(1) # downloads folder should contain 1 file
expect(downloaded_filename).to match(/.*\.xlsx/)
downloaded_content = extract_xlsx_rows(downloaded_filename, 1..5)
fixture_content = extract_xlsx_rows(report_file_xlsx, 1..5)
expect(downloaded_content).to eq(fixture_content)
end
def extract_xlsx_rows(file, range)
xlsx = Roo::Excelx.new(file)
range.map { |i| xlsx.row(i) }
end
end
context "pdf files" do
it 'downloads the file' do
expect(downloaded_filenames.length).to eq(0) # downloads folder should be empty
select "PDF", from: "report_format"
click_on "Go"
wait_for_download
expect(downloaded_filenames.length).to eq(1) # downloads folder should contain 1 file
expect(downloaded_filename).to match(/.*\.pdf/)
end
end
end
end
end

View File

@@ -1397,17 +1397,17 @@
resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
"@floating-ui/core@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.2.1.tgz#074182a1d277f94569c50a6b456e62585d463c8e"
integrity sha512-LSqwPZkK3rYfD7GKoIeExXOyYx6Q1O4iqZWwIehDNuv3Dv425FIAE8PRwtAx1imEolFTHgBEcoFHm9MDnYgPCg==
"@floating-ui/core@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.2.2.tgz#66f62cf1b7de2ed23a09c101808536e68caffaec"
integrity sha512-FaO9KVLFnxknZaGWGmNtjD2CVFuc0u4yeGEofoyXO2wgRA7fLtkngT6UB0vtWQWuhH3iMTZZ/Y89CMeyGfn8pA==
"@floating-ui/dom@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.1.tgz#8f93906e1a3b9f606ce78afb058e874344dcbe07"
integrity sha512-Rt45SmRiV8eU+xXSB9t0uMYiQ/ZWGE/jumse2o3i5RGlyvcbqOF4q+1qBnzLE2kZ5JGhq0iMkcGXUKbFe7MpTA==
"@floating-ui/dom@^1.2.3":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.3.tgz#8dc6fbf799fbb5c29f705b54bdd51f3ab0ee03a2"
integrity sha512-lK9cZUrHSJLMVAdCvDqs6Ug8gr0wmqksYiaoj/bxj2gweRQkSuhg2/V6Jswz2KiQ0RAULbqw1oQDJIMpQ5GfGA==
dependencies:
"@floating-ui/core" "^1.2.1"
"@floating-ui/core" "^1.2.2"
"@hotwired/stimulus-webpack-helpers@^1.0.0":
version "1.0.1"