Compare commits

..

36 Commits

Author SHA1 Message Date
jibees
532d566308 Merge pull request #9014 from openfoodfoundation/transifex
Transifex
2022-03-21 09:32:27 +01:00
Transifex-Openfoodnetwork
eae8129435 Updating translations for config/locales/en_FR.yml 2022-03-19 02:50:56 +11:00
Transifex-Openfoodnetwork
ed0ed3240e Updating translations for config/locales/fr.yml 2022-03-19 02:47:16 +11:00
Transifex-Openfoodnetwork
5d8cdc3246 Updating translations for config/locales/de_DE.yml 2022-03-19 01:36:44 +11:00
Transifex-Openfoodnetwork
27e31ae09d Updating translations for config/locales/de_DE.yml 2022-03-19 01:36:01 +11:00
Transifex-Openfoodnetwork
f4ce08d39c Updating translations for config/locales/de_DE.yml 2022-03-19 01:31:31 +11:00
Filipe
87c79a5941 Merge pull request #8294 from guidoDutra/8131-cancel-empty-orders-on-BOM-page
Cancel empty orders on BOM page
2022-03-18 11:24:26 +00:00
Filipe
19270f1777 Merge pull request #8987 from jibees/8981-BOM-correct-value-for-current-and-max-fullfilled
BOM: correct max and current fulfilled units values
2022-03-17 18:15:59 +00:00
Filipe
f079fcb49a Merge pull request #8992 from openfoodfoundation/dependabot/npm_and_yarn/flatpickr-4.6.11
Bump flatpickr from 4.6.9 to 4.6.11
2022-03-17 16:52:49 +00:00
Filipe
c535ed5789 Merge pull request #8936 from cillian/language-metatags
Include language metatags in html template when more than one language available
2022-03-17 16:16:07 +00:00
Filipe
53544ee66a Merge pull request #8805 from cillian/remove-inline-advanced-settings-toggle-js
Replace inline JS for toggling order cycle advanced settings with StimulusJs controller
2022-03-17 16:05:46 +00:00
Filipe
0dd398abba Merge pull request #8926 from mkllnk/8925-invalid-param
Gracefully handle admin UI failure on updating enterprise notifications
2022-03-17 14:19:34 +00:00
jibees
56912bb807 Merge pull request #9010 from openfoodfoundation/transifex
Transifex
2022-03-17 14:21:41 +01:00
Transifex-Openfoodnetwork
37801f1345 Updating translations for config/locales/en_IE.yml 2022-03-17 22:14:51 +11:00
jibees
43b284a175 Merge pull request #9005 from openfoodfoundation/transifex
Transifex
2022-03-17 11:04:47 +01:00
Maikel
ab5a323044 Merge pull request #8980 from openfoodfoundation/dependabot/npm_and_yarn/karma-chrome-launcher-3.1.1
Bump karma-chrome-launcher from 3.1.0 to 3.1.1
2022-03-17 09:47:11 +11:00
Transifex-Openfoodnetwork
08755acfd1 Updating translations for config/locales/hu.yml 2022-03-17 04:39:12 +11:00
jibees
3a0f50395f Merge pull request #8989 from openfoodfoundation/transifex
Transifex
2022-03-16 10:41:55 +01:00
Transifex-Openfoodnetwork
fb83ae2ad4 Updating translations for config/locales/en_GB.yml 2022-03-14 22:48:06 +11:00
dependabot[bot]
b9e0a5ecf7 Bump flatpickr from 4.6.9 to 4.6.11
Bumps [flatpickr](https://github.com/chmln/flatpickr) from 4.6.9 to 4.6.11.
- [Release notes](https://github.com/chmln/flatpickr/releases)
- [Commits](https://github.com/chmln/flatpickr/compare/v4.6.9...v4.6.11)

---
updated-dependencies:
- dependency-name: flatpickr
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 09:05:55 +00:00
Jean-Baptiste Bellet
ea3e15f0c8 Max|Current fulfilled value is the max|current divided by group_buy_unit_size
+ improve testing with representative values
 + Update bulk_order_management_spec.rb and revert previously changed values
2022-03-14 09:06:05 +01:00
jibees
483ec42328 Merge pull request #8990 from jibees/8984-sc-test-failed
SplitCheckout: improve test that failed
2022-03-14 09:03:26 +01:00
Jean-Baptiste Bellet
65596f8467 Do not replace shipping_methods array but push into 2022-03-11 14:34:58 +01:00
Transifex-Openfoodnetwork
d273e97b88 Updating translations for config/locales/de_DE.yml 2022-03-12 00:29:23 +11:00
Transifex-Openfoodnetwork
b410585449 Updating translations for config/locales/en_FR.yml 2022-03-11 23:43:53 +11:00
Transifex-Openfoodnetwork
ac08602d94 Updating translations for config/locales/fr.yml 2022-03-11 23:43:14 +11:00
dependabot[bot]
0b1697c62b Bump karma-chrome-launcher from 3.1.0 to 3.1.1
Bumps [karma-chrome-launcher](https://github.com/karma-runner/karma-chrome-launcher) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/karma-runner/karma-chrome-launcher/releases)
- [Changelog](https://github.com/karma-runner/karma-chrome-launcher/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma-chrome-launcher/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: karma-chrome-launcher
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-10 09:05:18 +00:00
Cillian O'Ruanaidh
21affa6250 Include language metatags in html template when more than one language available
Fixes #8902

This is to help Google find pages in all languages, see https://developers.google.com/search/docs/advanced/crawling/localized-versions
2022-02-25 12:49:49 +00:00
Maikel Linke
8ffe6f6052 Sanitise user_id param on enterprise update 2022-02-24 14:51:23 +11:00
Maikel Linke
8e070f55ff Spec fail on bad enterprise param
It looks like some JS component can submit an invalid value here and it
causes a server error.
2022-02-24 14:46:42 +11:00
Cillian O'Ruanaidh
1b8c1bd27a Only initialise Stimulus app once in Jest tests in :beforeAll rather than :beforeEach
Before there was an issue with the remote_toggle_controller tests, which contains two tests. If you commented out one test and ran the other it would pass and vice versa but if both tests were uncommented only the first test would ever pass, the second one would fail. See https://github.com/openfoodfoundation/openfoodnetwork/pull/8805#discussion_r801464322

Co-authored-by: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
2022-02-11 10:21:26 +00:00
Cillian O'Ruanaidh
b43a68d717 Merge branch 'master' into remove-inline-advanced-settings-toggle-js 2022-02-04 12:24:17 +00:00
Cillian O'Ruanaidh
05756616dd Add a remote-toggle controller that can toggle elements outside of its scope
This is instead of adding the :data-controller attribute to the div#wrapper because that will wrap pretty much all content on the admin pages.

Co-authored-by: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
2022-02-04 12:23:24 +00:00
Cillian O'Ruanaidh
d03b52a163 Revert "Replace inline JS for toggling order cycle advanced settings with StimulusJs controller"
This reverts commit 67ae2e72f3.
2022-02-04 11:47:38 +00:00
Cillian O'Ruanaidh
67ae2e72f3 Replace inline JS for toggling order cycle advanced settings with StimulusJs controller
Partially addresses #8699.

This adjusts the Stimulus toggle controller so you can toggle content in both directions via a single element. This is in addition to the previous behaviour for toggling via multiple elements like radio buttons when each element always toggles in one direction only.

If a toggle element contains a chevron icon this will automatically toggle the direction of that icon too.

Note, in order to not have to re-implement the animation provided by the slideToggle() function in standard JavaScript, this just switches the style :display between 'none' and 'block' so it is not as smooth. Perhaps it could be made more smooth later with a CSS transition.
2022-01-28 16:19:36 +00:00
Guido Oliveira
db45d7f4eb Cancel empty orders on BOM page 2021-11-06 10:25:34 -03:00
29 changed files with 428 additions and 88 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) ->
@@ -182,9 +205,9 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
if $scope.selectedUnitsProduct.hasOwnProperty("group_buy_unit_size") && $scope.selectedUnitsProduct.group_buy_unit_size > 0 &&
$scope.selectedUnitsProduct.hasOwnProperty("variant_unit") &&
( $scope.selectedUnitsProduct.variant_unit == "weight" || $scope.selectedUnitsProduct.variant_unit == "volume" )
scale = $scope.getScale($scope.selectedUnitsProduct, $scope.selectedUnitsVariant)
sumOfUnitValues = sumOfUnitValues / scale if scale == 28.35 || scale == 453.6 # divide by scale if smallest unit
$scope.roundToThreeDecimals(sumOfUnitValues / $scope.selectedUnitsProduct.group_buy_unit_size * $scope.selectedUnitsVariant.unit_value)
scale = $scope.selectedUnitsProduct.variant_unit_scale
sumOfUnitValues = sumOfUnitValues * scale unless scale == 28.35 || scale == 453.6
$scope.roundToThreeDecimals(sumOfUnitValues / $scope.selectedUnitsProduct.group_buy_unit_size)
else
''

View File

@@ -234,8 +234,10 @@ module Admin
end
def update_enterprise_notifications
if params.key? :receives_notifications
@enterprise.update_contact params[:receives_notifications]
user_id = params[:receives_notifications].to_i
if user_id.positive? && @enterprise.user_ids.include?(user_id)
@enterprise.update_contact(user_id)
end
end

View File

@@ -27,6 +27,17 @@ module ApplicationHelper
OpenFoodNetwork::FeatureToggle.enabled?(feature, user)
end
def language_meta_tags
return if I18n.available_locales.one?
I18n.available_locales.map do |locale|
tag.link(
hreflang: locale.to_s.gsub("_", "-").downcase,
href: "#{request.protocol}#{request.host_with_port}/locales/#{locale}"
)
end.join("\n").html_safe
end
def ng_form_for(name, *args, &block)
options = args.extract_options!

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

@@ -1,19 +1,8 @@
- content_for :page_actions do
:javascript
function toggleSettings(){
if( $('#advanced_settings').is(":visible") ){
$('button#toggle_settings i').switchClass("icon-chevron-up","icon-chevron-down")
}
else {
$('button#toggle_settings i').switchClass("icon-chevron-down","icon-chevron-up")
}
$("#advanced_settings").slideToggle()
}
%li
%button#toggle_settings{ onClick: 'toggleSettings()' }
%li{ "data-controller": "remote-toggle", "data-remote-toggle-selector-value": "#advanced_settings" }
%button#toggle_settings{ "data-action": "click->remote-toggle#toggle" }
= t('.advanced_settings')
%i.icon-chevron-down
%i.icon-chevron-down{ "data-remote-toggle-target": "chevron" }
#advanced_settings{ hidden: true }
#advanced_settings{ style: "display: none" }
= render partial: "/admin/order_cycles/advanced_settings"

View File

@@ -14,6 +14,7 @@
= favicon_link_tag "/favicon-staging.ico"
%link{href: "https://fonts.googleapis.com/css?family=Roboto:400,300italic,400italic,300,700,700italic|Oswald:300,400,700", rel: "stylesheet", type: "text/css"}
%link{href: asset_pack_path("media/fonts/OFN-v2.woff"), rel: "preload", as: "font", crossorigin: "anonymous"}
= language_meta_tags
= stylesheet_pack_tag "darkswarm", "data-turbo-track": "reload"
= javascript_pack_tag "application", "data-turbo-track": "reload"

View File

@@ -9,6 +9,7 @@
- else
= favicon_link_tag "/favicon-staging.ico"
%link{href: "https://fonts.googleapis.com/css?family=Roboto:400,300italic,400italic,300,700,700italic|Oswald:300,400,700", rel: "stylesheet", type: "text/css"}
= language_meta_tags
= stylesheet_pack_tag "darkswarm"
= javascript_include_tag "darkswarm/all"

View File

@@ -0,0 +1,17 @@
import { Controller } from "stimulus";
export default class extends Controller {
static targets = ["chevron"];
static values = { selector: String }
toggle(event) {
if (this.hasChevronTarget) {
this.chevronTarget.classList.toggle("icon-chevron-down")
this.chevronTarget.classList.toggle("icon-chevron-up")
}
const element = document.querySelector(this.selectorValue)
element.style.display = element.style.display === "none" ? "block" : "none"
}
}

View File

@@ -2397,9 +2397,9 @@ de_DE:
spree_distributors_error: "Mindestens ein Hub muss ausgewählt sein."
spree_user_enterprise_limit_error: "^ %{email} darf keine weiteren Unternehmen besitzen (maximale Anzahl ist %{enterprise_limit})."
spree_variant_product_error: muss mindestens eine Produktvariante haben
your_profil_live: "Ihr Profil live"
see: "Sehen Sie"
live: "live"
your_profil_live: "Ihr öffentlicher Auftritt im Open Food Network"
see: " "
live: "ansehen"
manage: "Verwalten"
resend: "Erneut senden"
add_and_manage_products: "Produkte hinzufügen und verwalten"
@@ -2711,6 +2711,7 @@ de_DE:
admin:
unit_price_tooltip: "Grundpreis: Er ermöglicht einen einfachen Preisvergleich von Produkten, unabhängig von Packungsgröße und -gewicht. Der im Online-Shop angezeigte Grundpreis kann ggf. aufgrund hinzukommender Gebühren abweichen."
enterprise_limit_reached: "Sie haben die maximale Anzahl der Unternehmen pro Konto erreicht. Schreiben Sie an %{contact_email}, wenn Sie das Limit erhöhen möchten."
deleting_item_will_cancel_order: "Das Löschen dieses Produkts führt zu einer oder mehreren leeren Bestellungen, die daher automatisch storniert werden. Möchten Sie fortfahren?"
modals:
got_it: "Verstanden"
close: "Schließen"
@@ -2909,7 +2910,8 @@ de_DE:
invalid: "ungültig"
quantity_adjusted: "Kein ausreichender Lagerbestand vorhanden. Die Position wurde auf die maximal verfügbare Menge aktualisiert."
quantity_unchanged: "Menge wurde nicht geändert."
cannot_remove_last_item: "Der letzte verbleibende Artikel einer Bestellung kann nicht entfernt werden. Bitte stornieren Sie stattdessen die Bestellung."
cancel_the_order_html: "Wenn Sie fortfahren, wird die aktuelle Bestellung storniert.<br /> Sind Sie sicher, dass Sie fortfahren möchten?"
cancel_the_order_send_cancelation_email: "Bestätigung der Stornierung per E-Mail an den Kunden senden"
resend_user_email_confirmation:
resend: "Erneut senden"
sending: "Wird erneut gesendet ..."
@@ -3275,6 +3277,7 @@ de_DE:
tracking: "Sendungsverfolgung"
tracking_number: "Sendungscode"
order_total: "Bestellung insgesamt"
order_updated: "Bestellung wurde aktualisiert."
customer_details: "Kundendetails"
customer_details_updated: "Kundendetails gespeichert"
customer_search: "Kundensuche"

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

@@ -2709,6 +2709,7 @@ en_FR:
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"
@@ -2899,7 +2900,8 @@ en_FR:
invalid: "invalid"
quantity_adjusted: "Insufficient stock available. Line item updated to maximum available quantity."
quantity_unchanged: "Quantity unchanged from previous amount."
cannot_remove_last_item: "Cannot remove last item from order. Please cancel order instead."
cancel_the_order_html: "This will cancel the current order. <br /> Are you sure you want to proceed?"
cancel_the_order_send_cancelation_email: "Send a cancellation email to the customer"
resend_user_email_confirmation:
resend: "Resend"
sending: "Resend..."
@@ -3266,6 +3268,7 @@ en_FR:
tracking: "Tracking"
tracking_number: "Tracking Number"
order_total: "Order Total"
order_updated: "Order updated"
customer_details: "Customer Details"
customer_details_updated: "Customer Details updated"
customer_search: "Customer Search"

View File

@@ -2905,7 +2905,8 @@ en_GB:
invalid: "invalid"
quantity_adjusted: "Insufficient stock available. Line item updated to maximum available quantity."
quantity_unchanged: "Quantity unchanged from previous amount."
cannot_remove_last_item: "Cannot remove last item from order. Please cancel order instead."
cancel_the_order_html: "This will cancel the current order.<br />Are you sure you want to proceed?"
cancel_the_order_send_cancelation_email: "Send a cancellation email to the customer"
resend_user_email_confirmation:
resend: "Resend"
sending: "Resend..."
@@ -3272,6 +3273,7 @@ en_GB:
tracking: "Tracking"
tracking_number: "Tracking Number"
order_total: "Order Total"
order_updated: "Order updated"
customer_details: "Customer Details"
customer_details_updated: "Customer Details updated"
customer_search: "Customer Search"

View File

@@ -1418,6 +1418,7 @@ en_IE:
login: "login"
contact: "contact"
require_customer_login: "Only approved customers can access this shop."
require_login_link_html: "If you're already an approved customer, %{login} to proceed."
require_login_2_html: "Want to start shopping here? Please %{contact} %{enterprise} and ask about joining."
require_customer_html: "If you'd like to start shopping here, please %{contact} %{enterprise} to ask about joining."
select_oc:
@@ -2904,7 +2905,8 @@ en_IE:
invalid: "invalid"
quantity_adjusted: "Insufficient stock available. Line item updated to maximum available quantity."
quantity_unchanged: "Quantity unchanged from previous amount."
cannot_remove_last_item: "Cannot remove last item from order. Please cancel order instead."
cancel_the_order_html: "This will cancel the current order.<br />Are you sure you want to proceed?"
cancel_the_order_send_cancelation_email: "Send a cancellation email to the customer"
resend_user_email_confirmation:
resend: "Resend"
sending: "Resend..."
@@ -3271,6 +3273,7 @@ en_IE:
tracking: "Tracking"
tracking_number: "Tracking Number"
order_total: "Order Total"
order_updated: "Order updated"
customer_details: "Customer Details"
customer_details_updated: "Customer Details updated"
customer_search: "Customer Search"

View File

@@ -642,7 +642,7 @@ fr:
import:
review: Vérifier
import: Importer
save: Sauvergarder
save: Sauvegarder
results: Résultats
save_imported: Sauvegarder les produits importés
no_valid_entries: Aucune entrée valide trouvée
@@ -2713,6 +2713,7 @@ fr:
admin:
unit_price_tooltip: "Le prix unitaire permet aux acheteurs de comparer les prix entre les produits et/ou les conditionnements. Attention, le prix final observé par l'acheteur peut être différent si des marges et/ou commissions sont appliquées."
enterprise_limit_reached: "Vous avez atteint le nombre limite d'entreprises autorisées par défaut. Ecrivez à %{contact_email} si vous avez besoin d'augmenter cette limite."
deleting_item_will_cancel_order: "Cette opération va rendre une ou plusieurs commandes vides, sans aucun produit. Elles vont ainsi être annulées. Souhaitez-vous continuer ?"
modals:
got_it: "J'ai compris"
close: "Fermer"
@@ -2927,7 +2928,8 @@ fr:
invalid: "invalide"
quantity_adjusted: "Le stock disponible est insuffisant. La quantité a été mise à jour en fonction du stock restant."
quantity_unchanged: "La quantité n'a pas été modifiée."
cannot_remove_last_item: "Vous ne pouvez pas supprimer le dernier produit d'une commande, veuillez annuler la commande si aucun produit ne doit y être ajouté."
cancel_the_order_html: "Cette action va annuler la commande. <br /> Etes-vous sûr de vouloir continuer ?"
cancel_the_order_send_cancelation_email: "Envoyer un email d'annulation à l'acheteur"
resend_user_email_confirmation:
resend: "Renvoyer"
sending: "Renvoi...."
@@ -3295,6 +3297,7 @@ fr:
tracking: "Suivi"
tracking_number: "Numéro de suivi"
order_total: "Total Commande"
order_updated: "La commande a été mise à jour"
customer_details: "Informations acheteur"
customer_details_updated: "Détails de l'acheteur mis à jour"
customer_search: "Recherche Acheteur"

View File

@@ -2961,7 +2961,8 @@ hu:
invalid: "érvénytelen"
quantity_adjusted: "Nem áll rendelkezésre elegendő készlet. A sor frissítve a maximális elérhető mennyiségre."
quantity_unchanged: "A mennyiség nem változott az előző mennyiséghez képest."
cannot_remove_last_item: "Az utolsó tétel nem távolítható el a rendelésből. Inkább törölje a rendelést."
cancel_the_order_html: "Ez megszakítja a vásárlási folyamatot. Biztosan folytatja?"
cancel_the_order_send_cancelation_email: "A törlés elküldése a vásárlónak (emailben)."
resend_user_email_confirmation:
resend: "Újraküldés"
sending: "Újraküldés..."
@@ -3329,6 +3330,7 @@ hu:
tracking: "Követés"
tracking_number: "Nyomon követési szám"
order_total: "Rendelés Összesen"
order_updated: "A megrendelés frissítve."
customer_details: "Vásárló adatai"
customer_details_updated: "Ügyféladatok frissítve"
customer_search: "Ügyfélkeresés"

View File

@@ -162,6 +162,28 @@ describe Admin::EnterprisesController, type: :controller do
expect(distributor.users).to_not include user
end
it "updates the contact for notifications" do
allow(controller).to receive_messages spree_current_user: distributor_manager
params = {
id: distributor,
receives_notifications: distributor_manager.id,
}
expect { spree_post :update, params }.
to change { distributor.contact }.to(distributor_manager)
end
it "updates the contact for notifications" do
allow(controller).to receive_messages spree_current_user: distributor_manager
params = {
id: distributor,
receives_notifications: "? object:null ?",
}
expect { spree_post :update, params }.
to_not change { distributor.contact }
end
it "updates enterprise preferences" do
allow(controller).to receive_messages spree_current_user: distributor_manager
update_params = { id: distributor,

View File

@@ -0,0 +1,45 @@
# frozen_string_literal: true
require 'spec_helper'
describe ApplicationHelper, type: :helper do
describe "#language_meta_tags" do
let(:request) { double("request", host_with_port: "test.host", protocol: "http://") }
before do
allow(helper).to receive(:request).and_return(request)
end
context "when there is more than one available locale" do
before do
allow(I18n).to receive(:available_locales) { ["en", "es", "pt"] }
end
it "displays a language tag for each available locale" do
expect(language_meta_tags).to include('<link hreflang="en" href="http://test.host/locales/en">')
expect(language_meta_tags).to include('<link hreflang="es" href="http://test.host/locales/es">')
expect(language_meta_tags).to include('<link hreflang="pt" href="http://test.host/locales/pt">')
end
end
context "when there is only one available locale" do
before do
allow(I18n).to receive(:available_locales) { ["en"] }
end
it "doesn't include any language tags" do
expect(language_meta_tags).to be_nil
end
end
context "when the availables locales have regional variations" do
before do
allow(I18n).to receive(:available_locales) { ["fr_CA", "en_CA"] }
end
it "includes the region code in the :hreflang attribute" do
expect(language_meta_tags).to include('<link hreflang="fr-ca" href="http://test.host/locales/fr_CA">')
expect(language_meta_tags).to include('<link hreflang="en-ca" href="http://test.host/locales/en_CA">')
end
end
end
end

View File

@@ -6,13 +6,18 @@ import { Application } from "stimulus";
import paymentmethod_controller from "../../../app/webpacker/controllers/paymentmethod_controller";
describe("PaymentmethodController", () => {
beforeAll(() => {
const application = Application.start();
application.register("paymentmethod", paymentmethod_controller);
});
describe("#selectPaymentMethod", () => {
beforeEach(() => {
document.body.innerHTML = `<div data-controller="paymentmethod">
<input id="paymentmethod_1" data-action="click->paymentmethod#selectPaymentMethod" data-paymentmethod-id="paymentmethod1" data-paymentmethod-target="input" />
<input id="paymentmethod_2" data-action="click->paymentmethod#selectPaymentMethod" data-paymentmethod-id="paymentmethod2" data-paymentmethod-target="input" checked="checked" />
<input id="paymentmethod_3" data-action="click->paymentmethod#selectPaymentMethod" data-paymentmethod-id="paymentmethod3" data-paymentmethod-target="input"/>
<div class="paymentmethod-container" id="paymentmethod1">
<input type="number" id="input1" />
<select id="select1" >
@@ -32,9 +37,6 @@ describe("PaymentmethodController", () => {
</select>
</div>
</div>`;
const application = Application.start();
application.register("paymentmethod", paymentmethod_controller);
});
it("fill the right payment container", () => {

View File

@@ -0,0 +1,59 @@
/**
* @jest-environment jsdom
*/
import { Application } from "stimulus";
import remote_toggle_controller from "../../../app/webpacker/controllers/remote_toggle_controller";
describe("RemoteToggleController", () => {
beforeAll(() => {
const application = Application.start();
application.register("remote-toggle", remote_toggle_controller);
});
describe("#toggle", () => {
beforeEach(() => {
document.body.innerHTML = `
<div data-controller="remote-toggle" data-remote-toggle-selector-value="#content">
<button id="remote-toggle" data-action="click->remote-toggle#toggle"></button>
<button id="remote-toggle-with-chevron" data-action="click->remote-toggle#toggle">
<i class="icon-chevron-down" data-remote-toggle-target="chevron"></i>
</button>
</div>
<div id="content">...</div>
`;
});
it("clicking a toggle switches the visibility of the :data-remote-toggle-selector element", () => {
const button = document.getElementById("remote-toggle");
const content = document.getElementById("content");
expect(content.style.display).toBe("");
button.click();
expect(content.style.display).toBe("none");
button.click();
expect(content.style.display).toBe("block");
});
it("clicking a toggle with a chevron icon switches the visibility of content and the direction of the icon", () => {
const button = document.getElementById("remote-toggle-with-chevron");
const chevron = button.querySelector("i");
const content = document.getElementById("content");
expect(content.style.display).toBe("");
expect(chevron.className).toBe("icon-chevron-down");
button.click();
expect(content.style.display).toBe("none");
expect(chevron.className).toBe("icon-chevron-up");
button.click();
expect(content.style.display).toBe("block");
expect(chevron.className).toBe("icon-chevron-down");
});
});
});

View File

@@ -6,6 +6,11 @@ import { Application } from "stimulus";
import stripe_cards_controller from "../../../app/webpacker/controllers/stripe_cards_controller";
describe("StripeCardsController", () => {
beforeAll(() => {
const application = Application.start();
application.register("stripe-cards", stripe_cards_controller);
});
beforeEach(() => {
document.body.innerHTML = `<div data-controller="stripe-cards">
<select data-action="change->stripe-cards#onSelectCard" id="select">
@@ -17,9 +22,6 @@ describe("StripeCardsController", () => {
<input type="hidden" id="input_1">
</div>
</div>`;
const application = Application.start();
application.register("stripe-cards", stripe_cards_controller);
});
describe("#connect", () => {
it("initialize with the right display state", () => {

View File

@@ -6,6 +6,11 @@ import { Application } from "stimulus";
import tabs_controller from "../../../app/webpacker/controllers/tabs_controller";
describe("TabsController", () => {
beforeAll(() => {
const application = Application.start();
application.register("tabs", tabs_controller);
});
describe("#select", () => {
beforeEach(() => {
document.body.innerHTML = `
@@ -13,7 +18,7 @@ describe("TabsController", () => {
<button data-tabs-target="tab" data-action="click->tabs#select">Dogs</button>
<button data-tabs-target="tab" data-action="click->tabs#select">Cats</button>
<button data-tabs-target="tab" data-action="click->tabs#select">Birds</button>
<div class="content-area" data-tabs-target="content" >
Dogs content
</div>
@@ -25,9 +30,6 @@ describe("TabsController", () => {
</div>
</div>
`;
const application = Application.start();
application.register("tabs", tabs_controller);
});
it("shows the corresponding content when a tab button is clicked", () => {

View File

@@ -6,6 +6,11 @@ import { Application } from "stimulus";
import toggle_controller from "../../../app/webpacker/controllers/toggle_controller";
describe("ToggleController", () => {
beforeAll(() => {
const application = Application.start();
application.register("toggle", toggle_controller);
});
describe("#toggle", () => {
beforeEach(() => {
document.body.innerHTML = `<div data-controller="toggle">
@@ -14,9 +19,6 @@ describe("ToggleController", () => {
content
</div>
</div>`;
const application = Application.start();
application.register("toggle", toggle_controller);
});
it("toggle the content", () => {

View File

@@ -6,15 +6,17 @@ import { Application } from "stimulus";
import updateinput_controller from "../../../app/webpacker/controllers/updateinput_controller";
describe("updateInput controller", () => {
beforeAll(() => {
const application = Application.start();
application.register("updateinput", updateinput_controller);
});
describe("#update", () => {
beforeEach(() => {
document.body.innerHTML = `<form data-controller="updateinput">
<input id="input" type="hidden" value="false" data-updateinput-target="input" />
<div id="submit" data-action="click->updateinput#update" data-updateinput-value="true" />
</form>`;
const application = Application.start();
application.register("updateinput", updateinput_controller);
});
it("update the input value", () => {

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
@@ -169,15 +251,19 @@ describe "LineItemsCtrl", ->
scope.fulfilled()
expect(Math.round).toHaveBeenCalled()
it "returns the quantity of fulfilled group buy units", ->
scope.selectedUnitsProduct = { variant_unit: "weight", group_buy_unit_size: 1000 }
scope.selectedUnitsVariant = { unit_value: 1 }
expect(scope.fulfilled(1500)).toEqual 1.5
it "returns the quantity of fulfilled group buy units by volume", ->
scope.selectedUnitsProduct = { variant_unit: "volume", group_buy_unit_size: 5000 }
scope.selectedUnitsVariant = { unit_value: 1000 }
expect(scope.fulfilled(5)).toEqual 1
describe "returns the quantity of fulfilled group buy units", ->
runs = [
{ selectedUnitsProduct: { variant_unit: "weight", group_buy_unit_size: 1000, variant_unit_scale: 1 }, arg: 1500, expected: 1.5 },
{ selectedUnitsProduct: { variant_unit: "weight", group_buy_unit_size: 60000, variant_unit_scale: 1000 }, arg: 9, expected: 0.15 },
{ selectedUnitsProduct: { variant_unit: "weight", group_buy_unit_size: 60000, variant_unit_scale: 1 }, arg: 9000, expected: 0.15 }
{ selectedUnitsProduct: { variant_unit: "weight", group_buy_unit_size: 5, variant_unit_scale: 28.35 }, arg: 12, expected: 2.4},
{ selectedUnitsProduct: { variant_unit: "volume", group_buy_unit_size: 5000, variant_unit_scale: 1 }, arg: 5, expected: 0.001}
];
runs.forEach ({selectedUnitsProduct, arg, expected}) ->
it "returns the quantity of fulfilled group buy units, group_buy_unit_size: " + selectedUnitsProduct.group_buy_unit_size + ", arg: " + arg + ", scale: " + selectedUnitsProduct.variant_unit_scale , ->
scope.selectedUnitsProduct = selectedUnitsProduct
expect(scope.fulfilled(arg)).toEqual expected
describe "allFinalWeightVolumesPresent()", ->
it "returns false if the unit_value of any item in filteredLineItems does not exist", ->

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: ''
@@ -823,9 +827,9 @@ describe '
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 "800"
expect(page).to have_text "0.8"
expect(page).to have_text "Max Fulfilled Units"
expect(page).to have_text "1800"
expect(page).to have_text "1.8"
expect(page).to have_selector "div.shared_resource", visible: true
within "div.shared_resource" do
expect(page).to have_selector "span", text: "Shared Resource?"

View File

@@ -65,7 +65,7 @@ describe "As a consumer, I want to checkout my order", js: true do
add_enterprise_fee enterprise_fee
set_order order
distributor.shipping_methods = [free_shipping_with_required_address, free_shipping, shipping_with_fee, free_shipping_without_required_address]
distributor.shipping_methods.push(free_shipping_with_required_address, free_shipping, shipping_with_fee, free_shipping_without_required_address)
end
context "guest checkout when distributor doesn't allow guest orders" do

View File

@@ -0,0 +1,24 @@
# frozen_string_literal: true
require "spec_helper"
describe "layouts/darkswarm.html.haml" do
helper InjectionHelper
helper I18nHelper
helper ShopHelper
before do
allow(view).to receive_messages(
current_order: nil,
spree_current_user: nil
)
end
it "displays language tags when there is more than one available locale" do
render
expect(rendered).to include('<link hreflang="en" href="http://test.host/locales/en">')
expect(rendered).to include('<link hreflang="es" href="http://test.host/locales/es">')
expect(rendered).to include('<link hreflang="pt" href="http://test.host/locales/pt">')
end
end

View File

@@ -0,0 +1,24 @@
# frozen_string_literal: true
require "spec_helper"
describe "layouts/registration.html.haml" do
helper InjectionHelper
helper I18nHelper
helper ShopHelper
before do
allow(view).to receive_messages(
current_order: nil,
spree_current_user: nil
)
end
it "displays language tags when there is more than one available locale" do
render
expect(rendered).to include('<link hreflang="en" href="http://test.host/locales/en">')
expect(rendered).to include('<link hreflang="es" href="http://test.host/locales/es">')
expect(rendered).to include('<link hreflang="pt" href="http://test.host/locales/pt">')
end
end

View File

@@ -6110,9 +6110,9 @@ findup-sync@^3.0.0:
resolve-dir "^1.0.1"
flatpickr@^4.6.9:
version "4.6.9"
resolved "https://registry.yarnpkg.com/flatpickr/-/flatpickr-4.6.9.tgz#9a13383e8a6814bda5d232eae3fcdccb97dc1499"
integrity sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw==
version "4.6.11"
resolved "https://registry.yarnpkg.com/flatpickr/-/flatpickr-4.6.11.tgz#c92f5108269c551c6b5069ecd754be610574574c"
integrity sha512-/rnbE/hu5I5zndLEyYfYvqE4vPDvI5At0lFcQA5eOPfjquZLcQ0HMKTL7rv5/+DvbPM3/vJcXpXjB/DjBh+1jw==
flatted@^3.2.2, flatted@^3.2.4:
version "3.2.4"
@@ -8203,9 +8203,9 @@ junk@^3.1.0:
integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==
karma-chrome-launcher@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738"
integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==
version "3.1.1"
resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea"
integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==
dependencies:
which "^1.2.1"