diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index e55124201f..ace78ed248 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -142,7 +142,6 @@ Layout/LineLength: - spec/controllers/api/product_images_controller_spec.rb - spec/controllers/api/products_controller_spec.rb - spec/controllers/api/promo_images_controller_spec.rb - - spec/controllers/api/shipments_controller_spec.rb - spec/controllers/api/variants_controller_spec.rb - spec/controllers/cart_controller_spec.rb - spec/controllers/checkout_controller_spec.rb diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 779fce90ae..cac1468c67 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,9 @@ # Contributing -We love pull requests from everyone. Any contribution is valuable, but there are two issue streams that we especially love people to work on: +We love pull requests from everyone. Any contribution is valuable! -1) Our delivery backlog, is managed via a ZenHub board (ZenHub extensions are available for most major browsers). We use a Kanban-style approach, whereby devs pick issues from the top of the backlog which has been organised according to current priorities. If you have some time and are interested in working on some issues from the backlog, please make yourself known on the [#dev][slack-dev] channel on Slack and we can direct you to the most appropriate issue to pick up. +If you have some time and are interested in working on some issues please make yourself known on the [#dev][slack-dev] channel on Slack. -2) Our list of bugs and other self-contained issues that we consider to be a good starting point for new contributors, or devs who aren’t able to commit to seeing a whole feature through. These issues are marked with the `# good first issue` label. +We have curated all issues we consider to be a good starting point for new members of the community within the [Welcome New Developers project board][welcome-dev]. Have a look and pick the one you would prefer working on! ## Set up @@ -19,10 +19,6 @@ If you want to run the whole test suite, we recommend using a free CI service to bundle exec rspec spec -## Which issue to pick first? - -We have curated all issues interesting for new members of the community within the [Welcome New Developers project board][welcome-dev]. Have a look and pick the one you would prefer working on! - ## Internationalisation (i18n) The locale `en` is maintained in the source code, but other locales are managed at [Transifex][ofn-transifex]. Read more about [internationalisation][i18n] in the developer wiki. diff --git a/Dockerfile b/Dockerfile index 202bbeccf7..c30df2f92f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,8 +13,8 @@ WORKDIR /usr/src/app COPY .ruby-version . # Install Rbenv & Ruby -RUN git clone https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \ - git clone https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \ +RUN git clone --depth 1 --branch v1.1.2 https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \ + git clone --depth 1 --branch v20200520 https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \ ${RBENV_ROOT}/plugins/ruby-build/install.sh && \ echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh && \ rbenv install $(cat .ruby-version) && \ @@ -43,4 +43,5 @@ RUN wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.z # Copy code and install app dependencies COPY . /usr/src/app/ -RUN bundle install +# Run bundler install in parallel with the amount of available CPUs +RUN bundle install --jobs="$(nproc)" diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md index 67f38e7390..b252993215 100644 --- a/GETTING_STARTED.md +++ b/GETTING_STARTED.md @@ -2,21 +2,17 @@ This is a general guide to setting up an Open Food Network development environment on your local machine. -The fastest way to make it work locally is to use Docker, see the [Docker setup guide](DOCKER.md). +### Requirements -The following guides are located in the wiki and provide more OS-specific step-by-step instructions: - -- [Ubuntu Setup Guide][ubuntu] -- [macOS Sierra Setup Guide][sierra] -- [OSX El Capitan Setup Guide][el-capitan] - -### Dependencies - -* Rails 3.2.x -* Ruby 2.3.7 +The fastest way to make it work locally is to use Docker, you only need to setup git, see the [Docker setup guide](DOCKER.md). +Otherwise, for a local setup you will need: +* Ruby 2.3.7 and bundler * PostgreSQL database -* PhantomJS (for testing) -* See Gemfile for a list of gems required +* Chrome (for testing) + +The following guides will provide OS-specific step-by-step instructions to get these requirements installed: +- [Ubuntu Setup Guide][ubuntu] +- [OSX Setup Guide][osx] If you are likely to need to manage multiple version of ruby on your local machine, we recommend version managers such as [rbenv](https://github.com/rbenv/rbenv) or [RVM](https://rvm.io/). @@ -52,14 +48,12 @@ This will create the "ofn" user as superuser and allowing it to create databases Once done, run `script/setup`. If the script succeeds you're ready to start developing. If not, take a look at the output as it should be informative enough to help you troubleshoot. -If you run into any other issues getting your local environment up and running please consult [the wiki][wiki]. - -If still you get stuck do not hesitate to open an issue reporting the full output of the script. - Now, your dreams of spinning up a development server can be realised: bundle exec rails server +Go to [http://localhost:3000](http://localhost:3000) to play around! + To login as the default user, use: email: ofn@example.com @@ -79,7 +73,7 @@ The tests of all custom engines can be run with: bundle exec rake ofn:specs:engines:rspec -Note: If your OS is not explicitly supported in the setup guides then not all tests may pass. However, you may still be able to develop. Get in touch with the [#dev][slack-dev] channel on Slack to troubleshoot issues and determine if they will preclude you from contributing to OFN. +Note: If your OS is not explicitly supported in the setup guides then not all tests may pass. However, you may still be able to develop. Note: The time zone on your machine should match the one defined in `config/application.yml`. @@ -120,8 +114,7 @@ $ createdb open_food_network_test --owner=ofn If these commands succeed, you should be able to [continue the setup process](#get-it-running). [developer-wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki -[sierra]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup%3A-macOS-%28Sierra%2C-HighSierra%2C-Mojave-and-Catalina%29 -[el-capitan]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-OS-X-(El-Capitan) +[osx]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-OS-X [ubuntu]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Ubuntu [wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki [zeus]: https://github.com/burke/zeus diff --git a/Gemfile b/Gemfile index 9d2e680a20..bf3570b803 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ ruby "2.3.7" git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" } gem 'i18n', '~> 0.6.11' -gem 'i18n-js', '~> 3.6.0' +gem 'i18n-js', '~> 3.7.0' gem 'rails', '~> 4.0.13' gem 'rails-i18n', '~> 4.0' gem 'rails_safe_tasks', '~> 1.0' @@ -161,11 +161,11 @@ group :test do end group :development do - gem 'byebug', '~> 11.0' # 11.1 requires ruby 2.4 + gem 'byebug', '~> 11.0.0' # 11.1 requires ruby 2.4 gem 'debugger-linecache' gem "newrelic_rpm", "~> 3.0" gem "pry", "~> 0.12.0" # pry 0.13 is not compatible with pry-byebug 3.7 - gem 'pry-byebug', '~> 3.7' # 3.8 requires ruby 2.4 + gem 'pry-byebug', '~> 3.7.0' # 3.8 requires ruby 2.4 gem 'rubocop' gem 'rubocop-rails' gem 'spring' diff --git a/Gemfile.lock b/Gemfile.lock index 3d841a7705..ee01f6b3a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -207,7 +207,7 @@ GEM activerecord (>= 3.2.0, < 5.0) fog (~> 1.0) rails (>= 3.2.0, < 5.0) - ddtrace (0.35.2) + ddtrace (0.36.0) msgpack debugger-linecache (1.2.0) delayed_job (4.1.8) @@ -421,7 +421,7 @@ GEM mime-types (~> 3.0) multi_xml (>= 0.5.2) i18n (0.6.11) - i18n-js (3.6.0) + i18n-js (3.7.0) i18n (>= 0.6.6) immigrant (0.3.6) activerecord (>= 3.0) @@ -502,6 +502,7 @@ GEM pg (0.21.0) polyamorous (0.6.4) activerecord (>= 3.0) + power_assert (1.2.0) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) @@ -510,7 +511,7 @@ GEM pry (~> 0.10) public_suffix (4.0.3) rack (1.5.5) - rack-mini-profiler (2.0.1) + rack-mini-profiler (2.0.2) rack (>= 1.2.0) rack-protection (1.5.5) rack @@ -643,9 +644,10 @@ GEM sprockets (>= 2.8, < 4.0) state_machine (1.2.0) stringex (1.5.1) - stripe (5.15.0) + stripe (5.22.0) temple (0.8.2) - test-unit (3.3.5) + test-unit (3.3.6) + power_assert thor (0.20.3) thread_safe (0.3.6) tilt (1.4.1) @@ -707,7 +709,7 @@ DEPENDENCIES aws-sdk (= 1.11.1) blockenspiel bugsnag - byebug (~> 11.0) + byebug (~> 11.0.0) cancan (~> 1.6.10) capybara (>= 2.18.0) catalog! @@ -741,7 +743,7 @@ DEPENDENCIES highline (= 1.6.18) httparty (~> 0.11) i18n (~> 0.6.11) - i18n-js (~> 3.6.0) + i18n-js (~> 3.7.0) immigrant jquery-migrate-rails jquery-rails (= 3.1.5) @@ -765,7 +767,7 @@ DEPENDENCIES paranoia (~> 2.0) pg (~> 0.21.0) pry (~> 0.12.0) - pry-byebug (~> 3.7) + pry-byebug (~> 3.7.0) rack-mini-profiler (< 3.0.0) rack-rewrite rack-ssl diff --git a/app/assets/images/home/groups-bg.svg b/app/assets/images/home/groups-bg.svg deleted file mode 100644 index 19d7f926c5..0000000000 --- a/app/assets/images/home/groups-bg.svg +++ /dev/null @@ -1,1051 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/assets/images/home/home-apples.jpg b/app/assets/images/home/home-apples.jpg deleted file mode 100644 index 91bfd4cfa5..0000000000 Binary files a/app/assets/images/home/home-apples.jpg and /dev/null differ diff --git a/app/assets/images/home/home-oranges.jpg b/app/assets/images/home/home-oranges.jpg deleted file mode 100644 index 671f02d979..0000000000 Binary files a/app/assets/images/home/home-oranges.jpg and /dev/null differ diff --git a/app/assets/images/home/home-strawberries.jpg b/app/assets/images/home/home-strawberries.jpg deleted file mode 100644 index cb2bf15c0e..0000000000 Binary files a/app/assets/images/home/home-strawberries.jpg and /dev/null differ diff --git a/app/assets/images/home/home1.jpg b/app/assets/images/home/home1.jpg deleted file mode 100644 index 015b203bcf..0000000000 Binary files a/app/assets/images/home/home1.jpg and /dev/null differ diff --git a/app/assets/images/home/home2.jpg b/app/assets/images/home/home2.jpg deleted file mode 100644 index 4e5cf61b08..0000000000 Binary files a/app/assets/images/home/home2.jpg and /dev/null differ diff --git a/app/assets/images/home/home3.jpg b/app/assets/images/home/home3.jpg deleted file mode 100644 index 307ad38c1b..0000000000 Binary files a/app/assets/images/home/home3.jpg and /dev/null differ diff --git a/app/assets/images/home/macbook.png b/app/assets/images/home/macbook.png deleted file mode 100644 index ab0d7dfe07..0000000000 Binary files a/app/assets/images/home/macbook.png and /dev/null differ diff --git a/app/assets/images/home/maps-bg.svg b/app/assets/images/home/maps-bg.svg deleted file mode 100644 index 48153cc191..0000000000 --- a/app/assets/images/home/maps-bg.svg +++ /dev/null @@ -1,1090 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/assets/images/home/producers-bg.svg b/app/assets/images/home/producers-bg.svg deleted file mode 100644 index 2a47eed65a..0000000000 --- a/app/assets/images/home/producers-bg.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index d92bc73566..94939f3f91 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -105,6 +105,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout $scope.producerFilter = "0" $scope.categoryFilter = "0" $scope.importDateFilter = "0" + $scope.fetchProducts() $scope.$watch 'sortOptions', (sort) -> return unless sort && sort.predicate != "" diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee index f6d4c964d6..751ddf8866 100644 --- a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -37,6 +37,7 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $timeout, Reque 'q[distributor_id_in][]': $scope['q']['distributor_id_in'], 'q[order_cycle_id_in][]': $scope['q']['order_cycle_id_in'], 'q[s]': $scope.sorting || 'completed_at desc', + shipping_method_id: $scope.shipping_method_id, per_page: $scope.per_page, page: page } diff --git a/app/assets/javascripts/admin/side_menu/services/side_menu.js.coffee b/app/assets/javascripts/admin/side_menu/services/side_menu.js.coffee index 4f6fe5ab59..4e1ae9abbb 100644 --- a/app/assets/javascripts/admin/side_menu/services/side_menu.js.coffee +++ b/app/assets/javascripts/admin/side_menu/services/side_menu.js.coffee @@ -4,7 +4,6 @@ angular.module("admin.side_menu") items: [] selected: null - # Checks for path and uses it to set the view # If no path, loads first view init: => @@ -31,11 +30,3 @@ angular.module("admin.side_menu") for item in @items when item.name is name return item null - - hide_item_by_name: (name) => - item = @find_by_name(name) - item.visible = false if item - - show_item_by_name: (name) => - item = @find_by_name(name) - item.visible = true if item diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index aa0fafa058..b697546b4d 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -8,6 +8,9 @@ #= require angular-sanitize #= require angular-animate #= require angular-resource +#= require autocomplete.min.js +#= require leaflet-1.6.0.js +#= require leaflet-providers.js #= require lodash.underscore.js # bluebird.js is a dependency of angular-google-maps.js 2.0.0 #= require bluebird.js diff --git a/app/assets/javascripts/darkswarm/controllers/group_page_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/group_page_controller.js.coffee index 7b44cb749b..ff7a695777 100644 --- a/app/assets/javascripts/darkswarm/controllers/group_page_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/group_page_controller.js.coffee @@ -1,6 +1,3 @@ -Darkswarm.controller "GroupPageCtrl", ($scope, enterprises, Enterprises, MapConfiguration, OfnMap) -> +Darkswarm.controller "GroupPageCtrl", ($scope, enterprises, Enterprises) -> $scope.Enterprises = Enterprises - - $scope.map = angular.copy MapConfiguration.options - $scope.mapMarkers = OfnMap.enterprise_markers enterprises $scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1 diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index a692af3fb5..fb8ac8d288 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -2,6 +2,5 @@ Darkswarm.controller "ProductNodeCtrl", ($scope, $modal, FilterSelectorsService) $scope.enterprise = $scope.product.supplier # For the modal, so it's consistent $scope.triggerProductModal = -> - $scope.productTaxonSelectors = FilterSelectorsService.createSelectors() $scope.productPropertySelectors = FilterSelectorsService.createSelectors() $modal.open(templateUrl: "product_modal.html", scope: $scope) diff --git a/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee b/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee new file mode 100644 index 0000000000..7dbdc73669 --- /dev/null +++ b/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee @@ -0,0 +1,100 @@ +Darkswarm.directive 'ofnOpenStreetMap', ($window, Enterprises, EnterpriseModal, availableCountries, openStreetMapConfig) -> + restrict: 'E' + replace: true + scope: true + template: "
" + + link: (scope, element, attrs, ctrl, transclude)-> + map = null + markers = [] + enterpriseNames = [] + openStreetMapProviderName = openStreetMapConfig.open_street_map_provider_name + openStreetMapProviderOptions = JSON.parse(openStreetMapConfig.open_street_map_provider_options) + + average = (values) -> + total = values.reduce (sum, value) -> + sum = sum + value + , 0 + total / values.length + + averageAngle = (angleName) -> + positiveAngles = [] + negativeAngles = [] + for enterprise in Enterprises.enterprises + if enterprise.latitude? && enterprise.longitude? + if enterprise[angleName] > 0 + positiveAngles.push(enterprise[angleName]) + else + negativeAngles.push(enterprise[angleName]) + + averageNegativeAngle = average(negativeAngles) + averagePositiveAngle = average(positiveAngles) + + if negativeAngles.length == 0 + averagePositiveAngle + else if positiveAngles.length == 0 + averageNegativeAngle + else if averagePositiveAngle > averageNegativeAngle + averagePositiveAngle - averageNegativeAngle + else + averageNegativeAngle - averagePositiveAngle + + buildMarker = (enterprise, latlng, title) -> + icon = L.icon + iconUrl: enterprise.icon + marker = L.marker latlng, + draggable: true, + icon: icon, + riseOnHover: true, + title: title + marker.on "click", -> + EnterpriseModal.open enterprise + marker + + enterpriseName = (enterprise) -> + return enterprise.name + " (" + enterprise.address.address1 + ", " + enterprise.address.city + ", " + enterprise.address.state_name + ")"; + + goToEnterprise = (selectedEnterpriseName) -> + enterprise = Enterprises.enterprises.find (enterprise) -> + enterpriseName(enterprise) == selectedEnterpriseName + map.setView([enterprise.latitude, enterprise.longitude], 12) + + displayMap = -> + setMapDimensions() + averageLatitude = averageAngle("latitude") + averageLongitude = averageAngle("longitude") + zoomLevel = 6 + map = L.map('open-street-map') + L.tileLayer.provider(openStreetMapProviderName, openStreetMapProviderOptions).addTo(map) + map.setView([averageLatitude, averageLongitude], zoomLevel) + + displayEnterprises = -> + for enterprise in Enterprises.enterprises + if enterprise.latitude? && enterprise.longitude? + marker = buildMarker(enterprise, { lat: enterprise.latitude, lng: enterprise.longitude }, enterprise.name).addTo(map) + enterpriseNames.push(enterpriseName(enterprise)) + markers.push(marker) + + displaySearchField = () -> + new Autocomplete('#open-street-map--search', + onSubmit: goToEnterprise + search: searchEnterprises + ) + overwriteInlinePositionRelativeToPositionSearchField = -> + $('#open-street-map--search').css("position", "absolute") + overwriteInlinePositionRelativeToPositionSearchField() + + searchEnterprises = (input) -> + if input.length < 1 + return [] + enterpriseNames.filter (country) -> + country.toLowerCase().includes input.toLowerCase() + + setMapDimensions = -> + height = $window.innerHeight - element.offset().top + element.css "width", "100%" + element.css "height", (height + "px") + + displayMap() + displayEnterprises() + displaySearchField() diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee index f0da646ebe..569382d52e 100644 --- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -21,8 +21,10 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE try @handle_checkout_error_response(response) catch error - @loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error - throw error # generate a BugsnagJS alert + try + @loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error + finally + throw error # generate a BugsnagJS alert handle_checkout_error_response: (response) => if response.data.path diff --git a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee index 46e50cb574..843749c2e6 100644 --- a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee @@ -1,4 +1,4 @@ -Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons, Dereferencer, Matcher, Geo, $rootScope) -> +Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons, Dereferencer, Matcher, GmapsGeo, $rootScope) -> new class Enterprises enterprises: [] enterprises_by_id: {} @@ -59,7 +59,7 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons false calculateDistance: (query, firstMatching) -> - if query?.length > 0 and Geo.OK + if query?.length > 0 and GmapsGeo.OK if firstMatching? @setDistanceFrom firstMatching else @@ -68,9 +68,9 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons @resetDistance() calculateDistanceGeo: (query) -> - Geo.geocode query, (results, status) => + GmapsGeo.geocode query, (results, status) => $rootScope.$apply => - if status == Geo.OK + if status == GmapsGeo.OK #console.log "Geocoded #{query} -> #{results[0].geometry.location}." @setDistanceFrom results[0].geometry.location else @@ -79,7 +79,7 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons setDistanceFrom: (locatable) -> for enterprise in @enterprises - enterprise.distance = Geo.distanceBetween enterprise, locatable + enterprise.distance = GmapsGeo.distanceBetween enterprise, locatable $rootScope.$broadcast 'enterprisesChanged' resetDistance: -> diff --git a/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee b/app/assets/javascripts/darkswarm/services/gmaps_geo.js.erb.coffee similarity index 93% rename from app/assets/javascripts/darkswarm/services/geo.js.erb.coffee rename to app/assets/javascripts/darkswarm/services/gmaps_geo.js.erb.coffee index ee5961be36..9b78ea4bcc 100644 --- a/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee +++ b/app/assets/javascripts/darkswarm/services/gmaps_geo.js.erb.coffee @@ -1,5 +1,5 @@ -Darkswarm.service "Geo", -> - new class Geo +Darkswarm.service "GmapsGeo", -> + new class GmapsGeo OK: google?.maps?.GeocoderStatus?.OK # Usage: diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml index 6282bc439e..9c65bbbad7 100644 --- a/app/assets/javascripts/templates/product_modal.html.haml +++ b/app/assets/javascripts/templates/product_modal.html.haml @@ -1,6 +1,5 @@ .row - - .columns.small-12.large-6.product-header + .columns.small-12.medium-6.large-6.product-header %h3{"ng-bind" => "::product.name"} %span %em {{'products_from' | t}} @@ -8,19 +7,14 @@ %br - .filter-shopfront.taxon-selectors.inline-block - %filter-selector{ 'selector-set' => "productTaxonSelectors", objects: "[product] | taxonsOf" } - .filter-shopfront.property-selectors.inline-block %filter-selector{ 'selector-set' => "productPropertySelectors", objects: "[product] | propertiesWithValuesOf" } - %div{"ng-if" => "product.description_html"} - %hr + .product-description{"ng-if" => "product.description_html"} %p.text-small{"ng-bind-html" => "::product.description_html"} - %hr - .columns.small-12.large-6 - %img.product-img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"} - %img.product-img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"} + .columns.small-12.medium-6.large-6.product-img + %img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"} + %img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"} %ng-include{src: "'partials/close.html'"} diff --git a/app/assets/stylesheets/darkswarm/_shop-filters.css.scss b/app/assets/stylesheets/darkswarm/_shop-filters.css.scss index 5bb8b5e381..91bb5c7933 100644 --- a/app/assets/stylesheets/darkswarm/_shop-filters.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-filters.css.scss @@ -27,13 +27,11 @@ a, a.button { display: block; - padding-top: 0.5rem; @include border-radius(0.5em); border: 1px solid $border-clr; padding: 0.5em 0.625em; - font-size: 0.875em; color: $base-clr; font-size: 0.75em; background: white; diff --git a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss index 6215e22c9f..bb6b6480dc 100644 --- a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss @@ -1,9 +1,30 @@ .product-header { + padding-left: 1.5rem; + h1, h2, h3, h4, h5, h6 { - margin: 0; + margin: 0.2rem 1.5rem 0 0; } - hr { - margin: 0.5em 0; + span { + color: $grey-500; + } + + .product-description { + margin: 1rem 0.25rem 0.25rem 0; + } + + .property-selectors li { + margin: 0 0.25rem 0.25rem 0; + padding: 0.4rem 0 0; + + a { + border: 1px solid $grey-300; + font-weight: normal; + padding: 0.15rem 0.5rem; + } + + span { + color: $grey-600; + } } } diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss index 95bd6b1059..a360c8f606 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss @@ -63,6 +63,8 @@ ordercycle { select { background-image: url('/assets/white-caret.svg'); + background-size: 30px auto; + background-position-x: 102%; } p { @@ -71,24 +73,27 @@ ordercycle { select, p { - width: inherit; display: inline-block; color: $white; background-color: transparent; border: 0; + border-radius: 0 $radius-small $radius-small 0; margin-bottom: 0; + padding: 0.5em 1.25em 0.5em 0.75em; font-size: 1em; line-height: 1.3em; - padding: 0.5em 1.25em 0.5em 0.75em; height: 2.35em; - background-size: 30px auto; - border-radius: 0 $radius-small $radius-small 0; min-width: 13em; + width: 200px; @include breakpoint(mobile) { width: 100%; min-width: 0; } + + @media all and (min-width: 640px) and (max-width: 1024px), (min-width: 1200px) { + width: 250px; + } } option { @@ -107,6 +112,7 @@ ordercycle { @include breakpoint(mobile) { display: flex; + margin-right: 0; } } @@ -162,7 +168,7 @@ shop ordercycle { @include breakpoint(tablet) { float: none; - padding: 0 0 10px; + padding: 0; } } diff --git a/app/assets/stylesheets/darkswarm/all.scss b/app/assets/stylesheets/darkswarm/all.scss index c40eb7e303..7698726035 100644 --- a/app/assets/stylesheets/darkswarm/all.scss +++ b/app/assets/stylesheets/darkswarm/all.scss @@ -3,6 +3,9 @@ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at * the top of the compiled file, but it's generally better to create a new file per style scope. + *= require autocomplete + *= require leaflet + *= require_self */ @import 'variables'; diff --git a/app/assets/stylesheets/darkswarm/animations.scss b/app/assets/stylesheets/darkswarm/animations.scss index b3848777ba..d7fb952907 100644 --- a/app/assets/stylesheets/darkswarm/animations.scss +++ b/app/assets/stylesheets/darkswarm/animations.scss @@ -143,8 +143,8 @@ } .reveal-modal-bg.in { - filter: alpha(opacity = 50); - opacity: 0.5; + filter: alpha(opacity = 75); + opacity: 0.75; } .animate-repeat { diff --git a/app/assets/stylesheets/darkswarm/distributor_header.css.scss b/app/assets/stylesheets/darkswarm/distributor_header.css.scss index 8e9ebf769b..f7591cd986 100644 --- a/app/assets/stylesheets/darkswarm/distributor_header.css.scss +++ b/app/assets/stylesheets/darkswarm/distributor_header.css.scss @@ -11,7 +11,7 @@ section { display: block; background: $white; position: relative; - z-index: 2; + z-index: 20; .details { box-sizing: border-box; @@ -20,10 +20,6 @@ section { padding: 30px 0 0; position: relative; - select { - width: 200px; - } - img { display: block; height: 100px; diff --git a/app/assets/stylesheets/darkswarm/images.css.scss b/app/assets/stylesheets/darkswarm/images.css.scss index cd939e3b42..739914d709 100644 --- a/app/assets/stylesheets/darkswarm/images.css.scss +++ b/app/assets/stylesheets/darkswarm/images.css.scss @@ -3,18 +3,22 @@ @import "branding"; .product-img { - padding: 5px; - margin-bottom: 10px; - outline: 1px solid #ccc; + text-align: center; - @include box-shadow(0 1px 2px 1px rgba(0, 0, 0, 0.15)); + img { + padding: 0.3rem; - // placeholder for when no product images - &.placeholder { - opacity: 0.35; + // placeholder for when no product images + &.placeholder { + opacity: 0.35; - @include breakpoint(desktop) { - display: none; + @include breakpoint(desktop) { + display: none; + } + } + + @media only screen and (max-width: 1024px) { + margin: 0 0 0.5rem; } } } @@ -49,10 +53,3 @@ .producer-logo { max-width: 220px; } - -@media only screen and (max-width: 1024px) { - .product-img { - margin-top: 2em; - margin-bottom: 1em; - } -} diff --git a/app/assets/stylesheets/darkswarm/map.css.scss b/app/assets/stylesheets/darkswarm/map.css.scss index b0df5b66da..8f9ee717f9 100644 --- a/app/assets/stylesheets/darkswarm/map.css.scss +++ b/app/assets/stylesheets/darkswarm/map.css.scss @@ -6,6 +6,7 @@ .map-container { width: 100%; + position: relative; map, .angular-google-map-container, google-map, .angular-google-map { display: block; @@ -38,6 +39,30 @@ background: rgba(255, 255, 255, 1); } } + + #open-street-map { + z-index: 1; + } + + #open-street-map--search { + top: 16px; + left: 54px; + width: 50%; + z-index: 1000; + + .autocomplete-input, + .autocomplete-result-list { + border: 2px solid $grey-500; + + &:hover, &:active, &:focus { + border-color: $clr-brick; + } + } + + .autocomplete-result-list { + border-top: 1px dotted $grey-500; + } + } } .map-footer { @@ -63,3 +88,8 @@ left: 0px; } } + +.tabs-content .map-footer { + position: relative; + bottom: 30px; +} diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss index 734d388acf..5f9cebc067 100644 --- a/app/assets/stylesheets/darkswarm/modals.css.scss +++ b/app/assets/stylesheets/darkswarm/modals.css.scss @@ -5,8 +5,6 @@ dialog , .reveal-modal { border: none; outline: none; - padding: 30px 20px 0 20px; - border-bottom: 30px solid white; overflow-y: scroll; overflow-x: hidden; min-height: 260px; @@ -18,23 +16,26 @@ dialog // Reveal.js break point: // @media only screen and (max-width: 40.063em) - // Small - when modal IS full screen + // Small - smaller outside area @media only screen and (max-width: 640px) { - left: 0; - max-height: 100%; - position: absolute !important; - top: 0; + left: 4%; + max-height: 92%; + max-width: 92%; + padding: 15px 0 0; + top: 4%; } - // Medium and up - when modal IS NOT full screen + // Medium and up - larger outside area @media only screen and (min-width: 641px) { + border-bottom: 30px solid $white; max-height: 90%; + padding: 30px 20px 0 20px; top: 5%; } } .reveal-modal-bg { - background-color: rgba(0, 0, 0, 0.85); + background-color: $black; position: fixed; } @@ -58,6 +59,10 @@ dialog dialog .close-reveal-modal , .reveal-modal .close-reveal-modal { @include close-button(0.25rem); + + background-color: $grey-500; + color: $white; + font-size: 1.5rem; right: 0.25rem; } diff --git a/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss b/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss index e6baba3393..265c74519c 100644 --- a/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss +++ b/app/assets/stylesheets/darkswarm/pages/login_modal.css.scss @@ -23,6 +23,12 @@ text-decoration: underline; } } + + @media only screen and (max-width: 640px) { + .tabbable { + margin: 0 15px; + } + } } @media only screen and (min-width: 1025px) { diff --git a/app/assets/stylesheets/darkswarm/registration.css.scss b/app/assets/stylesheets/darkswarm/registration.css.scss index 1f80038f18..f97f2b9271 100644 --- a/app/assets/stylesheets/darkswarm/registration.css.scss +++ b/app/assets/stylesheets/darkswarm/registration.css.scss @@ -2,6 +2,10 @@ @import "mixins"; #registration-modal { + @media only screen and (max-width: 640px) { + margin: 0 15px; + } + header { text-align: center; diff --git a/app/assets/stylesheets/darkswarm/shop.css.scss b/app/assets/stylesheets/darkswarm/shop.css.scss index 6c477acb48..0c46523184 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.scss +++ b/app/assets/stylesheets/darkswarm/shop.css.scss @@ -234,6 +234,7 @@ $sidebar-footer-height: 5em; .warning-sign { margin: 0 10px 0 5px; display: inline-block; + line-height: 1.9rem; strong { color: $grey-650; diff --git a/app/assets/stylesheets/darkswarm/shop_tabs.css.scss b/app/assets/stylesheets/darkswarm/shop_tabs.css.scss index e0ce5cc7b9..66bbb8998e 100644 --- a/app/assets/stylesheets/darkswarm/shop_tabs.css.scss +++ b/app/assets/stylesheets/darkswarm/shop_tabs.css.scss @@ -9,6 +9,7 @@ color: $dark-grey; box-shadow: $distributor-header-shadow; position: relative; + z-index: 10; .columns { display: flex; diff --git a/app/assets/stylesheets/mail/email.css.scss b/app/assets/stylesheets/mail/email.css.scss index bb1006c9ea..dee2738ead 100644 --- a/app/assets/stylesheets/mail/email.css.scss +++ b/app/assets/stylesheets/mail/email.css.scss @@ -68,6 +68,10 @@ table.social { background-color: white !important; border: 1px solid #ebebeb; } + + &.fullwidth { + width: 100%; + } } table.order-summary { diff --git a/app/controllers/admin/contents_controller.rb b/app/controllers/admin/contents_controller.rb index 7443ac6717..1769732ec4 100644 --- a/app/controllers/admin/contents_controller.rb +++ b/app/controllers/admin/contents_controller.rb @@ -32,7 +32,8 @@ module Admin PreferenceSections::GroupSignupPageSection.new, PreferenceSections::MainLinksSection.new, PreferenceSections::FooterAndExternalLinksSection.new, - PreferenceSections::UserGuideSection.new + PreferenceSections::UserGuideSection.new, + PreferenceSections::MapSection.new ] end end diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index d66e7eefd2..8b488c8bda 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -145,7 +145,7 @@ module Admin preload(:schedules). ransack(params[:q]). result. - accessible_by(spree_current_user) + visible_by(spree_current_user) end def load_data_for_index diff --git a/app/controllers/enterprises_controller.rb b/app/controllers/enterprises_controller.rb index 2c67600889..98fe17f0a7 100644 --- a/app/controllers/enterprises_controller.rb +++ b/app/controllers/enterprises_controller.rb @@ -65,7 +65,10 @@ class EnterprisesController < BaseController def reset_order order = current_order(true) - OrderCartReset.new(order, params[:id], try_spree_current_user, current_customer).call + # reset_distributor must be called before any call to current_customer or current_distributor + order_cart_reset = OrderCartReset.new(order, params[:id]) + order_cart_reset.reset_distributor + order_cart_reset.reset_other!(try_spree_current_user, current_customer) rescue ActiveRecord::RecordNotFound flash[:error] = I18n.t(:enterprise_shop_show_error) redirect_to shops_path diff --git a/app/controllers/spree/admin/mail_methods_controller.rb b/app/controllers/spree/admin/mail_methods_controller.rb index e95739148d..a21e3afe7d 100644 --- a/app/controllers/spree/admin/mail_methods_controller.rb +++ b/app/controllers/spree/admin/mail_methods_controller.rb @@ -23,7 +23,7 @@ module Spree rescue StandardError => e flash[:error] = Spree.t('admin.mail_methods.testmail.error') % { e: e } ensure - redirect_to edit_admin_mail_method_url + redirect_to edit_admin_mail_methods_url end private diff --git a/app/controllers/spree/admin/reports_controller.rb b/app/controllers/spree/admin/reports_controller.rb index 633ca8c8de..3ada1fbbcd 100644 --- a/app/controllers/spree/admin/reports_controller.rb +++ b/app/controllers/spree/admin/reports_controller.rb @@ -247,15 +247,17 @@ module Spree end def suppliers_of_products_distributed_by(distributors) - distributors.map { |d| Spree::Product.in_distributor(d).includes(:supplier).to_a }. - flatten.map(&:supplier).uniq + supplier_ids = Spree::Product.in_distributors(distributors). + select('spree_products.supplier_id') + + Enterprise.where(id: supplier_ids) end # Load order cycles the current user has access to def my_order_cycles OrderCycle. active_or_complete. - accessible_by(spree_current_user). + visible_by(spree_current_user). order('orders_close_at DESC') end diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb index 0dbbca9505..17c122f0a7 100644 --- a/app/helpers/injection_helper.rb +++ b/app/helpers/injection_helper.rb @@ -100,6 +100,10 @@ module InjectionHelper inject_json_ams "currencyConfig", {}, Api::CurrencyConfigSerializer end + def inject_open_street_map_config + inject_json_ams "openStreetMapConfig", {}, Api::OpenStreetMapConfigSerializer + end + def inject_spree_api_key render partial: "json/injection_ams", locals: { name: 'spreeApiKey', json: "'#{@spree_api_key}'" } end diff --git a/app/models/content_configuration.rb b/app/models/content_configuration.rb index 9c29a70576..29ab8f3308 100644 --- a/app/models/content_configuration.rb +++ b/app/models/content_configuration.rb @@ -17,6 +17,11 @@ class ContentConfiguration < Spree::Preferences::FileConfiguration preference :home_show_stats, :boolean, default: true has_attached_file :home_hero, default_url: "/assets/home/home.jpg" + # Map + preference :open_street_map_enabled, :boolean, default: false + preference :open_street_map_provider_name, :string, default: "OpenStreetMap.Mapnik" + preference :open_street_map_provider_options, :text, default: "{}" + # Producer sign-up page # All the following defaults using I18n don't work. # https://github.com/openfoodfoundation/openfoodnetwork/issues/3816 diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 066254b4f3..2b20033de6 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -70,7 +70,7 @@ class OrderCycle < ActiveRecord::Base } # Return order cycles that user coordinates, sends to or receives from - scope :accessible_by, lambda { |user| + scope :visible_by, lambda { |user| if user.has_spree_role?('admin') where(nil) else diff --git a/app/models/preference_sections/map_section.rb b/app/models/preference_sections/map_section.rb new file mode 100644 index 0000000000..cc16939c36 --- /dev/null +++ b/app/models/preference_sections/map_section.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module PreferenceSections + class MapSection + def name + I18n.t('admin.contents.edit.map') + end + + def preferences + [ + :open_street_map_enabled, + :open_street_map_provider_name, + :open_street_map_provider_options + ] + end + end +end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index dccfd4d756..f5e4e5f8b4 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -39,7 +39,7 @@ class AbilityDecorator # OR if they manage a producer which is included in any order cycles def can_manage_order_cycles?(user) can_manage_orders?(user) || - OrderCycle.accessible_by(user).any? + OrderCycle.visible_by(user).any? end # Users can manage orders if they have a sells own/any enterprise. @@ -193,7 +193,7 @@ class AbilityDecorator def add_order_cycle_management_abilities(user) can [:admin, :index, :read, :edit, :update, :incoming, :outgoing], OrderCycle do |order_cycle| - OrderCycle.accessible_by(user).include? order_cycle + OrderCycle.visible_by(user).include? order_cycle end can [:admin, :index, :create], Schedule can [:admin, :update, :destroy], Schedule do |schedule| diff --git a/app/models/spree/app_configuration_decorator.rb b/app/models/spree/app_configuration_decorator.rb index 5b11a0ee61..a039ddbd45 100644 --- a/app/models/spree/app_configuration_decorator.rb +++ b/app/models/spree/app_configuration_decorator.rb @@ -26,6 +26,7 @@ Spree::AppConfiguration.class_eval do preference :bugherd_api_key, :string, default: nil preference :matomo_url, :string, default: nil preference :matomo_site_id, :string, default: nil + preference :matomo_tag_manager_url, :string, default: nil # Invoices & Receipts preference :enable_invoices?, :boolean, default: true diff --git a/app/models/spree/calculator/price_sack_decorator.rb b/app/models/spree/calculator/price_sack_decorator.rb index b474f77861..389649f916 100644 --- a/app/models/spree/calculator/price_sack_decorator.rb +++ b/app/models/spree/calculator/price_sack_decorator.rb @@ -13,7 +13,7 @@ module Spree end def compute(object) - min = preferred_minimal_amount.to_i + min = preferred_minimal_amount.to_f order_amount = line_items_for(object).map { |x| x.price * x.quantity }.sum if order_amount < min diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 35f8af598d..602329b5c1 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -79,6 +79,12 @@ Spree::Product.class_eval do select('distinct spree_products.*') } + scope :in_distributors, lambda { |distributors| + with_order_cycles_outer. + where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id IN (?))', false, distributors). + uniq + } + # Products supplied by a given enterprise or distributed via that enterprise through an OC scope :in_supplier_or_distributor, lambda { |enterprise| enterprise = enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i @@ -153,18 +159,6 @@ Spree::Product.class_eval do self.class.in_order_cycle(order_cycle).include? self end - # overriding to check self.on_demand as well - def has_stock? - has_variants? ? variants.any?(&:in_stock?) : (on_demand || master.in_stock?) - end - - def has_stock_for_distribution?(order_cycle, distributor) - # This product has stock for a distribution if it is available on-demand - # or if one of its variants in the distribution is in stock - (!has_variants? && on_demand) || - variants_distributed_by(order_cycle, distributor).any?(&:in_stock?) - end - def variants_distributed_by(order_cycle, distributor) order_cycle.variants_distributed_by(distributor).where(product_id: self) end diff --git a/app/serializers/api/open_street_map_config_serializer.rb b/app/serializers/api/open_street_map_config_serializer.rb new file mode 100644 index 0000000000..8c5aec5dbb --- /dev/null +++ b/app/serializers/api/open_street_map_config_serializer.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Api + class OpenStreetMapConfigSerializer < ActiveModel::Serializer + attributes :open_street_map_enabled, + :open_street_map_provider_name, + :open_street_map_provider_options + + def open_street_map_enabled + ContentConfig.open_street_map_enabled + end + + def open_street_map_provider_name + ContentConfig.open_street_map_provider_name + end + + def open_street_map_provider_options + ContentConfig.open_street_map_provider_options.to_json + end + end +end diff --git a/app/services/bulk_invoice_service.rb b/app/services/bulk_invoice_service.rb index 18921bd413..ab69df03ca 100644 --- a/app/services/bulk_invoice_service.rb +++ b/app/services/bulk_invoice_service.rb @@ -7,9 +7,8 @@ class BulkInvoiceService def start_pdf_job(order_ids) pdf = CombinePDF.new - orders = Spree::Order.where(id: order_ids) - orders.each do |order| + orders_from(order_ids).each do |order| invoice = renderer.render_to_string(order) pdf << CombinePDF.parse(invoice) @@ -29,6 +28,10 @@ class BulkInvoiceService private + def orders_from(order_ids) + Spree::Order.where(id: order_ids).order("completed_at DESC") + end + def new_invoice_id Time.zone.now.to_i.to_s end diff --git a/app/services/order_cart_reset.rb b/app/services/order_cart_reset.rb index 077dc537a1..4faec18a30 100644 --- a/app/services/order_cart_reset.rb +++ b/app/services/order_cart_reset.rb @@ -2,25 +2,12 @@ # Resets an order by verifying it's state and fixing any issues class OrderCartReset - def initialize(order, distributor_id, current_user, current_customer) + def initialize(order, distributor_id) @order = order @distributor ||= Enterprise.is_distributor.find_by(permalink: distributor_id) || Enterprise.is_distributor.find(distributor_id) - @current_user = current_user - @current_customer = current_customer end - def call - reset_distributor - reset_user_and_customer if current_user - reset_order_cycle - order.save! - end - - private - - attr_reader :order, :distributor, :current_user, :current_customer - def reset_distributor if order.distributor && order.distributor != distributor order.empty! @@ -29,12 +16,24 @@ class OrderCartReset order.distributor = distributor end - def reset_user_and_customer + def reset_other!(current_user, current_customer) + reset_user_and_customer(current_user) + reset_order_cycle(current_customer) + order.save! + end + + private + + attr_reader :order, :distributor, :current_user + + def reset_user_and_customer(current_user) + return unless current_user + order.associate_user!(current_user) if order.user.blank? || order.email.blank? order.__send__(:associate_customer) if order.customer.nil? # Only associates existing customers end - def reset_order_cycle + def reset_order_cycle(current_customer) listed_order_cycles = Shop::OrderCyclesList.new(distributor, current_customer).call if order_cycle_not_listed?(order.order_cycle, listed_order_cycles) diff --git a/app/services/search_orders.rb b/app/services/search_orders.rb index 4ff0f717da..30afb964a7 100644 --- a/app/services/search_orders.rb +++ b/app/services/search_orders.rb @@ -24,13 +24,25 @@ class SearchOrders attr_reader :params, :current_user def fetch_orders - @search = ::Permissions::Order.new(current_user).editable_orders.ransack(params[:q]) + @search = search_query.ransack(params[:q]) return paginated_results if using_pagination? @search.result(distinct: true) end + def search_query + base_query = ::Permissions::Order.new(current_user).editable_orders + return base_query unless params[:shipping_method_id] + + base_query + .joins(shipments: :shipping_rates) + .where(spree_shipping_rates: { + selected: true, + shipping_method_id: params[:shipping_method_id] + }) + end + def paginated_results @search.result(distinct: true) .page(params[:page]) diff --git a/app/views/admin/matomo_settings/edit.html.haml b/app/views/admin/matomo_settings/edit.html.haml index 51f553bcff..0c553ae002 100644 --- a/app/views/admin/matomo_settings/edit.html.haml +++ b/app/views/admin/matomo_settings/edit.html.haml @@ -18,6 +18,10 @@ = label_tag(:matomo_site_id, t('.matomo_site_id')) + tag(:br) = preference_field_tag("preferences[#{:matomo_site_id}]", Spree::Config[:matomo_site_id], type: Spree::Config.preference_type(:matomo_site_id)) + .field + = label_tag(:matomo_tag_manager_url, t('.matomo_tag_manager_url')) + tag(:br) + = preference_field_tag("preferences[#{:matomo_tag_manager_url}]", Spree::Config[:matomo_tag_manager_url], type: Spree::Config.preference_type(:matomo_tag_manager_url)) + .warning.note= t('.config_instructions_tag_manager_html') .form-buttons{"data-hook" => "buttons"} = button t(:update), 'icon-refresh' diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index e8318faef9..3d5af8f08e 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -6,7 +6,9 @@ = @group.logo.url - content_for :injection_data do + = inject_available_countries = inject_group_enterprises + = inject_open_street_map_config #group-page.row.pad-top.footer-pad{"ng-controller" => "GroupPageCtrl"} .small-12.columns.pad-top @@ -32,13 +34,8 @@ %tab{heading: t(:label_map), active: "tabs.map.active", select: "select(\'map\')"} - .map-container - %map{"ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"} - %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} - %map-osm-tiles - %map-search - %ui-gmap-markers{models: "mapMarkers", fit: "true", - coords: "'self'", icon: "'icon'", click: "'reveal'"} + %div{"ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"} + = render partial: "shared/map" %tab{heading: t(:groups_about), active: "tabs.about.active", @@ -122,4 +119,4 @@ %span = t 'title' -= render "shared/footer" \ No newline at end of file += render "shared/footer" diff --git a/app/views/layouts/_matomo_tag.html.haml b/app/views/layouts/_matomo_tag.html.haml index aba1b19528..85a4cf47dc 100644 --- a/app/views/layouts/_matomo_tag.html.haml +++ b/app/views/layouts/_matomo_tag.html.haml @@ -1,6 +1,15 @@ + +- if Spree::Config.matomo_tag_manager_url.present? + :javascript + var _mtm = _mtm || []; + _mtm.push({'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start'}); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + var u="#{Spree::Config.matomo_tag_manager_url}"; + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u; s.parentNode.insertBefore(g,s); + - if Spree::Config.matomo_url.present? :javascript - var _paq = _paq || []; + var _paq = window._paq || []; _paq.push(["setDocumentTitle", document.domain + "/" + document.title]); _paq.push(["setCookieDomain", "*.#{Spree::Config.site_url}"]); _paq.push(["setDomains", ["*.#{Spree::Config.site_url}"]]); @@ -8,8 +17,8 @@ _paq.push(['enableLinkTracking']); (function() { var u="#{Spree::Config.matomo_url}"; - _paq.push(['setTrackerUrl', u+'piwik.php']); + _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '#{Spree::Config.matomo_site_id}']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; - g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index fc282d5c6e..fdf2cd4f17 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -39,7 +39,8 @@ = render "layouts/bugsnag_js" %script{:src => "https://js.stripe.com/v3/", :type => "text/javascript"} - %script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "} + - if !ContentConfig.open_street_map_enabled + %script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "} = javascript_include_tag "darkswarm/all" = javascript_include_tag "web/all" = render "layouts/i18n_script" diff --git a/app/views/map/index.html.haml b/app/views/map/index.html.haml index 294fa45f8e..741fa67064 100644 --- a/app/views/map/index.html.haml +++ b/app/views/map/index.html.haml @@ -2,15 +2,8 @@ = t :label_map - content_for :injection_data do + = inject_available_countries = inject_enterprise_shopfront_list + = inject_open_street_map_config -.map-container{"fill-vertical" => true} - %map{"ng-controller" => "MapCtrl"} - %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} - %map-osm-tiles - %map-search - %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", - coords: "'self'", icon: "'icon'", click: "'reveal'"} - -.map-footer - %a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors += render partial: "shared/map" diff --git a/app/views/shared/_map.html.haml b/app/views/shared/_map.html.haml new file mode 100644 index 0000000000..c7df6d5b2b --- /dev/null +++ b/app/views/shared/_map.html.haml @@ -0,0 +1,19 @@ +- if ContentConfig.open_street_map_enabled + .map-container + %ofn-open-street-map#open-street-map + %div#open-street-map--search + %input.autocomplete-input + %ul.autocomplete-result-list + +- else + .map-container + %map{"ng-controller" => "MapCtrl"} + %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", + styles: "map.styles", draggable: "true"} + %map-osm-tiles + %map-search + %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", + coords: "'self'", icon: "'icon'", click: "'reveal'"} + + .map-footer + %a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors diff --git a/app/views/shop/messages/_select_oc.html.haml b/app/views/shop/messages/_select_oc.html.haml index 69f037cdf4..2f44ed827f 100644 --- a/app/views/shop/messages/_select_oc.html.haml +++ b/app/views/shop/messages/_select_oc.html.haml @@ -1,3 +1,5 @@ .content.footer-pad{ "darker-background" => true, "ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id == null" } - .select-oc-message - = t '.select_oc_html' + .row + .small-12.columns + .select-oc-message + = t '.select_oc_html' diff --git a/app/views/spree/admin/adjustments/edit.html.haml b/app/views/spree/admin/adjustments/edit.html.haml index c31dfb145e..756288c4f4 100644 --- a/app/views/spree/admin/adjustments/edit.html.haml +++ b/app/views/spree/admin/adjustments/edit.html.haml @@ -1,4 +1,5 @@ -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' } += render :partial => 'spree/admin/shared/order_page_title' += render :partial => 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' } - content_for :page_title do %i.icon-arrow-right diff --git a/app/views/spree/admin/adjustments/index.html.haml b/app/views/spree/admin/adjustments/index.html.haml index 7268441e1e..02433a6e5c 100644 --- a/app/views/spree/admin/adjustments/index.html.haml +++ b/app/views/spree/admin/adjustments/index.html.haml @@ -1,4 +1,5 @@ -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' } += render partial: 'spree/admin/shared/order_page_title' += render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' } - content_for :page_title do %i.icon-arrow-right diff --git a/app/views/spree/admin/adjustments/new.html.haml b/app/views/spree/admin/adjustments/new.html.haml index 3eb6f5c58e..2af33aae54 100644 --- a/app/views/spree/admin/adjustments/new.html.haml +++ b/app/views/spree/admin/adjustments/new.html.haml @@ -1,4 +1,5 @@ -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' } += render partial: 'spree/admin/shared/order_page_title' += render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' } - content_for :page_title do %i.icon-arrow-right diff --git a/app/views/spree/admin/images/index.html.haml b/app/views/spree/admin/images/index.html.haml index 89124383e2..37cc53c70b 100644 --- a/app/views/spree/admin/images/index.html.haml +++ b/app/views/spree/admin/images/index.html.haml @@ -15,15 +15,13 @@ %colgroup %col{ style: "width: 5%" }/ %col{ style: "width: 10%" }/ - - if @product.has_variants? - %col{ style: "width: 25%" }/ + %col{ style: "width: 25%" }/ %col{ style: "width: 45%" }/ %col{ style: "width: 15%" }/ %thead %tr %th{:colspan => "2"}= t('spree.thumbnail') - - if @product.has_variants? - %th= Spree::Variant.model_name.human + %th= Spree::Variant.model_name.human %th= t('spree.alt_text') %th.actions %tbody @@ -35,8 +33,7 @@ %span.handle %td = link_to image_tag(image.attachment.url(:mini)), image.attachment.url(:product) - - if @product.has_variants? - %td= options_text_for(image) + %td= options_text_for(image) %td= image.alt %td.actions = link_to_with_icon 'icon-edit', t('spree.edit'), edit_admin_product_image_url(@product, image), no_text: true, data: { action: 'edit'} diff --git a/app/views/spree/admin/mail_methods/edit.html.haml b/app/views/spree/admin/mail_methods/edit.html.haml index 90938e4542..9e79403270 100644 --- a/app/views/spree/admin/mail_methods/edit.html.haml +++ b/app/views/spree/admin/mail_methods/edit.html.haml @@ -5,11 +5,11 @@ - content_for :page_actions do %li - = link_to_with_icon 'icon-envelope-alt', t("spree.admin.mail_methods.send_testmail"), testmail_admin_mail_method_path, method: :post, title: t("spree.admin.mail_methods.send_testmail"), class: 'send_mail button no-text' + = link_to_with_icon 'icon-envelope-alt', t("spree.admin.mail_methods.send_testmail"), testmail_admin_mail_methods_path, method: :post, title: t("spree.admin.mail_methods.send_testmail"), class: 'send_mail button no-text' = render partial: 'spree/shared/error_messages', locals: { target: @mail_method } -= form_tag admin_mail_method_path, method: :put do |f| += form_tag admin_mail_methods_path, method: :put do |f| %fieldset.no-border-top = render partial: 'form', locals: { f: f } .form-buttons.filter-actions.actions= button t("spree.actions.update"), 'icon-refresh' diff --git a/app/views/spree/admin/orders/_filters.html.haml b/app/views/spree/admin/orders/_filters.html.haml index 5b1c9b4024..0479e26a62 100644 --- a/app/views/spree/admin/orders/_filters.html.haml +++ b/app/views/spree/admin/orders/_filters.html.haml @@ -32,6 +32,11 @@ %label = check_box_tag "q[completed_at_not_null]", 1, true, {'ng-model' => 'q.completed_at_not_null'} = t(:show_only_complete_orders) + .field + = label_tag nil, t(:shipping_method) + = select_tag("shipping_method_id", + options_for_select(Spree::ShippingMethod.managed_by(spree_current_user).collect {|s| [t("spree.shipping_method.#{s.name}"), s.id]}), + {include_blank: true, class: 'select2', 'ng-model' => 'shipping_method_id'}) .field-block.alpha.eight.columns = label_tag nil, t(:distributors) = select_tag("q[distributor_id_in]", diff --git a/app/views/spree/admin/orders/customer_details/edit.html.haml b/app/views/spree/admin/orders/customer_details/edit.html.haml index f6a83316da..584c3350b9 100644 --- a/app/views/spree/admin/orders/customer_details/edit.html.haml +++ b/app/views/spree/admin/orders/customer_details/edit.html.haml @@ -1,4 +1,5 @@ -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Customer Details' } += render partial: 'spree/admin/shared/order_page_title' += render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Customer Details' } = csrf_meta_tags diff --git a/app/views/spree/admin/orders/edit.html.haml b/app/views/spree/admin/orders/edit.html.haml index 69abbe8f38..d2047e6bf4 100644 --- a/app/views/spree/admin/orders/edit.html.haml +++ b/app/views/spree/admin/orders/edit.html.haml @@ -8,7 +8,8 @@ - if can?(:admin, Spree::Order) %li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left' -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Order Details' } += render partial: "spree/admin/shared/order_page_title" += render partial: "spree/admin/shared/order_tabs", locals: { current: 'Order Details' } %div{"data-hook" => "admin_order_edit_header"} -# Suppress errors when manually creating a new order - needs to proceed to edit page diff --git a/app/views/spree/admin/orders/new.html.haml b/app/views/spree/admin/orders/new.html.haml index 9ec198b2d7..556e464cd4 100644 --- a/app/views/spree/admin/orders/new.html.haml +++ b/app/views/spree/admin/orders/new.html.haml @@ -1,5 +1,7 @@ - content_for :page_title do - = t(:new) + = t(:new_order) + \# + = @order.number - content_for :page_actions do %li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left' diff --git a/app/views/spree/admin/orders/set_distribution.html.haml b/app/views/spree/admin/orders/set_distribution.html.haml index f5e259321e..3579619185 100644 --- a/app/views/spree/admin/orders/set_distribution.html.haml +++ b/app/views/spree/admin/orders/set_distribution.html.haml @@ -1,12 +1,14 @@ -- content_for :page_title do - = t(:new) - - content_for :page_actions do %li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left' = admin_inject_shops(module: 'admin.orders') = admin_inject_order_cycles +- content_for :page_title do + = t(:new_order) + \# + = @order.number + = render 'spree/admin/shared/order_tabs', :current => 'Order Details' = csrf_meta_tags diff --git a/app/views/spree/admin/payment_methods/_form.html.haml b/app/views/spree/admin/payment_methods/_form.html.haml index a740f575e2..7c2e1c4085 100644 --- a/app/views/spree/admin/payment_methods/_form.html.haml +++ b/app/views/spree/admin/payment_methods/_form.html.haml @@ -1,42 +1,44 @@ = admin_inject_payment_method = admin_inject_json_ams_array "admin.paymentMethods", "shops", @hubs, Api::Admin::BasicEnterpriseSerializer -%div.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" } +.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" } + .row + = t '.deactivation_warning' .row .alpha.three.columns - = label_tag nil, t(:name) + = label_tag nil, t('.name') .omega.eight.columns = text_field :payment_method, :name, class: 'fullwidth' .row .alpha.three.columns - = label_tag nil, t(:description) + = label_tag nil, t('.description') .omega.eight.columns = text_area :payment_method, :description, {cols: 60, rows: 6, class: 'fullwidth'} - if spree_current_user.admin? .row .alpha.three.columns - = label_tag nil, t(:environment) + = label_tag nil, t('.environment') .omega.eight.columns = collection_select(:payment_method, :environment, Rails.configuration.database_configuration.keys.sort, :to_s, :titleize, {}, {id: 'gtwy-env', class: 'select2 fullwidth'}) - .row - .alpha.three.columns - = label_tag nil, t(:display) - .omega.eight.columns - = select(:payment_method, :display_on, Spree::PaymentMethod::DISPLAY.collect { |display| [t(display), display == :both ? nil : display.to_s] }, {}, {class: 'select2 fullwidth'}) .row .alpha.three.columns - = label_tag nil, t(:active) + = label_tag nil, t('.display') + .omega.eight.columns + = select(:payment_method, :display_on, Spree::PaymentMethod::DISPLAY.collect { |display| [t('.' + display.to_s), display == :both ? nil : display.to_s] }, {}, {class: 'select2 fullwidth'}) + .row + .alpha.three.columns + = label_tag nil, t('.active') .two.columns = radio_button :payment_method, :active, true   - = label_tag nil, t(:say_yes) + = label_tag nil, t('.active_yes') .omega.six.columns = radio_button :payment_method, :active, false   - = label_tag nil, t(:say_no) + = label_tag nil, t('.active_no') .row .alpha.three.columns - = label(:payment_method, :tags, t(:tags)) + = label(:payment_method, :tags, t('.tags')) .omega.eight.columns = hidden_field(:payment_method, :tag_list, "ng-value" => "paymentMethod.tag_list") %tags-with-translation#something{ object: "paymentMethod" } diff --git a/app/views/spree/admin/payment_methods/_providers.html.haml b/app/views/spree/admin/payment_methods/_providers.html.haml index 657e21029e..2311eaa78f 100644 --- a/app/views/spree/admin/payment_methods/_providers.html.haml +++ b/app/views/spree/admin/payment_methods/_providers.html.haml @@ -1,7 +1,7 @@ #provider-settings{ ng: { controller: "ProvidersCtrl" } } .row .alpha.three.columns - = label :payment_method, :type, t(:provider) + = label :payment_method, :type, t('.provider') .omega.eight.columns = collection_select(:payment_method, :type, @providers, :to_s, :clean_name, (!@object.persisted? ? { :selected => "Spree::PaymentMethod::Check"} : {}), { class: 'select2 fullwidth', 'provider-prefs-for' => "#{@object.id}"}) diff --git a/app/views/spree/admin/payment_methods/edit.html.haml b/app/views/spree/admin/payment_methods/edit.html.haml index 9d8f6b147d..f1c98aeb43 100644 --- a/app/views/spree/admin/payment_methods/edit.html.haml +++ b/app/views/spree/admin/payment_methods/edit.html.haml @@ -4,7 +4,7 @@ = @payment_method.name - content_for :page_actions do %li - = button_link_to t(:new), spree.new_admin_payment_method_path, icon: 'icon-plus' + = button_link_to t('.new'), spree.new_admin_payment_method_path, icon: 'icon-plus' %li = button_link_to t('.back_to_payment_methods_list'), spree.admin_payment_methods_path, icon: 'icon-arrow-left' = render partial: 'spree/shared/error_messages', locals: { target: @payment_method } diff --git a/app/views/spree/admin/payment_methods/index.html.haml b/app/views/spree/admin/payment_methods/index.html.haml index 4e79bf1c9d..ab1333f2c5 100644 --- a/app/views/spree/admin/payment_methods/index.html.haml +++ b/app/views/spree/admin/payment_methods/index.html.haml @@ -1,9 +1,9 @@ - content_for :page_title do - = Spree.t(:payment_methods) + = t('.payment_methods') - content_for :page_actions do %li - = button_link_to Spree.t(:new_payment_method), new_object_url, icon: 'icon-plus', id: 'admin_new_payment_methods_link' + = button_link_to t('.new_payment_method'), new_object_url, icon: 'icon-plus', id: 'admin_new_payment_methods_link' - if @payment_methods.any? %table#listing_payment_methods.index @@ -17,12 +17,12 @@ %col{style: "width: 11%"} %thead %tr - %th= Spree.t(:name) - %th= t(:products_distributor) - %th= Spree.t(:provider) - %th= Spree.t(:environment) - %th= Spree.t(:display) - %th= Spree.t(:active) + %th= t('.name') + %th= t('.products_distributor') + %th= t('.provider') + %th= t('.environment') + %th= t('.display') + %th= t('.active') %th.actions %tbody - @payment_methods.each do |method| @@ -34,10 +34,10 @@ %br/ %td= method.type %td.align-center= method.environment.to_s.titleize - %td.align-center= method.display_on.blank? ? Spree.t(:both) : Spree.t(method.display_on) - %td.align-center= method.active ? Spree.t(:say_yes) : Spree.t(:say_no) + %td.align-center= method.display_on.blank? ? t('.both') : t('.' + method.display_on.to_s) + %td.align-center= method.active ? t('.active_yes') : t('.active_no') %td.actions = link_to_edit method, no_text: true = link_to_delete method, no_text: true - else - .alpha.twelve.columns.no-objects-found= Spree.t(:no_payment_methods_found) + .alpha.twelve.columns.no-objects-found= t('.no_payment_methods_found') diff --git a/app/views/spree/admin/payments/index.html.haml b/app/views/spree/admin/payments/index.html.haml index 3c62b54843..7fbe76429f 100644 --- a/app/views/spree/admin/payments/index.html.haml +++ b/app/views/spree/admin/payments/index.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' } - content_for :page_actions do diff --git a/app/views/spree/admin/payments/new.html.haml b/app/views/spree/admin/payments/new.html.haml index 7c825051ad..710456cc2d 100644 --- a/app/views/spree/admin/payments/new.html.haml +++ b/app/views/spree/admin/payments/new.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' } - content_for :page_title do diff --git a/app/views/spree/admin/payments/show.html.haml b/app/views/spree/admin/payments/show.html.haml index 97850cb19a..acbc2d8aaf 100644 --- a/app/views/spree/admin/payments/show.html.haml +++ b/app/views/spree/admin/payments/show.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' } - content_for :page_title do diff --git a/app/views/spree/admin/products/_form.html.haml b/app/views/spree/admin/products/_form.html.haml index 616f7977f3..08386e10dd 100644 --- a/app/views/spree/admin/products/_form.html.haml +++ b/app/views/spree/admin/products/_form.html.haml @@ -43,37 +43,6 @@ .clear - - unless @product.has_variants? - = f.field_container :sku do - = f.label :sku, t(:sku) - = f.text_field :sku, :size => 16 - - .alpha.two.columns - = f.field_container :on_hand do - = f.label :on_hand, t(:on_hand) - = f.number_field :on_hand, :min => 0 - .omega.two.columns - = f.field_container :on_demand, :class => ['checkbox'] do - %label - = f.check_box :on_demand - = t(:on_demand) - - .clear - - %ul#shipping_specs - %li#shipping_specs_weight_field.field.alpha.two.columns - = f.label :weight, t(:weight) - = f.text_field :weight, :size => 4 - %li#shipping_specs_height_field.field.omega.two.columns - = f.label :height, t(:height) - = f.text_field :height, :size => 4 - %li#shipping_specs_width_field.field.alpha.two.columns - = f.label :width, t(:width) - = f.text_field :width, :size => 4 - %li#shipping_specs_depth_field.field.omega.two.columns - = f.label :depth, t(:depth) - = f.text_field :depth, :size => 4 - = f.field_container :shipping_categories do = f.label :shipping_category_id, t(:shipping_categories) = f.collection_select(:shipping_category_id, @shipping_categories, :id, :name, { :include_blank => 'None' }, { :class => 'select2' }) diff --git a/app/views/spree/admin/return_authorizations/edit.html.haml b/app/views/spree/admin/return_authorizations/edit.html.haml index 2847c10965..9f5429640d 100644 --- a/app/views/spree/admin/return_authorizations/edit.html.haml +++ b/app/views/spree/admin/return_authorizations/edit.html.haml @@ -6,6 +6,7 @@ - if @return_authorization.can_cancel? = button_link_to t('actions.cancel'), fire_admin_order_return_authorization_url(@order, @return_authorization, e: 'cancel'), method: :put, data: { confirm: t('.are_you_sure') }, icon: 'icon-remove' += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' } - content_for :page_title do diff --git a/app/views/spree/admin/return_authorizations/index.html.haml b/app/views/spree/admin/return_authorizations/index.html.haml index acf016b50d..bc8ed9dd80 100644 --- a/app/views/spree/admin/return_authorizations/index.html.haml +++ b/app/views/spree/admin/return_authorizations/index.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' } - content_for :page_actions do diff --git a/app/views/spree/admin/return_authorizations/new.html.haml b/app/views/spree/admin/return_authorizations/new.html.haml index 54573f7392..5594288cf3 100644 --- a/app/views/spree/admin/return_authorizations/new.html.haml +++ b/app/views/spree/admin/return_authorizations/new.html.haml @@ -1,3 +1,4 @@ += render partial: 'spree/admin/shared/order_page_title' = render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' } - content_for :page_title do diff --git a/app/views/spree/admin/shared/_configuration_menu.html.haml b/app/views/spree/admin/shared/_configuration_menu.html.haml index 5810cc97b2..c5f302f0db 100644 --- a/app/views/spree/admin/shared/_configuration_menu.html.haml +++ b/app/views/spree/admin/shared/_configuration_menu.html.haml @@ -6,7 +6,7 @@ %ul.sidebar = configurations_sidebar_menu_item Spree.t(:general_settings), edit_admin_general_settings_path - if Spree::Config[:override_actionmailer_config] - = configurations_sidebar_menu_item Spree.t(:mail_method_settings), edit_admin_mail_method_path + = configurations_sidebar_menu_item Spree.t(:mail_method_settings), edit_admin_mail_methods_path = configurations_sidebar_menu_item Spree.t(:image_settings), edit_admin_image_settings_path = configurations_sidebar_menu_item Spree.t(:tax_categories), admin_tax_categories_path = configurations_sidebar_menu_item Spree.t(:tax_rates), admin_tax_rates_path diff --git a/app/views/spree/admin/shared/_order_page_title.html.haml b/app/views/spree/admin/shared/_order_page_title.html.haml new file mode 100644 index 0000000000..927062d4f7 --- /dev/null +++ b/app/views/spree/admin/shared/_order_page_title.html.haml @@ -0,0 +1,4 @@ +- content_for :page_title do + = t(:order) + \# + = @order.number diff --git a/app/views/spree/admin/shared/_order_tabs.html.haml b/app/views/spree/admin/shared/_order_tabs.html.haml index 89d7299fdc..f96a5dd140 100644 --- a/app/views/spree/admin/shared/_order_tabs.html.haml +++ b/app/views/spree/admin/shared/_order_tabs.html.haml @@ -1,8 +1,3 @@ -- content_for :page_title do - = t(:order) - \# - = @order.number - - if @order.bill_address.present? = @order.bill_address.firstname = @order.bill_address.lastname diff --git a/app/views/spree/admin/shared/_tabs.html.haml b/app/views/spree/admin/shared/_tabs.html.haml index 920480fc8b..e0134ee272 100644 --- a/app/views/spree/admin/shared/_tabs.html.haml +++ b/app/views/spree/admin/shared/_tabs.html.haml @@ -3,7 +3,7 @@ = tab :order_cycles, url: main_app.admin_order_cycles_path, icon: 'icon-refresh' = tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path('q[s]' => 'completed_at desc'), icon: 'icon-shopping-cart' = tab :reports, icon: 'icon-file' -= tab :general_settings, :mail_method, :image_settings, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path += tab :general_settings, :mail_methods, :image_settings, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path = tab :enterprises, :enterprise_relationships, url: main_app.admin_enterprises_path = tab :customers, url: main_app.admin_customers_path = tab :enterprise_groups, url: main_app.admin_enterprise_groups_path, label: 'groups' diff --git a/app/views/spree/admin/shipping_methods/_form.html.haml b/app/views/spree/admin/shipping_methods/_form.html.haml index b95481cc04..13d7667745 100644 --- a/app/views/spree/admin/shipping_methods/_form.html.haml +++ b/app/views/spree/admin/shipping_methods/_form.html.haml @@ -15,13 +15,12 @@ .omega.eight.columns = f.text_area :description, class: 'fullwidth', rows: 2, placeholder: t(:spree_admin_eg_collect_your_order) = error_message_on :shipping_method, :description - - if spree_current_user.admin? - .row - .alpha.three.columns - = f.label :display_on, t(:display) - .omega.eight.columns - = select(:shipping_method, :display_on, [[t(".both"), nil], [t(".back_end"), "back_end"]], {}, {class: 'select2 fullwidth'}) - = error_message_on :shipping_method, :display_on + .row + .alpha.three.columns + = f.label :display_on, t(:display) + .omega.eight.columns + = select(:shipping_method, :display_on, [[t(".both"), nil], [t(".back_end"), "back_end"]], {}, {class: 'select2 fullwidth'}) + = error_message_on :shipping_method, :display_on .row .alpha.three.columns diff --git a/app/views/spree/admin/variants/_autocomplete.js.erb b/app/views/spree/admin/variants/_autocomplete.js.erb index 527b55568c..5ef095925c 100644 --- a/app/views/spree/admin/variants/_autocomplete.js.erb +++ b/app/views/spree/admin/variants/_autocomplete.js.erb @@ -57,7 +57,7 @@ {{else}} - <%= Spree.t(:out_of_stock) %> + <%= t('.out_of_stock') %> 0 {{/if}} diff --git a/app/views/spree/admin/variants/index.html.haml b/app/views/spree/admin/variants/index.html.haml index 199bcc0501..ce9c1edd86 100644 --- a/app/views/spree/admin/variants/index.html.haml +++ b/app/views/spree/admin/variants/index.html.haml @@ -3,40 +3,32 @@ = render partial: 'spree/admin/shared/product_tabs', locals: {current: 'Variants'} #new_variant -- if @variants.any? - %table.index.sortable{"data-sortable-link" => update_positions_admin_product_variants_path(@product)} - %colgroup - %col{style: "width: 5%"}/ - %col{style: "width: 25%"}/ - %col{style: "width: 20%"}/ - %col{style: "width: 20%"}/ - %col{style: "width: 15%"}/ - %col{style: "width: 15%"}/ - %thead - %tr - %th{colspan: "2"}= t('.options') - %th= t('.price') - %th= t('.sku') - %th.actions - %tbody - - @variants.each do |variant| - %tr{id: spree_dom_id(variant), class: cycle('odd', 'even'), style: "#{"color:red;" if variant.deleted? }" } - %td.no-border - %span.handle - %td= variant.full_name - %td.align-center= variant.display_price.to_html - %td.align-center= variant.sku - %td.actions - = link_to_edit(variant, no_text: true) unless variant.deleted? - = link_to_delete(variant, no_text: true) unless variant.deleted? - - unless @product.has_variants? - %tr - %td{colspan: "5"}= t(:none) -- else - .alpha.twelve.columns.no-objects-found - = t('.no_results') - \. +%table.index.sortable{"data-sortable-link" => update_positions_admin_product_variants_path(@product)} + %colgroup + %col{style: "width: 5%"}/ + %col{style: "width: 25%"}/ + %col{style: "width: 20%"}/ + %col{style: "width: 20%"}/ + %col{style: "width: 15%"}/ + %col{style: "width: 15%"}/ + %thead + %tr + %th{colspan: "2"}= t('.options') + %th= t('.price') + %th= t('.sku') + %th.actions + %tbody + - @variants.each do |variant| + %tr{id: spree_dom_id(variant), class: cycle('odd', 'even'), style: "#{"color:red;" if variant.deleted? }" } + %td.no-border + %span.handle + %td= variant.full_name + %td.align-center= variant.display_price.to_html + %td.align-center= variant.sku + %td.actions + = link_to_edit(variant, no_text: true) unless variant.deleted? + = link_to_delete(variant, no_text: true) unless variant.deleted? - if @product.empty_option_values? %p.first_add_option_types.no-objects-found diff --git a/app/views/spree/order_mailer/cancel_email.html.haml b/app/views/spree/order_mailer/cancel_email.html.haml index 47b577e79d..0965d522b8 100755 --- a/app/views/spree/order_mailer/cancel_email.html.haml +++ b/app/views/spree/order_mailer/cancel_email.html.haml @@ -1,11 +1,29 @@ -%h3 - = t(".customer_greeting", name: @order.bill_address.firstname) -%h4 - = t(".instructions") -%span.clear +%table.social.white-bg.fullwidth + %table.column + %tr + %td + %h3 + = t(".customer_greeting", name: @order.bill_address.firstname) + %h4 + = t(".instructions_html", distributor: @order.distributor.name ) + %img{src: "#{@order.distributor.logo.url(:medium)}"} + +%p.callout + = t(".dont_cancel", email: @order.distributor.contact.email) %p   +%h4 + = t(".order_summary_canceled_html", number: @order.number) +%p + = t(".details") -= t(".order_summary_canceled") = render 'order_summary' + +%p + - if @order.paid? + = t(".paid_order", distributor: @order.distributor.name) + - else + = t(".unpaid_order") + = render 'signoff' += render 'shared/mailers/social_and_contact' diff --git a/app/views/spree/shared/_error_messages.html.haml b/app/views/spree/shared/_error_messages.html.haml index 54fabd313e..b0ced1b317 100644 --- a/app/views/spree/shared/_error_messages.html.haml +++ b/app/views/spree/shared/_error_messages.html.haml @@ -1,10 +1,9 @@ - if target && target.errors.any? #errorExplanation.errorExplanation %h2 - = Spree.t(:errors_prohibited_this_record_from_being_saved, count: target.errors.count) - \: + = t(".errors_prohibited_this_record_from_being_saved", count: target.errors.count) %p - = Spree.t(:there_were_problems_with_the_following_fields) + = t(".there_were_problems_with_the_following_fields") \: %ul - target.errors.full_messages.each do |msg| diff --git a/app/views/spree/users/_open_orders.html.haml b/app/views/spree/users/_open_orders.html.haml index 2b8578a658..73be12b346 100644 --- a/app/views/spree/users/_open_orders.html.haml +++ b/app/views/spree/users/_open_orders.html.haml @@ -7,8 +7,8 @@ %th.order3.show-for-large-up= t('.changes_allowed_until') %th.order4.show-for-large-up= t('.items') %th.order5.text-right= t('.total') - %th.order6.text-right.show-for-large-up= t('.edit') - %th.order7.text-right= t('.cancel') + %th.order6.text-right= t('.edit') + %th.order7.show-for-large-up.text-right= t('.cancel') %tbody.transaction-group{"ng-repeat" => "order in Orders.changeable", "ng-class-odd"=>"'odd'", "ng-class-even"=>"'even'"} %tr.order-row %td.order1 @@ -18,7 +18,7 @@ %td.order3.show-for-large-up{"ng-bind" => "::order.changes_allowed_until"} %td.order4.show-for-large-up{"ng-bind" => "::order.item_count"} %td.order5.text-right{"ng-class" => "{'credit' : order.total < 0, 'debit' : order.total > 0, 'paid' : order.total == 0}","ng-bind" => "::order.total | localizeCurrency"} - %td.order6.text-right.show-for-large-up.brick + %td.order6.text-right.brick %a{"ng-href" => "{{::order.path}}" }= t('.edit') - %td.order7.text-right + %td.order7.show-for-large-up.text-right = link_to t('.cancel'), "", method: :put, "ng-href" => "{{::order.cancel_path}}", "confirm-link-click" => t('orders_confirm_cancel') diff --git a/config/database.yml b/config/database.yml index 20c6760868..617ee5ae93 100644 --- a/config/database.yml +++ b/config/database.yml @@ -5,6 +5,7 @@ defaults: &defaults host: <%= ENV.fetch('OFN_DB_HOST', 'localhost') %> username: <%= ENV.fetch('OFN_DB_USERNAME', 'ofn') %> password: <%= ENV.fetch('OFN_DB_PASSWORD', 'f00d') %> + port: <%= ENV.fetch('OFN_DB_PORT', 5432) %> development: <<: *defaults diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 537091cb62..278d54f8dd 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -363,7 +363,6 @@ ar: title: "إعدادات Matomo" matomo_url: "العنوان الالكتروني ل Matomo " matomo_site_id: "معرف موقع Matomo" - info_html: "Matomo هو تحليلات الويب والجوال. يمكنك إما تنصيب Matomo محليًا أو استخدام خدمة استضافة سحابية. انظر matomo.org لمزيد من المعلومات." config_instructions_html: "هنا يمكنك تهيئة تكامل Matomo لشبكة الغذاء المفتوح. يجب أن يشير عنوان الالكتروني URL الخاص بـ Matomo أدناه إلى مثيل Matomo حيث سيتم إرسال معلومات تتبع المستخدم إلى ؛ إذا تم تركه فارغًا ، فسيتم تعطيل تتبع مستخدم Matomo. حقل معرف الموقع ليس إلزاميًا ولكنه مفيد إذا كنت تتعقب أكثر من موقع ويب على مثيل Matomo ؛ يمكن العثور عليه على وحدة تحكم مثيل Matomo." customers: index: @@ -398,6 +397,7 @@ ar: footer_and_external_links: تذييل والروابط الخارجية your_content: المحتوى الخاص بك user_guide: دليل المستخدم + map: خريطة enterprise_fees: index: title: "رسوم الشركة" @@ -2752,6 +2752,8 @@ ar: new_payment: "دفعة جديد" capture: "إلتقاط" void: "فارغ" + login: "تسجيل الدخول" + password: "كلمه السر" configurations: "تهيئة" general_settings: "الاعدادات العامة" site_name: "اسم الموقع" @@ -2816,8 +2818,6 @@ ar: abbreviation: "الاختصار" new_state: "محافظة جديدة" payment_methods: "طرق الدفع" - new_payment_method: "طريقة الدفع الجديدة" - provider: "مزود" taxonomies: "التصنيفات" new_taxonomy: "تصنيف جديد" back_to_taxonomies_list: "العودة إلى قائمة التصنيفات" @@ -3024,10 +3024,23 @@ ar: categories: "التصنيفات" zones: "مناطق" payment_methods: + index: + payment_methods: "طريقة الدفع" + new_payment_method: "طريقة الدفع الجديدة" + name: "الاسم" + products_distributor: "الموزع" + provider: "مزود" + environment: "بيئة" + display: "عرض" + active: "نشط" + both: "على حد سواء" + active_yes: "نعم" + active_no: "لا" new: new_payment_method: "طريقة الدفع الجديدة" back_to_payment_methods_list: "العودة إلى قائمة طرق الدفع" edit: + new: "جديد" editing_payment_method: "تحرير طريقة الدفع" back_to_payment_methods_list: "العودة إلى قائمة طرق الدفع" stripe_connect: @@ -3043,6 +3056,17 @@ ar: account_id: معرف الحساب business_name: الاسم التجاري charges_enabled: تم تمكين الدفع + form: + name: "الاسم" + description: "وصف" + environment: "بيئة" + display: "عرض" + active: "نشط" + active_yes: "نعم" + active_no: "لا" + tags: "الاوسمة" + providers: + provider: "مزود" payments: source_forms: stripe: @@ -3143,6 +3167,7 @@ ar: display_as: "عرض ب" display_name: "اسم العرض" autocomplete: + out_of_stock: "غير متوفر" producer_name: "المنتج" unit: "وحدة" shared: @@ -3207,9 +3232,6 @@ ar: invalid: غير صالحة order_mailer: cancel_email: - customer_greeting: "مرحبًا %{name}!" - instructions: "تم إلغاء طلبك. يرجى الاحتفاظ بمعلومات الإلغاء هذه بسجلاتك." - order_summary_canceled: "ملخص الطلب [ملغى]" subject: "إلغاء الطلب" confirm_email: subject: "تأكيد الطلب" diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 30ff63509a..fe72aeeb3a 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -368,8 +368,10 @@ ca: title: "Configuració de Matomo" matomo_url: "URL de Matomo" matomo_site_id: "Identificador de Matomo" - info_html: "Matomo és un analitzador de webs i mòbils. Podeu allotjar Matomo de manera local o utilitzar un servei al núvol. Vegeu matomo.org per obtenir més informació." + matomo_tag_manager_url: "URL de Matomo Tag Manager" + info_html: "Matomo és una aplicació d'analytics web i mòbil. Podeu allotjar Matomo en local o bé utilitzar un servei allotjat al núvol. Consulteu matomo.org per obtenir més informació." config_instructions_html: "Aquí podeu configurar la integració Matomo OFN. L'URL de Matomo que us apareix a continuació ha d'indicar la instància de Matomo en la qual s'enviarà la informació de seguiment de l'usuari; si es deixa buit, el seguiment de l'usuari de Matomo estarà desactivat. El camp d'identificació del lloc no és obligatori, però és útil si fa un seguiment de més d'un lloc web en una sola instància de Matomo; es pot trobar a la consola d'instància de Matomo." + config_instructions_tag_manager_html: "En configurar l'URL de Matomo Tag Manager s'activa Matomo Tag Manager. Aquesta eina us permet configurar esdeveniments d’analítica. L’URL de Matomo Tag Manager es copia de la secció Instal·lar codi de Matomo Tag Manager. Assegureu-vos de seleccionar el contenidor i l’entorn adequats ja que aquestes opcions canvien l’URL." customers: index: new_customer: "Nova consumidora" @@ -403,6 +405,7 @@ ca: footer_and_external_links: Peu de pàgina i enllaços externs your_content: El vostre contingut user_guide: Guia de l'usuari + map: Mapa enterprise_fees: index: title: "Comissions de l'organització" @@ -687,6 +690,7 @@ ca: ofn_uid_tip: L'identificador únic que s’utilitza per identificar l'organització a Open Food Network. shipping_methods: name: "Nom" + applies: "Actiu?" manage: "Gestiona els mètodes d'enviament" create_button: "Crea un nou mètode d'enviament" create_one_button: "Crea'n un ara" @@ -2811,6 +2815,14 @@ ca: new_payment: "Nou pagament" capture: "Captura" void: "Buit" + login: "Inicia sessió" + password: "Contrasenya" + signature: "Signatura" + solution: "Solució" + landing_page: "Pàgina d'inici" + server: "Servidor" + test_mode: "Mode de prova" + logourl: "URL del logo" configurations: "Configuracions" general_settings: "Configuració general" site_name: "Nom del lloc" @@ -2875,8 +2887,6 @@ ca: abbreviation: "Abreviatura" new_state: "Nou estat" payment_methods: "Mètodes de Pagament" - new_payment_method: "Nou mètode de pagament" - provider: "Proveïdor" taxonomies: "Taxonomies" new_taxonomy: "Nova taxonomia" back_to_taxonomies_list: "Torna a la llista de taxonomies" @@ -2929,6 +2939,12 @@ ca: options: "Opcions" actions: update: "Actualitzar" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "Un error va prohibir guardar aquest registre:" + other: "%{count} errors han impedit guardar aquest registre:" + there_were_problems_with_the_following_fields: "Hi ha hagut problemes amb els camps següents" errors: messages: blank: "no es pot deixar en blanc" @@ -3071,6 +3087,8 @@ ca: zone: "Zona" calculator: "Calculadora" display: "Mostra" + both: "Ambdues, validació de comanda i administració" + back_end: "Només pàgina administració (back office) " no_shipping_methods_found: "No s’han trobat mètodes d’enviament" new: new_shipping_method: "Nou mètode d'enviament" @@ -3083,11 +3101,29 @@ ca: categories: "Categories" zones: "Zones" both: "Comandes com administració" + back_end: "Només pàgina administració (back office) " + deactivation_warning: "Desactivar un mètode d'enviament pot fer que desaparegui de la teva llista. Pots ocultar-lo de la pàgina de validació de comanda configurant l'opció \"Mostrar\" a \"només a la pàgina d'administració\" (back end)." payment_methods: + index: + payment_methods: "Mètodes de Pagament" + new_payment_method: "Nou mètode de pagament" + name: "Nom" + products_distributor: "Distribuïdora" + provider: "Proveïdor" + environment: "Ambient" + display: "Mostra" + active: "Actiu" + both: "Ambdós" + front_end: "Visible només per al comprador" + back_end: "Només pàgina administració (back office) " + active_yes: "Sí" + active_no: "No" + no_payment_methods_found: "No s'han trobat mètodes de pagament" new: new_payment_method: "Nou mètode de pagament" back_to_payment_methods_list: "Tornar a la llista de mètodes de pagament" edit: + new: "Nou" editing_payment_method: "Edició del mètode de pagament" back_to_payment_methods_list: "Tornar a la llista de mètodes de pagament" stripe_connect: @@ -3103,6 +3139,21 @@ ca: account_id: Identificador del compte business_name: Nom de l'empresa charges_enabled: Càrrecs habilitats + form: + name: "Nom" + description: "Descripció" + environment: "Ambient" + display: "Mostra" + active: "Actiu" + active_yes: "Sí" + active_no: "No" + both: "Ambdues, validació de comanda i administració" + front_end: "Visible només per al comprador" + back_end: "Només pàgina administració (back office) " + tags: "Etiquetes" + deactivation_warning: "Desactivar un mètode de pagament pot fer que el mètode de pagament desapareixi de la vostra llista. De forma alternativa, podeu amagar un mètode de pagament a la pàgina de compra configurant l'opció \"Mostrar\" a \"només a la pàgina d'administració\" (back end)." + providers: + provider: "Proveïdor" payments: source_forms: stripe: @@ -3205,6 +3256,7 @@ ca: display_as_placeholder: 'per exemple. 2 kg' display_name_placeholder: 'per exemple. Tomàquets' autocomplete: + out_of_stock: "Fora d'existència" producer_name: "Productor" unit: "Unitat" shared: @@ -3242,6 +3294,7 @@ ca: format: '%d-% m-% Y' js_format: 'dd-mm-yy' orders: + error_flash_for_unavailable_items: "Un ítem del teu carret ja no està disponible. Sis plau actualitza les quantitats seleccionades." edit: login_to_view_order: "Si us plau inicia sessió per veure la teva comanda." bought: @@ -3269,9 +3322,14 @@ ca: invalid: invàlid order_mailer: cancel_email: - customer_greeting: "Hola %{name}!" - instructions: "La teva comanda ha estat anul·lada. Conserva aquesta informació de cancel·lació per als teus registres." - order_summary_canceled: "Resum de comanda [CANCEL·LADA]" + customer_greeting: "Benvolgut/da,%{name}" + instructions_html: "La teva comanda %{distributor} ha estat CANCEL·LADA" + dont_cancel: "Si heu canviat d'opinió o no voleu cancel·lar aquesta comanda, poseu-vos en contacte amb %{email}" + order_summary_canceled_html: "Resum de comanda # %{number} [CANCELAT]" + details: "Aquí teniu els detalls del que vau demanar:" + unpaid_order: "La vostra comanda no s'havia pagat, per la qual cosa no s'ha realitzat cap reemborsament" + paid_order: "La vostra comanda s'havia pagat per la qual cosa %{distributor} ha reemborsat l'import complet" + credit_order: "La vostra comanda s'havia pagat i per tant, s'ha abonat l'import al vostre compte" subject: "Cancel·lació de la comanda" confirm_email: subject: "Confirmació de la comanda" diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml index 5ddcdc89a3..f15957eb07 100644 --- a/config/locales/de_DE.yml +++ b/config/locales/de_DE.yml @@ -367,7 +367,6 @@ de_DE: title: "Matomo-Einstellungen" matomo_url: "Matomo-URL" matomo_site_id: "Matomo-Site-ID" - info_html: "Matomo ist eine Web- und Mobile Analytics. Sie können Matomo entweder lokal hosten oder einen von der Cloud gehosteten Dienst verwenden. Weitere Informationen finden Sie unter matomo.org ." config_instructions_html: "Hier können Sie die OFN Matomo Integration konfigurieren. Die unten angegebene Matomo-URL sollte auf die Matomo-Instanz verweisen, an die die Benutzerverfolgungsinformationen gesendet werden. Wenn es leer bleibt, wird das Matomo-Benutzer-Tracking deaktiviert. Das Feld Site-ID ist nicht obligatorisch, aber nützlich, wenn Sie mehr als eine Website in einer einzelnen Matomo-Instanz verfolgen. Es kann auf der Matomo-Instanzkonsole gefunden werden." customers: index: @@ -402,6 +401,7 @@ de_DE: footer_and_external_links: Fußzeile und externe Links your_content: Ihr Inhalt user_guide: Benutzerhandbuch + map: Karte enterprise_fees: index: title: "Unternehmensgebühren" @@ -2785,6 +2785,8 @@ de_DE: new_payment: "Neue Zahlung" capture: "Erfassung" void: "Leere" + login: "Anmeldung" + password: "Passwort" configurations: "Konfigurationen" general_settings: "Allgemeine Einstellungen" site_name: "Site-Name" @@ -2849,8 +2851,6 @@ de_DE: abbreviation: "Abkürzung" new_state: "Neuer Staat" payment_methods: "Zahlungsarten" - new_payment_method: "Neue Zahlungsart" - provider: "Anbieter" taxonomies: "Taxonomien" new_taxonomy: "Neue Taxonomie" back_to_taxonomies_list: "Zurück zur Taxonomieliste" @@ -3057,6 +3057,13 @@ de_DE: categories: "Kategorien" zones: "Zonen" payment_methods: + index: + payment_methods: "Zahlungsarten" + name: "Name" + products_distributor: "Verteiler" + both: "Beide" + active_yes: "Ja" + active_no: "Nein" new: new_payment_method: "Neue Zahlungsart" back_to_payment_methods_list: "Zurück zur Liste der Zahlungsmethoden" @@ -3076,6 +3083,12 @@ de_DE: account_id: Konto-ID business_name: Geschäftsname charges_enabled: Gebühren aktiviert + form: + name: "Name" + description: "Beschreibung" + active_yes: "Ja" + active_no: "Nein" + tags: "Stichwörter" payments: source_forms: stripe: @@ -3236,9 +3249,6 @@ de_DE: invalid: ungültig order_mailer: cancel_email: - customer_greeting: "Hallo %{name}!" - instructions: "Ihre Bestellung wurde storniert. Bitte bewahren Sie diese Stornierungsinformationen für Ihre Unterlagen auf." - order_summary_canceled: "Bestellübersicht [STORNIERT]" subject: "Stornierung der Bestellung" confirm_email: subject: "Bestellbestätigung" diff --git a/config/locales/en.yml b/config/locales/en.yml index 1aee3bfa2c..0c23d12125 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -44,6 +44,8 @@ en: base: "Credit Card" order_cycle: orders_close_at: Close date + variant_override: + count_on_hand: "On Hand" errors: models: spree/user: @@ -415,8 +417,10 @@ en: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." + matomo_tag_manager_url: "Matomo Tag Manager URL" + info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." + config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL." customers: index: @@ -452,6 +456,7 @@ en: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: @@ -2879,6 +2884,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using customer_details: "Customer Details" adjustments: "Adjustments" payments: "Payments" + return_authorizations: "Return Authorizations" payment: "Payment" payment_method: "Payment Method" @@ -2952,6 +2958,14 @@ See the %{link} to find out more about %{sitename}'s features and to start using new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" + signature: "Signature" + solution: "Solution" + landing_page: "Landing Page" + server: "Server" + test_mode: "Test Mode" + logourl: "Logourl" configurations: "Configurations" general_settings: "General Settings" @@ -3025,8 +3039,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" @@ -3089,6 +3101,12 @@ See the %{link} to find out more about %{sitename}'s features and to start using actions: update: "Update" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 error prohibited this record from being saved:" + other: "%{count} errors prohibited this record from being saved:" + there_were_problems_with_the_following_fields: "There were problems with the following fields" errors: messages: blank: "can't be blank" @@ -3248,10 +3266,26 @@ See the %{link} to find out more about %{sitename}'s features and to start using back_end: "Back office only" deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + front_end: "Checkout only" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" + no_payment_methods_found: "No payment methods found" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3267,6 +3301,21 @@ See the %{link} to find out more about %{sitename}'s features and to start using account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + front_end: "Checkout only" + back_end: "Back office only" + tags: "Tags" + deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'." + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3369,6 +3418,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3434,9 +3484,14 @@ See the %{link} to find out more about %{sitename}'s features and to start using invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" + customer_greeting: "Dear %{name}," + instructions_html: "Your order with %{distributor} has been CANCELED. Please retain this cancellation information for your records." + dont_cancel: "If you have changed your mind or don't wish to cancel this order please contact %{email}" + order_summary_canceled_html: "Order Summary #%{number} [CANCELED]" + details: "Here are the details of what you ordered:" + unpaid_order: "Your order was unpaid so no refund has been made" + paid_order: "Your order was paid so %{distributor} has refunded the full amount" + credit_order: "Your order was paid so your account has been credited" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml index fb801884fe..85e74324b9 100644 --- a/config/locales/en_AU.yml +++ b/config/locales/en_AU.yml @@ -359,7 +359,6 @@ en_AU: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -394,6 +393,7 @@ en_AU: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2703,6 +2703,8 @@ en_AU: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2767,8 +2769,6 @@ en_AU: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2970,10 +2970,23 @@ en_AU: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -2989,6 +3002,17 @@ en_AU: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3089,6 +3113,7 @@ en_AU: display_as: "Display As" display_name: "Display Name" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3153,9 +3178,6 @@ en_AU: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml index 963ef29366..ccefbc27d6 100644 --- a/config/locales/en_BE.yml +++ b/config/locales/en_BE.yml @@ -354,7 +354,6 @@ en_BE: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -389,6 +388,7 @@ en_BE: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2658,6 +2658,8 @@ en_BE: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2722,8 +2724,6 @@ en_BE: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2888,10 +2888,23 @@ en_BE: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -2907,6 +2920,17 @@ en_BE: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -2996,6 +3020,7 @@ en_BE: price: "Price" display_as: "Display As" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3060,9 +3085,6 @@ en_BE: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi%{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index 07db8c348f..8eb65e9a43 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -31,6 +31,10 @@ en_CA: taken: "There's already an account for this email. Please login or reset your password." spree/order: no_card: There are no authorised credit cards available to charge + spree/credit_card: + attributes: + base: + card_expired: "has expired" order_cycle: attributes: orders_close_at: @@ -319,6 +323,7 @@ en_CA: show_n_more: Show %{num} more choose: "Choose..." please_select: Please select... + column_save_as_default: Save as Default columns: Columns actions: Actions viewing: "Viewing: %{current_view_name}" @@ -363,7 +368,6 @@ en_CA: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -398,6 +402,7 @@ en_CA: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -659,8 +664,8 @@ en_CA: name: Name name_placeholder: eg. Professor Plum's Biodynamic Truffles groups: Groups - groups_tip: Select any groups or regions that you are a member of. This will help customers find your enterprise. - groups_placeholder: Start typing to search available groups... + groups_tip: Select any markets or groups that you are a member of. This will help customers find your enterprise. + groups_placeholder: Start typing to search available markets or groups... primary_producer: Primary Producer? primary_producer_tip: Select 'Producer' if you are a primary producer, grower, maker or designer producer: Producer @@ -681,6 +686,7 @@ en_CA: ofn_uid_tip: The unique id used to identify the enterprise on Open Food Network shipping_methods: name: "Name" + applies: "Active?" manage: "Manage Shipping/Pick-Up Methods" create_button: "Create New Shipping Method" create_one_button: "Create One Now" @@ -859,6 +865,7 @@ en_CA: incoming: "Incoming" supplier: "Supplier" products: "Products" + receival_details: "Receival Details" fees: "Fees" save: "Save" save_and_next: "Save and Next" @@ -870,6 +877,7 @@ en_CA: distributor: "Distributor" products: "Products" tags: "Tags" + delivery_details: "Delivery Details" fees: "Fees" previous: "Previous" save: "Save" @@ -1167,7 +1175,11 @@ en_CA: signup: "signup" contact: "contact" require_customer_login: "Only approved customers can access this shop" + require_login_html: "If you're already an approved customer, %{login} or %{signup} 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: + select_oc_html: "Please 1choose when you want your order1, to see what products are available." card_could_not_be_updated: Card could not be updated card_could_not_be_saved: card could not be saved spree_gateway_error_flash_for_checkout: "There was a problem with your payment information: %{error}" @@ -1201,7 +1213,7 @@ en_CA: menu_2_url: "/map" menu_3_title: "Producers" menu_3_url: "/producers" - menu_4_title: "Groups" + menu_4_title: "Markets" menu_4_url: "/groups" menu_5_title: "About" menu_5_url: "https://about.openfoodnetwork.ca" @@ -1257,7 +1269,7 @@ en_CA: label_map: "Map" label_producer: "Producer" label_producers: "Producers" - label_groups: "Groups" + label_groups: "Markets" label_about: "About" label_connect: "Connect" label_learn: "Learn" @@ -1348,7 +1360,7 @@ en_CA: brandstory_part6: "We all love food. Now we can love our food system too." learn_body: "Explore models, stories and resources to support you to develop your local business or organisation. Find training, events and other opportunities to learn from peers." learn_cta: "Get Inspired" - connect_body: "Search our full directories of producers, hubs and groups to find fair and sustainably produced products near you. List your business or organisation on the OFN so buyers can find you. Join the community to get advice and solve problems together." + connect_body: "Search our full directories of producers, hubs and markets to find fair and sustainably produced products near you. List your business or organisation on the OFN so buyers can find you. Join the community to get advice and solve problems together." connect_cta: "Go Exploring" system_headline: "Shopping - here's how it works." system_step1: "1. Search" @@ -1527,12 +1539,17 @@ en_CA: orders_changeable_orders_alert_html: This order has been confirmed, but you can make changes until %{oc_close}. products_clear: Clear products_showing: "Showing:" + products_results_for: "Results for" products_or: "or" products_and: "and" + products_filters_in: "in" products_with: with + products_search: "Search" products_filter_by: "Filter by" products_filter_selected: "selected" + products_filter_heading: "Filters" products_filter_clear: "Clear" + products_filter_done: "Done" products_loading: "Loading products..." products_updating_cart: "Updating cart..." products_cart_empty: "Cart empty" @@ -1543,18 +1560,20 @@ en_CA: products_update_error_msg: "Saving failed." products_update_error_data: "Save failed due to invalid data:" products_changes_saved: "Changes saved." + products_no_results_html: "Sorry, no results found for %{query}" + products_clear_search: "Clear search" search_no_results_html: "Sorry, no results found for %{query}. Try another search?" components_profiles_popover: "Profiles do not have a shopfront on the Open Food Network, but may have their own physical or online shop elsewhere" components_profiles_show: "Show profiles" components_filters_nofilters: "No filters" 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_title: Markets + groups_headline: 'Markets / Regions ' + groups_text: "Markets 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_search: "Search name or keyword" groups_no_groups: "No groups found" groups_about: "About Us" - groups_producers: "Our producers" + groups_producers: "Our vendors" groups_hubs: "Our hubs" groups_contact_web: Contact groups_contact_social: Follow @@ -1898,6 +1917,7 @@ en_CA: admin_enterprise_relationships_permits: "permits" admin_enterprise_relationships_seach_placeholder: "Search" admin_enterprise_relationships_button_create: "Create" + admin_enterprise_relationships_to: "to" admin_enterprise_groups: "Enterprise Groups" admin_enterprise_groups_name: "Name" admin_enterprise_groups_owner: "Owner" @@ -2303,6 +2323,10 @@ en_CA: resolve_errors: Please resolve the following errors more_items: "+ %{count} More" default_card_updated: Default Card Updated + cart: + add_to_cart_failed: > + There was a problem adding this product to the cart. Perhaps it has become + unavailable or the shop is closing admin: enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it." modals: @@ -2781,6 +2805,8 @@ en_CA: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2845,8 +2871,6 @@ en_CA: abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3041,6 +3065,8 @@ en_CA: zone: "Zone" calculator: "Calculator" display: "Display" + both: "Both Checkout and Back office" + back_end: "Back office only" no_shipping_methods_found: "No shipping methods found" new: new_shipping_method: "New Shipping Method" @@ -3052,11 +3078,28 @@ en_CA: form: categories: "Categories" zones: "Zones" + both: "Both Checkout and Back office" + back_end: "Back office only" + deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3072,6 +3115,19 @@ en_CA: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + back_end: "Back office only" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3171,7 +3227,10 @@ en_CA: price: "Price" display_as: "Display As" display_name: "Display Name" + display_as_placeholder: 'eg. 2 kg' + display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3209,6 +3268,7 @@ en_CA: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "An item in your cart has become unavailable. Please update the selected quantities." edit: login_to_view_order: "Please log in to view your order." bought: @@ -3236,9 +3296,14 @@ en_CA: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" + customer_greeting: "Dear %{name}," + instructions_html: "Your order with 1%{distributor}1 has been CANCELED. Please retain this cancellation information for your records." + dont_cancel: "If you have changed your mind or don't wish to cancel this order please contact %{email} " + order_summary_canceled_html: "Order Summary #%{number} [CANCELED]" + details: "Here are the details of what you ordered:" + unpaid_order: "Your order was unpaid so no refund has been made" + paid_order: "Your order was paid so %{distributor} has refunded the full amount" + credit_order: "Your order was paid so your account has been credited" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index a847a5bf98..43f8f6dd44 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -359,7 +359,6 @@ en_DE: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -394,6 +393,7 @@ en_DE: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2670,6 +2670,8 @@ en_DE: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2734,8 +2736,6 @@ en_DE: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2904,10 +2904,23 @@ en_DE: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -2923,6 +2936,17 @@ en_DE: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3012,6 +3036,7 @@ en_DE: price: "Price" display_as: "Display As" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3076,9 +3101,6 @@ en_DE: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 20356fecae..352eedea77 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -368,8 +368,10 @@ en_FR: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." + matomo_tag_manager_url: "Matomo Tag Manager URL" + info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.orgfor more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." + config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL." customers: index: new_customer: "New Customer" @@ -403,6 +405,7 @@ en_FR: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -686,6 +689,7 @@ en_FR: ofn_uid_tip: The unique id used to identify the enterprise on Open Food Network. shipping_methods: name: "Name" + applies: "Active?" manage: "Manage Shipping Methods" create_button: "Create New Shipping Method" create_one_button: "Create One Now" @@ -2805,6 +2809,14 @@ en_FR: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" + signature: "Signature" + solution: "Solution" + landing_page: "Landing Page" + server: "Server" + test_mode: "Test Mode" + logourl: "Logourl" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2869,8 +2881,6 @@ en_FR: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2923,6 +2933,12 @@ en_FR: options: "Options" actions: update: "Update" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 error prohibited this record from being saved:" + other: "%{count} errors prohibited this record from being saved:" + there_were_problems_with_the_following_fields: "There were problems with the following fields" errors: messages: blank: "can't be blank" @@ -3080,11 +3096,28 @@ en_FR: zones: "Zones" both: "Both Checkout and Back office" back_end: "Back office only" + deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + front_end: "Checkout only" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" + no_payment_methods_found: "No payment methods found" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3100,6 +3133,21 @@ en_FR: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + front_end: "Checkout only" + back_end: "Back office only" + tags: "Tags" + deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'." + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3202,6 +3250,7 @@ en_FR: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3239,6 +3288,7 @@ en_FR: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "An item in your cart has become unavailable. Please update the selected quantities." edit: login_to_view_order: "Please log in to view your order." bought: @@ -3266,9 +3316,14 @@ en_FR: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" + customer_greeting: "Dear %{name}," + instructions_html: "Your order with%{distributor} has been CANCELED. Please retain this cancellation information for your records" + dont_cancel: "If you have changed your mind or don't wish to cancel this order please contact %{email}" + order_summary_canceled_html: "Order Summary #%{number}[CANCELED]" + details: "Here are the details of what you ordered:" + unpaid_order: "Your order was unpaid so no refund has been made" + paid_order: "Your order was paid so %{distributor} has refunded the full amount" + credit_order: "Your order was paid so your account has been credited" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index a2853f61a7..71358c855d 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -368,7 +368,6 @@ en_GB: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -403,6 +402,7 @@ en_GB: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -686,6 +686,7 @@ en_GB: ofn_uid_tip: The unique id used to identify the enterprise on Open Food Network. shipping_methods: name: "Name" + applies: "Active?" manage: "Manage Shipping Methods" create_button: "Create New Shipping Method" create_one_button: "Create One Now" @@ -2811,6 +2812,8 @@ en_GB: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2875,8 +2878,6 @@ en_GB: abbreviation: "Abbreviation" new_state: "New County" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3071,6 +3072,8 @@ en_GB: zone: "Zone" calculator: "Calculator" display: "Display" + both: "Both Checkout and Back office" + back_end: "Back office only" no_shipping_methods_found: "No shipping methods found" new: new_shipping_method: "New Shipping Method" @@ -3082,11 +3085,28 @@ en_GB: form: categories: "Categories" zones: "Zones" + both: "Both Checkout and Back office" + back_end: "Back office only" + deactivation_warning: "De-activating a shipping method can make the shipping method disappear from your list. Alternatively, you can hide a shipping method from the checkout page by setting the option 'Display' to 'back office only'." payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3102,6 +3122,19 @@ en_GB: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + back_end: "Back office only" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3204,6 +3237,7 @@ en_GB: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3241,6 +3275,7 @@ en_GB: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "An item in your basket has become unavailable. Please update the selected quantities." edit: login_to_view_order: "Please log in to view your order." bought: @@ -3268,9 +3303,6 @@ en_GB: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_IE.yml b/config/locales/en_IE.yml index 6970317b5b..69bcb54e04 100644 --- a/config/locales/en_IE.yml +++ b/config/locales/en_IE.yml @@ -368,7 +368,6 @@ en_IE: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -403,6 +402,7 @@ en_IE: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2811,6 +2811,8 @@ en_IE: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2875,8 +2877,6 @@ en_IE: abbreviation: "Abbreviation" new_state: "New County" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3083,10 +3083,23 @@ en_IE: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3102,6 +3115,17 @@ en_IE: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3204,6 +3228,7 @@ en_IE: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3268,9 +3293,6 @@ en_IE: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index edd74cbdb3..fa30c62f25 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -368,7 +368,6 @@ en_NZ: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -403,6 +402,7 @@ en_NZ: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2805,6 +2805,8 @@ en_NZ: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2869,8 +2871,6 @@ en_NZ: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3081,10 +3081,24 @@ en_NZ: both: "Both Checkout and Back office" back_end: "Back office only" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + back_end: "Back office only" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3100,6 +3114,19 @@ en_NZ: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + both: "Both Checkout and Back office" + back_end: "Back office only" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3202,6 +3229,7 @@ en_NZ: display_as_placeholder: 'eg. 2 kg' display_name_placeholder: 'eg. Tomatoes' autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3266,9 +3294,6 @@ en_NZ: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml index 884b680f84..da4c883de1 100644 --- a/config/locales/en_PH.yml +++ b/config/locales/en_PH.yml @@ -367,7 +367,6 @@ en_PH: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -402,6 +401,7 @@ en_PH: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2787,6 +2787,8 @@ en_PH: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2851,8 +2853,6 @@ en_PH: abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Category" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3059,10 +3059,23 @@ en_PH: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3078,6 +3091,17 @@ en_PH: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3178,6 +3202,7 @@ en_PH: display_as: "Display As" display_name: "Display Name" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3242,9 +3267,6 @@ en_PH: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index e3c8f3950d..feb491c764 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -363,7 +363,6 @@ en_US: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo locally or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -398,6 +397,7 @@ en_US: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2780,6 +2780,8 @@ en_US: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2844,8 +2846,6 @@ en_US: abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -3052,10 +3052,23 @@ en_US: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -3071,6 +3084,17 @@ en_US: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3170,6 +3194,7 @@ en_US: display_as: "Display As" display_name: "Display Name" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3234,9 +3259,6 @@ en_US: invalid: Invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 225939fb6f..8017668827 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -368,7 +368,6 @@ en_ZA: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." customers: index: @@ -403,6 +402,7 @@ en_ZA: footer_and_external_links: Footer and External Links your_content: Your content user_guide: User Guide + map: Map enterprise_fees: index: title: "Enterprise Fees" @@ -2732,6 +2732,8 @@ en_ZA: new_payment: "New Payment" capture: "Capture" void: "Void" + login: "Login" + password: "Password" configurations: "Configurations" general_settings: "General Settings" site_name: "Site Name" @@ -2796,8 +2798,6 @@ en_ZA: abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - new_payment_method: "New Payment Method" - provider: "Provider" taxonomies: "Taxonomies" new_taxonomy: "New Taxonomy" back_to_taxonomies_list: "Back to Taxonomies List" @@ -2963,10 +2963,23 @@ en_ZA: categories: "Categories" zones: "Zones" payment_methods: + index: + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + name: "Name" + products_distributor: "Distributor" + provider: "Provider" + environment: "Environment" + display: "Display" + active: "Active" + both: "Both" + active_yes: "Yes" + active_no: "No" new: new_payment_method: "New Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" edit: + new: "New" editing_payment_method: "Editing Payment Method" back_to_payment_methods_list: "Back To Payment Methods List" stripe_connect: @@ -2982,6 +2995,17 @@ en_ZA: account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled + form: + name: "Name" + description: "Description" + environment: "Environment" + display: "Display" + active: "Active" + active_yes: "Yes" + active_no: "No" + tags: "Tags" + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3072,6 +3096,7 @@ en_ZA: price: "Price" display_as: "Display As" autocomplete: + out_of_stock: "Out of Stock" producer_name: "Producer" unit: "Unit" shared: @@ -3136,9 +3161,6 @@ en_ZA: invalid: invalid order_mailer: cancel_email: - customer_greeting: "Hi %{name}!" - instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." - order_summary_canceled: "Order Summary [CANCELED]" subject: "Cancellation of Order" confirm_email: subject: "Order Confirmation" diff --git a/config/locales/es.yml b/config/locales/es.yml index b04da91a62..f4ea131b1e 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -323,6 +323,7 @@ es: show_n_more: Mostrar %{num} más choose: "Escoger..." please_select: Por favor selecciona ... + column_save_as_default: Guardar por defecto columns: Columnas actions: Acciones viewing: "Viendo: %{current_view_name}" @@ -367,8 +368,10 @@ es: title: "Configuración de Matomo" matomo_url: "URL de Matomo" matomo_site_id: "ID de sitio de Matomo" - info_html: "Matomo es un analizador web y móvil. Puede alojar Matomo en sus servidores o utilizar un servicio alojado en la nube. Consulte matomo.org para obtener más información." + matomo_tag_manager_url: "URL de Matomo Tag Manager" + info_html: "Matomo es una aplicación de análisis web y móvil. Puede alojar Matomo localmente o utilizar un servicio alojado en la nube. Ver matomo.org para más información." config_instructions_html: "Aquí puede configurar la integración de OFN Matomo. La siguiente URL de Matomo debe apuntar a la instancia de Matomo a la que se enviará la información de seguimiento del usuario; si se deja vacío, el seguimiento del usuario Matomo se desactivará. El campo ID del sitio no es obligatorio, pero es útil si está rastreando más de un sitio web en una sola instancia de Matomo; se puede encontrar en la consola de la instancia de Matomo." + config_instructions_tag_manager_html: "La configuración de la URL de Matomo Tag Manager habilita Matomo Tag Manager. Esta herramienta le permite configurar eventos analíticos. La URL de Matomo Tag Manager se copia de la sección Código de instalación de Matomo Tag Manager. Asegúrese de seleccionar el contenedor y el entorno correctos, ya que estas opciones cambian la URL." customers: index: new_customer: "Nuevo Consumidor" @@ -402,6 +405,7 @@ es: footer_and_external_links: Pie de página y enlaces externos your_content: Tu contenido user_guide: Manual de Usuario + map: Mapa enterprise_fees: index: title: "Comisiones de la Organización" @@ -686,6 +690,7 @@ es: ofn_uid_tip: La identificación única utilizada para identificar la organización en Open Food Network. shipping_methods: name: "Nombre" + applies: "¿Activo?" manage: "Gestionar métodos de envío" create_button: "Crear nuevo método de envío" create_one_button: "Crear una ahora" @@ -865,6 +870,7 @@ es: incoming: "Entrante" supplier: "Proveedora" products: "Productos" + receival_details: "Detalles de la recepción" fees: "Comisiones" save: "Guardar" save_and_next: "Salvar y continuar" @@ -1174,7 +1180,11 @@ es: signup: "Regístrate" contact: "contactar" require_customer_login: "Sólo las consumidoras aprobadas pueden acceder a esta tienda." + require_login_html: "Si ya eres un cliente aprovado, %{login} o %{signup} para continuar" + require_login_2_html: "¿Quieres comprar en esta tienda? %{contact}%{enterprise}y solicita tu admisión." require_customer_html: "Si desea comenzar a comprar aquí, por favor %{contact} %{enterprise} para preguntar acerca de incorporación." + select_oc: + select_oc_html: "Por favor debes elegir cuando quieres tu pedido, para poder ver qué productos hay disponibles." card_could_not_be_updated: La tarjeta no se pudo actualizar card_could_not_be_saved: la tarjeta no se pudo guardar spree_gateway_error_flash_for_checkout: "Hubo un problema con tu información de pago: %{error}" @@ -1534,12 +1544,17 @@ es: orders_changeable_orders_alert_html: Este pedido ha sido confirmado, pero puede realizar cambios hasta %{oc_close}. products_clear: Limpiar products_showing: "Mostrando:" + products_results_for: "Resultados para" products_or: "o" products_and: "y" + products_filters_in: "en" products_with: con + products_search: "Buscar…" products_filter_by: "Fitrar por" products_filter_selected: "seleccionado" + products_filter_heading: "Filtros" products_filter_clear: "Limpiar" + products_filter_done: "Hecho" products_loading: "Cargando productos..." products_updating_cart: "Actualizando su carrito..." products_cart_empty: "Carrito vacío" @@ -1550,6 +1565,8 @@ es: products_update_error_msg: "No se ha podido guardar." products_update_error_data: "Error al guardar datos no válidos:" products_changes_saved: "Cambios guardados." + products_no_results_html: "Lo sentimos, no se han encontrado resultados para %{query}" + products_clear_search: "Limpiar la búsqueda" search_no_results_html: "Lo sentimos, no hay resultados para %{query}. ¿Intentar otra búsqueda?" components_profiles_popover: "Los perfiles no tienen una tienda en Open Food Network, pero pueden tener su propia tienda física o en línea en otro lugar" components_profiles_show: "Mostrar perfiles" @@ -1905,6 +1922,7 @@ es: admin_enterprise_relationships_permits: "Permite" admin_enterprise_relationships_seach_placeholder: "Buscar" admin_enterprise_relationships_button_create: "Crear" + admin_enterprise_relationships_to: "para" admin_enterprise_groups: "Redes de organizaciones" admin_enterprise_groups_name: "Nombre" admin_enterprise_groups_owner: "Propietaria" @@ -2310,6 +2328,10 @@ es: resolve_errors: Resuelve los siguientes errores more_items: "+ %{count} Más" default_card_updated: Tarjeta predeterminada actualizada + cart: + add_to_cart_failed: > + Ha habido un problema al añadir este producto en el carrito. Puede que haya + dejado de estar disponible o que la tinda haya cerrado. admin: enterprise_limit_reached: "Has alcanzado el límite estándar de organizaciones por cuenta. Escriba a %{contact_email} si necesita aumentarlo." modals: @@ -2793,6 +2815,14 @@ es: new_payment: "Nuevo pago" capture: "Captura" void: "Vacío" + login: "Iniciar sesión" + password: "Contraseña" + signature: "Firma" + solution: "Solución" + landing_page: "Página de inicio" + server: "Servidor" + test_mode: "Modo de prueba" + logourl: "URL del logo" configurations: "Configuraciones" general_settings: "Configuración general" site_name: "Nombre del sitio" @@ -2857,8 +2887,6 @@ es: abbreviation: "Abreviatura" new_state: "Nuevo estado" payment_methods: "Métodos de Pago" - new_payment_method: "Nuevo método de pago" - provider: "Proveedor" taxonomies: "Taxonomias" new_taxonomy: "Nueva taxonomía" back_to_taxonomies_list: "Volver a la Lista de Taxonomías" @@ -2911,6 +2939,12 @@ es: options: "Opciones" actions: update: "Actualizar" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 error prohibió guardar este registro:" + other: "%{count} errores impidieron que se guardara este registro:" + there_were_problems_with_the_following_fields: "Hubo problemas con los siguientes campos" errors: messages: blank: "no puede estar vacío" @@ -3053,6 +3087,8 @@ es: zone: "Zona" calculator: "Calculadora" display: "Mostrar" + both: "Tanto en Hacer pedido como en Administración" + back_end: "Solo en Administración" no_shipping_methods_found: "No se encontraron métodos de envío" new: new_shipping_method: "Nuevo método de envío" @@ -3064,11 +3100,30 @@ es: form: categories: "Categorías" zones: "Zonas" + both: "Tanto en Hacer pedido como en Administración" + back_end: "Solo en Administración" + deactivation_warning: "Desactivar un método de envío puede hacer que el método de envío desaparezca de tu lista. Como alternativa, puedes ocultar el método de envío de la página \"Hacer pedidos\" configurándolo con la opción \"Solo en Administración\" " payment_methods: + index: + payment_methods: "Métodos de Pago" + new_payment_method: "Nuevo método de pago" + name: "Nombre" + products_distributor: "Distribuidora" + provider: "Proveedor" + environment: "Ambiente" + display: "Mostrar" + active: "Activo" + both: "Ambos" + front_end: "Solo visible para el comprador" + back_end: "Solo en Administración" + active_yes: "Sí" + active_no: "No" + no_payment_methods_found: "No se encontraron métodos de pago." new: new_payment_method: "Nuevo método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" edit: + new: "Nuevo" editing_payment_method: "Edición del método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" stripe_connect: @@ -3084,6 +3139,21 @@ es: account_id: Account ID business_name: Nombre de la Organización charges_enabled: Cargos habilitados + form: + name: "Nombre" + description: "Descripción" + environment: "Ambiente" + display: "Mostrar" + active: "Activo" + active_yes: "Sí" + active_no: "No" + both: "Tanto en Hacer pedido como en Administración" + front_end: "Solo visible para el comprador" + back_end: "Solo en Administración" + tags: "Tags" + deactivation_warning: "La desactivación de un método de pago puede hacer que el método de pago desaparezca de su lista. Alternativamente, puede ocultar un método de pago desde la página de pago configurando la opción 'Mostrar' como 'Solo visible para el administrador'." + providers: + provider: "Proveedor" payments: source_forms: stripe: @@ -3183,7 +3253,10 @@ es: price: "Precio" display_as: "Mostrar como" display_name: "Nombre para mostrar" + display_as_placeholder: 'p. ej. 2 Kg' + display_name_placeholder: 'p. ej. Tomates' autocomplete: + out_of_stock: "Agotado" producer_name: "Productora" unit: "Unidad" shared: @@ -3221,6 +3294,7 @@ es: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "Un artículo de tu carrito ahora no está disponible. Por favor actualiza las cantidades seleccionadas" edit: login_to_view_order: "Por favor inicie sesión para ver su pedido." bought: @@ -3248,9 +3322,14 @@ es: invalid: inválido order_mailer: cancel_email: - customer_greeting: "Hola %{name}!" - instructions: "Su pedido ha sido CANCELADO. Por favor, conserve esta información de cancelación para sus registros." - order_summary_canceled: "Resumen del pedido [CANCELADO]" + customer_greeting: "Hola %{name}" + instructions_html: "Tu pedido con %{distributor} ha sido CANCELADO. Por favor guarda esta información de la cancelación por si es necesaria en el futuro. " + dont_cancel: "Si has cambiado de opinión o no deseas cancelar este pedido, por favor contacta con %{email}" + order_summary_canceled_html: "Resumen del pedido [CANCELADO] %{number} " + details: "Estos son los detalles de su pedido:" + unpaid_order: "Como su pedido no se había pagado, no se ha hecho ninguna devolución." + paid_order: "Su pedido estaba pagado por lo que %{distributor}ha devuelto el importe completo." + credit_order: "Su pedido estaba pagado por lo que se ha abonado en su cuenta." subject: "Cancelación del pedido" confirm_email: subject: "Confirmación del pedido" diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index 660a0744c1..8dce3680ee 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -368,7 +368,6 @@ es_CR: title: "Configuración de Matomo" matomo_url: "URL de Matomo" matomo_site_id: "ID de sitio de Matomo" - info_html: "Matomo es un analizador web y móvil. Puede alojar Matomo en sus servidores o utilizar un servicio alojado en la nube. Consulte matomo.org para obtener más información." config_instructions_html: "Aquí puede configurar la integración de OFN Matomo. La siguiente URL de Matomo debe apuntar a la instancia de Matomo a la que se enviará la información de seguimiento del usuario; si se deja vacío, el seguimiento del usuario Matomo se desactivará. El campo ID del sitio no es obligatorio, pero es útil si está rastreando más de un sitio web en una sola instancia de Matomo; se puede encontrar en la consola de la instancia de Matomo." customers: index: @@ -403,6 +402,7 @@ es_CR: footer_and_external_links: Pie de página y enlaces externos your_content: Tu contenido user_guide: Manual de usuario + map: Mapa enterprise_fees: index: title: "Comisiones de la organización" @@ -2795,6 +2795,8 @@ es_CR: new_payment: "Nuevo pago" capture: "Captura" void: "Vacío" + login: "Iniciar sesión" + password: "Contraseña" configurations: "Configuraciones" general_settings: "Configuración general" site_name: "Nombre del sitio" @@ -2859,8 +2861,6 @@ es_CR: abbreviation: "Abreviatura" new_state: "Nueva provincia" payment_methods: "Métodos de pago" - new_payment_method: "Nuevo método de pago" - provider: "Proveedor" taxonomies: "Taxonomías" new_taxonomy: "Nueva taxonomía" back_to_taxonomies_list: "Volver a la lista de taxonomías" @@ -3067,10 +3067,23 @@ es_CR: categories: "Categorías" zones: "Zonas" payment_methods: + index: + payment_methods: "Métodos de pago" + new_payment_method: "Nuevo método de pago" + name: "Nombre" + products_distributor: "Distribuidor" + provider: "Proveedor" + environment: "Ambiente" + display: "Mostrar" + active: "Activo" + both: "Ambos" + active_yes: "Sí" + active_no: "No" new: new_payment_method: "Nuevo método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" edit: + new: "Nuevo" editing_payment_method: "Edición del método de pago" back_to_payment_methods_list: "Volver a la lista de métodos de pago" stripe_connect: @@ -3086,6 +3099,17 @@ es_CR: account_id: ID de cuenta business_name: Nombre de la organización charges_enabled: Cargos habilitados + form: + name: "Nombre" + description: "Descripción" + environment: "Ambiente" + display: "Mostrar" + active: "Activo" + active_yes: "Sí" + active_no: "No" + tags: "Etiquetas" + providers: + provider: "Proveedor" payments: source_forms: stripe: @@ -3186,6 +3210,7 @@ es_CR: display_as: "Mostrar como" display_name: "Nombre para mostrar" autocomplete: + out_of_stock: "Agotado" producer_name: "Productor" unit: "Unidad" shared: @@ -3250,9 +3275,6 @@ es_CR: invalid: inválido order_mailer: cancel_email: - customer_greeting: "Hola %{name}!" - instructions: "Su pedido ha sido CANCELADO. Por favor, conserve esta información de cancelación para sus registros." - order_summary_canceled: "Resumen del pedido [CANCELADO]" subject: "Cancelación del pedido" confirm_email: subject: "Confirmación del pedido" diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index 25d2da2a32..0c7bf87148 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -368,7 +368,6 @@ fil_PH: title: "Matomo Settings" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "ang Matomo ay isang Web at Mobile Analytics. Maaari kang mag-host ng Matomo sa mga lugar o gumamit ng mga serbisyong naka-cloud. Tignanmatomo.org para sa karagdagang impormasyon." config_instructions_html: "Dito ay maaaring ayusin ang pagsasama ng OFN Matomo. ang URL ng Matomo sa ibaba ay ituturo ka sa Matomo kung saan ipapadala ang impormasyon ukol sa pagtatrack ng gumagamit; kung iiwanang blanko, ay hindi gagana ang pag-track ng Matomo. ang paglagay ng SITE ID ay hindi sapilitan ngunit maaaring makatulong kung ikaw ay nagta-track na mahigit sa isang website sa isang pagkakataon; ito ay matatagpuan sa Matomo instance console." customers: index: @@ -403,6 +402,7 @@ fil_PH: footer_and_external_links: Footer at panlabas na mga link your_content: ang iyong nilalaman user_guide: gabay sa gumagamit + map: Mapa enterprise_fees: index: title: "fees para sa Enterprise" @@ -1908,18 +1908,18 @@ fil_PH: admin_enterprise_relationships_button_create: "gumawa" admin_enterprise_relationships_to: "sa" admin_enterprise_groups: "mga grupo ng enterprise" - admin_enterprise_groups_name: "pangalan" + admin_enterprise_groups_name: "Pangalan" admin_enterprise_groups_owner: "may-ari" admin_enterprise_groups_on_front_page: "sa harapang pahina?" - admin_enterprise_groups_enterprise: "enterprises" + admin_enterprise_groups_enterprise: "Mga Enterprise" admin_enterprise_groups_data_powertip: "ang pangunahing gumagamit na responsable sa grupo na ito" - admin_enterprise_groups_data_powertip_logo: "ito ang logo ng inyong grupo" + admin_enterprise_groups_data_powertip_logo: "ito ang logo para sa grupo" admin_enterprise_groups_data_powertip_promo_image: "ang larawan na ito ay makikita sa taas ng profile ng grupo" admin_enterprise_groups_contact: "Makipag-ugnayan" admin_enterprise_groups_contact_phone_placeholder: "hal. 98 7654 3210" - admin_enterprise_groups_contact_address1_placeholder: "eg. 123 High Street" + admin_enterprise_groups_contact_address1_placeholder: "eg. 123 Kalayaan Street" admin_enterprise_groups_contact_city: "lungsod" - admin_enterprise_groups_contact_city_placeholder: "hal. Northcote" + admin_enterprise_groups_contact_city_placeholder: "hal. Mandaluyong" admin_enterprise_groups_contact_zipcode: "Postcode" admin_enterprise_groups_contact_zipcode_placeholder: "hal. 3070" admin_enterprise_groups_contact_state_id: "Lalawigan" @@ -1982,14 +1982,14 @@ fil_PH: spree_admin_overview_enterprises_header: "ang aking mga enterprise" spree_admin_overview_enterprises_footer: "PAMAHALAAN ANG AKING MGA ENTERPRISE" spree_admin_enterprises_hubs_name: "pangalan" - spree_admin_enterprises_create_new: "GUMAWA NG BAGO" + spree_admin_enterprises_create_new: "LUMIKHA NG BAGO" spree_admin_enterprises_shipping_methods: "mga paraan ng pagpapadala" spree_admin_enterprises_fees: "bayad para sa enterprise" - spree_admin_enterprises_none_create_a_new_enterprise: "GUMAWA NG BAGONG ENTERPRISE" + spree_admin_enterprises_none_create_a_new_enterprise: "LUMIKHA NG BAGONG ENTERPRISE" spree_admin_enterprises_none_text: "wala ka pang mga enterprise" spree_admin_enterprises_tabs_hubs: "MGA HUB" spree_admin_enterprises_producers_manage_products: "PAMAHALAAN ANG MGA PRODUKTO" - spree_admin_enterprises_create_new_product: "GUMAWA NG BAGONG PRODUKTO" + spree_admin_enterprises_create_new_product: "LUMIKHA NG BAGONG PRODUKTO" spree_admin_single_enterprise_alert_mail_confirmation: "kumpirmahin ang email address para sa/kay" spree_admin_single_enterprise_alert_mail_sent: "naipadala na ang email sa" spree_admin_overview_action_required: "kailangan ng aksyon" @@ -2004,8 +2004,8 @@ fil_PH: unit_name: "pangalan ng yunit" change_package: "palitan ang package" spree_admin_single_enterprise_hint: "payo: para mahanap ka ng mga tao, i-turn on ang visibility sa ilalim ng" - spree_admin_eg_pickup_from_school: "hal. 'Pick-up from Primary School'" - spree_admin_eg_collect_your_order: "hal. 'Please collect your order from 123 Imaginary St, Northcote, 3070'" + spree_admin_eg_pickup_from_school: "hal. 'Pick-up mula sa Primary School'" + spree_admin_eg_collect_your_order: "hal. 'Kolektahin ang inyong order sa 123 Kapayapaan St., Tobias Fornier, Antique 5716'" spree_classification_primary_taxon_error: "ang Tax sa%{taxon}ay ang pangunahing tax ng %{product}at hindi maaaring tanggalin" spree_order_availability_error: "ang distributor o order cycle ay hindi kayang ibigay ang mga produkto sa inyong cart" spree_order_populator_error: "ang distributor o order cycle na ito ay hindi kayang ibigay lahat ng mga produkto sa inyong cart. pumili ng iba." @@ -2023,10 +2023,10 @@ fil_PH: add_and_manage_order_cycles: "magdagdag at pamahalaan ang mga order cycle" manage_order_cycles: "pamahalaan ang mga order cycle" manage_products: "pamahalaan ang mga produkto" - edit_profile_details: "ayusin ang mga detalye ng profile" - edit_profile_details_etc: "palitan ang paglalarawan, larawan at iba pa ng iyong profile" + edit_profile_details: "i-edit ang mga detalye ng profile" + edit_profile_details_etc: "palitan ang paglalarawan ng profile, larawan at iba pa" order_cycle: "order cycle" - order_cycles: "order cycles" + order_cycles: "mga order cycle" enterprise_relationships: "mga permiso ng enterprise" remove_tax: "alisin ang tax" first_name_begins_with: "ang pangalan ay nagsisimula sa" @@ -2037,20 +2037,20 @@ fil_PH: enterprise_tos_agree: "ako ay sumasang-ayon sa palatuntunan ng serbisyo na nasa itaas." tax_settings: "settings ng tax" products_require_tax_category: "ang mga produkto ay kailangang may kategorya ng tax" - admin_shared_address_1: "tirahan" + admin_shared_address_1: "address" admin_shared_address_2: "address (pagpapatuloy)" admin_share_city: "Lungsod" admin_share_zipcode: "Postcode" admin_share_country: "Bansa" admin_share_state: "Status" - hub_sidebar_hubs: "Hubs" + hub_sidebar_hubs: "Mga Hub" hub_sidebar_none_available: "walang available" hub_sidebar_manage: "pamahalaan" hub_sidebar_at_least: "pumili ng kahit isa sa mga Hub" hub_sidebar_blue: "bughaw" hub_sidebar_red: "pula" report_customers_distributor: "Distributor" - report_customers_supplier: "Suuplier" + report_customers_supplier: "Supplier" report_customers_cycle: "order cycle" report_customers_type: "uri ng ulat" report_customers_csv: "i-download bilang csv" @@ -2077,7 +2077,7 @@ fil_PH: report_header_last_name: Apelyido report_header_phone: telepono report_header_suburb: lungsod - report_header_address: tirahan + report_header_address: address report_header_billing_address: Billing Address report_header_relationship: relasyon report_header_hub: Hub @@ -2185,7 +2185,7 @@ fil_PH: report_header_total_cost: "Kabuuang Gastos" report_header_total_ordered: Kabuuang na-order report_header_total_max: kabuuang pinakamataas na limit - report_header_total_units: kabuuang yunit + report_header_total_units: kabuuang mga yunit report_header_sum_max_total: "kabuuan" report_header_total_excl_vat: "Kabuuang tax na hindi kasama (%{currency_symbol})" report_header_total_incl_vat: "Kabuuang tax na kasama (%{currency_symbol})" @@ -2217,8 +2217,8 @@ fil_PH: failure: "pagkabigo" unsaved_changes_confirmation: "ang mga hindi na-save na pagbabago ay mawawala. magpatuloy pa rin?" one_product_unsaved: "ang mga pagbabagong ginawa sa isang produkto ay hindi pa nase-save." - products_unsaved: "ang mga pagbabagong ginawa sa%{n} produkto ay hindi pa nase-save." - is_already_manager: "ay isa nang tagapamahala" + products_unsaved: "ang mga pagbabagong ginawa sa%{n} mga produkto ay hindi pa nase-save." + is_already_manager: "ay isa nang tagapamahala!" no_change_to_save: "walang pagbabagong ise-save" user_invited: "%{email}ay naimbitahan na para pamahalaan ang enterprise na ito." add_manager: "magdagdag ng gumagamit" @@ -2431,7 +2431,7 @@ fil_PH: producer sa mga mamili, maaaring sa pamamagitan ng pagsasama sama, pagmamarka, pagbabalot, pagbebenta o pagde-deliver ng pagkain. producer_desc: mga producer ng pagkain - producer_example: hal. NAGPAPATUBO, PANADERO, MANGANGALAKAL, YUMAYARI + producer_example: hal. NAGTATANIM, PANADERO, MANGANGALAKAL, YUMAYARI non_producer_desc: Iba pang mga enterprise ng pagkain non_producer_example: hal. Grocery, Food co-ops, Buying groups enterprise_status: @@ -2447,13 +2447,13 @@ fil_PH: loading_variants: "nilo-load ang Variants" tag_rules: shipping_method_tagged_top: "naka-tag ng mga paraan ng pagpapadala" - shipping_method_tagged_bottom: "ay:" - payment_method_tagged_top: "naka-tag na paraan ng pagbabayad" - payment_method_tagged_bottom: "ay:" + shipping_method_tagged_bottom: "ay ang mga:" + payment_method_tagged_top: "naka-tag na mga paraan ng pagbabayad" + payment_method_tagged_bottom: "ay ang mga:" order_cycle_tagged_top: "naka-tag na mga Order Cycle" - order_cycle_tagged_bottom: "ay:" + order_cycle_tagged_bottom: "ay ang mga:" inventory_tagged_top: "nakatag- na mga uri ng imbentaryo" - inventory_tagged_bottom: "ay:" + inventory_tagged_bottom: "ay ang mga:" new_tag_rule_dialog: select_rule_type: "pumili ng uri ng panuntunan:" add_rule: "magdagdag ng panuntunan" @@ -2463,12 +2463,12 @@ fil_PH: index: per_page: "%{results}kada pahina" view_file: "tignan ang file" - compiling_invoices: "tipunin ang mga invoice" + compiling_invoices: "tinitipon ang mga invoice" bulk_invoice_created: "nagawa ang maramihang invoice" bulk_invoice_failed: "hindi nagtagumpay na gumawa ng maramihang invoice" please_wait: "hintayin na maihanda ang PDF bago isara ang modal na ito." order_state: - address: "tirahan" + address: "address" adjustments: "mga pagsasaayos" awaiting_return: "naghihintay ng pagbalik" canceled: "kanselado" @@ -2507,23 +2507,23 @@ fil_PH: failed: "hindi matagumpay ang muling pagpapadala ✗" order_cycles: schedules: - adding_a_new_schedule: "Pagdadagdag ng Bagong Iskedyul" - updating_a_schedule: "pag-update sa iskedyul" - create_schedule: "Gumawa ng iskedyul" + adding_a_new_schedule: "nagdadagdag ng Bagong Iskedyul" + updating_a_schedule: "ina-update ang iskedyul" + create_schedule: "Lumikha ng iskedyul" update_schedule: "i-update ang iskedyul" - delete_schedule: "burahin ang iskedyul" + delete_schedule: "tanggalin ang iskedyul" schedule_name_placeholder: "pangalan ng iskedyul" - created_schedule: "nakagawa ng iskedyul" + created_schedule: "nakalikha ng iskedyul" updated_schedule: "na-update na iskedyul" deleted_schedule: "binurang iskedyul" - name_required_error: "Maglagay ng name para sa iskedyul na ito" + name_required_error: "Maglagay ng pangalan para sa iskedyul na ito" no_order_cycles_error: "pumili kahit isang order cycle (i-drag at i-drop)" available: "Available" selected: "napili" customers: index: add_customer: "magdagdag ng Customer" - add_a_new_customer_for: "magdadag ng customer para sa%{shop_name}" + add_a_new_customer_for: "magdadag ng bagong customer para sa%{shop_name}" customer_placeholder: "customer@example.org" valid_email_error: "maglagay ng valid na email address" subscriptions: @@ -2801,6 +2801,8 @@ fil_PH: new_payment: "Bagong Pagbabayad" capture: "kunan" void: "walang bisa" + login: "Login" + password: "Password" configurations: "mga pagsasaayos" general_settings: "Pangkalahatang Setting" site_name: "Pangalan ng site" @@ -2865,8 +2867,6 @@ fil_PH: abbreviation: "Pinaikli" new_state: "Bagong Status" payment_methods: "Mga Paraan ng Pagbabayad" - new_payment_method: "Bagong Paraan ng pagbabayad" - provider: "tagapagbigay ng serbisyo" taxonomies: "taxonomies" new_taxonomy: "bagong taxonomy" back_to_taxonomies_list: "bumalik sa listahan ng mga taxonomy" @@ -3073,10 +3073,23 @@ fil_PH: categories: "mga kategorya" zones: "mga sona" payment_methods: + index: + payment_methods: "Mga Paraan ng Pagbabayad" + new_payment_method: "Bagong Paraan ng pagbabayad" + name: "Pangalan" + products_distributor: "Distributor" + provider: "tagapagbigay ng serbisyo" + environment: "kapaligiran" + display: "Ipakita" + active: "aktibo" + both: "pareho" + active_yes: "Oo" + active_no: "Hindi" new: new_payment_method: "Bagong Paraan ng pagbabayad" back_to_payment_methods_list: "bumalik sa listahan ng mga paraan ng pagbabayad" edit: + new: "Bago" editing_payment_method: "iayos ang paraan ng pagbabayad" back_to_payment_methods_list: "bumalik sa listahan ng mga paraan ng pagbabayad" stripe_connect: @@ -3092,6 +3105,17 @@ fil_PH: account_id: Account ID business_name: pangalan ng negosyo charges_enabled: pinagana ang paniningil + form: + name: "Pangalan" + description: "paglalarawan" + environment: "kapaligiran" + display: "Ipakita" + active: "aktibo" + active_yes: "Oo" + active_no: "Hindi" + tags: "tags" + providers: + provider: "tagapagbigay ng serbisyo" payments: source_forms: stripe: @@ -3192,6 +3216,7 @@ fil_PH: display_as: "Ipakita Bilang" display_name: "Pangalan na nakikita" autocomplete: + out_of_stock: "Walang stock" producer_name: "Producer" unit: "yunit" shared: @@ -3256,9 +3281,6 @@ fil_PH: invalid: invalid order_mailer: cancel_email: - customer_greeting: "hi %{name}!" - instructions: "ang iyong order ay NAKANSELA. Panatilihin ang impormasyon na ito ng kanselasyon para sa inyong talaan." - order_summary_canceled: "Buod ng order [KANSELADO]" subject: "Pagkansela ng order" confirm_email: subject: "Kumpirmasyon ng order" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index daf6a635e3..6f4cf8df9b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -368,8 +368,10 @@ fr: title: "Configuration Matomo" matomo_url: "URL de l'instance sur Matomo" matomo_site_id: "ID de l'instance sur Matomo" - info_html: "Matomo est un outil d'analyse de trafic web (ordinateur et téléphone). Vous pouvez installer vous-même Matomo ou utiliser une version hébergée. Voir matomo.org pour plus d'information." + matomo_tag_manager_url: "URL du Matomo Tag Manager" + info_html: "Matomo est un outil de suivi de traffic et de comportement des utilisateurs. Matomo est open source et validée par la CNIL française car non intrusif dans les données personnelles des utilisateurs. Pour plus d'infos : matomo.org." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec Open Food France. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." + config_instructions_tag_manager_html: "Ajouter l'URL du Tag Manager rend actif Matomo Tag Manager. Cet outil vous permet de suivre des évènements en particulier. Pour trouver l'URL rendez-vous sur l' \"Install Code section\" du Tag Manager. Attention à bien copier le bon contener et le bon environnement, car ils font varier l'URL." customers: index: new_customer: "Nouvel acheteur" @@ -403,6 +405,7 @@ fr: footer_and_external_links: Pied de page et Liens Externes your_content: Votre contenu user_guide: Guide utilisateur + map: Carte enterprise_fees: index: title: "Marges et Commissions" @@ -687,6 +690,7 @@ fr: ofn_uid_tip: L'identifiant unique pour les comptes entreprises sur Open Food Network. shipping_methods: name: "Nom" + applies: "Active ?" manage: "Gérer les méthodes de livraison" create_button: "Créer nouvelle méthode de livraison" create_one_button: "En créer une maintenant" @@ -2133,7 +2137,7 @@ fr: report_header_customer_code: Code acheteur report_header_product: Produit report_header_product_properties: Propriétés / labels Produits - report_header_quantity: Nb commandé + report_header_quantity: Quantité report_header_max_quantity: Quantité Max report_header_variant: Variante report_header_variant_value: Nb Unités Variante @@ -2192,7 +2196,7 @@ fr: report_header_eft_price: "TEF / Transfert Electronique (%{currency})" report_header_paypal_price: "Paypal (%{currency})" report_header_sku: Référence Produit - report_header_amount: Quantité + report_header_amount: Montant report_header_balance: Solde report_header_total_cost: "Coût Total" report_header_total_ordered: Total Commandé @@ -2476,7 +2480,7 @@ fr: load_more_variants: "Afficher plus de variantes" load_all_variants: "Afficher toutes les variantes" select_all_variants: "Sélectionnez toutes les %{total_number_of_variants} variantes" - variants_loaded: " %{num_of_variants_loaded}sur %{total_number_of_variants} variantes" + variants_loaded: " %{num_of_variants_loaded} sur %{total_number_of_variants} variantes" loading_variants: "Chargement des variantes" tag_rules: shipping_method_tagged_top: "Les méthodes de livraison taguées" @@ -2784,7 +2788,7 @@ fr: new: "Nouveau" start: "Début" end: "Fin" - stop: "Arrêter" + stop: "Fin" first: "Début" previous: "Précédent" last: "Fin" @@ -2835,6 +2839,14 @@ fr: new_payment: "Nouveau paiement" capture: "Payée" void: "Annulé" + login: "Se connecter" + password: "Mot de passe" + signature: "Signature" + solution: "Solution" + landing_page: "Page d'accueil (landing page)" + server: "Serveur" + test_mode: "Mode test" + logourl: "URL du logo" configurations: "Configurations" general_settings: "Configurations générales" site_name: "Nom du site" @@ -2899,8 +2911,6 @@ fr: abbreviation: "Code" new_state: "Nouveau département" payment_methods: "Méthodes de paiement" - new_payment_method: "Nouvelle méthode de paiement" - provider: "Fournisseur" taxonomies: "Taxonomies" new_taxonomy: "Nouvelle taxonomie" back_to_taxonomies_list: "Retour à la liste des taxonomies" @@ -2953,6 +2963,12 @@ fr: options: "Options" actions: update: "Mettre à jour" + shared: + error_messages: + errors_prohibited_this_record_from_being_saved: + one: "1 erreur n'a pas permis de sauvegarder:" + other: "%{count} erreurs ne permettent pas de sauvegarder:" + there_were_problems_with_the_following_fields: "Ils a eu des soucis avec les champs suivants" errors: messages: blank: "Champ obligatoire" @@ -3110,11 +3126,28 @@ fr: zones: "Zones" both: "Vu par l'acheteur sur la boutique" back_end: "Visible pour l'administration uniquement" + deactivation_warning: "Désactiver une méthode de livraison peut engendre sa disparition de la liste ici. Si vous souhaitez uniquement ne plus l'afficher pour l'acheteur, modifiez-là et utilisez l'option d'affichage \"visible pour l'administrateur uniquement\"." payment_methods: + index: + payment_methods: "Méthodes de paiement" + new_payment_method: "Nouvelle méthode de paiement" + name: "Produit/Variante" + products_distributor: "Distributeur" + provider: "Fournisseur" + environment: "Environnement" + display: "Afficher" + active: "Actif" + both: "Les deux" + front_end: "Visible par l'acheteur uniquement" + back_end: "Visible pour l'administration uniquement" + active_yes: "Oui" + active_no: "Non" + no_payment_methods_found: "Aucune méthode de paiement n'a été trouvée" new: new_payment_method: "Nouvelle méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" edit: + new: "Nouveau" editing_payment_method: "Modification de la méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" stripe_connect: @@ -3130,6 +3163,21 @@ fr: account_id: Identifiant Compte business_name: Nom de l'entreprise charges_enabled: Frais activés + form: + name: "Produit/Variante" + description: "Description" + environment: "Environnement" + display: "Afficher" + active: "Actif" + active_yes: "Oui" + active_no: "Non" + both: "Visible par l'acheteur sur la boutique" + front_end: "Visible par l'acheteur uniquement" + back_end: "Visible pour l'administration uniquement" + tags: "Tags" + deactivation_warning: "Désactiver une méthode de paiement peut faire disparaitre cette méthode de votre liste. Si vous souhaitez uniquement la rendre invisible par l'acheteur, modifiez la méthode et utilisez l'affichage pour l'administrateur uniquement." + providers: + provider: "Fournisseur" payments: source_forms: stripe: @@ -3232,6 +3280,7 @@ fr: display_as_placeholder: 'ex. 2 kg' display_name_placeholder: 'ex. Tomates' autocomplete: + out_of_stock: "En rupture de stock" producer_name: "Producteur" unit: "Unité" shared: @@ -3269,6 +3318,7 @@ fr: format: '%Y-%m-%d' js_format: 'yy-mm-dd' orders: + error_flash_for_unavailable_items: "Un élément de votre panier est épuisé. Veuillez mettre à jour les quantités sélectionnées." edit: login_to_view_order: "Veuillez vous connecter pour voir votre commande." bought: @@ -3296,9 +3346,14 @@ fr: invalid: invalide order_mailer: cancel_email: - customer_greeting: "Bonjour %{name} !" - instructions: "Votre commande a été ANNULÉE. Vous trouverez ci-dessous les informations concernant cette commande. " - order_summary_canceled: "Résumé de la commande [ANNULEE]" + customer_greeting: "Bonjour %{name}," + instructions_html: "Votre commande avec %{distributor}a été annulée. Merci de conserver cet email." + dont_cancel: "Si vous avez changé d'avis ou l'annulation a été réalisée par erreur, merci de contacter %{email}" + order_summary_canceled_html: "[ANNULATION] Commande #%{number}" + details: "Voici le détail des produits commandés:" + unpaid_order: "Votre commande n'avait pas été réglée, aucun remboursement n'a donc été effectué" + paid_order: "Votre commande avait été réglée, ainsi %{distributor}a remboursé la totalité du montant" + credit_order: "Votre commande avait été payée, votre compte a donc été crédité" subject: "Annulation de Commande" confirm_email: subject: "Confirmation de commande" diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index ab4a5e02d3..60c840f730 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -367,7 +367,6 @@ fr_BE: title: "Configuration Matomo" matomo_url: "URL de l'instance sur Matomo" matomo_site_id: "ID de l'instance sur Matomo" - info_html: "Matomo est un outil d'analyse de trafic web (ordinateur et téléphone). Vous pouvez installer vous-même Matomo ou utiliser une version hébergée. Voir matomo.org pour plus d'information." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec Open Food France. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." customers: index: @@ -402,6 +401,7 @@ fr_BE: footer_and_external_links: Pied de page et Liens Externes your_content: Votre contenu user_guide: Guide d'utilisation + map: Carte enterprise_fees: index: title: "Marges et Commissions" @@ -2738,6 +2738,8 @@ fr_BE: new_payment: "Nouveau paiement" capture: "Payée" void: "Vide" + login: "Se connecter" + password: "Mot de passe" configurations: "Configurations" general_settings: "Réglages Généraux" site_name: "Nom du site" @@ -2802,8 +2804,6 @@ fr_BE: abbreviation: "Abréviation" new_state: "Nouvelle Province" payment_methods: "Méthodes de paiement" - new_payment_method: "Nouvelle méthode de paiement" - provider: "Fournisseur" taxonomies: "Taxonomies " new_taxonomy: "Nouvelle taxonomie" back_to_taxonomies_list: "Retour à la liste des taxonomies" @@ -3010,10 +3010,23 @@ fr_BE: categories: "Les catégories" zones: "Zones" payment_methods: + index: + payment_methods: "Méthodes de paiement" + new_payment_method: "Nouvelle méthode de paiement" + name: "Nom" + products_distributor: "Distributeur·trice" + provider: "Fournisseur" + environment: "Environnement" + display: "Ecran" + active: "Actif" + both: "Tou·te·s les deux" + active_yes: "Oui" + active_no: "Non" new: new_payment_method: "Nouvelle méthode de paiement" back_to_payment_methods_list: "Retour à la liste des paiements" edit: + new: "Nouveau" editing_payment_method: "Modification des méthodes de paiement en cours" back_to_payment_methods_list: "Retour à la liste des paiements" stripe_connect: @@ -3029,6 +3042,17 @@ fr_BE: account_id: Identifiant Compte business_name: Nom de l'entreprise charges_enabled: Frais activés + form: + name: "Nom" + description: "Description" + environment: "Environnement" + display: "Ecran" + active: "Actif" + active_yes: "Oui" + active_no: "Non" + tags: "Tags" + providers: + provider: "Fournisseur" payments: source_forms: stripe: @@ -3129,6 +3153,7 @@ fr_BE: display_as: "Unité affichéé" display_name: "Nom d'affichage" autocomplete: + out_of_stock: "Pas en stock" producer_name: "Producteur·trice" unit: "Unité" shared: @@ -3193,9 +3218,6 @@ fr_BE: invalid: invalide order_mailer: cancel_email: - customer_greeting: "Bonjour%{name}! " - instructions: "Votre commande a été ANNULÉE. Veuillez conserver ces informations d'annulation pour vos dossiers." - order_summary_canceled: "Résumé de la commande [ANNULÉE]" subject: "Annulation de Commande" confirm_email: subject: "Confirmation de commande" diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index a9cbb2d1e6..5f7f23ce5f 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -363,7 +363,6 @@ fr_CA: title: "Configuration Matomo" matomo_url: "URL de l'instance sur Matomo" matomo_site_id: "ID de l'instance sur Matomo" - info_html: "Matomo est un outil d'analyse de trafic web (ordinateur et téléphone). Vous pouvez installer vous-même Matomo ou utiliser une version hébergée. Voir matomo.org pour plus d'information." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec Open Food France. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." customers: index: @@ -398,6 +397,7 @@ fr_CA: footer_and_external_links: Pied de page et Liens Externes your_content: Votre contenu user_guide: Guide utilisateur + map: Carte enterprise_fees: index: title: "Marges et Commissions" @@ -2792,6 +2792,8 @@ fr_CA: new_payment: "Nouveau paiement" capture: "Payée" void: "Annulé" + login: "Se connecter" + password: "Mot de passe" configurations: "Configurations" general_settings: "Configurations générales" site_name: "Nom du site" @@ -2856,8 +2858,6 @@ fr_CA: abbreviation: "Code" new_state: "Nouveau Région:" payment_methods: "Méthodes de paiement" - new_payment_method: "Nouvelle méthode de paiement" - provider: "Fournisseur" taxonomies: "Taxonomies" new_taxonomy: "Nouvelle taxonomie" back_to_taxonomies_list: "Retour à la liste des taxonomies" @@ -3062,10 +3062,23 @@ fr_CA: categories: "Conditions de transport" zones: "Zones" payment_methods: + index: + payment_methods: "Méthodes de paiement" + new_payment_method: "Nouvelle méthode de paiement" + name: "Nom" + products_distributor: "Hub-distributeur" + provider: "Fournisseur" + environment: "Environnement" + display: "Afficher" + active: "Actif" + both: "Les deux" + active_yes: "Oui" + active_no: "Non" new: new_payment_method: "Nouvelle méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" edit: + new: "Nouveau" editing_payment_method: "Modification de la méthode de paiement" back_to_payment_methods_list: "Retour à la liste des méthodes de paiement" stripe_connect: @@ -3081,6 +3094,17 @@ fr_CA: account_id: Identifiant Compte business_name: Nom de l'entreprise charges_enabled: Frais activés + form: + name: "Nom" + description: "Description" + environment: "Environnement" + display: "Afficher" + active: "Actif" + active_yes: "Oui" + active_no: "Non" + tags: "Tags" + providers: + provider: "Fournisseur" payments: source_forms: stripe: @@ -3181,6 +3205,7 @@ fr_CA: display_as: "Afficher comme" display_name: "Nom affiché" autocomplete: + out_of_stock: "En rupture de stock" producer_name: "Producteur" unit: "Unité" shared: @@ -3245,9 +3270,6 @@ fr_CA: invalid: invalide order_mailer: cancel_email: - customer_greeting: "Bonjour %{name}!" - instructions: "Votre commande a été ANNULÉE. Vous trouverez ci-dessous les informations concernant cette commande. " - order_summary_canceled: "Résumé de la commande [ANNULEE]" subject: "Annulation de Commande" confirm_email: subject: "Confirmation de commande" diff --git a/config/locales/it.yml b/config/locales/it.yml index 70c28a0515..13a6c49aeb 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -3,20 +3,20 @@ it: activerecord: attributes: enterprise_fee: - fee_type: Tipo di tariffa + fee_type: Tipo Tariffa spree/order: - payment_state: Stato del pagamento - shipment_state: Stato della spedizione - completed_at: Completo al + payment_state: Stato Pagamento + shipment_state: Stato Spedizione + completed_at: Completato Al number: Numero state: Stato - email: Mail consumatore + email: E-Mail Cliente spree/payment: amount: Quantità spree/product: - primary_taxon: "Categoria prodotto" + primary_taxon: "Categoria Prodotto" supplier: "Fornitore" - shipping_category_id: "Categoria di spedizione" + shipping_category_id: "Categoria Spedizioni" variant_unit: "Unità Variante" variant_unit_name: "Nome Unità Variante" spree/credit_card: @@ -31,6 +31,10 @@ it: taken: "Esiste già un account con questa email. Ti preghiamo di effettuare il login o impostare una nuova password." spree/order: no_card: Non ci sono carte di credito autorizzate disponibili per l'addebito + spree/credit_card: + attributes: + base: + card_expired: "è scaduto" order_cycle: attributes: orders_close_at: @@ -39,7 +43,7 @@ it: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "deve restare vuoto perché si stanno utilizzando le impostazioni di magazzino del produttore" on_demand_but_count_on_hand_set: "deve restare vuoto se su richiesta" - limited_stock_but_no_count_on_hand: "Torna alla lista dei pagamenti" + limited_stock_but_no_count_on_hand: "deve essere specificato a causa di una disponibilità limitata" activemodel: attributes: order_management/reports/enterprise_fee_summary/parameters: @@ -47,10 +51,10 @@ it: end_at: "Fine" distributor_ids: "Distributori" producer_ids: "Produttori" - order_cycle_ids: "Cicli di richieste" - enterprise_fee_ids: "Nome commissione" - shipping_method_ids: "Metodi di spedizione" - payment_method_ids: "Metodi di pagamento" + order_cycle_ids: "Cicli di Richieste" + enterprise_fee_ids: "Nomi Tariffe" + shipping_method_ids: "Metodi di Spedizione" + payment_method_ids: "Metodi di Pagamento" errors: messages: inclusion: "non incluso nella lista" @@ -58,7 +62,7 @@ it: order_management/subscriptions/validator: attributes: subscription_line_items: - at_least_one_product: "^Aggiungi almeno un prodotto" + at_least_one_product: "^Per favore aggiungi almeno un prodotto" not_available: "^%{name} non è disponibile nel programma selezionato" ends_at: after_begins_at: "deve essere dopo l'inizio il" @@ -67,28 +71,28 @@ it: schedule: not_coordinated_by_shop: "non è coordinato da %{shop}" payment_method: - not_available_to_shop: "non è disponibile al %{shop}" - invalid_type: "Il metodo dev'essere Cash o Stripe" - charges_not_allowed: "L'addebito su carta di credito non è consentito da questo consumatore" - no_default_card: "Nessuna carta predefinita è consentita per questo consumatore" + not_available_to_shop: "non è disponibile da %{shop}" + invalid_type: "il metodo deve essere Cash o Stripe" + charges_not_allowed: "L'addebito su carta di credito non è consentito per questo cliente" + no_default_card: "^Nessuna carta predefinita è disponibile per questo cliente" shipping_method: not_available_to_shop: "non è disponibile al %{shop}" devise: confirmations: - send_instructions: "A breve riceverai un'email con le istruzioni utili a confermare il tuo account." - failed_to_send: "C'è stato un errore nell'invio della tua mail di conferma." - resend_confirmation_email: "Re-invia la mail di conferma" - confirmed: "Grazie per aver confermato la tua mail! Ora puoi effettuare il log in." + send_instructions: "A breve riceverai una email con le istruzioni per la conferma del tuo account." + failed_to_send: "C'è stato un errore nell'invio dell'email di conferma." + resend_confirmation_email: "Invia di nuovo l'email di conferma." + confirmed: "Grazie per aver confermato la tua email! Ora puoi effettuare il log in." not_confirmed: "Il tuo indirizzo email non può essere confermato. Forse avevi già completato questo passaggio?" user_confirmations: spree_user: - send_instructions: "A breve riceverai un'email con le istruzioni utili a confermare il tuo account." + send_instructions: "A breve riceverai una email con le istruzioni per la conferma del tuo account." confirmation_sent: "Email di conferma inviata" confirmation_not_sent: "Errore invio emai di conferma" user_registrations: spree_user: signed_up_but_unconfirmed: "Abbiamo inviato un link di conferma al tuo indirizzo email. Per favore apri il link per attivare il tuo account." - unknown_error: "Qualcosa è andato storto durante la creazione del tuo account. Controlla il tuo indirizzo e-mail e riprova" + unknown_error: "Qualcosa è andato storto durante la creazione del tuo account. Controlla il tuo indirizzo email e riprova" failure: invalid: | Email o password non valida. @@ -101,29 +105,29 @@ it: spree_user: updated_not_active: "La tua password è stata resettata, ma la tua email non è ancora stata confermata." updated: "La tua password è stata modificata con successo.\nOra sei collegato." - send_instructions: "A breve riceverai un'email con le istruzioni utili a confermare il tuo account." + send_instructions: "A breve riceverai una email con le istruzioni per la conferma del tuo account." models: order_cycle: cloned_order_cycle_name: "COPIA DI %{order_cycle}" validators: date_time_string_validator: - not_string_error: "Deve essere una linea" - invalid_format_error: "Deve essere valido" + not_string_error: "deve essere una stringa" + invalid_format_error: "deve essere valido" integer_array_validator: - not_array_error: "Deve essere una sequenza" - invalid_element_error: "Deve contenere solo numeri interi" + not_array_error: "deve essere un array" + invalid_element_error: "deve contenere solo numeri interi" enterprise_mailer: confirmation_instructions: - subject: "Per favore conferma l'indirizzo email per %{enterprise}" + subject: "Per favore conferma l'indirizzo email di %{enterprise}" welcome: subject: "%{enterprise} è ora su %{sitename}" email_welcome: "Benvenuto" email_registered: "è ora parte di" - email_userguide_html: "La Guida Utente con supporto dettagliato per l'impostazione del tuo Produttore o Hub è qui: %{link}" - userguide: "Guida di Open Food Network" + email_userguide_html: "La Guida Utente con supporto dettagliato per l'impostazione del tuo Produttore o Distributore è qui: %{link}" + userguide: "Guida Utente di Open Food Network" email_admin_html: "Puoi gestire il tuo profilo facendo il log in al link %{link} o cliccando sull'ingranaggio in alto a destra della homepage, e selezionando Amministrazione" - admin_panel: "Pannello di controllo" - email_community_html: "Abbiamo anche un forum on-line per le discussioni della comunità sul software OFN e le sfide uniche legate all'avere un'impresa del cibo. Sei invitato ad unirti. Ci evolviamo in continuo e il tuo contributo in questo forum plasmerà ciò che sarà. %{link}" + admin_panel: "Panello Amministrativo" + email_community_html: "Abbiamo anche un forum per le discussioni comunitarie legate al software di OFN e le sfide uniche legate all'avere un'impresa alimentare. Ti incoraggiamo a farne parte. Siamo in continua evoluzione e il tuo contributo al forum delineerà quello che succederà in futuro. %{link}" join_community: "Unisciti alla community" invite_manager: subject: "%{enterprise} ti a invitato ad essere un referente" @@ -132,30 +136,30 @@ it: subject: "Resoconto degli ordini per %{producer}" shipment_mailer: shipped_email: - dear_customer: "Caro consumatore," + dear_customer: "Caro Cliente," instructions: "Il tuo ordine è stato spedito" - shipment_summary: "Riepilogo della spedizione" - subject: "Avviso di spedizione" - thanks: "Grazie per utilizzare la piattaforma per il tuo commercio" - track_information: "Informazioni di tracciamento" - track_link: "Link del tracciamento" + shipment_summary: "Riepilogo della Spedizione" + subject: "Notifica di Spedizione" + thanks: "Grazie per il tuo lavoro." + track_information: "Informazioni Tracking: %{tracking}" + track_link: "Tracking Link: %{url}" subscription_mailer: placement_summary_email: subject: Riassunto degli ordini più recenti greeting: "Ciao %{name}," - intro: "Qui sotto un riassunto degli ordini appena inviati per%{shop} ," + intro: "Qui sotto un riassunto degli ordini appena inviati per%{shop}," confirmation_summary_email: subject: Riassunto delle richieste recentemente confermate greeting: "Ciao %{name}," intro: "Qui sotto un riassunto delle richieste che hai appena confermato per %{shop}." summary_overview: - total: Un totale di %{count} abbonamenti sono stati contrassegnati per l'elaborazione automatica.. - success_zero: Di questi, nessuno è stato modificato con successo + total: Un totale di %{count} sottoscrizioni sono stati contrassegnati per l'elaborazione automatica. + success_zero: Di questi, nessuno è stato elaborato con successo. success_some: Di questi, %{count} sono stati elaborati con successo. success_all: Tutti sono stati elaborati con successo. - issues: Qui sotto i dettagli dei problemi incontrati. + issues: Qui sotto i dettagli dei problemi riscontrati. summary_detail: - no_message_provided: 'Nessun messaggio di errore ' + no_message_provided: Nessun messaggio di errore fornito changes: title: Scorte insufficienti (%{count} gentili richieste) explainer: Queste gentili richieste sono state elaborate, ma la quantità richiesta di alcuni prodotti non è disponibile @@ -176,7 +180,7 @@ it: explainer: L'elaborazione automatica di queste gentili richieste non è riuscita per una ragione sconosciuta. Questo non dovrebbe accadere, ti preghiamo di contattarci se visualizzi questo messaggio. home: "OFN" title: Open Food Network - welcome_to: 'Benvenuto a' + welcome_to: 'Benvenuto su' site_meta_description: "Cominciamo da zero. Con i produttori e gli allevatori pronti a raccontare le loro storie, sinceramente e orgogliosamente. Con i distributori pronti a connettere le persone con i prodotti in modo giusto ed equo. Con i compratori che credono che migliori decisioni per l'acquisto settimanale possano..." search_by_name: Cerca per nome o zona... producers_join: I Produttori sono ora invitati ad unirsi ad Open Food Network @@ -184,12 +188,12 @@ it: print_invoice: "Stampa fattura" print_ticket: "Stampa Biglietto" select_ticket_printer: "Seleziona la stampante per i biglietti" - send_invoice: "Manda fattura" - resend_confirmation: "Rimanda conferma" - view_order: "Vedi l'ordine" - edit_order: "Modifica l'ordine" - ship_order: "Invia l'ordine" - cancel_order: "Cancella l'ordine" + send_invoice: "Invia Fattura" + resend_confirmation: "Rimanda Conferma" + view_order: "Vedi Ordine" + edit_order: "Modifica Ordine" + ship_order: "Invia Ordine" + cancel_order: "Cancella Ordine" confirm_send_invoice: "Una fattura per quest'ordine verrà mandata al cliente. Sei sicuro di voler continuare?" confirm_resend_order_confirmation: "Sei sicuro di voler inviare di nuovo l'email di conferma per l'ordine?" must_have_valid_business_number: "%{enterprise_name} deve avere una partita iva valida per poter emettere fattura." @@ -198,11 +202,11 @@ it: say_no: "No" say_yes: "Sì" ongoing: Attivo - bill_address: Indirizzo di fatturazione - ship_address: Indirizzo di consegna - sort_order_cycles_on_shopfront_by: "Ordina cicli d'ordine in vetrina per" + bill_address: Indirizzo Fatturazione + ship_address: Indirizzo Consegna + sort_order_cycles_on_shopfront_by: "Ordina Cicli Ordine in Vetrina per" required_fields: I campi obbligatori sono contrassegnati con un asterisco - select_continue: Seleziona e continua + select_continue: Seleziona e Continua remove: Rimuovi or: o collapse_all: Riduci tutto @@ -215,7 +219,7 @@ it: edit: Modifica clone: Duplica distributors: Distributori - bulk_order_management: Gestione richieste all'ingrosso + bulk_order_management: Gestione Ordini Massivi enterprises: Aziende enterprise_groups: Gruppi reports: Resoconti @@ -223,15 +227,15 @@ it: import: Importazione spree_products: Prodotti Spree all: Tutti - current: Attuali + current: Correnti available: Disponibile dashboard: Pannello di controllo undefined: non definito unused: non in uso admin_and_handling: Admin profile: Profilo - supplier_only: Solo per i fornitori - has_shopfront: Informazioni di tracciamento + supplier_only: Solo Fornitori + has_shopfront: Ha una Vetrina weight: Peso volume: Volume items: Prodotti @@ -246,26 +250,26 @@ it: blocked_cookies_alert: "Il tuo browser sembra stia bloccando i cookies necessari ad usare questa pagina del negozio. Clicca sotto per consentire i cookies e ricaricare la pagina." allow_cookies: "Accetta i cookies" notes: Note - error: Eorrore + error: Errore processing_payment: "Elaborazione pagamento..." - no_pending_payments: "nessun pagamento in sospeso" - invalid_payment_state: "stato del pagamento non valido" + no_pending_payments: "Nessun pagamento in sospeso" + invalid_payment_state: "Stato del pagamento non valido" filter_results: Filtra i risultati quantity: Quantità pick_up: Ritiro copy: Copia change_my_password: "Cambia la mia password" update_password: "Aggiorna password" - password_confirmation: 'Conferma password ' + password_confirmation: 'Conferma Password ' reset_password_token: Token per il reset della password expired: è scaduto, si prega di richiederne uno nuovo - back_to_payments_list: "Torna alla lista dei pagamenti" - maestro_or_solo_cards: "carte Maestro/Solo" - backordered: "ordini arretrati" + back_to_payments_list: "Torna alla Lista dei Pagamenti" + maestro_or_solo_cards: "Carte Maestro/Solo" + backordered: "Ordini arretrati" on hand: "Disponibile" ship: "Spedizione" actions: - create_and_add_another: "Crea e aggiungi un altro" + create_and_add_another: "Crea e Aggiungi un Altro" create: "Crea" cancel: "Annulla" save: "Salva" @@ -275,7 +279,7 @@ it: admin: begins_at: Inizia a begins_on: Inizia da - customer: Consumatore + customer: Cliente date: Data email: Email ends_at: Termina a @@ -319,6 +323,7 @@ it: show_n_more: Mostra %{num} di più choose: "Scegli..." please_select: Seleziona... + column_save_as_default: Salva Come Predefinito columns: Colonne actions: Azioni viewing: "Vista: %{current_view_name}" @@ -363,11 +368,10 @@ it: title: "Impostazioni Matomo" matomo_url: "URL Matomo" matomo_site_id: "Site ID Matomo" - info_html: "Matomo è una Web and Mobile Analytics. È possibile ospitare Matomo in sede o utilizzare un servizio cloud. Vedi matomo.org per maggiori informazionimatomo.org for more information." config_instructions_html: "Qui è possibile configurare l'integrazione OFN Matomo. L'URL di Matomo qui sotto dovrebbe puntare l'istanza di Matomo a cui saranno inviate le informazioni di monitoraggio dell'utente; se lasciato vuoto, il monitoraggio dell'utente da parte di Matomo sarà disabilitato. Il campo Site ID non è obbligatorio ma è utile se si sta tracciando più di un sito web su una singola istanza di Matomo; si può trovare sulla console dell'istanza di Matomo. " customers: index: - new_customer: "Nuovo cliente" + new_customer: "Nuovo Cliente" code: Codice duplicate_code: "Questo codice è già usato." bill_address: "Indirizzo di fatturazione" @@ -385,7 +389,7 @@ it: search_by_email: "Cerca per email/codice..." guest_label: 'Check-out ospite' destroy: - has_associated_orders: 'Cancellazione non riuscita: l''utente ha ordini associati al suo negozio' + has_associated_orders: 'Cancellazione fallita: l''utente ha ordini associati al negozio' contents: edit: title: Contenuto @@ -398,6 +402,7 @@ it: footer_and_external_links: Footer e link esterni your_content: I tuoi contenuti user_guide: Guida per gli utenti + map: Mappa enterprise_fees: index: title: "Tariffe azienda" @@ -608,7 +613,7 @@ it: desc_short: Breve descrizione desc_short_placeholder: Raccontaci la tua attività in una o due frasi desc_long: Chi siamo - desc_long_placeholder: Racconta di te ai consumatori. Questa informazione comparirà nel tuo profilo pubblico. + desc_long_placeholder: Racconta di te ai tuoi clienti. Questa informazione comparirà nel tuo profilo pubblico. business_details: abn: ABN abn_placeholder: es. 99 123 456 789 @@ -660,7 +665,7 @@ it: name: Nome name_placeholder: es. Tartufi Biodinamici Alba groups: Gruppi - groups_tip: Seleziona i gruppi o le regioni di cui sei membro. Questo aiuterà i consumatori a trovare la tua azienda. + groups_tip: Seleziona i gruppi o le regioni di cui sei membro. Questo aiuterà i clienti a trovare la tua azienda. groups_placeholder: 'Inizia a digitare per trovare i gruppi ' primary_producer: Produttore primario? primary_producer_tip: Seleziona "Produttore" se sei un produttore primario di cibo @@ -669,9 +674,9 @@ it: none: Nessuno own: Proprio sells: Vende - sells_tip: "Nessuno - L'azienda non vende direttamente ai consumatori.
Proprio - L'azienda vende i propri prodotti ai consumatori.
Proprio e altrui - L'azienda può vendere prodotti propri o di altre aziende.
" + sells_tip: "Nessuno - L'azienda non vende direttamente ai clienti.
Proprio - L'azienda vende i propri prodotti ai clienti.
Proprio e altrui - L'azienda può vendere prodotti propri o di altre aziende.
" visible_in_search: Visibile nella ricerca? - visible_in_search_tip: Determina se questa azienda sarà visibile ai consumatori quando cercano nel sito. + visible_in_search_tip: Determina se questa azienda sarà visibile ai clienti quando cercano nel sito. visible: Visibile not_visible: Non visibile permalink: Permalink (nessuno spazio) @@ -682,13 +687,14 @@ it: ofn_uid_tip: Il codice univoco utilizzato per identificare l'azienda su OFN shipping_methods: name: "Nome" + applies: "Attivo?" manage: "Gestisci metodi di spedizione" create_button: "Crea un nuovo metodo di consegna" create_one_button: "Crea uno ora" no_method_yet: "Non hai ancora un metodo di consegna" shop_preferences: shopfront_requires_login: "Vetrina visibile pubblicamente?" - shopfront_requires_login_tip: "Scegli se i consumatori devono essere registrati per poter vedere la vetrina o se è visibile a tutti" + shopfront_requires_login_tip: "Scegli se i clienti devono essere registrati per poter vedere la vetrina o se è visibile a tutti." shopfront_requires_login_false: "Pubblica" shopfront_requires_login_true: "Visibile solo agli utenti registrati" recommend_require_login: "Consigliamo di richiedere la registrazione quando si dà la possibilità di modificare gli ordini." @@ -697,7 +703,7 @@ it: allow_guest_orders_false: "Richiedi il login per ordinare" allow_guest_orders_true: "Permetti acquisto come ospite" allow_order_changes: "Modifica gentili richieste" - allow_order_changes_tip: "Permetti ai consumatori di modificare le proprie richieste finché il ciclo di richieste è aperto." + allow_order_changes_tip: "Permetti ai clienti di modificare i propri ordini fino a quando il ciclo degli ordini è aperto." allow_order_changes_false: "Le gentili richieste confermate non possono essere modificate / annullate" allow_order_changes_true: "Gli utenti possono modificare / annullare le gentili richieste mentre il ciclo di richieste è aperto" enable_subscriptions: "Sottoscrizioni" @@ -706,7 +712,7 @@ it: enable_subscriptions_true: "Abilitata" shopfront_message: "Messaggio vetrina" shopfront_message_placeholder: > - Un messaggio opzionale per dare in benvenuto ai clienti e spiegare come + Un messaggio opzionale per dare il benvenuto ai clienti e spiegare come acquistare. Il testo inserito qui verrà mostrato nel tab principale della vetrina. shopfront_message_link_tooltip: "Inserisci / modifica link" @@ -734,7 +740,7 @@ it: title: Collegati con Stripe part1: Stripe è un servizio di elaborazione dei pagamenti che permette ai negozi su OFN di accettare pagamenti con carta di credito da parte dei clienti. part2: Per utilizzare questa funzione, è necessario collegare il proprio account Stripe a OFN. Cliccando su 'Accetto' qui sotto sarai reindirizzato al sito web Stripe dove potrai collegare un account Stripe esistente o crearne uno nuovo se non ne hai già uno. - part3: Questo consentirà alla piattaforma di accettare pagamenti con carta di credito da clienti di tua fiducia. Tieni presente che dovrai mantenere il tuo conto Stripe, pagare la tariffa di Strip e gestire gli eventuali rimborsi e i servizi al cliente. + part3: Questo consentirà alla piattaforma di accettare pagamenti con carta di credito da clienti di tua fiducia. Tieni presente che dovrai mantenere il tuo conto Stripe, pagare la commissione di Stripe e gestire gli eventuali rimborsi e i servizi al cliente. i_agree: Sono d'accordo cancel: Annulla tag_rules: @@ -744,7 +750,7 @@ it: add_new_button: ' + Aggiungi una nuova regola predefinita' no_tags_yet: Nessuna etichetta per questa azienda no_rules_yet: Nessuna regola per questa etichetta - for_customers_tagged: 'Per i clienti etichettati' + for_customers_tagged: 'Per i clienti etichettati:' add_new_rule: '+ Aggiungi una nuova regola' add_new_tag: '+ Aggiungi una nuova tag' users: @@ -788,7 +794,7 @@ it: producer_description_text: Aggiungi i tuoi prodotti, permettendo agli hubs di inserire i tuoi prodotti nei loro negozi. producer_shop: Negozio produttore sell_your_produce: Vendi i tuoi prodotti - producer_shop_description_text: Vendi i tuoi prodotti direttamente ai consumatori tramite la tua propria vetrina su OFN + producer_shop_description_text: Vendi i tuoi prodotti direttamente ai clienti tramite la tua personale vetrina su Open Food Network. producer_shop_description_text2: Un Negozio produttore è solo per i tuoi prodotti. Se vuoi vendere prodotti altrui, seleziona "Hub produttore". producer_hub: Hub produttore producer_hub_text: Vendi prodotti tuoi e di altri @@ -860,6 +866,7 @@ it: incoming: "In arrivo" supplier: "Fornitore" products: "Prodotti" + receival_details: "Dettagli Ricevimento" fees: "Tariffe" save: "Salva" save_and_next: "Salva e continua" @@ -871,6 +878,7 @@ it: distributor: "Distributore" products: "Prodotti" tags: "Tag" + delivery_details: "Dettagli Spedizione" fees: "Tariffe" previous: "Precedente" save: "Salva" @@ -882,7 +890,7 @@ it: incoming: "2. Prodotti in entrata" outgoing: "3. Prodotti in uscita" exchange_form: - pickup_time_tip: Quando gli ordini di questa Lista d'ordine saranno pronti per il cliente + pickup_time_tip: Quando gli ordini di questo ciclo saranno pronti per il cliente pickup_instructions_placeholder: "Istruzioni per la consegna" pickup_instructions_tip: Queste istruzioni saranno visibili agli utenti dopo che hanno completato una gentile richiesta pickup_time_placeholder: "Pronto per (es. Data / Ora)" @@ -934,12 +942,12 @@ it: simple_form: ready_for: Pronto per ready_for_placeholder: Data / Ora - customer_instructions: Istruzioni consumatori + customer_instructions: Istruzioni per i consumatori customer_instructions_placeholder: Note per ritiro / consegna products: Prodotti fees: Tariffe destroy_errors: - orders_present: Questo ciclo di richieste è stato selezionato da un consumatore e non può essere cancellato. Per evitare altri accessi, chiudi il ciclo. + orders_present: Questo ciclo di richieste è stato selezionato da un cliente e non può essere cancellato. Per prevenire altri accessi da parte dei clienti, per favore chiudi il ciclo. schedule_present: Questo ciclo di richieste è connesso a un programma e non può essere cancellato. Puoi eliminare il link o cancellare il programma prima. bulk_update: no_data: mmm, qualcosa è andato storto. Nessun dato per ciclo di richieste trovato. @@ -977,7 +985,7 @@ it: supplier_totals: Totali Ciclo di richieste fornitori supplier_totals_by_distributor: Totali Ciclo di richieste fornitori per distributore totals_by_supplier: Totali Ciclo di richieste fornitori per fornitore - customer_totals: Totali ciclo di richieste consumatori + customer_totals: Ciclo Ordini Cliente Totale all_products: Tutti i prodotti inventory: Inventario (in mano) lettuce_share: LettuceShare @@ -987,7 +995,7 @@ it: delivery: Rapporto Consegne tax_types: Tipologia tariffe tax_rates: Aliquote d'imposta - pack_by_customer: Smistato dai consumatori + pack_by_customer: Imballato dal Cliente pack_by_supplier: Smistato dai fornitori orders_and_distributors: name: Gentili richieste e distributori @@ -1001,7 +1009,7 @@ it: orders_and_fulfillment: name: Gentili richieste e resoconti di soddifazione customers: - name: Consumatori + name: Clienti products_and_inventory: name: Prodotti e inventario users_and_enterprises: @@ -1038,7 +1046,7 @@ it: enable_subscriptions_step_2: 2. In "Preferenze Negozio", attiva l'opzione Abbonamenti set_up_shipping_and_payment_methods_html: 'Imposta i metodi %{shipping_link} e %{payment_link} ' set_up_shipping_and_payment_methods_note_html: Nota con gli abbonamenti può
essere utilizzato solo il metodo Contanti - ensure_at_least_one_customer_html: 'Assicurati che esista almeno un %{customer_link} ' + ensure_at_least_one_customer_html: Assicurati che almeno un %{customer_link} esista create_at_least_one_schedule: Crea almeno un programma create_at_least_one_schedule_step_1_html: '1. Vai alla pagina %{order_cycles_link} ' create_at_least_one_schedule_step_2: 2. Crea un Ciclo di Richieste se non l'hai già fatto @@ -1064,9 +1072,9 @@ it: invalid_error: Oops! Per favore compila i campi obbligatori... allowed_payment_method_types_tip: Al momento può essere utilizzato solo il metodo di pagamento Contanti credit_card: Carta di Credito - charges_not_allowed: Non sono consentiti Oneri per questo cliente + charges_not_allowed: Non sono consentiti ricarichi per questo cliente no_default_card: Il cliente non ha carte disponibili da caricare - card_ok: il cliente ha una carta disponibile da caricare + card_ok: Il cliente ha una carta disponibile da caricare begins_at_placeholder: "Seleziona una data" ends_at_placeholder: "Facoltativo" loading_flash: @@ -1091,9 +1099,9 @@ it: cancel_failure_msg: "Ci dispiace, eliminazione non riuscita!" confirm_pause_msg: "Sei sicura/o di voler mettere in pausa questo abbonamento?" pause_failure_msg: "Spiacente, pausa fallita!" - confirm_unpause_msg: "Se hai un ciclo di richieste aperto durante questa registrazione, sarà creato un ordine per l'utente registrato. Vuoi annullare la registrazione?" + confirm_unpause_msg: "Se hai aperto un Ciclo d'Ordini durante questa sottoscrizione pianificata, un ordine per l'utente verrà creato per questo cliente. Sei sicuro di voler attivare questa sottoscrizione?" unpause_failure_msg: "Ci dispiace, ripresa non riuscita!" - confirm_cancel_open_orders_msg: "Alcune di queste richieste sono attualmente attive. I consumatori sono già stati avvisati che le richieste verranno soddisfatte. Vuoi eliminare questa/e richiesta/e o mantenerla?" + confirm_cancel_open_orders_msg: "Alcuni ordini per questa sottoscrizione sono attualmente aperti. I clienti sono già stati avvisati che le richieste verranno soddisfatte. Vuoi eliminare questa/e richiesta/e o mantenerle?" resume_canceled_orders_msg: "Alcuni ordini per questo abbonamento possono essere ripresi in questo momento. Puoi riprenderli dal menu a discesa degli ordini." yes_cancel_them: Cancella l'articolo no_keep_them: Tieni l'articolo @@ -1167,8 +1175,12 @@ it: login: "fai il login" signup: "Registrati" contact: "contatto" - require_customer_login: "Solo utenti approvati hanno accesso a questo negozio" + require_customer_login: "Solo clienti approvati hanno accesso a questo negozio" + require_login_html: "Se sei già un cliente approvato, %{login} o %{signup} per procedere." + require_login_2_html: "Vuoi iniziare a acquistare qui? Per favore %{contact}%{enterprise}e chiedi di essere aggiunto." require_customer_html: "Se vuoi iniziare a comprare, per favore %{contact} %{enterprise} per chiedere di raggiungerci." + select_oc: + select_oc_html: "Per favore scegli quando vuoi il tuo ordine , per vedere quali prodotti sono disponibili." card_could_not_be_updated: La Carta non ha potuto essere rinnovata card_could_not_be_saved: La Carta non ha potuto essere salvata spree_gateway_error_flash_for_checkout: "C'è stato un problema con le informazioni sul pagamento: %{error}" @@ -1176,7 +1188,7 @@ it: invoice_column_tax: "IVA" invoice_column_price: "Prezzo" invoice_column_item: "Articolo" - invoice_column_qty: "Qtà." + invoice_column_qty: "Qtà" invoice_column_unit_price_with_taxes: "Prezzo unitario (incl. tasse)" invoice_column_unit_price_without_taxes: "Prezzo unitario (escl. tasse)" invoice_column_price_with_taxes: "Prezzo totale (incl. tasse)" @@ -1392,14 +1404,14 @@ it: order_paid: PAGATO order_not_paid: NON PAGATO order_total: Totale dell'ordine - order_payment: "Pagamento via:" + order_payment: "Pagamento attraverso:" order_billing_address: Indirizzo di fatturazione order_delivery_on: Consegna il order_delivery_address: Indirizzo di consegna order_delivery_time: Tempo di consegna order_special_instructions: "Tue note:" order_pickup_time: Pronto per il ritiro - order_pickup_instructions: Istruzioni per la raccolta + order_pickup_instructions: Istruzioni per la Distribuzione order_produce: Produrre order_total_price: Totale order_includes_tax: (include le tasse) @@ -1425,17 +1437,17 @@ it: email_social: "Connettiti con Noi:" email_contact: "Scrivici:" email_signoff: "Saluti," - email_signature: "Team di %{sitename}" + email_signature: "Il team di %{sitename}" email_confirm_customer_greeting: "Ciao %{name}," email_confirm_customer_intro_html: "Grazie per aver acquistato presso %{distributor}!" email_confirm_customer_number_html: "Conferma dell'Ordine #%{number}" - email_confirm_customer_details_html: "Qui sono i dettagli del tuo ordine da %{distributor}:" + email_confirm_customer_details_html: "Ecco i dettagli del tuo ordine da %{distributor}:" email_confirm_customer_signoff: "Cordiali saluti," email_confirm_shop_greeting: "Ciao %{name}," email_confirm_shop_order_html: "Ben fatto! Hai un nuovo ordine per %{distributor}!" email_confirm_shop_number_html: "Conferma dell'Ordine #%{number}" email_order_summary_item: "Articolo" - email_order_summary_quantity: "Qtà." + email_order_summary_quantity: "Qtà" email_order_summary_sku: "SKU" email_order_summary_price: "Prezzo" email_order_summary_subtotal: "Subtotale:" @@ -1443,8 +1455,8 @@ it: email_order_summary_includes_tax: "(include le tasse)" email_payment_paid: PAGATO email_payment_not_paid: NON PAGATO - email_payment_summary: Riassunto del pagamento - email_payment_method: "Pagamento via:" + email_payment_summary: Riepilogo di pagamento + email_payment_method: "Pagamento attraverso:" email_so_placement_intro_html: "Hai una nuova gentile richiesta di %{distributor}" email_so_placement_details_html: "Ecco i dettagli della gentile richiesta per %{distributor}:" email_so_placement_changes: "Purtroppo alcuni prodotti richiesti non sono disponibili. Le quantità originali richieste sono barrate qui sotto." @@ -1468,13 +1480,13 @@ it: email_shipping_delivery_address: "Indirizzo di consegna" email_shipping_collection_details: Dettagli della raccolta email_shipping_collection_time: "Pronto per il ritiro:" - email_shipping_collection_instructions: "Istruzioni per la raccolta:" + email_shipping_collection_instructions: "Istruzioni per la distribuzione:" email_special_instructions: "Tue note:" email_signup_greeting: Ciao! email_signup_welcome: "Benvenuto a %{sitename}!" email_signup_confirmed_email: "Grazie di aver confermato la tua mail." email_signup_shop_html: "Puoi effettuare il log in qui: %{link}." - email_signup_text: "Grazie per esserti unito alla rete. Se sei un cliente, non vediamo l'ora di introdurti a molti produttori fantastici, distributori di cibo spettacolari e cibo delizioso! Se sei un produttore o un'impresa del cibo, siamo entusiasti di averti come parte della rete." + email_signup_text: "Grazie per esserti unito alla rete. Se sei un cliente, non vediamo l'ora di introdurti a molti produttori fantastici, distributori di cibo spettacolari e cibo delizioso! Se sei un produttore o un'impresa alimentare, siamo entusiasti di averti come parte della rete." email_signup_help_html: "Accettiamo volentieri tutte le tue domane e i tuoi suggerimenti: puoi usare il bottone Invia Feedback sul sito o scriverci a %{email}" invite_email: greeting: "Ciao!" @@ -1528,12 +1540,17 @@ it: orders_changeable_orders_alert_html: Questa gentile richiesta è stata confermata, ma puoi effettuare modifiche fino a %{oc_close}. products_clear: Pulisci products_showing: "Mostra:" + products_results_for: "Risultati per" products_or: "o" products_and: "e" + products_filters_in: "in" products_with: con + products_search: "Ricerca..." products_filter_by: "Filtra per" products_filter_selected: "selezionato" + products_filter_heading: "Filtri" products_filter_clear: "Pulisci" + products_filter_done: "Fatto" products_loading: "Caricamento prodotti..." products_updating_cart: "Aggiornamento del carrello..." products_cart_empty: "Carrello vuoto" @@ -1544,6 +1561,8 @@ it: products_update_error_msg: "Salvataggio fallito." products_update_error_data: "Salvataggio fallito per dati non validi:" products_changes_saved: "Modifiche salvate." + products_no_results_html: "Mi spiace, nessun risultato per %{query}" + products_clear_search: "Pulisci ricerca" search_no_results_html: "Mi dispiace, nessun risultato per %{query}. Vuoi provare un'altra ricerca?" components_profiles_popover: "I profili non hanno una vetrina su Open Food Network, ma potrebbero avere il proprio negozio fisico o online altrove" components_profiles_show: "Mostra profili" @@ -1899,6 +1918,7 @@ it: admin_enterprise_relationships_permits: "permessi" admin_enterprise_relationships_seach_placeholder: "Cerca" admin_enterprise_relationships_button_create: "Crea" + admin_enterprise_relationships_to: "a" admin_enterprise_groups: "Gruppi dell'azienda" admin_enterprise_groups_name: "Nome" admin_enterprise_groups_owner: "Proprietario" @@ -1959,7 +1979,7 @@ it: scheduled_for: "Programmato per" customers: "Clienti" please_select_hub: "Seleziona un hub" - loading_customers: "Clienti in caricamento" + loading_customers: "Caricamento Clienti" no_customers_found: "Nessun cliente trovato" go: "Vai" hub: "Distributore" @@ -2109,8 +2129,8 @@ it: report_header_tax_on_fees: "Oneri sulle provvigioni (%{currency_symbol})" report_header_total_tax: "Oneri totali (%{currency_symbol})" report_header_enterprise: Azienda - report_header_customer: Consumatore - report_header_customer_code: Codice cliente + report_header_customer: Cliente + report_header_customer_code: Codice Cliente report_header_product: Prodotto report_header_product_properties: Proprietà prodotto report_header_quantity: Quantità @@ -2154,10 +2174,10 @@ it: report_header_order_id: ID richiesta report_header_item_name: Nome articolo report_header_temp_controlled_items: Articolo a Temperatura Controllata - report_header_customer_name: Nome Consumatore - report_header_customer_email: Email consumatore - report_header_customer_phone: Telefono Consumatore - report_header_customer_city: Città consumatore + report_header_customer_name: Nome Cliente + report_header_customer_email: Email Cliente + report_header_customer_phone: Telefono Cliente + report_header_customer_city: Città Cliente report_header_payment_state: Stato Pagamento report_header_payment_type: Tipo Pagamento report_header_item_price: "Articolo (%{currency})" @@ -2257,12 +2277,12 @@ it: adjustments_tax_rate_error: "^Verificate che l'aliquota d'imposta per questo adeguamento sia corretta." active_distributors_not_ready_for_checkout_message_singular: >- L'hub %{distributor_names} figura in un ciclo di richieste attivo, ma non ha - metodi di consegna e di pagamento validi. Finché non li imposti, i consumatori - non potranno acquistare da questo hub. + metodi di consegna e di pagamento validi. Finché non li imposti, i clienti non + potranno acquistare da questo hub. active_distributors_not_ready_for_checkout_message_plural: >- - Gli hub %{distributor_names}figurano in un ciclo di richieste attivo, ma non - hanno metodi di consegna e di pagamento validi. Finché non li imposti, i consumatori - non potranno acquistare da questi hub. + I distributori %{distributor_names} figurano in un ciclo di richieste attivo, + ma non hanno metodi di consegna e di pagamento validi. Finché non li imposti, + i clienti non potranno acquistare da questi distributori. enterprise_fees_update_notice: Le tariffe della tua azienda sono state aggiornate. enterprise_register_package_error: "Per favore seleziona un pacchetto" enterprise_register_error: "Non abbiamo potuto completare la registrazione per %{enterprise}" @@ -2304,6 +2324,10 @@ it: resolve_errors: 'Per favore risolvi i seguenti errori:' more_items: "+ %{count} ancora" default_card_updated: Carta predefinita aggiornata + cart: + add_to_cart_failed: > + C'è stato un problema nell'aggiungere questo prodotto al carrello. Forse + non é più disponibile o il negozio sta chiudendo. admin: enterprise_limit_reached: "Hai raggiunto il limite standard di aziende per account. Scrivi a %{contact_email} se hai bisogno di aumentarlo." modals: @@ -2315,9 +2339,9 @@ it: title: Regole Tag overview: Panoramica overview_text: > - Le regole per le tag forniscono un modo per definire quali elementi - sono visibili, o a quali utenti. Gli elementi possono essere: metodi - di consegna, metodi di pagamento, prodotti e cicli di richieste. + Le regole per le tag forniscono un modo per descrivere quali elementi + sono visibili, o a quali utenti. Gli elementi possono essere: Metodi + di Consegna, Metodi di Pagamento, Prodotti e Cicli d'Ordine. by_default_rules: "Regole predefinite" by_default_rules_text: > Le regole predefinite ti permettono di nascondere gli elementi affinché @@ -2560,7 +2584,7 @@ it: edit_profile: "modifica profilo" add_products_to_inventory: "aggiungi prodotti all'inventario" resources: - could_not_delete_customer: 'Non è possibile annullare utente' + could_not_delete_customer: 'Non è possibile cancellare il cliente' product_import: confirmation: | Questo imposterà il livello delle scorte a zero su tutti i prodotti per questa @@ -2569,7 +2593,7 @@ it: create_failure: "Impossibile creare il ciclo dell'ordine" update_success: 'Il tuo ciclo di richieste è stato aggiornato' update_failure: "Impossibile aggiornare il ciclo dell'ordine" - no_distributors: Non ci sono distributori in questo ciclo dell'ordine. Questo ciclo dell'ordine non sarà visibile ai consumatori fino a quando non ne verrà aggiunto uno. Vuoi continuare a salvare questo ciclo dell'ordine? + no_distributors: Non ci sono distributori in questo ciclo d'ordine. Questo ciclo d'ordine non sarà visibile ai clienti fino a quando non ne verrà aggiunto uno. Vuoi continuare a salvare questo ciclo d'ordine? enterprises: producer: "Produttore" non_producer: "Non-produttore" @@ -2695,7 +2719,7 @@ it: fee_type: "Tipo di tariffa" enterprise_name: "Proprietario dell'azienda" fee_name: "Nome della tariffa" - customer_name: "Consumatore" + customer_name: "Cliente" fee_placement: "Posizionamento della tariffa" fee_calculated_on_transfer_through_name: "Calcolo della commissione sul trasferimento tramite" tax_category_name: "Categoria d'imposta" @@ -2705,7 +2729,7 @@ it: fee_type: "Tipo di tariffa" enterprise_name: "Proprietario dell'azienda" fee_name: "Nome della tariffa" - customer_name: "Consumatore" + customer_name: "Cliente" fee_placement: "Posizionamento della tariffa" fee_calculated_on_transfer_through_name: "Calcolo della commissione sul trasferimento tramite" tax_category_name: "Categoria d'imposta" @@ -2714,7 +2738,7 @@ it: order: "Gentile Richiesta" distribution: "Distribuzione" order_details: "Dettagli ordine" - customer_details: "Dettagli cliente" + customer_details: "Dettagli Cliente" adjustments: "Regolazioni" payments: "Pagamenti" payment: "Pagamento" @@ -2763,8 +2787,8 @@ it: cannot_set_shipping_method_without_address: "Impossibile impostare il metodo di spedizione finché non vengono forniti i dettagli del cliente." no_tracking_present: "Nessun dettaglio di tracciamento fornito." order_total: "Ordine totale" - customer_details: "Dettagli cliente" - customer_search: "Ricerca clienti" + customer_details: "Dettagli Cliente" + customer_search: "Ricerca Clienti" choose_a_customer: "Scegli un cliente" account: "Account" billing_address: "Indirizzo di fatturazione" @@ -2782,10 +2806,18 @@ it: use_billing_address: "Utilizzare l'indirizzo di fatturazione" adjustments: "Regolazioni" continue: "Continua" - fill_in_customer_info: "Si prega di compilare le informazioni del cliente" + fill_in_customer_info: "Per favore compila le informazioni del cliente" new_payment: "Nuovo pagamento" capture: "Cattura" void: "vuoto" + login: "Login" + password: "Password" + signature: "Firma" + solution: "Soluzione" + landing_page: "Landing Page" + server: "Server" + test_mode: "Modalità di Test" + logourl: "Logourl" configurations: "Configurazioni" general_settings: "Impostazioni generali" site_name: "Nome del sito" @@ -2850,8 +2882,6 @@ it: abbreviation: "Abbreviazione" new_state: "Nuovo stato" payment_methods: "Metodi di pagamento" - new_payment_method: "Nuovo metodo di pagamento" - provider: "Provider" taxonomies: "Tassonomie" new_taxonomy: "Nuova tassonomia" back_to_taxonomies_list: "Torna all'elenco delle tassonomie" @@ -2929,7 +2959,7 @@ it: order_cycles: "Cicli di richieste" enterprises: "Aziende" enterprise_relationships: "permessi" - customers: "Consumatori" + customers: "Clienti" groups: "Gruppi" product_properties: index: @@ -3005,12 +3035,13 @@ it: completed_at: "Completo al" number: "Numero" state: "Stato" - email: "Mail consumatore" + email: "E-mail Cliente" invoice: issued_on: "Emesso il" tax_invoice: "FATTURA DELLE TASSE" code: "Codice" from: "Da" + to: "Pagamento a" shipping: "Spedizione" form: distribution_fields: @@ -3030,7 +3061,7 @@ it: other: "Hai il %{count} di prodotti disponibili" order_cycles: order_cycles: "Cicli di richieste" - order_cycles_tip: "I cicli di richieste determinano dove e quando i tuoi prodotti sono disponibili per i consumatori." + order_cycles_tip: "I cicli di richieste determinano dove e quando i tuoi prodotti sono disponibili per i clienti." you_have_active: zero: "Non hai nessun ciclo di richieste attivo." one: "Hai un ciclo di richieste attivo." @@ -3045,6 +3076,8 @@ it: zone: "Zone" calculator: "Calcolatrice" display: "Visualizza" + both: "Entrambi Checkout e Back office" + back_end: "Solo Back office" no_shipping_methods_found: "Nessun metodo di spedizione trovato" new: new_shipping_method: "Nuovo metodo di spedizione" @@ -3056,11 +3089,30 @@ it: form: categories: "categorie" zones: "Zone" + both: "Entrambi Checkout e Back Office" + back_end: "Solo Back office" + deactivation_warning: "Disattivare un metodo di spedizione può far sparire il metodo di spedizione dalla tua lista. Alternativamente, puoi nascondere il metodo di spedizione dalla pagina di checkout impostando l'opzione 'Visualizza' su 'Solo Back office'." payment_methods: + index: + payment_methods: "Metodi di pagamento" + new_payment_method: "Nuovo metodo di pagamento" + name: "Nome" + products_distributor: "Distributore" + provider: "Provider" + environment: "Ambiente" + display: "Visualizza" + active: "Attivo" + both: "Entrambi" + front_end: "Solo checkout" + back_end: "Solo Back office" + active_yes: "Sì" + active_no: "No" + no_payment_methods_found: "Nessun metodo di pagamento trovato" new: new_payment_method: "Nuovo metodo di pagamento" back_to_payment_methods_list: "Torna all'elenco dei metodi di pagamento" edit: + new: "Nuovo" editing_payment_method: "Modifica metodo di pagamento" back_to_payment_methods_list: "Torna all'elenco dei metodi di pagamento" stripe_connect: @@ -3076,6 +3128,21 @@ it: account_id: Account ID business_name: Ragione sociale charges_enabled: Cambi Consentiti + form: + name: "Nome" + description: "Descrizione" + environment: "Ambiente" + display: "Visualizza" + active: "Attivo" + active_yes: "Sì" + active_no: "No" + both: "Entrambi Checkout e Back Office" + front_end: "Solo checkout" + back_end: "Solo Back office" + tags: "Tag" + deactivation_warning: "Disattivare un metodo di pagamento può far sparire il metodo di pagamento dalla tua lista. Alternativamente, puoi nascondere il metodo di pagamento dalla pagina di checkout impostando l'opzione 'Visualizza' su 'Solo Back office'." + providers: + provider: "Provider" payments: source_forms: stripe: @@ -3133,7 +3200,7 @@ it: bulk_coop_supplier_report: 'Totali per fornitore - tabella' bulk_coop_allocation: 'Assegnazione - tabella' bulk_coop_packing_sheets: 'Imballaggio - tabella' - bulk_coop_customer_payments: 'Pagamenti clienti - tabella' + bulk_coop_customer_payments: 'Bulk Co-op - Pagamenti Clienti' users: index: listing_users: "Elenco Utenti" @@ -3175,7 +3242,10 @@ it: price: "Prezzo" display_as: "Visualizza come" display_name: "Nome da visualizzare" + display_as_placeholder: 'es. 2 kg' + display_name_placeholder: 'es. Pomodori' autocomplete: + out_of_stock: "Esaurito" producer_name: "Produttore" unit: "Unità" shared: @@ -3213,6 +3283,7 @@ it: format: '%Y-%m-%d' js_format: 'aa-mm-gg' orders: + error_flash_for_unavailable_items: "Un oggetto nel tuo carrello è diventato non disponibile, Per favore aggiorna le quantità selezionate." edit: login_to_view_order: "Effettua il login per visualizzare il tuo ordine." bought: @@ -3240,9 +3311,14 @@ it: invalid: invalido order_mailer: cancel_email: - customer_greeting: "Ciao %{name}!" - instructions: "Il tuo ordine è stato ANNULLATO. Per favore conserva queste informazioni di cancellazione per i tuoi record." - order_summary_canceled: "Riepilogo dell'ordine [CANCELLATO]" + customer_greeting: "Caro %{name}," + instructions_html: "Il tuo ordine con %{distributor} è stato CANCELLATO. Per favore conserva questa informazione per i tuoi dati." + dont_cancel: "Se hai cambiato idea o non desideri annullare questo ordine, ti preghiamo di contattare%{email}" + order_summary_canceled_html: "Riepilogo Ordine #%{number} [CANCELLATO]" + details: "Qui ci sono i dettagli di quello che hai ordinato:" + unpaid_order: "Il tuo ordine risulta pendente nessun rimborso è stato eseguito" + paid_order: "Il tuo ordine era già stato pagato così %{distributor} ha rimborsato l'intero costo" + credit_order: "Il tuo ordine è stato pagato, quindi il tuo acconto è stato accreditato" subject: "Cancellazione dell'ordine" confirm_email: subject: "Conferma dell'ordine" diff --git a/config/locales/nb.yml b/config/locales/nb.yml index f8a72d5423..f25465f87e 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -368,7 +368,6 @@ nb: title: "Matomo Innstillinger" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo er en web- og mobilanalyse. Du kan enten hoste Matomo selv eller bruke en skytjeneste. Se matomo.org for mer informasjon." config_instructions_html: "Her kan du konfigurere OFN-Matomo integrasjonen. URL til Matomo nedenfor skal peke på Matomo-instansen der brukersporingsinformasjonen skal sendes til; Hvis den er tom, blir Matomo-brukersporing deaktivert. Site-ID feltet er ikke obligatorisk, men nyttig hvis du sporer mer enn ett nettsted på en enkelt Matomo-instans; den kan bli funnet på Matomo-konsollen." customers: index: @@ -403,6 +402,7 @@ nb: footer_and_external_links: Footer og eksterne lenker your_content: Ditt innhold user_guide: Brukermanual + map: Kart enterprise_fees: index: title: "Bedriftsavgifter" @@ -2788,6 +2788,8 @@ nb: new_payment: "Ny betaling" capture: "Fang" void: "Ugyldig" + login: "Logg inn" + password: "Passord" configurations: "Konfigurasjoner" general_settings: "Generelle innstillinger" site_name: "Sidenavn" @@ -2852,8 +2854,6 @@ nb: abbreviation: "Forkortelse" new_state: "Ny Region" payment_methods: "Betalingsmetoder" - new_payment_method: "Ny Betalingsmetode" - provider: "Tilbyder" taxonomies: "Taksonomier" new_taxonomy: "Ny Taksonomi" back_to_taxonomies_list: "Tilbake til Taksonomiliste" @@ -3060,10 +3060,23 @@ nb: categories: "Kategorier" zones: "Soner" payment_methods: + index: + payment_methods: "Betalingsmetoder" + new_payment_method: "Ny Betalingsmetode" + name: "Navn" + products_distributor: "Distributør" + provider: "Tilbyder" + environment: "Miljø" + display: "Visning" + active: "Aktiv" + both: "Begge" + active_yes: "Ja" + active_no: "Nei" new: new_payment_method: "Ny Betalingsmetode" back_to_payment_methods_list: "Tilbake til listen over betalingsmetoder" edit: + new: "Ny" editing_payment_method: "Redigerer betalingsmetode" back_to_payment_methods_list: "Tilbake til listen over betalingsmetoder" stripe_connect: @@ -3079,6 +3092,17 @@ nb: account_id: Konto-ID business_name: Bedriftsnavn charges_enabled: Avgifter Aktivert + form: + name: "Navn" + description: "Beskrivelse" + environment: "Miljø" + display: "Visning" + active: "Aktiv" + active_yes: "Ja" + active_no: "Nei" + tags: "Merkelapper" + providers: + provider: "Tilbyder" payments: source_forms: stripe: @@ -3181,6 +3205,7 @@ nb: display_as_placeholder: 'f.eks. 2 kg' display_name_placeholder: 'f.eks. Tomater' autocomplete: + out_of_stock: "Ikke på Lager" producer_name: "Produsent" unit: "Enhet" shared: @@ -3245,9 +3270,6 @@ nb: invalid: ugyldig order_mailer: cancel_email: - customer_greeting: "Hei %{name}!" - instructions: "Din bestilling har blitt avbrutt. Vennligst behold denne avbestillingsinformasjonen som referanse." - order_summary_canceled: "Bestillingssammendrag [KANSELLERT]" subject: "Kansellering av bestilling" confirm_email: subject: "Ordrebekreftelse" diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml index d17754b707..952d7a5579 100644 --- a/config/locales/nl_BE.yml +++ b/config/locales/nl_BE.yml @@ -354,7 +354,6 @@ nl_BE: title: "Matomo instellingen" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo is een Web en Mobile Analytics. U kunt Matomo on-premises hosten of gebruik maken van een cloud-hosted service. Zie matomo.org voor meer informatie." config_instructions_html: "Hier kunt u de OFN Matomo integratie configureren. De Matomo URL hieronder zou moeten verwijzen naar de Matomo instantie waar de gebruiker tracking informatie naartoe wordt gestuurd; als deze leeg wordt gelaten, wordt Matomo gebruiker tracking uitgeschakeld. Het veld Site ID is niet verplicht, maar handig als je meer dan één website volgt op één Matomo instance; het is te vinden op de Matomo instance console. Vertaald met www.DeepL.com/Translator" customers: index: @@ -389,6 +388,7 @@ nl_BE: footer_and_external_links: Voettekst en externe links your_content: Uw inhoud user_guide: Gebruikershandleiding + map: Kaart enterprise_fees: index: title: "Ondernemingsvergoedingen" @@ -2667,6 +2667,8 @@ nl_BE: new_payment: "Nieuwe betaling" capture: "Capture" void: "leegte" + login: "Log in" + password: "Wachtwoord" configurations: "configuraties " general_settings: "Algemene instellingen" site_name: "Website Naam" @@ -2731,8 +2733,6 @@ nl_BE: abbreviation: "Afkortingen " new_state: "Nieuw Provincie" payment_methods: "Betalingsmethode" - new_payment_method: "Nieuwe betalingswijze" - provider: "Leverancier" taxonomies: "Taxonomies " new_taxonomy: "Nieuwe taxonomie " back_to_taxonomies_list: "Terug naar de lijst Taxonomies" @@ -2897,10 +2897,23 @@ nl_BE: categories: "Categorieën" zones: "Zones " payment_methods: + index: + payment_methods: "Betalingsmethode" + new_payment_method: "Nieuwe betalingswijze" + name: "Naam" + products_distributor: "Distributeur" + provider: "Leverancier" + environment: "Omgeving" + display: "Display" + active: "Aktief" + both: "Beide" + active_yes: "Ya" + active_no: "Néé" new: new_payment_method: "Nieuwe betalingswijze" back_to_payment_methods_list: "Terug naar de lijst van de betalingswijzes" edit: + new: "Nieuw" editing_payment_method: "Wijziging van de betalingswijze" back_to_payment_methods_list: "Terug naar de lijst van de betalingswijzes" stripe_connect: @@ -2916,6 +2929,17 @@ nl_BE: account_id: Account ID business_name: Bedrijfsnaam charges_enabled: Kosten ingeschakeld + form: + name: "Naam" + description: "Beschrijving" + environment: "Omgeving" + display: "Display" + active: "Aktief" + active_yes: "Ya" + active_no: "Néé" + tags: "Tags" + providers: + provider: "Leverancier" payments: source_forms: stripe: @@ -3005,6 +3029,7 @@ nl_BE: price: "Prijs" display_as: "Weergeven als" autocomplete: + out_of_stock: "Geen voorraad" producer_name: "Producent" unit: "Unit" shared: @@ -3069,9 +3094,6 @@ nl_BE: invalid: fout order_mailer: cancel_email: - customer_greeting: "Hello%{name}!" - instructions: "Uw bestelling is GEANNULEERD. Bewaar deze annuleringsinformatie voor uw administratie." - order_summary_canceled: "Overzicht van de bestelling [KANNELD]" subject: "Annulering van de bestelling" confirm_email: subject: "Bestellingsinformatie" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 2b46b8d146..1e8b8f7efe 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -347,7 +347,6 @@ pt: title: "Configurações Matomo" matomo_url: "URL Matomo" matomo_site_id: "Site ID Matomo" - info_html: "Matomo é uma ferramenta de análise web e mobile. Pode instalar o Matomo no seu servidor ou utilizar um serviço na cloud. Veja matomo.org para mais informações." config_instructions_html: "Aqui pode configurar a integração com Matomo. O URL Matomo em baixo deve apontar para o serviror para onde a informação de tracking de utilizadores será enviada; se deixado vazio, o tracking de utilizadores através do Matomo ficará desactivado. O campo Site ID não é obrigatório mas útil se estive a fazer tracking de mais do que um website numa instância única do Matomo; pode ser encontrado na consola da instância Matomo." customers: index: @@ -382,6 +381,7 @@ pt: footer_and_external_links: Rodapé e Ligações Externas your_content: O seu conteúdo user_guide: Manual do Utilizador + map: Mapa enterprise_fees: index: title: "Taxas de Organização" @@ -2623,6 +2623,8 @@ pt: fill_in_customer_info: "Por favor preencha informação do/a consumidor/a" new_payment: "Novo Pagamento" capture: "Capturar" + login: "Entrar" + password: "Palavra-passe" configurations: "Configurações" general_settings: "Configurações Gerais" site_name: "Nome do Site" @@ -2687,8 +2689,6 @@ pt: abbreviation: "Abreviatura" new_state: "Nova Região" payment_methods: "Métodos de pagamento" - new_payment_method: "Novo Método de Pagamento" - provider: "Fornecedor" taxonomies: "Taxonomias" new_taxonomy: "Nova Taxonomia" back_to_taxonomies_list: "Voltar à Lista de Taxonomias" @@ -2837,10 +2837,22 @@ pt: form: zones: "Zonas" payment_methods: + index: + payment_methods: "Métodos de pagamento" + new_payment_method: "Novo Método de Pagamento" + name: "Nome" + products_distributor: "Distribuidor" + provider: "Fornecedor" + environment: "Ambiente" + display: "Mostrar" + active: "Ativo" + active_yes: "Sim" + active_no: "Não" new: new_payment_method: "Novo Método de Pagamento" back_to_payment_methods_list: "Voltar à Lista de Métodos de Pagamento" edit: + new: "Novo" editing_payment_method: "Editar Método de Pagamento" back_to_payment_methods_list: "Voltar à Lista de Métodos de Pagamento" stripe_connect: @@ -2856,6 +2868,17 @@ pt: account_id: ID de Conta business_name: Nome do Negócio charges_enabled: Taxas activas + form: + name: "Nome" + description: "Descrição" + environment: "Ambiente" + display: "Mostrar" + active: "Ativo" + active_yes: "Sim" + active_no: "Não" + tags: "Etiquetas" + providers: + provider: "Fornecedor" payments: source_forms: stripe: @@ -2943,6 +2966,7 @@ pt: price: "Preço" display_as: "Mostrar como" autocomplete: + out_of_stock: "Sem Stock" producer_name: "Produtor" unit: "Unidade" shared: @@ -3007,9 +3031,6 @@ pt: invalid: inválido order_mailer: cancel_email: - customer_greeting: "Olá %{name}!" - instructions: "A sua encomenda foi cancelada. Para seu registo, por favor guarde esta informação de cancelamento." - order_summary_canceled: "Sumário de Encomenda [CANCELADA]" subject: "Cancelamento de Encomenda" confirm_email: subject: "Confimação de Encomenda" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 718dd700c5..3c2ac7d748 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -53,7 +53,7 @@ pt_BR: producer_ids: "Produtores" order_cycle_ids: "Ciclos de pedidos" enterprise_fee_ids: "Nomes das taxas" - shipping_method_ids: "Métodos de envio" + shipping_method_ids: "Método de Envio" payment_method_ids: "Métodos de pagamento" errors: messages: @@ -204,7 +204,7 @@ pt_BR: ongoing: Em progresso bill_address: Endereço de Cobrança ship_address: Endereço de Entrega - sort_order_cycles_on_shopfront_by: "Ordenar Ciclo de Pedidos na Loja Virtual Por" + sort_order_cycles_on_shopfront_by: "Ordenar Ciclos de Pedidos na Loja Virtual Por" required_fields: Campos obrigatórios são indicados com um asterisco select_continue: Selecionar e continuar remove: Remover @@ -219,7 +219,7 @@ pt_BR: edit: Editar clone: Cópia distributors: Distribuidores - bulk_order_management: Gerenciamento de Pedidos em Atacado + bulk_order_management: Gestão de Pedidos em Atacado enterprises: Iniciativas enterprise_groups: Grupos reports: Relatórios @@ -303,7 +303,7 @@ pt_BR: shop: Loja sku: SKU status_state: Estado - tags: Etiqueta + tags: Tags variant: Variante weight: Peso volume: Tamanho @@ -329,7 +329,7 @@ pt_BR: viewing: "Visualizando: %{current_view_name}" description: Descrição whats_this: O que é isso? - tag_has_rules: "Regras existentes para essa etiqueta: %{num}" + tag_has_rules: "Regras existentes para essa tag: %{num}" has_one_rule: "possui uma regra" has_n_rules: "tem %{num} regras" unsaved_confirm_leave: "Existem alterações não salvas nesta página. Continuar sem salvar? " @@ -368,7 +368,6 @@ pt_BR: title: "Configurações do Matomo" matomo_url: "Matomo URL" matomo_site_id: "Matomo Site ID" - info_html: "Matomo é uma Web e Mobile Analytics. Você pode hospedar o Matomo localmente ou usar um serviço hospedado na nuvem. Veja matomo.org para mais informações." config_instructions_html: "Aqui você pode configurar a integração do OFN Matomo. O URL do Matomo abaixo deve apontar para a instância do Matomo para onde as informações de rastreamento do usuário serão enviadas; se for deixado em branco, o rastreamento de usuários do Matomo será desativado. O campo ID do site não é obrigatório, mas é útil se você estiver controlando mais de um site em uma única instância do Matomo. ele pode ser encontrado no console da instância Matomo." customers: index: @@ -403,6 +402,7 @@ pt_BR: footer_and_external_links: Rodapé e links externos your_content: Seu conteúdo user_guide: Guia do Usuário + map: Mapa enterprise_fees: index: title: "Taxas da iniciativa" @@ -450,7 +450,7 @@ pt_BR: editing_product: "Editando Produto" tabs: product_details: "Detalhes do Produto" - group_buy_options: "Opções de Grupo de Compras" + group_buy_options: "Opções de Compra em Grupo" images: "Imagens" variants: "Variantes" product_properties: "Propriedades do produto" @@ -583,18 +583,18 @@ pt_BR: order_no: "Pedido nº" order_date: "Concluído em" max: "Máximo" - product_unit: "Produto: unidade" + product_unit: "Produto: Unidade" weight_volume: "Peso/Volume" ask: "Perguntar?" - page_title: "Gestão de Pedidos em Atacado" + page_title: "Gestão de Pedidos em Atacado" actions_delete: "Deletar selecionado" loading: "Carregando pedidos" no_results: "Nenhum pedido encontrado. " - group_buy_unit_size: "Unidade de Medida para Grupo de Compras" + group_buy_unit_size: "Unidade de Medida para Compra em Grupo" total_qtt_ordered: "Quantidade total do pedido" max_qtt_ordered: "Quantidade máxima do pedido" - current_fulfilled_units: "Unidades completadas no momento" - max_fulfilled_units: "Máximo de unidades completadas " + current_fulfilled_units: "Pedidos / Limite Mínimo (Atual)" + max_fulfilled_units: "Pedidos / Limite Mínimo (Max)" order_error: "Alguns erros devem ser corrigidos antes de atualizar os pedidos.\nOs campos com bordas vermelhas contém erros." variants_without_unit_value: "AVISO: Algumas variantes não possuem unidade de medida" select_variant: "Selecione uma variante" @@ -687,22 +687,22 @@ pt_BR: shipping_methods: name: "Nome" applies: "Ativo?" - manage: "Gerenciar formas de envio" + manage: "Gerenciar métodos de envio" create_button: "Criar nova forma de envio" create_one_button: "Criar um agora" - no_method_yet: "Você ainda não tem nenhuma forma de envio." + no_method_yet: "Você ainda não tem nenhum método de envio." shop_preferences: - shopfront_requires_login: "Loja virtual visível publicamente?" + shopfront_requires_login: "Loja virtual visível ao público?" shopfront_requires_login_tip: "Escolha se os clientes precisarão fazer o login para ver os produtos da loja virtual, ou se eles estarão visíveis para todos." shopfront_requires_login_false: "Publico" shopfront_requires_login_true: "Disponível somente para clientes registrados" recommend_require_login: "Recomendamos pedir login dos usuários quando permitido que pedidos possam ser alterados." - allow_guest_orders: "Pedidos dos convidados" + allow_guest_orders: "Pedidos de convidados" allow_guest_orders_tip: "Permitir o checkout como convidado, ou requisitar um usuário registrado. " allow_guest_orders_false: "Requisitar o login para fazer pedidos" allow_guest_orders_true: "Permitir checkout de convidados" allow_order_changes: "Mudar pedidos" - allow_order_changes_tip: "Permitir que os consumidores mudem seus pedidos enquanto a compra estiver aberta." + allow_order_changes_tip: "Permitir que os consumidores mudem seus pedidos enquanto o ciclo de pedidos estiver aberto." allow_order_changes_false: "Pedidos enviados não podem ser mudados ou cancelados." allow_order_changes_true: "Consumidor pode mudar ou cancelar pedidos enquanto a compra estiver aberta." enable_subscriptions: "Assinaturas" @@ -721,7 +721,7 @@ pt_BR: Uma mensagem que forneça uma explicação detalhada sobre o porque de a loja estar fechada e quando os consumidores podem esperar que abra novamente, a ser exibida quando não houver nenhum ciclo de pedidos ativo. - shopfront_category_ordering: "Organização das Categorias da Loja Virtual" + shopfront_category_ordering: "Organização da Loja Virtual por Categorias" open_date: "Dia de abertura" close_date: "Dia de fechamento" social: @@ -746,11 +746,11 @@ pt_BR: by_default: Por padrão no_rules_yet: Ainda não existe nenhuma regra padrão add_new_button: '+ Adicionar nova regra padrão' - no_tags_yet: Nenhuma etiqueta foi aplicada a esta iniciativa - no_rules_yet: Nenhuma regra foi aplicada a essa etiqueta + no_tags_yet: Nenhuma tag foi aplicada a esta iniciativa + no_rules_yet: Nenhuma regra foi aplicada a essa tag for_customers_tagged: 'Para consumidores marcados:' add_new_rule: '+ Adicionar nova regra' - add_new_tag: '+ Adicionar nova etiqueta' + add_new_tag: '+ Adicionar nova tag' users: email_confirmation_notice_html: "Confirmação de e-mail está pendente. Enviamos um e-mail de confirmação para %{email}." resend: Reenviar @@ -774,8 +774,8 @@ pt_BR: properties: Propriedades payment_methods: Formas de pagamento payment_methods_tip: Essa iniciativa não tem formas de pagamento - shipping_methods: Formas de entrega - shipping_methods_tip: Essa iniciativa não tem formas de entrega + shipping_methods: Métodos de envio + shipping_methods_tip: Essa iniciativa não tem métodos de envio enterprise_fees: Taxas da iniciativa enterprise_fees_tip: Essa iniciativa não tem taxas admin_index: @@ -875,7 +875,7 @@ pt_BR: outgoing: "Saída" distributor: "Distribuidor" products: "Produtos" - tags: "Etiqueta" + tags: "Tag" delivery_details: "Sobre a Entrega" fees: "Taxas" previous: "Anterior" @@ -921,8 +921,8 @@ pt_BR: outgoing: Saída distributor: Distribuidor products: Produtos - tags: Etiquetas - add_a_tag: Adicionar etiqueta + tags: Tags + add_a_tag: Adicionar tag delivery_details: Detalhes de entrega/retirada index: schedule: Cronograma @@ -948,7 +948,7 @@ pt_BR: orders_present: Esse ciclo de pedidos foi selecionado por um cliente e não pode ser excluído. Para impedir que os clientes acessem, feche-o. schedule_present: Esse ciclo de pedidos está vinculado a um cronograma e não pode ser excluído. Desvincule ou exclua o cronograma primeiro. bulk_update: - no_data: Hum, algo deu errado. Não foram encontrados dados do ciclo do pedido. + no_data: Hum, algo deu errado. Não foram encontrados dados do ciclo do pedidos. date_warning: msg: Esse ciclo de pedidos está vinculado a %{n}de pedidos abertos. Alterar essa data agora não afetará nenhum pedido que já tenha sido feito, mas deve ser evitado, se possível. Tem certeza de que deseja continuar? cancel: Cancelar @@ -1080,7 +1080,7 @@ pt_BR: details: Detalhes address: Endereço products: Produtos - no_open_or_upcoming_order_cycle: "Nenhum ciclo de pedido futuro" + no_open_or_upcoming_order_cycle: "Nenhum ciclo de pedidos agendado" products_panel: save: "SALVAR" saving: "SALVANDO" @@ -1145,7 +1145,7 @@ pt_BR: cart: "Carrinho" joyride: checkout: "Fechar pedido agora" - already_ordered_products: "Já pediu neste ciclo de pedido" + already_ordered_products: "Já pediu neste ciclo de pedidos" register_call: selling_on_ofn: "Interessado em registrar a sua iniciativa na Open Food Brasil?" register: "Registre-se aqui" @@ -1248,7 +1248,7 @@ pt_BR: city_placeholder: 'ex: República' postcode: CEP postcode_placeholder: 'ex: 05429-130' - suburb: Bairro + suburb: Cidade state: Estado country: País unauthorized: Não autorizado @@ -1688,11 +1688,11 @@ pt_BR: products_cart_distributor_change: "O distribuidor para este pedido será trocado para %{name} se você adicionar este produto no carrinho." products_cart_distributor_is: "O distribuidor para este pedido é %{name}." products_distributor_error: "Por favor complete seu pedido no %{link} antes de comprar com outro distribuidor." - products_oc: "Ciclo de pedido para seu pedido:" - products_oc_change: "O ciclo de pedido para esse pedido será trocada para %{name} se você adicionar este produto ao carrinho." - products_oc_is: "O ciclo de pedido para este pedido é %{name}." + products_oc: "Ciclo de pedidos para seu pedido:" + products_oc_change: "O ciclo de pedidos para esse pedido será trocado para %{name} se você adicionar este produto ao carrinho." + products_oc_is: "O ciclo de pedidos para este pedido é %{name}." products_oc_error: "Por favor complete seu pedido no %{link} antes de comprar em outro ciclo de pedido." - products_oc_current: "seu ciclo de pedido atual" + products_oc_current: "seu ciclo de pedidos atual" products_max_quantity: Quantidade máxima products_distributor: Distribuidor products_distributor_info: Quando você selecionar um distribuidor para seu pedido, o endereço e data para retirada serão exibidos aqui. @@ -1927,7 +1927,7 @@ pt_BR: admin_enterprise_groups_contact: "Contato" admin_enterprise_groups_contact_phone_placeholder: "ex: 987654321" admin_enterprise_groups_contact_address1_placeholder: "ex: Rua Alta, 123" - admin_enterprise_groups_contact_city: "Bairro" + admin_enterprise_groups_contact_city: "Cidade" admin_enterprise_groups_contact_city_placeholder: "ex: República" admin_enterprise_groups_contact_zipcode: "CEP" admin_enterprise_groups_contact_zipcode_placeholder: "ex: 02341-001" @@ -1961,8 +1961,8 @@ pt_BR: flat_rate_per_order: "Taxa fixa ( por pedido)" flexible_rate: "Tarifa flexível" price_sack: "Preço da saca" - new_order_cycles: "Novo ciclo de pedidos" - new_order_cycle: "Novo ciclo de pedido" + new_order_cycles: "Novos ciclos de pedidos" + new_order_cycle: "Novo ciclo de pedidos" select_a_coordinator_for_your_order_cycle: "Selecione um coordenador para o seu ciclo de pedidos" notify_producers: 'Notificar produtores' edit_order_cycle: "Editar ciclo de pedidos" @@ -1992,7 +1992,7 @@ pt_BR: spree_admin_overview_enterprises_footer: "GERENCIAR MINHAS INICIATIVAS" spree_admin_enterprises_hubs_name: "Nome" spree_admin_enterprises_create_new: "CRIAR NOVA" - spree_admin_enterprises_shipping_methods: "Métodos de entrega" + spree_admin_enterprises_shipping_methods: "Métodos de envio" spree_admin_enterprises_fees: "Taxas da iniciativa" spree_admin_enterprises_none_create_a_new_enterprise: "CRIAR NOVA INICIATIVA" spree_admin_enterprises_none_text: "Você ainda não possui nenhuma iniciativa" @@ -2016,7 +2016,7 @@ pt_BR: spree_admin_eg_pickup_from_school: "ex: 'Buscar na Escola'" spree_admin_eg_collect_your_order: "ex: 'Por favor, colete seu pedido na Rua dos Sonhos, 123, casa 5, Bairro Liberdade" spree_classification_primary_taxon_error: "O táxon %{taxon} é o táxon principal de %{product} e não pode ser excluído" - spree_order_availability_error: "O ciclo do distribuidor ou do pedido não pode fornecer os produtos no seu carrinho" + spree_order_availability_error: "O distribuidor ou o ciclo de pedidos não pode fornecer os produtos no seu carrinho" spree_order_populator_error: "Distribuidor ou ciclo de pedidos não pode fornecer os produtos no seu carrinho. Por favor, escolha outro." spree_order_populator_availability_error: "Esse produto não está disponível no distribuidor escolhido ou no ciclo de pedidos." spree_distributors_error: "Pelo menos uma central deve ser selecionado" @@ -2029,7 +2029,7 @@ pt_BR: manage: "Gerenciar" resend: "Re-enviar" add_and_manage_products: "Adicionar e gerenciar produtos" - add_and_manage_order_cycles: "Adicione e gerenciar ciclos de pedidos" + add_and_manage_order_cycles: "Adicionar e gerenciar ciclos de pedidos" manage_order_cycles: "Gerenciar ciclos de pedidos" manage_products: "Gerenciar produtos" edit_profile_details: "Editar detalhes de perfil " @@ -2085,7 +2085,7 @@ pt_BR: report_header_first_name: Nome report_header_last_name: Sobrenome report_header_phone: Telefone - report_header_suburb: Bairro + report_header_suburb: Cidade report_header_address: Endereço report_header_billing_address: Endereço de cobrança report_header_relationship: Relação @@ -2116,7 +2116,7 @@ pt_BR: report_header_order_number: Número do pedido report_header_date: Data report_header_confirmation_date: Data de Confirmação - report_header_tags: Etiqueta + report_header_tags: Tags report_header_items: Itens report_header_items_total: "Total de itens%{currency_symbol}" report_header_taxable_items_total: "Total de itens tributáveis ​​(%{currency_symbol})" @@ -2143,7 +2143,7 @@ pt_BR: report_header_producer: Produtor report_header_producer_suburb: Subúrbio do produtor report_header_unit: Unidade - report_header_group_buy_unit_quantity: Quantidade da Unidade para Grupo de Compras + report_header_group_buy_unit_quantity: Quantidade da Unidade para Compra em Grupo report_header_cost: Custo report_header_shipping_cost: ' Custo de envio' report_header_curr_cost_per_unit: Custo unitário atual @@ -2159,7 +2159,7 @@ pt_BR: report_header_distributor_postcode: CEP do distribuidor report_header_delivery_address: Endereço para entrega report_header_delivery_postcode: CEP para entrega - report_header_bulk_unit_size: Unidade de Medida para atacado + report_header_bulk_unit_size: Quantidade Mínima para Compra em Atacado report_header_weight: Peso report_header_sum_total: Soma total report_header_date_of_order: Data do pedido @@ -2337,18 +2337,18 @@ pt_BR: overview: Visão geral overview_text: > As regras de tag fornecem uma maneira para descrever quais itens são - visíveis ou não e para quais clientes, como formas de pagamento, formas + visíveis ou não e para quais clientes, como métodos de pagamento, método de entrega, produtos e ciclos de pedidos. by_default_rules: "Regras \"Padrão ...\"" by_default_rules_text: > As regras padrão permitem ocultar itens para que eles não estejam visíveis por padrão. Esse comportamento pode ser substituído por regras não padrão - para clientes com etiquetas específicas. + para clientes com tags específicas. customer_tagged_rules: "Regras de \"Clientes marcados ...\"" customer_tagged_rules_text: > - Ao criar regras relacionadas a uma etiqueta de cliente específica, você - pode substituir o comportamento padrão (seja para mostrar ou para ocultar - itens) para clientes com a etiqueta especificada. + Ao criar regras relacionadas a uma tag de cliente específica, você pode + substituir o comportamento padrão (seja para mostrar ou para ocultar + itens) para clientes com a tagespecificada. panels: save: SALVAR saved: SALVO @@ -2460,7 +2460,7 @@ pt_BR: payment_method_tagged_bottom: "são:" order_cycle_tagged_top: "Ciclos de pedidos marcados" order_cycle_tagged_bottom: "são:" - inventory_tagged_top: "Variantes de inventário marcadas" + inventory_tagged_top: "Variantes do inventário marcadas com tag" inventory_tagged_bottom: "são:" new_tag_rule_dialog: select_rule_type: "Selecione um tipo de regra:" @@ -2525,7 +2525,7 @@ pt_BR: updated_schedule: "Lista atualizada" deleted_schedule: "Lista excluída" name_required_error: "Digite um nome para esta lista" - no_order_cycles_error: "Selecione pelo menos um ciclo de pedido (arraste e solte)" + no_order_cycles_error: "Selecione pelo menos um ciclo de pedidos (arraste e solte)" available: "Disponível" selected: "Selecionado" customers: @@ -2589,9 +2589,9 @@ pt_BR: Isso ajustará o nível de estoque para zero em todos os produtos para esta iniciativa que não está presente no arquivo carregado. order_cycles: - create_failure: "Falha ao criar o ciclo do pedido" + create_failure: "Falha ao criar o ciclo do pedidos" update_success: 'O seu ciclo de pedidos foi atualizado.' - update_failure: "Falha ao atualizar o ciclo do pedido" + update_failure: "Falha ao atualizar o ciclo do pedidos" no_distributors: Não há distribuidores neste ciclo de pedidos. Este ciclo de pedidos não será visível para os clientes até você adicionar um. Você gostaria de continuar salvando esse ciclo de pedidos? enterprises: producer: "Produtor" @@ -2809,6 +2809,8 @@ pt_BR: new_payment: "Novo Pagamento" capture: "Capturar" void: "Vazio" + login: "Login" + password: "Senha" configurations: "Configurações" general_settings: "Configurações Gerais" site_name: "Nome do site" @@ -2873,8 +2875,6 @@ pt_BR: abbreviation: "Abreviação" new_state: "Estado novo" payment_methods: "Métodos de pagamento" - new_payment_method: "Novo método de pagamento" - provider: "Fornecedor" taxonomies: "Taxonomias" new_taxonomy: "Nova taxonomia" back_to_taxonomies_list: "Voltar à lista de taxonomias" @@ -2939,7 +2939,7 @@ pt_BR: tab: dashboard: "Painel" orders: "Encomendas" - bulk_order_management: "Gestão de Pedidos em Atacado" + bulk_order_management: "Gestão de Pedidos em Atacado" subscriptions: "Assinaturas" products: "Produtos" option_types: "Tipos de opção" @@ -3040,7 +3040,7 @@ pt_BR: distribution_fields: title: "Distribuição" distributor: "Distribuidor:" - order_cycle: "Ciclo de pedido:" + order_cycle: "Ciclo de pedidos:" line_item_adjustments: "Ajustes de itens de linha" order_adjustments: "Ajustes de Pedidos" order_total: "total de pedidos" @@ -3057,7 +3057,7 @@ pt_BR: order_cycles_tip: "Os ciclos de pedidos determinam quando e onde seus produtos estão disponíveis para os clientes." you_have_active: zero: "Você não possui ciclos de pedidos ativos." - one: "Você tem um ciclo de pedido ativo." + one: "Você tem um ciclo de pedidos ativo." other: "Você tem %{count} ciclos de pedidos ativos." manage_order_cycles: "GERENCIAR CICLOS DE PEDIDOS" shipping_methods: @@ -3069,6 +3069,8 @@ pt_BR: zone: "Zona" calculator: "Calculadora" display: "Exibição" + both: "Tanto Checkout quanto Área Administrativa" + back_end: "Somente Área Administrativa" no_shipping_methods_found: "Nenhum método de envio encontrado" new: new_shipping_method: "Novo método de envio" @@ -3080,12 +3082,26 @@ pt_BR: form: categories: "Categorias" zones: "Zonas" + both: "Tanto Checkout quanto Área Administrativa" + back_end: "Somente Área Administrativa" deactivation_warning: "Desativar um método de envio pode fazer com que ele desapareça da sua lista. Como alternativa, você pode esconder um método de envio da página de checkout s" payment_methods: + index: + payment_methods: "Métodos de pagamento" + new_payment_method: "Novo método de pagamento" + name: "Nome" + products_distributor: "Distribuidor" + environment: "Ambiente" + display: "Exibição" + both: "Ambos" + back_end: "Somente Área Administrativa" + active_yes: "Sim" + active_no: "Não" new: new_payment_method: "Novo método de pagamento" back_to_payment_methods_list: "Voltar à lista de formas de pagamento" edit: + new: "Novo" editing_payment_method: "Editando método de pagamento" back_to_payment_methods_list: "Voltar à lista de formas de pagamento" stripe_connect: @@ -3101,6 +3117,16 @@ pt_BR: account_id: ID da conta business_name: Nome da iniciativa/negócio charges_enabled: Taxas habilitadas + form: + name: "Nome" + description: "Descrição" + environment: "Ambiente" + display: "Exibição" + active_yes: "Sim" + active_no: "Não" + both: "Tanto Checkout quanto Área Administrativa" + back_end: "Somente Área Administrativa" + tags: "Tags" payments: source_forms: stripe: @@ -3147,8 +3173,8 @@ pt_BR: primary_taxon_form: product_category: Categoria de Produto group_buy_form: - group_buy: "Grupo de Compras?" - bulk_unit_size: Tamanho da unidade em massa + group_buy: "Compra em Grupo?" + bulk_unit_size: Quantidade Mínima para Compra em Atacado display_as: display_as: Mostrar como reports: @@ -3203,6 +3229,7 @@ pt_BR: display_as_placeholder: 'ex. 2 kg' display_name_placeholder: 'ex. Tomates' autocomplete: + out_of_stock: "Sem estoque" producer_name: "Produtor" unit: "Unidade" shared: @@ -3240,10 +3267,11 @@ pt_BR: format: '%A-%m-' js_format: 'aa-mm-dd' orders: + error_flash_for_unavailable_items: "Um item no seu carrinho ficou indisponível. Por favor atualize as quantidades selecionadas. " edit: login_to_view_order: "Faça o login para visualizar seu pedido." bought: - item: "Já pediu neste ciclo de pedido" + item: "Já pediu neste ciclo de pedidos" line_item: insufficient_stock: "Estoque disponível insuficiente, apenas %{on_hand} restante" out_of_stock: "Fora de estoque" @@ -3267,9 +3295,6 @@ pt_BR: invalid: inváliod order_mailer: cancel_email: - customer_greeting: "Oi %{name}!" - instructions: "Seu pedido foi CANCELADO. Guarde essas informações de cancelamento para seus registros." - order_summary_canceled: "Resumo do pedido [CANCELADO]" subject: "Cancelamento do Pedido" confirm_email: subject: "Confimação de Pedido" diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 8bb42e8411..600a91ef7f 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -194,6 +194,7 @@ sv: footer_and_external_links: Sidfot och externa länkar your_content: Ditt innehåll user_guide: Användarinstruktion + map: Karta enterprise_fees: index: title: "Företagsavgifter" @@ -1905,6 +1906,8 @@ sv: update: "Uppdatera" continue: "Fortsätt" capture: "Fånga" + login: "Logga in" + password: "Lösenord" tax rate: "Skattesatser" tax_category: "Skattekategori" tax_settings: "Skatteskalor" @@ -1996,6 +1999,19 @@ sv: name: "Namn" products_distributor: "Distributör" calculator: "Beräkning" + payment_methods: + index: + payment_methods: "Betalningssätt" + name: "Namn" + products_distributor: "Distributör" + active_yes: "Ja" + active_no: "Nej" + form: + name: "Namn" + description: "Beskrivning" + active_yes: "Ja" + active_no: "Nej" + tags: "Taggar" products: new: supplier: "Leverantör" diff --git a/config/locales/tr.yml b/config/locales/tr.yml index f850080a53..825fab2b41 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -182,7 +182,7 @@ tr: title: Açık Gıda Ağı welcome_to: 'Hoşgeldiniz' site_meta_description: "Açık Gıda Ağı, bağımsız, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Kar amacı gütmez, toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." - search_by_name: İsim veya konuma göre arama yapın... + search_by_name: Üretici adına veya konuma göre arama yapın... producers_join: Temiz gıda üreticileri! Açık Gıda Ağı sizler için kullanıma açıldı. charges_sales_tax: KDV Uyguluyor mu? print_invoice: "Faturayı yazdır" @@ -368,7 +368,6 @@ tr: title: "Matomo Ayarları" matomo_url: "Matomo URL'si" matomo_site_id: "Matomo Site Kimliği" - info_html: "Matomo bir Web ve Mobil Analitik programıdır. Matomo'yu şirket içinde kullanabilir veya bulutta saklanan bir hizmet olarak kullanabilirsiniz. Daha fazla bilgi için matomo.org adresini ziyaret edin." config_instructions_html: "Burada OFN Matomo entegrasyonunu yapılandırabilirsiniz. Aşağıdaki Matomo URL'si, kullanıcı izleme bilgilerinin gönderileceği Matomo örneğini göstermelidir; boş bırakılırsa Matomo kullanıcı takibi devre dışı bırakılır. Site Kimliği alanı zorunlu değildir, ancak tek bir Matomo örneğinde birden fazla web sitesini izliyorsanız yararlıdır; Matomo örnek konsolunda bulunabilir." customers: index: @@ -387,7 +386,7 @@ tr: edit: 'Düzenle' update_address: 'Adresi Güncelle' confirm_delete: 'Silmek istediğinizden emin misiniz?' - search_by_email: "E-posta / kod ile arama ..." + search_by_email: "E-posta/kod ile arama ..." guest_label: 'Misafir Ödemesi' destroy: has_associated_orders: 'Silme başarısız oldu: müşterinin bağlantılı siparişleri var' @@ -403,6 +402,7 @@ tr: footer_and_external_links: Altbilgi ve Dış Bağlantılar your_content: İçeriğiniz user_guide: Kullanici Kılavuzu + map: HARİTA enterprise_fees: index: title: "İşletme Ücretleri" @@ -612,7 +612,7 @@ tr: about_us: desc_short: Kısa Açıklama desc_short_placeholder: Bir veya iki cümleyle bize işletmenizden bahsedin - desc_long: Hakkımızda + desc_long: HAKKIMIZDA desc_long_placeholder: Müşterilerinize kendinizden bahsedin. Bu bilgiler profilinizde görünür. business_details: abn: VKN/TCKN @@ -686,12 +686,13 @@ tr: ofn_uid_tip: Açık Gıda Ağı'na kayıtlı işletmenize özel tanımlanan kimlik numarası shipping_methods: name: "Ad" + applies: "Aktif?" manage: "Teslimat Yöntemlerini Yönet" create_button: "Yeni Teslimat Yöntemi Oluştur" create_one_button: "Şimdi Oluştur" no_method_yet: "Henüz herhangi bir teslimat yönteminiz yok." shop_preferences: - shopfront_requires_login: "MAĞAZANIZ HARİTADA GÖRÜNÜR OLSUN MU?" + shopfront_requires_login: "MAĞAZANIZ HERKESE AÇIK MI?" shopfront_requires_login_tip: "Mağazanızın yalnızca üyelerinize mi yoksa herkese mi açık olduğunu seçin." shopfront_requires_login_false: "Herkese açık" shopfront_requires_login_true: "Yalnızca kayıtlı müşteriler tarafından görülebilir" @@ -702,8 +703,8 @@ tr: allow_guest_orders_true: "Misafir alışverişine izin ver" allow_order_changes: "Siparişleri düzenle" allow_order_changes_tip: "Sipariş dönemi açık olduğu sürece müşterilerin siparişlerini düzenlemelerine izin verin." - allow_order_changes_false: "Oluşturulan siparişler değiştirilemez / iptal edilemez" - allow_order_changes_true: "Müşteriler sipariş dönemi açıkken siparişleri değiştirebilir / iptal edebilir" + allow_order_changes_false: "Oluşturulan siparişler değiştirilemez/iptal edilemez" + allow_order_changes_true: "Müşteriler sipariş dönemi açıkken siparişleri değiştirebilir/iptal edebilir" enable_subscriptions: "Üyelikler" enable_subscriptions_tip: "Üyelik işlevselliği etkinleştirilsin mi?" enable_subscriptions_false: "Kapalı" @@ -713,7 +714,7 @@ tr: Müşterilerinize merhaba diyebilir, tezgahınız ve alışveriş şartlarınız ile ilgili bilgi verebilirsiniz. Yazdıklarınız, müşteriler mağazanızı ziyaret ettiğinde görünür olacak. - shopfront_message_link_tooltip: "Bağlantı ekle / düzenle" + shopfront_message_link_tooltip: "Bağlantı ekle/düzenle" shopfront_message_link_prompt: "Lütfen eklemek için bir URL girin" shopfront_closed_message: "KAPALI MAĞAZA MESAJI" shopfront_closed_message_placeholder: > @@ -794,7 +795,7 @@ tr: producer_shop_description_text: Açık Gıda Ağı üzerinden açtığınız bireysel mağazanız ile ürünlerinizi doğrudan müşterilere ulaştırabilirsiniz. producer_shop_description_text2: Üretici Tezgahı sadece sizin ürünleriniz içindir. Üretiminiz haricindeki ürünleri satabilmek için lütfen 'Üretici Pazarı' seçeneğini seçin. producer_hub: ÜRETİCİ PAZARI - producer_hub_text: Kendi ürünleriniz ile beraber başkalarından ürünlerini de satın + producer_hub_text: Kendi ürünleriniz ile beraber başkalarının ürünlerini de satın producer_hub_description_text: İşletmeniz, yerel gıda sisteminizin bel kemiğidir. Açık Gıda Ağı'ndaki mağazanız aracılığıyla kendi ürünlerinizi ve çevrenizdeki diğer üreticilerin ürünlerini beraber satabilirsiniz. profile: Yalnızca Profil get_listing: Görünür ol @@ -857,7 +858,7 @@ tr: next: "Sonrakİ" cancel: "İptal et" back_to_list: "Listeye geri dön" - save_and_back_to_list: "Kaydet ve Listeye Dön" + save_and_back_to_list: "KAYDET VE LİSTEYE DÖN" choose_products_from: "Ürünlerİ Buradan SeÇ:" incoming: incoming: "Gelen" @@ -879,7 +880,7 @@ tr: fees: "Ücretler" previous: "Önceki" save: "Kaydet" - save_and_back_to_list: "Kaydet ve Listeye Dön" + save_and_back_to_list: "KAYDET VE LİSTEYE DÖN" cancel: "İptal et" back_to_list: "Listeye geri dön" wizard_progress: @@ -903,7 +904,7 @@ tr: choose_product_tip: Gelen ve giden ürünleri sadece stokların %{inventory} 'i ile kısıtlayabilirsiniz. preferred_product_selection_from_coordinator_inventory_only_here: Yalnızca Koordinatör Stokları preferred_product_selection_from_coordinator_inventory_only_all: Tüm Mevcut Ürünler - save_reload: Sayfayı Kaydet ve Yeniden Yükle + save_reload: SAYFAYI KAYDET VE YENİDEN YÜKLE coordinator_fees: add: Koordinatör ücreti ekle filters: @@ -922,7 +923,7 @@ tr: products: Ürünler tags: Etiketler add_a_tag: Etiket ekle - delivery_details: Teslimat / Gönderim Bilgileri + delivery_details: Teslimat/Gönderim Bilgileri index: schedule: Takvim schedules: Takvimler @@ -938,7 +939,7 @@ tr: variants: Varyantlar simple_form: ready_for: ŞU TARİHTE HAZIR - ready_for_placeholder: Tarih / saat + ready_for_placeholder: Tarih/saat customer_instructions: Müşteri talimatları customer_instructions_placeholder: Teslimat / Gönderim Notları products: Ürünler @@ -1147,7 +1148,7 @@ tr: checkout: "Alışverişi Tamamla" already_ordered_products: "Bu sipariş dönemi içinde zaten sipariş verildi" register_call: - selling_on_ofn: "Açık Gıda Ağı'na katılmak ister misiniz?" + selling_on_ofn: "Açık Gıda Ağı üzerinden satış yapmak ister misiniz?" register: "Buradan kaydolun" footer: footer_secure: "Güvenli ve güvenilir." @@ -1156,7 +1157,7 @@ tr: footer_contact_email: "Bize e-posta gönderin" footer_nav_headline: "Gezin" footer_join_headline: "Bize katılın" - footer_join_body: "Açık Gıda Ağı üzerinden aracısız, adil ve temiz gıdaya ulaşma yollarını keşfedin." + footer_join_body: "Açık Gıda Ağı üzerinden ürünlerinizi sergileyin, çevirimiçi mağazanızı oluşturun veya grubunuzu listeleyin." footer_join_cta: "Daha fazlasını anlat!" footer_legal_call: "Okuyun" footer_legal_tos: "Şartlar ve koşullar" @@ -1164,18 +1165,18 @@ tr: footer_legal_text_html: "Açık Gıda Ağı ücretsiz ve açık kaynaklı bir yazılım platformudur. İçeriklerimiz %{content_license} ve kodumuz %{code_license} ile lisanslıdır." footer_data_text_with_privacy_policy_html: "Verilerinize iyi bakıyoruz. Bkz. %{privacy_policy} ve %{cookies_policy}" footer_data_text_without_privacy_policy_html: "Verilerinize iyi bakıyoruz. Bkz. %{cookies_policy}" - footer_data_privacy_policy: "Gizlilik Politikası" - footer_data_cookies_policy: "çerez politikası" + footer_data_privacy_policy: "Gizlilik ve Kişisel Verilerin Korunması Politikası " + footer_data_cookies_policy: "Çerez Politikası" shop: messages: customer_required: - login: "Oturum Aç" + login: "Oturum Aç / Kaydol" signup: "Kaydol" contact: "İLETİŞİM" require_customer_login: "Yalnızca onaylı müşteriler buradan alışveriş yapabilir." require_login_html: "Zaten onaylanmış bir müşteri iseniz, devam etmek için %{login} veya %{signup}" - require_login_2_html: "Buradan alışveriş mi yapmak istiyorsunuz? Lütfen katılmak için %{contact}%{enterprise} ile iletişime geçin!" - require_customer_html: "Buradan alışveriş yapmaya başlamak istiyorsanız, katılmak için lütfen %{contact} %{enterprise} 'a sorun." + require_login_2_html: "Buradan alışveriş mi yapmak istiyorsunuz? Lütfen katılmak için sorun: %{contact}%{enterprise} " + require_customer_html: "Buradan alışveriş yapmaya başlamak istiyorsanız, katılmak için lütfen sorun: %{contact} %{enterprise} " select_oc: select_oc_html: "Hangi ürünlerin uygun olduğunu görmek için lütfen ne zaman için sipariş vermek istediğinizi seçin " card_could_not_be_updated: Kart güncellenemedi @@ -1213,12 +1214,12 @@ tr: menu_3_url: "/producers" menu_4_title: "Gruplar" menu_4_url: "/groups" - menu_5_title: "hakkında" - menu_5_url: "https://acikgida.com" + menu_5_title: "HAKKIMIZDA" + menu_5_url: "https://hakkimizda.acikgida.com" menu_6_title: "Bağlan" - menu_6_url: "https://acikgida.com" + menu_6_url: "https://acikgida.com/connect" menu_7_title: "öğren" - menu_7_url: "https://acikgida.com" + menu_7_url: "https://acikgida.com/learn" logo: "Logo (640x130)" logo_mobile: "Cep telefonu logosu (75x26)" logo_mobile_svg: "Cep Telefonu logo (SVG)" @@ -1233,7 +1234,7 @@ tr: footer_pinterest_url: "Pinterest URL" footer_email: "E-posta" footer_links_md: "Bağlantılar" - footer_about_url: "URL hakkında" + footer_about_url: "HAKKIMIZDA URL" user_guide_link: "Kullanıcı Kılavuzu Linki" name: İSİM first_name: Ad @@ -1268,7 +1269,7 @@ tr: label_producer: "ÜRETİCİ" label_producers: "ÜRETİCİLER" label_groups: "Gruplar" - label_about: "HAKKINDA" + label_about: "HAKKIMIZDA" label_connect: "Bağlan" label_learn: "Öğren" label_blog: "Blog" @@ -1358,11 +1359,11 @@ tr: brandstory_part6: "Hepimiz gıdamızı seviyoruz. Artık gıda sistemimizi de sevmeye başlayabiliriz." learn_body: "Adil ve temiz gıda işletmenizi veya topluluğunuzu geliştirmenize yardımcı olacak modelleri, hikayeleri ve kaynakları keşfedin. Dostlardan öğrenmek için eğitim, etkinlikler ve diğer fırsatlara göz atın." learn_cta: "İlham Alın" - connect_body: "Yakınınızdaki adil ve temiz gıda tüccarlarını bulmak için üreticilerin, pazarların ve topluluklarının tümünü gözden geçirin. İşletmenizi veya topluluğunuzu Açık Gıda Ağı üzerinden listeleyin, böylece alıcılar sizi bulabilir. Ortak hareket etmek için diğer hesaplar ile iletişime geçmekten çekinmeyin, birlikte daha güçlüsünüz. Tavsiye almak ve sorunları birlikte çözmek için topluluğa katılın." + connect_body: "Yakınınızdaki adil ve temiz gıda noktalarını bulmak için üreticilerin, pazarların ve topluluklarının tümünü gözden geçirin. İşletmenizi veya topluluğunuzu Açık Gıda Ağı üzerinden listeleyin, böylece alıcılar sizi bulabilir. Ortak hareket etmek için diğer hesaplar ile iletişime geçmekten çekinmeyin, birlikte daha güçlüsünüz. Tavsiye almak ve sorunları birlikte çözmek için topluluğa katılın." connect_cta: "Keşfedin" system_headline: "Nasıl çalışıyor ?" system_step1: "1. Ara" - system_step1_text: "Yerel, adil, temiz ve mevsimsel gıda için, bağımsız ve cesur üreticilerimizin pazarlarından alışveriş yapın. Uzaklığa göre, ürün kategorisine veya teslimat tercihlerine göre arama yapabilirsiniz. " + system_step1_text: "Yerel, adil, temiz ve mevsimsel gıda için, bağımsız ve cesur üreticilerimizin mağazalarından alışveriş yapın. Konuma, ürün kategorisine, üretici özelliklerine veya teslimat tercihlerine göre arama yapabilirsiniz. " system_step2: "2. Alışveriş Yap" system_step2_text: "Gıdanızı yerel üretici tezgahlarından, üretici ve türetici pazarlarından temin edin. Yaşanabilir bir dünya için alışkanlıklarınızı şimdi değiştirin. Gıdanızın ve onu size getiren insanların hikayelerini öğrenin!" system_step3: "3. Teslimat " @@ -1382,7 +1383,7 @@ tr: checkout_headline: "Tamam, ödeme yapmaya hazır mısın?" checkout_as_guest: "Misafir olarak ödeme yap" checkout_details: "Bilgilerin" - checkout_billing: "fatura bilgisi" + checkout_billing: "Fatura Bilgisi" checkout_default_bill_address: "Varsayılan fatura adresi olarak kaydet" checkout_shipping: Teslimat bilgileri checkout_default_ship_address: "Varsayılan teslimat adresi olarak kaydet" @@ -1566,7 +1567,7 @@ tr: components_filters_nofilters: "Filtresiz" components_filters_clearfilters: "Tüm filtreleri temizle" groups_title: Gruplar - groups_headline: Gruplar / bölgeler + groups_headline: Gruplar groups_text: "Her üretici özeldir ve her işletmenin ortaya koyabileceği farklı bir değer vardır. Üyelerimiz, ürünlerini ve emeklerini, ya da sadece gıdanın ortak değerleri paylaşan üretici, türetici ve dağıtımcı kolektifleridir. Bu bileşenler, adil ve temiz gıdaya ulaşım yollarını kolaylaştırır ve bozulmuş gıda sistemini hep beraber düzeltmemize yardımcı olur." groups_search: "İsim veya anahtar kelime ile ara" groups_no_groups: "Grup bulunamadı" @@ -1636,10 +1637,10 @@ tr: sell_producers_detail: "AGA üzerinden işletmeniz adına bir profil oluşturun. Dilediğiniz zaman profilinizi bir tezgaha yükseltebilir ve ürünlerinizi müşterilerinize doğrudan satabilirsiniz." sell_hubs_detail: "AGA üzerinden gıda işletmeniz veya topluluğunuz için bir profil oluşturun. İstediğiniz zaman profilinizi çok üreticili bir pazara yükseltebilirsiniz." sell_groups_detail: "Bölgenizdeki veya ağınızdaki işletmelerin (üreticilerin, pazarların veya diğer grupların) detaylı rehber listesini oluşturun." - sell_user_guide: "Kullanım kılavuzumuzda daha fazla bilgi edinin." - sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. Fiyatlandırma hakkında daha fazla bilgi için, üst menüdeki Hakkında bağlantısını kullanarak Yazılım Platformu bölümünü ziyaret edin." - sell_embed: "Açık Gıda Ağı üzerinden oluşturduğunuz tezgahınızı kendi web siteniz üzerinden de kullanmanıza yardımcı olabiliriz. Müşterileriniz mevcut internet siteniz üzerinden de aynı şekilde sipariş verebilirler. " - sell_ask_services: "Bize AGA hizmetleri hakkında soru sorun." + sell_user_guide: "Kullanım kılavuzumuzdan daha fazla bilgi edinin." + sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. Platform üzerinden satış yapan işletmeler için işlem başına uygulanan ücretlendirme KDV dahil %5'tir. Kar amacı gütmeyen topluluklar, kooperatifler ve ekoloji/gıda temelli dernekler ile çalışan üreticiler karşılıklı dayanışma ve özel fiyatlandırma için iletişime geçebilirler. Fiyatlandırma hakkında bilgi almak için, üst menüdeki Hakkımızda bağlantısını kullanarak Fiyatlandırma bölümünü ziyaret edin." + sell_embed: "Kendi e-ticaret siteniz olsa bile Açık Gıda Ağı size hikayenizi anlatmanız ve ürünlerinizi satmanız için yeni ve farklı bir seçenek sunuyor. Siz de bu ailenin bir parçası olun, hep beraber büyüyelim!" + sell_ask_services: "Detaylar için bizimle iletişime geçin." shops_title: Mağazalar shops_headline: Alışveriş biçim değiştiriyor shops_text: Gıda dönemsel yetiştirilir, dönemsel hasat edilir ve dönemsel sipariş edilir. Aradığınız mağazanın sipariş dönemi kapalı ise kısa süre sonra tekrar kontrol edin. @@ -1712,7 +1713,7 @@ tr: filter_by: "Filtrele" hide_filters: "Filtreleri gizle" one_filter_applied: "1 filtre uygulandı" - x_filters_applied: "filtreler uygulandı" + x_filters_applied: "filtre uygulandı" submitting_order: "Siparişiniz gönderiliyor: lütfen bekleyin" confirm_hub_change: "Emin misiniz? Seçtiğiniz pazar değiştirilecek ve alışveriş sepetinizdeki tüm ürünler kaldırılacak." confirm_oc_change: "Emin misiniz? Seçtiğiniz sipariş dönemi değiştirilecek ve alışveriş sepetinizdeki tüm ürünler kaldırılacak." @@ -1752,14 +1753,14 @@ tr: steps: introduction: registration_greeting: "Merhaba!" - registration_intro: "Şimdi AGA üzerinden bir Üretici veya Türetici profili oluşturabilirsiniz" + registration_intro: "Şimdi AGA üzerinden Üretici veya Türetici profilleri oluşturabilirsiniz" registration_checklist: "Neye ihtiyacım var?" registration_time: "5-10 dakika" registration_enterprise_address: "İşletme adresi" registration_contact_details: "Birincil iletişim bilgileri" registration_logo: "Logo resminiz" registration_promo_image: "Profiliniz için duvar resmi" - registration_about_us: "'Hakkımızda' metni" + registration_about_us: "'Hakkımızda' metni - Hikayeniz" registration_outcome_headline: "Ne kazanacağım?" registration_outcome1_html: "Profiliniz, insanların Açık Gıda Ağı üzerinde sizi bulmasına ve sizinle iletişim kurmasına yardımcı olur." registration_outcome2: "Bu alanı kendinizin, çiftliğinizin ve işletmenizin hikayesini anlatmak, yeni işbirlikleri, yeni bağlantılar kurmak için kullanın. " @@ -1807,7 +1808,7 @@ tr: no_producer_help: "Üretici değilseniz muhtemelen gıdaya ulaşım sağlayan, dağıtım veya satış yapan bir grup ya da işletmesiniz. Bir dükkan, kooperatif, gıda topluluğu, restaurant veya toptancı bile olabilirsiniz. " create_profile: "Profil oluştur" about: - title: "Hakkında" + title: "HAKKIMIZDA" headline: "Güzel!" message: "Şimdi ayrıntıları açıklayalım" success: "Sonunda! %{enterprise} Açık Gıda Ağı'na eklendi" @@ -1912,10 +1913,10 @@ tr: outstanding_balance: "Ödenmemiş bakiye" admin_enterprise_relationships: "İŞLETME İZİNLERİ" admin_enterprise_relationships_everything: "her şey" - admin_enterprise_relationships_permits: "izinler" + admin_enterprise_relationships_permits: "izin veriyor" admin_enterprise_relationships_seach_placeholder: "Ara" admin_enterprise_relationships_button_create: "Oluştur" - admin_enterprise_relationships_to: "'a" + admin_enterprise_relationships_to: "-" admin_enterprise_groups: "İşletme Grupları" admin_enterprise_groups_name: "Ad" admin_enterprise_groups_owner: "Sahip" @@ -1985,7 +1986,7 @@ tr: price: "Fiyat" on_hand: "Mevcut" review: "gözden geçir" - save_changes: "Değişiklikleri Kaydet" + save_changes: "DEĞİŞİKLİKLERİ KAYDET" order_saved: "Sipariş Kaydedildi" no_products: Ürün yok spree_admin_overview_enterprises_header: "İşletmelerim" @@ -2041,7 +2042,7 @@ tr: first_name_begins_with: "Adının BAŞ HARFİ" last_name_begins_with: "Soyadının BAŞ HARFİ" enterprise_tos_link: "İşletme Üyelik Sözleşmesi bağlantısı" - enterprise_tos_message: "Amaçlarımızı ve değerlerimizi paylaşan insanlarla çalışmak istiyoruz. Bu nedenle yeni işletmelerden bunu kabul etmesini istiyoruz:" + enterprise_tos_message: "Amaçlarımızı ve değerlerimizi paylaşan insanlarla çalışmak istiyoruz. Yasal zorunluluk gereği de yeni işletmelerden kabul etmesini istiyoruz:" enterprise_tos_link_text: "Üyelik Sözleşmesi" enterprise_tos_agree: "Yukarıdaki Üyelik Sözleşmesini kabul ediyorum" tax_settings: "Vergi Ayarları" @@ -2232,7 +2233,7 @@ tr: user_invited: "%{email} bu işletmeyi yönetmeye davet edildi" add_manager: "Mevcut bir kullanıcıyı ekle" users: "Kullanıcılar" - about: "Hakkında" + about: "HAKKIMIZDA" images: "Görseller" web: "Web" primary_details: "Temel Bilgiler" @@ -2260,7 +2261,7 @@ tr: content_configuration_pricing_table: "(YAPILACAKLAR: Fiyatlandırma tablosu)" content_configuration_case_studies: "(TODO: Vaka çalışmaları)" content_configuration_detail: "(YAPILACAKLAR: Detay)" - enterprise_name_error: "çoktan alındı. İşletme size aitse ve sahiplik talebinde bulunmak istiyorsanız veya bu işletmeyle ticaret yapmak istiyorsanız lütfen %{email} numaralı telefondan bu profilin şu anki yöneticisiyle iletişime geçin." + enterprise_name_error: "çoktan alındı. İşletme size aitse ve sahiplik talebinde bulunmak istiyorsanız veya bu işletmeyle ticaret yapmak istiyorsanız lütfen %{email} üzerinden bu profilin şu anki yöneticisiyle iletişime geçin." enterprise_owner_error: "^ %{email}‘ın daha fazla işletmeye sahip olmasına izin verilmiyor (limit %{enterprise_limit})." enterprise_role_uniqueness_error: "^ Bu rol zaten var." inventory_item_visibility_error: doğru veya yanlış olmalı @@ -2295,7 +2296,7 @@ tr: order_cycles_no_permission_to_coordinate_error: "Hiçbir işletmenizin sipariş dönemini koordine etme izni yok" order_cycles_no_permission_to_create_error: "Bu işletme tarafından koordine edilen bir sipariş dönemi oluşturma izniniz yok" back_to_orders_list: "Sipariş listesine geri dön" - no_orders_found: "Sipariş bulunamadı" + no_orders_found: "SİPARİŞ BULUNAMADI" order_information: "Sipariş Bilgisi" date_completed: "Tamamlanma Tarihi" amount: "Tutar" @@ -2353,7 +2354,7 @@ tr: saved: KAYDEDİLDİ saving: KAYDEDİYOR enterprise_package: - hub_profile: Türetici Pazarı Profili + hub_profile: Pazar Profili hub_profile_cost: "MALİYET: HER ZAMAN ÜCRETSİZ" hub_profile_text1: > İnsanlar Açık Gıda Ağı üzerinden size ulaşabilir. Haritada görünür ve @@ -2368,8 +2369,7 @@ tr: alıcılara ulaştırabilirsiniz. hub_shop_text2: > Pazarlar gerçek anlamı dışında da bir çok şekil alabilir: Gıda kooperatifleri, - gıda toplulukları, haftalık gıda kolisi üyelikleri, alım grupları, dükkanlar - vs. + gıda toplulukları, haftalık gıda kolisi üyelikleri, alım grupları vs. hub_shop_text3: > Kendi ürünlerinizi de satmak isterseniz, işletme bilginizi üretici olarak güncellemelisiniz. @@ -2452,14 +2452,14 @@ tr: variants_loaded: "%{total_number_of_variants} Varyanttan %{num_of_variants_loaded} Tanesi Yüklendi" loading_variants: "Varyantlar Yükleniyor" tag_rules: - shipping_method_tagged_top: "Teslimat yöntemleri etiketlendi" - shipping_method_tagged_bottom: "şunlardır:" - payment_method_tagged_top: "Ödeme yöntemleri etiketleri" - payment_method_tagged_bottom: "şunlardır:" - order_cycle_tagged_top: "Sipariş Dönemleri etiketlendi" - order_cycle_tagged_bottom: "şunlardır:" - inventory_tagged_top: "Stok varyantları etiketlendi" - inventory_tagged_bottom: "şunlardır:" + shipping_method_tagged_top: "Teslimat Yöntemi etiketi" + shipping_method_tagged_bottom: "ise durumu:" + payment_method_tagged_top: "Ödeme Yönteml etiketi" + payment_method_tagged_bottom: "ise durumu:" + order_cycle_tagged_top: "Sipariş Dönemi etiketi" + order_cycle_tagged_bottom: "ise durumu:" + inventory_tagged_top: "Stok varyant etiketi" + inventory_tagged_bottom: "ise durumu:" new_tag_rule_dialog: select_rule_type: "Bir kural türü seçin:" add_rule: "Kural Ekle" @@ -2748,7 +2748,7 @@ tr: temperature_controlled: "Soğuk Sevkiyat" new_product: "Yeni ürün" administration: "yönetim" - logged_in_as: "olarak giriş yapıldı" + logged_in_as: "Giriş yapıldı" account: "Hesap" logout: "Çıkış Yap" date_range: "Tarih aralığı" @@ -2784,7 +2784,7 @@ tr: cannot_set_shipping_method_without_address: "Müşteri bilgileri girilmeden teslimat yöntemi belirlenemez.." no_tracking_present: "Hiçbir takip detayı sağlanmadı." order_total: "sipariş toplamı" - customer_details: "Müşteri detayları" + customer_details: "MÜŞTERİ DETAYLARI" customer_search: "Müşteri Arama" choose_a_customer: "Bir müşteri seçin" account: "Hesap" @@ -2807,6 +2807,14 @@ tr: new_payment: "Yeni Ödeme" capture: "Tahsilat" void: "Geçersiz" + login: "Oturum aç" + password: "Parola" + signature: "İmza" + solution: "Çözüm" + landing_page: "Ana Sayfa" + server: "Server" + test_mode: "Test Modu" + logourl: "Logourl" configurations: "yapılandırmalar" general_settings: "Genel Ayarlar" site_name: "Site adı" @@ -2871,8 +2879,6 @@ tr: abbreviation: "Kısaltma" new_state: "Yeni Şehir" payment_methods: "Ödeme yöntemleri" - new_payment_method: "Yeni Ödeme Yöntemi" - provider: "Sağlayıcı" taxonomies: "cinsler" new_taxonomy: "Yeni Cins" back_to_taxonomies_list: "Cinsler Listesine Geri Dön" @@ -2886,7 +2892,7 @@ tr: default: "varsayılan" calculator: "Hesaplama" zone: "bölge" - display: "Görüntüle" + display: "GÖSTER" environment: "çevre" active: "Aktif" nore: "Daha fazla" @@ -2936,7 +2942,7 @@ tr: admin: tab: dashboard: "KONTROL PANELİ" - orders: "Siparişler" + orders: "SİPARİŞLER" bulk_order_management: "Toplu Sipariş Yönetimi" subscriptions: "Üyelikler" products: "Ürünler" @@ -2975,7 +2981,7 @@ tr: index: new_return_authorization: "Yeni İade Yetkisi" return_authorizations: "İade Yetkileri" - back_to_orders_list: "Siparişler Listesine Geri Dön" + back_to_orders_list: "SİPARİŞLER LİSTESİNE GERİ DÖN" rma_number: "RMA Numarası" status: "Durum" amount: "Miktar" @@ -3004,7 +3010,7 @@ tr: canceled: "İptal edildi" orders: index: - listing_orders: "Siparişler Listeleniyor" + listing_orders: "SİPARİŞLER LİSTELENİYOR" new_order: "Yeni Sipariş" capture: "Tahsilat" ship: "Teslimat" @@ -3016,7 +3022,7 @@ tr: previous: "Önceki" next: "Sonraki" loading: "Yükleniyor" - no_orders_found: "Sipariş Bulunamadı" + no_orders_found: "SİPARİŞ BULUNAMADI" results_found: "%{number} Sonuç bulundu." viewing: "%{start} - %{end} görüntüleniyor." print_invoices: "Faturaları Yazdır" @@ -3066,7 +3072,9 @@ tr: products_distributor: "Dağıtımcı" zone: "bölge" calculator: "Hesaplama" - display: "Görüntüle" + display: "GÖSTER" + both: "Ödeme Sayfası ve Panel" + back_end: "Sadece panel" no_shipping_methods_found: "Hiçbir teslimat yöntemi bulunamadı" new: new_shipping_method: "Yeni Teslimat Yöntemi" @@ -3078,11 +3086,30 @@ tr: form: categories: "Kategoriler" zones: "bölgeler" + both: "Ödeme Sayfası ve Panel" + back_end: "Sadece panel" + deactivation_warning: "Bir teslimat yöntemini etkisiz hale getirmek listenizden kaldırılmasına sebep olabilir. Alternatif olarak, ayarlarınızı 'Göster' yerine 'sadece panel' olarak değiştirerek teslimat yöntemini ödeme sayfasında gizleyebilirsiniz." payment_methods: + index: + payment_methods: "ÖDEME YÖNTEMLERİ" + new_payment_method: "Yeni Ödeme Yöntemi" + name: "İSİM" + products_distributor: "Dağıtımcı" + provider: "Sağlayıcı" + environment: "Çevre" + display: "GÖSTER" + active: "Aktif" + both: "Her ikisi de" + front_end: "Sadece Ödeme" + back_end: "Sadece panel" + active_yes: "Evet" + active_no: "Hayır" + no_payment_methods_found: "Ödeme yöntemi bulunamadı" new: new_payment_method: "Yeni Ödeme Yöntemi" back_to_payment_methods_list: "Ödeme Yöntemleri Listesine Geri Dön" edit: + new: "Yeni" editing_payment_method: "Ödeme Yöntemi Düzenleniyor" back_to_payment_methods_list: "Ödeme Yöntemleri Listesine Geri Dön" stripe_connect: @@ -3098,6 +3125,21 @@ tr: account_id: Hesap Kimliği business_name: işletme adı charges_enabled: Masraflar Etkin + form: + name: "İSİM" + description: "Açıklama" + environment: "Çevre" + display: "GÖSTER" + active: "Aktif" + active_yes: "Evet" + active_no: "Hayır" + both: "Ödeme Sayfası ve Panel" + front_end: "Sadece Ödeme" + back_end: "Sadece panel" + tags: "Etiketler" + deactivation_warning: "Bir ödeme yöntemini kaldırmak listenizden silinmesine sebep olabilir. Alternatif olarak, ödeme yöntemi ayarını 'Göster' yerine 'Sadece Panel' olarak değiştirebilirsiniz. " + providers: + provider: "Sağlayıcı" payments: source_forms: stripe: @@ -3200,6 +3242,7 @@ tr: display_as_placeholder: 'örn. 2 kg' display_name_placeholder: 'örn. Domates' autocomplete: + out_of_stock: "Stok tükendi" producer_name: "Üretici" unit: "Birim" shared: @@ -3237,6 +3280,7 @@ tr: format: '% Y-% A-%d' js_format: 'yy-aa-gg' orders: + error_flash_for_unavailable_items: "Sepetinizdeki ürünlerden biri bitti veya azaldı. Lütfen seçili miktarı güncelleyin." edit: login_to_view_order: "Siparişinizi görmek için lütfen giriş yapın." bought: @@ -3264,9 +3308,14 @@ tr: invalid: geçersiz order_mailer: cancel_email: - customer_greeting: "Merhaba %{name}!" - instructions: "Siparişiniz iptal edildi. Lütfen kayıtlarınız için bu iptal bilgilerini saklayın." - order_summary_canceled: "Sipariş Özeti [İPTAL EDİLDİ]" + customer_greeting: "Sevgili %{name}," + instructions_html: "%{distributor} siparişiniz İPTAL EDİLDİ. Lütfen not edin." + dont_cancel: "Eğer fikrinizi değiştirdiyseniz ve siparişi iptal etmek istemiyorsanız lütfen %{email} ile iletişime geçin." + order_summary_canceled_html: "Sipariş Özeti #%{number}(İPTAL EDİLDİ)" + details: "İşte siparişinizin özeti:" + unpaid_order: "Sipariş ödemeniz yapılmadığı için iade işlemi yapılmadı" + paid_order: "Siparişinizin ödemesi yapılmıştı, bu sebeple %{distributor}iade işlemi gerçekleştirdi." + credit_order: "Siparişinizin ödemesi yapılmıştı, bu sebeple hesabınızdan düşüldü." subject: "Sipariş İptali" confirm_email: subject: "Sipariş Onayı" @@ -3311,14 +3360,14 @@ tr: account_settings: Hesap Ayarları show: tabs: - orders: Siparişler + orders: SİPARİŞLER cards: Kredi kartları transactions: İşlemler settings: Hesap ayarları unconfirmed_email: "Bekleyen e-posta onayı: %{unconfirmed_email}. Yeni e-posta onaylandıktan sonra e-posta adresiniz güncellenecektir." orders: - open_orders: Açık Siparişler - past_orders: Geçmiş Siparişler + open_orders: AÇIK SİPARİŞLER + past_orders: GEÇMİŞ SİPARİŞLER transactions: transaction_history: İşlem Geçmişi open_orders: diff --git a/config/routes/spree.rb b/config/routes/spree.rb index 0c05dd2fbb..ca5993aca5 100644 --- a/config/routes/spree.rb +++ b/config/routes/spree.rb @@ -133,7 +133,7 @@ Spree::Core::Engine.routes.draw do # Configuration section resource :general_settings - resource :mail_method, :only => [:edit, :update] do + resource :mail_methods, :only => [:edit, :update] do post :testmail, :on => :collection end diff --git a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/permissions.rb b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/permissions.rb index 2077931627..95ce055f24 100644 --- a/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/permissions.rb +++ b/engines/order_management/app/services/order_management/reports/enterprise_fee_summary/permissions.rb @@ -3,7 +3,7 @@ module OrderManagement module EnterpriseFeeSummary class Permissions < ::Reports::Permissions def allowed_order_cycles - @allowed_order_cycles ||= OrderCycle.accessible_by(user) + @allowed_order_cycles ||= OrderCycle.visible_by(user) end def allowed_distributors diff --git a/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss b/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss index 4c3706d8d7..583c10525a 100644 --- a/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss +++ b/engines/web/app/assets/stylesheets/web/pages/cookies_policy_modal.css.scss @@ -4,6 +4,10 @@ background: $cookies-policy-modal-background-color; border-bottom-color: $cookies-policy-modal-border-bottom-color; + @media only screen and (max-width: 640px) { + padding: .9rem; + } + table { width: 100%; diff --git a/spec/controllers/api/exchange_products_controller_spec.rb b/spec/controllers/api/exchange_products_controller_spec.rb index c39546358b..f94089280c 100644 --- a/spec/controllers/api/exchange_products_controller_spec.rb +++ b/spec/controllers/api/exchange_products_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module Api @@ -52,7 +54,7 @@ module Api let(:products_relation) { Spree::Product.includes(:variants).where("spree_variants.id": exchange.variants.map(&:id)) } before do - stub_const("Api::ExchangeProductsController::DEFAULT_PER_PAGE", 1) + stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1) end describe "when a specific page is requested" do diff --git a/spec/controllers/api/shipments_controller_spec.rb b/spec/controllers/api/shipments_controller_spec.rb index 333d3c3220..f4dba19f11 100644 --- a/spec/controllers/api/shipments_controller_spec.rb +++ b/spec/controllers/api/shipments_controller_spec.rb @@ -4,8 +4,9 @@ describe Api::ShipmentsController, type: :controller do render_views let!(:shipment) { create(:shipment) } - let!(:attributes) { [:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id] } - let!(:resource_scoping) { { order_id: shipment.order.to_param, id: shipment.to_param } } + let!(:attributes) do + [:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id] + end let(:current_api_user) { build(:user) } before do @@ -14,12 +15,12 @@ describe Api::ShipmentsController, type: :controller do context "as a non-admin" do it "cannot make a shipment ready" do - api_put :ready + api_put :ready, order_id: shipment.order.to_param, id: shipment.to_param assert_unauthorized! end it "cannot make a shipment shipped" do - api_put :ship + api_put :ship, order_id: shipment.order.to_param, id: shipment.to_param assert_unauthorized! end end @@ -92,7 +93,7 @@ describe Api::ShipmentsController, type: :controller do it "can make a shipment ready" do allow_any_instance_of(Spree::Order).to receive_messages(paid?: true, complete?: true) - api_put :ready + api_put :ready, order_id: shipment.order.to_param, id: shipment.to_param expect(attributes.all?{ |attr| json_response.key? attr.to_s }).to be_truthy expect(json_response["state"]).to eq("ready") @@ -101,7 +102,7 @@ describe Api::ShipmentsController, type: :controller do it "cannot make a shipment ready if the order is unpaid" do allow_any_instance_of(Spree::Order).to receive_messages(paid?: false) - api_put :ready + api_put :ready, order_id: shipment.order.to_param, id: shipment.to_param expect(json_response["error"]).to eq("Cannot ready shipment.") expect(response.status).to eq(422) @@ -109,21 +110,26 @@ describe Api::ShipmentsController, type: :controller do context 'for completed shipments' do let(:order) { create :completed_order_with_totals } - let!(:resource_scoping) { { order_id: order.to_param, id: order.shipments.first.to_param } } it 'adds a variant to a shipment' do - api_put :add, variant_id: variant.to_param, quantity: 2 + api_put :add, variant_id: variant.to_param, + quantity: 2, + order_id: order.to_param, + id: order.shipments.first.to_param expect(response.status).to eq(200) - expect(order.shipment.reload.inventory_units.select { |h| h['variant_id'] == variant.id }.size).to eq 2 + expect(inventory_units_for(variant).size).to eq 2 end it 'removes a variant from a shipment' do order.contents.add(variant, 2) - api_put :remove, variant_id: variant.to_param, quantity: 1 + api_put :remove, variant_id: variant.to_param, + quantity: 1, + order_id: order.to_param, + id: order.shipments.first.to_param expect(response.status).to eq(200) - expect(order.shipment.reload.inventory_units.select { |h| h['variant_id'] == variant.id }.size).to eq(1) + expect(inventory_units_for(variant).size).to eq(1) end end @@ -140,7 +146,9 @@ describe Api::ShipmentsController, type: :controller do it "can transition a shipment from ready to ship" do shipment.reload - api_put :ship, order_id: shipment.order.to_param, id: shipment.to_param, shipment: { tracking: "123123" } + api_put :ship, order_id: shipment.order.to_param, + id: shipment.to_param, + shipment: { tracking: "123123" } expect(attributes.all?{ |attr| json_response.key? attr.to_s }).to be_truthy expect(json_response["state"]).to eq("shipped") diff --git a/spec/controllers/api/shops_controller_spec.rb b/spec/controllers/api/shops_controller_spec.rb index 127dd83848..a90f606f57 100644 --- a/spec/controllers/api/shops_controller_spec.rb +++ b/spec/controllers/api/shops_controller_spec.rb @@ -33,7 +33,7 @@ describe Api::ShopsController, type: :controller do describe "#closed_shops" do it "returns data for all closed shops" do - spree_get :closed_shops, nil + spree_get :closed_shops, {} expect(json_response).not_to match hub.name diff --git a/spec/controllers/api/variants_controller_spec.rb b/spec/controllers/api/variants_controller_spec.rb index a5c81329dd..c91f25f2ec 100644 --- a/spec/controllers/api/variants_controller_spec.rb +++ b/spec/controllers/api/variants_controller_spec.rb @@ -113,7 +113,6 @@ describe Api::VariantsController, type: :controller do let(:product) { create(:product) } let(:variant) { product.master } - let(:resource_scoping) { { product_id: variant.product.to_param } } context "deleted variants" do before do @@ -121,7 +120,7 @@ describe Api::VariantsController, type: :controller do end it "are visible by admin" do - api_get :index, show_deleted: 1 + api_get :index, show_deleted: 1, product_id: variant.product.to_param expect(json_response.count).to eq(2) end @@ -129,7 +128,7 @@ describe Api::VariantsController, type: :controller do it "can create a new variant" do original_number_of_variants = variant.product.variants.count - api_post :create, variant: { sku: "12345", unit_value: "weight", unit_description: "L" } + api_post :create, variant: { sku: "12345", unit_value: "weight", unit_description: "L" }, product_id: variant.product.to_param expect(attributes.all?{ |attr| json_response.include? attr.to_s }).to eq(true) expect(response.status).to eq(201) diff --git a/spec/controllers/enterprises_controller_spec.rb b/spec/controllers/enterprises_controller_spec.rb index 43cc38fa71..f67972563f 100644 --- a/spec/controllers/enterprises_controller_spec.rb +++ b/spec/controllers/enterprises_controller_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' describe EnterprisesController, type: :controller do describe "shopping for a distributor" do + let(:user) { create(:user) } let(:order) { controller.current_order(true) } let(:line_item) { create(:line_item) } let!(:current_distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) } @@ -17,10 +18,23 @@ describe EnterprisesController, type: :controller do it "sets the shop as the distributor on the order when shopping for the distributor" do spree_get :shop, id: distributor + expect(controller.current_distributor).to eq(distributor) expect(controller.current_order.distributor).to eq(distributor) expect(controller.current_order.order_cycle).to be_nil end + context "when user is logged in" do + before { allow(controller).to receive(:spree_current_user) { user } } + + it "sets the shop as the distributor on the order when shopping for the distributor" do + spree_get :shop, id: distributor + + expect(controller.current_distributor).to eq(distributor) + expect(controller.current_order.distributor).to eq(distributor) + expect(controller.current_order.order_cycle).to be_nil + end + end + it "sorts order cycles by the distributor's preferred ordering attr" do distributor.update_attribute(:preferred_shopfront_order_cycle_order, 'orders_close_at') spree_get :shop, id: distributor @@ -32,7 +46,6 @@ describe EnterprisesController, type: :controller do end context "using FilterOrderCycles tag rules" do - let(:user) { create(:user) } let!(:order_cycle3) { create(:simple_order_cycle, distributors: [distributor], orders_open_at: 3.days.ago, orders_close_at: 4.days.from_now) } let!(:oc3_exchange) { order_cycle3.exchanges.outgoing.to_enterprise(distributor).first } let(:customer) { create(:customer, user: user, enterprise: distributor) } diff --git a/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb b/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb new file mode 100644 index 0000000000..69774fb043 --- /dev/null +++ b/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb @@ -0,0 +1,136 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to create/update complex order cycles with a specific time +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") } + let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 0o0, 0o0).strftime("%F %T %z") } + + scenario "creating an order cycle with full interface", js: true do + # Given coordinating, supplying and distributing enterprises with some products with variants + coordinator = create(:distributor_enterprise, name: 'My coordinator') + supplier = create(:supplier_enterprise, name: 'My supplier') + product = create(:product, supplier: supplier) + v1 = create(:variant, product: product) + v2 = create(:variant, product: product) + distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + + # Relationships required for interface to work + create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) + + # And some enterprise fees + supplier_fee = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee') + coordinator_fee = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee') + distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee') + + # When I go to the new order cycle page + quick_login_as_admin + visit admin_order_cycles_path + click_link 'New Order Cycle' + + # Select a coordinator since there are two available + select2_select 'My coordinator', from: 'coordinator_id' + click_button "Continue >" + + # I cannot save before filling in the required fields + expect(page).to have_button("Create", disabled: true) + + # The Create button is enabled once Name is entered + fill_in 'order_cycle_name', with: 'Plums & Avos' + expect(page).to have_button("Create", disabled: false) + + # If I fill in the basic fields + fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time + fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time + + # And I add a coordinator fee + click_button 'Add coordinator fee' + select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id' + + click_button 'Create' + expect(page).to have_content 'Your order cycle has been created.' + + # I should not be able to add a blank supplier + expect(page).to have_select 'new_supplier_id', selected: '' + expect(page).to have_button 'Add supplier', disabled: true + + # And I add a supplier and some products + select 'My supplier', from: 'new_supplier_id' + click_button 'Add supplier' + fill_in 'order_cycle_incoming_exchange_0_receival_instructions', with: 'receival instructions' + page.find('table.exchanges tr.supplier td.products').click + check "order_cycle_incoming_exchange_0_variants_#{v1.id}" + check "order_cycle_incoming_exchange_0_variants_#{v2.id}" + + # I should not be able to re-add the supplier + expect(page).not_to have_select 'new_supplier_id', with_options: ['My supplier'] + expect(page).to have_button 'Add supplier', disabled: true + expect(page.all("td.supplier_name").map(&:text)).to eq(['My supplier']) + + # And I add a supplier fee + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + select 'My supplier', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id' + select 'Supplier fee', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Next' + + # And I add a distributor with the same products + select 'My distributor', from: 'new_distributor_id' + click_button 'Add distributor' + + fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time' + fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions' + + page.find('table.exchanges tr.distributor td.products').click + check "order_cycle_outgoing_exchange_0_variants_#{v1.id}" + check "order_cycle_outgoing_exchange_0_variants_#{v2.id}" + + page.find('table.exchanges tr.distributor td.tags').click + within ".exchange-tags" do + find(:css, "tags-input .tags input").set "wholesale\n" + end + + # And I add a distributor fee + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + select 'My distributor', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id' + select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Back to List' + + oc = OrderCycle.last + toggle_columns "Producers", "Shops" + + expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" + expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time + expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time + expect(page).to have_content "My coordinator" + + expect(page).to have_selector 'td.producers', text: 'My supplier' + expect(page).to have_selector 'td.shops', text: 'My distributor' + + # And it should have some fees + expect(oc.exchanges.incoming.first.enterprise_fees).to eq([supplier_fee]) + expect(oc.coordinator_fees).to eq([coordinator_fee]) + expect(oc.exchanges.outgoing.first.enterprise_fees).to eq([distributor_fee]) + + # And it should have some variants selected + expect(oc.exchanges.first.variants.count).to eq(2) + expect(oc.exchanges.last.variants.count).to eq(2) + + # And my receival and pickup time and instructions should have been saved + exchange = oc.exchanges.incoming.first + expect(exchange.receival_instructions).to eq('receival instructions') + + exchange = oc.exchanges.outgoing.first + expect(exchange.pickup_time).to eq('pickup time') + expect(exchange.pickup_instructions).to eq('pickup instructions') + expect(exchange.tag_list).to eq(['wholesale']) + end +end diff --git a/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb b/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb new file mode 100644 index 0000000000..d6ef3554fa --- /dev/null +++ b/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to manage complex order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + scenario "editing an order cycle with an exchange between the same enterprise" do + c = create(:distributor_enterprise, is_primary_producer: true) + + # Given two order cycles, one with a mono-enterprise incoming exchange... + oc_incoming = create(:simple_order_cycle, suppliers: [c], coordinator: c) + + # And the other with a mono-enterprise outgoing exchange + oc_outgoing = create(:simple_order_cycle, coordinator: c, distributors: [c]) + + # When I edit the first order cycle, the exchange should appear as incoming + quick_login_as_admin + visit admin_order_cycle_incoming_path(oc_incoming) + expect(page).to have_selector 'table.exchanges tr.supplier' + visit admin_order_cycle_outgoing_path(oc_incoming) + expect(page).not_to have_selector 'table.exchanges tr.distributor' + + # And when I edit the second order cycle, the exchange should appear as outgoing + visit admin_order_cycle_outgoing_path(oc_outgoing) + expect(page).to have_selector 'table.exchanges tr.distributor' + visit admin_order_cycle_incoming_path(oc_outgoing) + expect(page).not_to have_selector 'table.exchanges tr.supplier' + end +end diff --git a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb new file mode 100644 index 0000000000..5ff181e7f5 --- /dev/null +++ b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' + +feature ' + As an administrator + I want to manage complex order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + describe "editing an order cycle with multiple pages of products", js: true do + let(:order_cycle) { create(:order_cycle) } + let(:supplier_enterprise) { order_cycle.exchanges.incoming.first.sender } + let!(:new_product) { create(:product, supplier: supplier_enterprise) } + + before do + stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1) + + quick_login_as_admin + visit admin_order_cycle_incoming_path(order_cycle) + expect(page).to have_content "1 / 2 selected" + + page.find("tr.supplier-#{supplier_enterprise.id} td.products").click + expect(page).to have_selector ".exchange-product-details" + + expect(page).to have_content "1 of 2 Variants Loaded" + expect(page).to_not have_content new_product.name + end + + scenario "load all products" do + page.find(".exchange-load-all-variants a").click + + expect_all_products_loaded + end + + scenario "select all products" do + # replace with scroll_to method when upgrading to Capybara >= 3.13.0 + checkbox_id = "order_cycle_incoming_exchange_0_select_all_variants" + page.execute_script("document.getElementById('#{checkbox_id}').scrollIntoView()") + check checkbox_id + + expect_all_products_loaded + + expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{new_product.variants.first.id}", disabled: false + end + + def expect_all_products_loaded + expect(page).to have_content new_product.name.upcase + expect(page).to have_content "2 of 2 Variants Loaded" + end + end +end diff --git a/spec/features/admin/order_cycles/complex_editing_spec.rb b/spec/features/admin/order_cycles/complex_editing_spec.rb new file mode 100644 index 0000000000..0b6b9d8ac0 --- /dev/null +++ b/spec/features/admin/order_cycles/complex_editing_spec.rb @@ -0,0 +1,95 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to manage complex order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + scenario "editing an order cycle" do + # Given an order cycle with all the settings + oc = create(:order_cycle) + oc.suppliers.first.update_attribute :name, 'AAA' + oc.suppliers.last.update_attribute :name, 'ZZZ' + oc.distributors.first.update_attribute :name, 'AAAA' + oc.distributors.last.update_attribute :name, 'ZZZZ' + + # When I edit it + quick_login_as_admin + visit edit_admin_order_cycle_path(oc) + + wait_for_edit_form_to_load_order_cycle(oc) + + # Then I should see the basic settings + expect(page.find('#order_cycle_name').value).to eq(oc.name) + expect(page.find('#order_cycle_orders_open_at').value).to eq(oc.orders_open_at.to_s) + expect(page.find('#order_cycle_orders_close_at').value).to eq(oc.orders_close_at.to_s) + expect(page).to have_content "COORDINATOR #{oc.coordinator.name}" + + click_button 'Next' + + # And I should see the suppliers + expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.first.name + expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.last.name + + expect(page).to have_field 'order_cycle_incoming_exchange_0_receival_instructions', with: 'instructions 0' + expect(page).to have_field 'order_cycle_incoming_exchange_1_receival_instructions', with: 'instructions 1' + + # And the suppliers should have products + page.all('table.exchanges tbody tr.supplier').each_with_index do |row, i| + row.find('td.products').click + + products_panel = page.all('table.exchanges tr.panel-row .exchange-supplied-products').select(&:visible?).first + expect(products_panel).to have_selector "input[name='order_cycle_incoming_exchange_#{i}_select_all_variants']" + + row.find('td.products').click + end + + # And the suppliers should have fees + supplier = oc.suppliers.min_by(&:name) + expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id', selected: supplier.name + expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name + + supplier = oc.suppliers.max_by(&:name) + expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_id', selected: supplier.name + expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name + + click_button 'Next' + + # And I should see the distributors + expect(page).to have_selector 'td.distributor_name', text: oc.distributors.first.name + expect(page).to have_selector 'td.distributor_name', text: oc.distributors.last.name + + expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_time', with: 'time 0' + expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'instructions 0' + expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_time', with: 'time 1' + expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'instructions 1' + + # And the distributors should have products + page.all('table.exchanges tbody tr.distributor').each_with_index do |row, i| + row.find('td.products').click + + products_panel = page.all('table.exchanges tr.panel-row .exchange-distributed-products').select(&:visible?).first + expect(products_panel).to have_selector "input[name='order_cycle_outgoing_exchange_#{i}_select_all_variants']" + + row.find('td.products').click + end + + # And the distributors should have fees + distributor = oc.distributors.min_by(&:id) + expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id', selected: distributor.name + expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name + + distributor = oc.distributors.max_by(&:id) + expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_id', selected: distributor.name + expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name + end + + private + + def wait_for_edit_form_to_load_order_cycle(order_cycle) + expect(page).to have_field "order_cycle_name", with: order_cycle.name + end +end diff --git a/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb b/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb new file mode 100644 index 0000000000..2e569fc0ce --- /dev/null +++ b/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb @@ -0,0 +1,166 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to create/update complex order cycles with a specific time +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") } + let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 0o0, 0o0).strftime("%F %T %z") } + + scenario "updating an order cycle", js: true do + # Given an order cycle with all the settings + oc = create(:order_cycle) + initial_variants = oc.variants.sort_by(&:id) + + # And a coordinating, supplying and distributing enterprise with some products with variants + coordinator = oc.coordinator + supplier = create(:supplier_enterprise, name: 'My supplier') + distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + product = create(:product, supplier: supplier) + v1 = create(:variant, product: product) + v2 = create(:variant, product: product) + + # Relationships required for interface to work + create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) + create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) + + # And some enterprise fees + supplier_fee1 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 1') + supplier_fee2 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 2') + coordinator_fee1 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 1') + coordinator_fee2 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 2') + distributor_fee1 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 1') + distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2') + + # When I go to its edit page + quick_login_as_admin + visit admin_order_cycles_path + within "tr.order-cycle-#{oc.id}" do + find("a.edit-order-cycle").click + end + + wait_for_edit_form_to_load_order_cycle(oc) + + # And I update it + fill_in 'order_cycle_name', with: 'Plums & Avos' + fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time + fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time + + # And I configure some coordinator fees + click_button 'Add coordinator fee' + select 'Coord fee 1', from: 'order_cycle_coordinator_fee_0_id' + click_button 'Add coordinator fee' + click_button 'Add coordinator fee' + click_link 'order_cycle_coordinator_fee_2_remove' + select 'Coord fee 2', from: 'order_cycle_coordinator_fee_1_id' + + click_button 'Save and Next' + expect(page).to have_content 'Your order cycle has been updated.' + + # And I add a supplier and some products + expect(page).to have_selector("table.exchanges tr.supplier") + select 'My supplier', from: 'new_supplier_id' + click_button 'Add supplier' + expect(page).to have_selector("table.exchanges tr.supplier", text: "My supplier") + page.all("table.exchanges tr.supplier td.products").each(&:click) + + expect(page).to have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true + page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter) + check "order_cycle_incoming_exchange_2_variants_#{v1.id}" + check "order_cycle_incoming_exchange_2_variants_#{v2.id}" + + # And I configure some supplier fees + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' + select 'Supplier fee 1', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } + click_link 'order_cycle_incoming_exchange_2_enterprise_fees_0_remove' + select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' + select 'Supplier fee 2', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' + + click_button 'Save and Next' + + # And I add a distributor and some products + select 'My distributor', from: 'new_distributor_id' + click_button 'Add distributor' + expect(page).to have_field("order_cycle_outgoing_exchange_2_pickup_time") + + fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0' + fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0' + fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1' + fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1' + fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2' + fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2' + + page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click + within ".exchange-tags" do + find(:css, "tags-input .tags input").set "wholesale\n" + end + + exchange_rows = page.all("table.exchanges tbody") + exchange_rows.each do |exchange_row| + exchange_row.find("td.products").click + # Wait for the products panel to be visible. + expect(exchange_row).to have_selector "tr", count: 2 + end + + uncheck "order_cycle_outgoing_exchange_2_variants_#{v1.id}" + check "order_cycle_outgoing_exchange_2_variants_#{v2.id}" + + # And I configure some distributor fees + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' + select 'Distributor fee 1', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } + click_link 'order_cycle_outgoing_exchange_2_enterprise_fees_0_remove' + select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' + select 'Distributor fee 2', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' + + expect(page).to have_selector "#save-bar" + click_button 'Save and Back to List' + + oc = OrderCycle.last + toggle_columns "Producers", "Shops" + + expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" + expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time + expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time + expect(page).to have_content coordinator.name + + expect(page).to have_selector 'td.producers', text: 'My supplier' + expect(page).to have_selector 'td.shops', text: 'My distributor' + + # And my coordinator fees should have been configured + expect(oc.coordinator_fee_ids).to match_array [coordinator_fee1.id, coordinator_fee2.id] + + # And my supplier fees should have been configured + expect(oc.exchanges.incoming.last.enterprise_fee_ids).to eq([supplier_fee2.id]) + + # And my distributor fees should have been configured + expect(oc.exchanges.outgoing.last.enterprise_fee_ids).to eq([distributor_fee2.id]) + + # And my tags should have been save + expect(oc.exchanges.outgoing.last.tag_list).to eq(['wholesale']) + + # And it should have some variants selected + selected_initial_variants = initial_variants.take initial_variants.size - 1 + expect(oc.variants.map(&:id)).to match_array((selected_initial_variants.map(&:id) + [v1.id, v2.id])) + + # And the collection details should have been updated + expect(oc.exchanges.where(pickup_time: 'New time 0', pickup_instructions: 'New instructions 0')).to be_present + expect(oc.exchanges.where(pickup_time: 'New time 1', pickup_instructions: 'New instructions 1')).to be_present + end + + private + + def wait_for_edit_form_to_load_order_cycle(order_cycle) + expect(page).to have_field "order_cycle_name", with: order_cycle.name + end +end diff --git a/spec/features/admin/order_cycles/list_spec.rb b/spec/features/admin/order_cycles/list_spec.rb new file mode 100644 index 0000000000..ba5f2d4048 --- /dev/null +++ b/spec/features/admin/order_cycles/list_spec.rb @@ -0,0 +1,162 @@ +require 'spec_helper' + +feature ' + As an administrator + I want to list and filter order cycles +', js: true do + include AdminHelper + include AuthenticationWorkflow + include WebHelper + + scenario "listing and filtering order cycles" do + # Given some order cycles (created in an arbitrary order) + oc4 = create(:simple_order_cycle, name: 'oc4', + orders_open_at: 2.days.from_now, orders_close_at: 1.month.from_now) + oc2 = create(:simple_order_cycle, name: 'oc2', orders_close_at: 1.month.from_now) + oc6 = create(:simple_order_cycle, name: 'oc6', + orders_open_at: 1.month.ago, orders_close_at: 3.weeks.ago) + oc3 = create(:simple_order_cycle, name: 'oc3', + orders_open_at: 1.day.from_now, orders_close_at: 1.month.from_now) + oc5 = create(:simple_order_cycle, name: 'oc5', + orders_open_at: 1.month.ago, orders_close_at: 2.weeks.ago) + oc1 = create(:order_cycle, name: 'oc1') + oc0 = create(:simple_order_cycle, name: 'oc0', + orders_open_at: nil, orders_close_at: nil) + oc7 = create(:simple_order_cycle, name: 'oc7', + orders_open_at: 2.months.ago, orders_close_at: 5.weeks.ago) + schedule1 = create(:schedule, name: 'Schedule1', order_cycles: [oc1, oc3]) + create(:proxy_order, subscription: create(:subscription, schedule: schedule1), order_cycle: oc1) + + # When I go to the admin order cycles page + login_to_admin_section + click_link 'Order Cycles' + + # Then the order cycles should be ordered correctly + expect(page).to have_selector "#listing_order_cycles tr td:first-child", count: 7 + + order_cycle_names = ["oc0", "oc1", "oc2", "oc3", "oc4", "oc5", "oc6"] + expect(all("#listing_order_cycles tr td:first-child input").map(&:value)).to eq order_cycle_names + + # And the rows should have the correct classes + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}.undated" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}.open" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}.open" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}.upcoming" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc4.id}.upcoming" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc5.id}.closed" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc6.id}.closed" + + toggle_columns "Producers", "Shops" + + # And I should see all the details for an order cycle + within('table#listing_order_cycles tbody tr:nth-child(2)') do + # Then I should see the basic fields + expect(page).to have_input "oc#{oc1.id}[name]", value: oc1.name + expect(page).to have_input "oc#{oc1.id}[orders_open_at]", value: oc1.orders_open_at + expect(page).to have_input "oc#{oc1.id}[orders_close_at]", value: oc1.orders_close_at + expect(page).to have_content oc1.coordinator.name + + # And I should see the suppliers and distributors + oc1.suppliers.each { |s| expect(page).to have_content s.name } + oc1.distributors.each { |d| expect(page).to have_content d.name } + + # And I should see the number of variants + expect(page).to have_selector 'td.products', text: '2 variants' + end + + # I can load more order_cycles + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc7.id}" + click_button "Show 30 more days" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc7.id}" + + # I can filter order cycle by involved enterprises + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + select2_select oc1.suppliers.first.name, from: "involving_filter" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + select2_select "Any Enterprise", from: "involving_filter" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + + # I can filter order cycles by name + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + fill_in "query", with: oc0.name + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + fill_in "query", with: '' + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + + # I can filter order cycle by schedule + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" + select2_select schedule1.name, from: "schedule_filter" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" + select2_select 'Any Schedule', from: "schedule_filter" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" + expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" + + # Attempting to edit dates of an open order cycle with active subscriptions + find("#oc#{oc1.id}_orders_open_at").click + expect(page).to have_selector "#confirm-dialog .message", text: I18n.t('admin.order_cycles.date_warning.msg', n: 1) + end + + describe 'listing order cycles with other locales' do + let!(:oc_pt) { create(:simple_order_cycle, name: 'oc', orders_open_at: '2012-01-01 00:00') } + + around(:each) do |spec| + I18n.locale = :pt + spec.run + I18n.locale = :en + end + + context 'using datepickers' do + it "correctly opens the datepicker and changes the date field" do + quick_login_as_admin + visit admin_order_cycles_path + + within("tr.order-cycle-#{oc_pt.id}") do + expect(find('input.datetimepicker', match: :first).value).to start_with '2012-01-01 00:00' + find('img.ui-datepicker-trigger', match: :first).click + end + + within("#ui-datepicker-div") do + expect(page).to have_selector 'a.ui-state-active', text: '1' + + click_link '30' + find('button.ui-datepicker-close', match: :first).click + end + + within("tr.order-cycle-#{oc_pt.id}") do + expect(find('input.datetimepicker', match: :first).value).to eq '2012-01-30 00:00' + end + end + end + end + + private + + def wait_for_edit_form_to_load_order_cycle(order_cycle) + expect(page).to have_field "order_cycle_name", with: order_cycle.name + end + + def select_incoming_variant(supplier, exchange_no, variant) + page.find("table.exchanges tr.supplier-#{supplier.id} td.products").click + check "order_cycle_incoming_exchange_#{exchange_no}_variants_#{variant.id}" + end +end diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles/simple_spec.rb similarity index 51% rename from spec/features/admin/order_cycles_spec.rb rename to spec/features/admin/order_cycles/simple_spec.rb index 7d1567396a..979dc0be8b 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles/simple_spec.rb @@ -2,570 +2,12 @@ require 'spec_helper' feature ' As an administrator - I want to manage order cycles + I want to manage simple order cycles ', js: true do include AdminHelper include AuthenticationWorkflow include WebHelper - scenario "listing and filtering order cycles" do - # Given some order cycles (created in an arbitrary order) - oc4 = create(:simple_order_cycle, name: 'oc4', - orders_open_at: 2.days.from_now, orders_close_at: 1.month.from_now) - oc2 = create(:simple_order_cycle, name: 'oc2', orders_close_at: 1.month.from_now) - oc6 = create(:simple_order_cycle, name: 'oc6', - orders_open_at: 1.month.ago, orders_close_at: 3.weeks.ago) - oc3 = create(:simple_order_cycle, name: 'oc3', - orders_open_at: 1.day.from_now, orders_close_at: 1.month.from_now) - oc5 = create(:simple_order_cycle, name: 'oc5', - orders_open_at: 1.month.ago, orders_close_at: 2.weeks.ago) - oc1 = create(:order_cycle, name: 'oc1') - oc0 = create(:simple_order_cycle, name: 'oc0', - orders_open_at: nil, orders_close_at: nil) - oc7 = create(:simple_order_cycle, name: 'oc7', - orders_open_at: 2.months.ago, orders_close_at: 5.weeks.ago) - schedule1 = create(:schedule, name: 'Schedule1', order_cycles: [oc1, oc3]) - create(:proxy_order, subscription: create(:subscription, schedule: schedule1), order_cycle: oc1) - - # When I go to the admin order cycles page - login_to_admin_section - click_link 'Order Cycles' - - # Then the order cycles should be ordered correctly - expect(page).to have_selector "#listing_order_cycles tr td:first-child", count: 7 - - order_cycle_names = ["oc0", "oc1", "oc2", "oc3", "oc4", "oc5", "oc6"] - expect(all("#listing_order_cycles tr td:first-child input").map(&:value)).to eq order_cycle_names - - # And the rows should have the correct classes - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}.undated" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}.open" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}.open" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}.upcoming" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc4.id}.upcoming" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc5.id}.closed" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc6.id}.closed" - - toggle_columns "Producers", "Shops" - - # And I should see all the details for an order cycle - within('table#listing_order_cycles tbody tr:nth-child(2)') do - # Then I should see the basic fields - expect(page).to have_input "oc#{oc1.id}[name]", value: oc1.name - expect(page).to have_input "oc#{oc1.id}[orders_open_at]", value: oc1.orders_open_at - expect(page).to have_input "oc#{oc1.id}[orders_close_at]", value: oc1.orders_close_at - expect(page).to have_content oc1.coordinator.name - - # And I should see the suppliers and distributors - oc1.suppliers.each { |s| expect(page).to have_content s.name } - oc1.distributors.each { |d| expect(page).to have_content d.name } - - # And I should see the number of variants - expect(page).to have_selector 'td.products', text: '2 variants' - end - - # I can load more order_cycles - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc7.id}" - click_button "Show 30 more days" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc7.id}" - - # I can filter order cycle by involved enterprises - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - select2_select oc1.suppliers.first.name, from: "involving_filter" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - select2_select "Any Enterprise", from: "involving_filter" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - - # I can filter order cycles by name - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - fill_in "query", with: oc0.name - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - fill_in "query", with: '' - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - - # I can filter order cycle by schedule - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" - select2_select schedule1.name, from: "schedule_filter" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_no_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" - select2_select 'Any Schedule', from: "schedule_filter" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc0.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" - expect(page).to have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" - - # Attempting to edit dates of an open order cycle with active subscriptions - find("#oc#{oc1.id}_orders_open_at").click - expect(page).to have_selector "#confirm-dialog .message", text: I18n.t('admin.order_cycles.date_warning.msg', n: 1) - end - - describe 'listing order cycles with other locales' do - let!(:oc_pt) { create(:simple_order_cycle, name: 'oc', orders_open_at: '2012-01-01 00:00') } - - around(:each) do |spec| - I18n.locale = :pt - spec.run - I18n.locale = :en - end - - context 'using datepickers' do - it "correctly opens the datepicker and changes the date field" do - quick_login_as_admin - visit admin_order_cycles_path - - within("tr.order-cycle-#{oc_pt.id}") do - expect(find('input.datetimepicker', match: :first).value).to start_with '2012-01-01 00:00' - find('img.ui-datepicker-trigger', match: :first).click - end - - within("#ui-datepicker-div") do - expect(page).to have_selector 'a.ui-state-active', text: '1' - - click_link '30' - find('button.ui-datepicker-close', match: :first).click - end - - within("tr.order-cycle-#{oc_pt.id}") do - expect(find('input.datetimepicker', match: :first).value).to eq '2012-01-30 00:00' - end - end - end - end - - context "with specific time" do - let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") } - let(:order_cycle_closing_time) { Time.zone.local(2040, 11, 13, 17, 0o0, 0o0).strftime("%F %T %z") } - - scenario "creating an order cycle with full interface", js: true do - # Given coordinating, supplying and distributing enterprises with some products with variants - coordinator = create(:distributor_enterprise, name: 'My coordinator') - supplier = create(:supplier_enterprise, name: 'My supplier') - product = create(:product, supplier: supplier) - v1 = create(:variant, product: product) - v2 = create(:variant, product: product) - distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) - - # Relationships required for interface to work - create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - - # And some enterprise fees - supplier_fee = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee') - coordinator_fee = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee') - distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee') - - # When I go to the new order cycle page - quick_login_as_admin - visit admin_order_cycles_path - click_link 'New Order Cycle' - - # Select a coordinator since there are two available - select2_select 'My coordinator', from: 'coordinator_id' - click_button "Continue >" - - # I cannot save before filling in the required fields - expect(page).to have_button("Create", disabled: true) - - # The Create button is enabled once Name is entered - fill_in 'order_cycle_name', with: 'Plums & Avos' - expect(page).to have_button("Create", disabled: false) - - # If I fill in the basic fields - fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time - fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time - - # And I add a coordinator fee - click_button 'Add coordinator fee' - select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id' - - click_button 'Create' - expect(page).to have_content 'Your order cycle has been created.' - - # I should not be able to add a blank supplier - expect(page).to have_select 'new_supplier_id', selected: '' - expect(page).to have_button 'Add supplier', disabled: true - - # And I add a supplier and some products - select 'My supplier', from: 'new_supplier_id' - click_button 'Add supplier' - fill_in 'order_cycle_incoming_exchange_0_receival_instructions', with: 'receival instructions' - page.find('table.exchanges tr.supplier td.products').click - check "order_cycle_incoming_exchange_0_variants_#{v1.id}" - check "order_cycle_incoming_exchange_0_variants_#{v2.id}" - - # I should not be able to re-add the supplier - expect(page).not_to have_select 'new_supplier_id', with_options: ['My supplier'] - expect(page).to have_button 'Add supplier', disabled: true - expect(page.all("td.supplier_name").map(&:text)).to eq(['My supplier']) - - # And I add a supplier fee - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - select 'My supplier', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id' - select 'Supplier fee', from: 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Next' - - # And I add a distributor with the same products - select 'My distributor', from: 'new_distributor_id' - click_button 'Add distributor' - - fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time' - fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions' - - page.find('table.exchanges tr.distributor td.products').click - check "order_cycle_outgoing_exchange_0_variants_#{v1.id}" - check "order_cycle_outgoing_exchange_0_variants_#{v2.id}" - - page.find('table.exchanges tr.distributor td.tags').click - within ".exchange-tags" do - find(:css, "tags-input .tags input").set "wholesale\n" - end - - # And I add a distributor fee - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - select 'My distributor', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id' - select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Back to List' - - oc = OrderCycle.last - toggle_columns "Producers", "Shops" - - expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" - expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time - expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time - expect(page).to have_content "My coordinator" - - expect(page).to have_selector 'td.producers', text: 'My supplier' - expect(page).to have_selector 'td.shops', text: 'My distributor' - - # And it should have some fees - expect(oc.exchanges.incoming.first.enterprise_fees).to eq([supplier_fee]) - expect(oc.coordinator_fees).to eq([coordinator_fee]) - expect(oc.exchanges.outgoing.first.enterprise_fees).to eq([distributor_fee]) - - # And it should have some variants selected - expect(oc.exchanges.first.variants.count).to eq(2) - expect(oc.exchanges.last.variants.count).to eq(2) - - # And my receival and pickup time and instructions should have been saved - exchange = oc.exchanges.incoming.first - expect(exchange.receival_instructions).to eq('receival instructions') - - exchange = oc.exchanges.outgoing.first - expect(exchange.pickup_time).to eq('pickup time') - expect(exchange.pickup_instructions).to eq('pickup instructions') - expect(exchange.tag_list).to eq(['wholesale']) - end - - scenario "updating an order cycle", js: true do - # Given an order cycle with all the settings - oc = create(:order_cycle) - initial_variants = oc.variants.sort_by(&:id) - - # And a coordinating, supplying and distributing enterprise with some products with variants - coordinator = oc.coordinator - supplier = create(:supplier_enterprise, name: 'My supplier') - distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) - product = create(:product, supplier: supplier) - v1 = create(:variant, product: product) - v2 = create(:variant, product: product) - - # Relationships required for interface to work - create(:enterprise_relationship, parent: supplier, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: distributor, child: coordinator, permissions_list: [:add_to_order_cycle]) - create(:enterprise_relationship, parent: supplier, child: distributor, permissions_list: [:add_to_order_cycle]) - - # And some enterprise fees - supplier_fee1 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 1') - supplier_fee2 = create(:enterprise_fee, enterprise: supplier, name: 'Supplier fee 2') - coordinator_fee1 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 1') - coordinator_fee2 = create(:enterprise_fee, enterprise: coordinator, name: 'Coord fee 2') - distributor_fee1 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 1') - distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2') - - # When I go to its edit page - quick_login_as_admin - visit admin_order_cycles_path - within "tr.order-cycle-#{oc.id}" do - find("a.edit-order-cycle").click - end - - wait_for_edit_form_to_load_order_cycle(oc) - - # And I update it - fill_in 'order_cycle_name', with: 'Plums & Avos' - fill_in 'order_cycle_orders_open_at', with: order_cycle_opening_time - fill_in 'order_cycle_orders_close_at', with: order_cycle_closing_time - - # And I configure some coordinator fees - click_button 'Add coordinator fee' - select 'Coord fee 1', from: 'order_cycle_coordinator_fee_0_id' - click_button 'Add coordinator fee' - click_button 'Add coordinator fee' - click_link 'order_cycle_coordinator_fee_2_remove' - select 'Coord fee 2', from: 'order_cycle_coordinator_fee_1_id' - - click_button 'Save and Next' - expect(page).to have_content 'Your order cycle has been updated.' - - # And I add a supplier and some products - expect(page).to have_selector("table.exchanges tr.supplier") - select 'My supplier', from: 'new_supplier_id' - click_button 'Add supplier' - expect(page).to have_selector("table.exchanges tr.supplier", text: "My supplier") - page.all("table.exchanges tr.supplier td.products").each(&:click) - - - expect(page).to have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true - page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter) - check "order_cycle_incoming_exchange_2_variants_#{v1.id}" - check "order_cycle_incoming_exchange_2_variants_#{v2.id}" - - # And I configure some supplier fees - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' - select 'Supplier fee 1', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - within("tr.supplier-#{supplier.id}") { click_button 'Add fee' } - click_link 'order_cycle_incoming_exchange_2_enterprise_fees_0_remove' - select 'My supplier', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_id' - select 'Supplier fee 2', from: 'order_cycle_incoming_exchange_2_enterprise_fees_0_enterprise_fee_id' - - click_button 'Save and Next' - - # And I add a distributor and some products - select 'My distributor', from: 'new_distributor_id' - click_button 'Add distributor' - expect(page).to have_field("order_cycle_outgoing_exchange_2_pickup_time") - - fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0' - fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0' - fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1' - fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1' - fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2' - fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2' - - page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click - within ".exchange-tags" do - find(:css, "tags-input .tags input").set "wholesale\n" - end - - exchange_rows = page.all("table.exchanges tbody") - exchange_rows.each do |exchange_row| - exchange_row.find("td.products").click - # Wait for the products panel to be visible. - expect(exchange_row).to have_selector "tr", count: 2 - end - - uncheck "order_cycle_outgoing_exchange_2_variants_#{v1.id}" - check "order_cycle_outgoing_exchange_2_variants_#{v2.id}" - - # And I configure some distributor fees - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' - select 'Distributor fee 1', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - within("tr.distributor-#{distributor.id}") { click_button 'Add fee' } - click_link 'order_cycle_outgoing_exchange_2_enterprise_fees_0_remove' - select 'My distributor', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_id' - select 'Distributor fee 2', from: 'order_cycle_outgoing_exchange_2_enterprise_fees_0_enterprise_fee_id' - - expect(page).to have_selector "#save-bar" - click_button 'Save and Back to List' - - oc = OrderCycle.last - toggle_columns "Producers", "Shops" - - expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos" - expect(page).to have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time - expect(page).to have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time - expect(page).to have_content coordinator.name - - expect(page).to have_selector 'td.producers', text: 'My supplier' - expect(page).to have_selector 'td.shops', text: 'My distributor' - - # And my coordinator fees should have been configured - expect(oc.coordinator_fee_ids).to match_array [coordinator_fee1.id, coordinator_fee2.id] - - # And my supplier fees should have been configured - expect(oc.exchanges.incoming.last.enterprise_fee_ids).to eq([supplier_fee2.id]) - - # And my distributor fees should have been configured - expect(oc.exchanges.outgoing.last.enterprise_fee_ids).to eq([distributor_fee2.id]) - - # And my tags should have been save - expect(oc.exchanges.outgoing.last.tag_list).to eq(['wholesale']) - - # And it should have some variants selected - selected_initial_variants = initial_variants.take initial_variants.size - 1 - expect(oc.variants.map(&:id)).to match_array((selected_initial_variants.map(&:id) + [v1.id, v2.id])) - - # And the collection details should have been updated - expect(oc.exchanges.where(pickup_time: 'New time 0', pickup_instructions: 'New instructions 0')).to be_present - expect(oc.exchanges.where(pickup_time: 'New time 1', pickup_instructions: 'New instructions 1')).to be_present - end - end - - scenario "editing an order cycle" do - # Given an order cycle with all the settings - oc = create(:order_cycle) - oc.suppliers.first.update_attribute :name, 'AAA' - oc.suppliers.last.update_attribute :name, 'ZZZ' - oc.distributors.first.update_attribute :name, 'AAAA' - oc.distributors.last.update_attribute :name, 'ZZZZ' - - # When I edit it - quick_login_as_admin - visit edit_admin_order_cycle_path(oc) - - wait_for_edit_form_to_load_order_cycle(oc) - - # Then I should see the basic settings - expect(page.find('#order_cycle_name').value).to eq(oc.name) - expect(page.find('#order_cycle_orders_open_at').value).to eq(oc.orders_open_at.to_s) - expect(page.find('#order_cycle_orders_close_at').value).to eq(oc.orders_close_at.to_s) - expect(page).to have_content "COORDINATOR #{oc.coordinator.name}" - - click_button 'Next' - - # And I should see the suppliers - expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.first.name - expect(page).to have_selector 'td.supplier_name', text: oc.suppliers.last.name - - expect(page).to have_field 'order_cycle_incoming_exchange_0_receival_instructions', with: 'instructions 0' - expect(page).to have_field 'order_cycle_incoming_exchange_1_receival_instructions', with: 'instructions 1' - - # And the suppliers should have products - page.all('table.exchanges tbody tr.supplier').each_with_index do |row, i| - row.find('td.products').click - - products_panel = page.all('table.exchanges tr.panel-row .exchange-supplied-products').select(&:visible?).first - expect(products_panel).to have_selector "input[name='order_cycle_incoming_exchange_#{i}_select_all_variants']" - - row.find('td.products').click - end - - # And the suppliers should have fees - supplier = oc.suppliers.min_by(&:name) - expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_id', selected: supplier.name - expect(page).to have_select 'order_cycle_incoming_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name - - supplier = oc.suppliers.max_by(&:name) - expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_id', selected: supplier.name - expect(page).to have_select 'order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: supplier.enterprise_fees.first.name - - click_button 'Next' - - # And I should see the distributors - expect(page).to have_selector 'td.distributor_name', text: oc.distributors.first.name - expect(page).to have_selector 'td.distributor_name', text: oc.distributors.last.name - - expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_time', with: 'time 0' - expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'instructions 0' - expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_time', with: 'time 1' - expect(page).to have_field 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'instructions 1' - - # And the distributors should have products - page.all('table.exchanges tbody tr.distributor').each_with_index do |row, i| - row.find('td.products').click - - products_panel = page.all('table.exchanges tr.panel-row .exchange-distributed-products').select(&:visible?).first - expect(products_panel).to have_selector "input[name='order_cycle_outgoing_exchange_#{i}_select_all_variants']" - - row.find('td.products').click - end - - # And the distributors should have fees - distributor = oc.distributors.min_by(&:id) - expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_id', selected: distributor.name - expect(page).to have_select 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name - - distributor = oc.distributors.max_by(&:id) - expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_id', selected: distributor.name - expect(page).to have_select 'order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_fee_id', selected: distributor.enterprise_fees.first.name - end - - scenario "editing an order cycle with an exchange between the same enterprise" do - c = create(:distributor_enterprise, is_primary_producer: true) - - # Given two order cycles, one with a mono-enterprise incoming exchange... - oc_incoming = create(:simple_order_cycle, suppliers: [c], coordinator: c) - - # And the other with a mono-enterprise outgoing exchange - oc_outgoing = create(:simple_order_cycle, coordinator: c, distributors: [c]) - - # When I edit the first order cycle, the exchange should appear as incoming - quick_login_as_admin - visit admin_order_cycle_incoming_path(oc_incoming) - expect(page).to have_selector 'table.exchanges tr.supplier' - visit admin_order_cycle_outgoing_path(oc_incoming) - expect(page).not_to have_selector 'table.exchanges tr.distributor' - - # And when I edit the second order cycle, the exchange should appear as outgoing - visit admin_order_cycle_outgoing_path(oc_outgoing) - expect(page).to have_selector 'table.exchanges tr.distributor' - visit admin_order_cycle_incoming_path(oc_outgoing) - expect(page).not_to have_selector 'table.exchanges tr.supplier' - end - - describe "editing an order cycle with multiple pages of products", js: true do - let(:order_cycle) { create(:order_cycle) } - let(:supplier_enterprise) { order_cycle.exchanges.incoming.first.sender } - let!(:new_product) { create(:product, supplier: supplier_enterprise) } - - before do - stub_const("Api::ExchangeProductsController::DEFAULT_PER_PAGE", 1) - - quick_login_as_admin - visit admin_order_cycle_incoming_path(order_cycle) - expect(page).to have_content "1 / 2 selected" - - page.find("tr.supplier-#{supplier_enterprise.id} td.products").click - expect(page).to have_selector ".exchange-product-details" - - expect(page).to have_content "1 of 2 Variants Loaded" - expect(page).to_not have_content new_product.name - end - - scenario "load all products" do - page.find(".exchange-load-all-variants a").click - - expect_all_products_loaded - end - - scenario "select all products" do - check "order_cycle_incoming_exchange_0_select_all_variants" - - expect_all_products_loaded - - expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{new_product.variants.first.id}", disabled: false - end - - def expect_all_products_loaded - expect(page).to have_content new_product.name.upcase - expect(page).to have_content "2 of 2 Variants Loaded" - end - end - scenario "updating many order cycle opening/closing times at once", js: true do # Given three order cycles oc1 = create(:simple_order_cycle) @@ -1171,4 +613,4 @@ feature ' page.find("table.exchanges tr.supplier-#{supplier.id} td.products").click check "order_cycle_incoming_exchange_#{exchange_no}_variants_#{variant.id}" end -end +end \ No newline at end of file diff --git a/spec/features/admin/payment_method_spec.rb b/spec/features/admin/payment_method_spec.rb index 34d96dc061..356c450611 100644 --- a/spec/features/admin/payment_method_spec.rb +++ b/spec/features/admin/payment_method_spec.rb @@ -158,6 +158,8 @@ feature ' it "creates payment methods" do visit spree.new_admin_payment_method_path fill_in 'payment_method_name', with: 'Cheque payment method' + expect(page).to have_field 'payment_method_description' + expect(page).to have_select 'payment_method_display_on' check "payment_method_distributor_ids_#{distributor1.id}" find(:css, "tags-input .tags input").set "local\n" diff --git a/spec/features/admin/shipping_methods_spec.rb b/spec/features/admin/shipping_methods_spec.rb index 2572194a0b..84de423581 100644 --- a/spec/features/admin/shipping_methods_spec.rb +++ b/spec/features/admin/shipping_methods_spec.rb @@ -108,7 +108,7 @@ feature 'shipping methods' do # Show the correct fields expect(page).to have_field 'shipping_method_name' expect(page).to have_field 'shipping_method_description' - expect(page).not_to have_select 'shipping_method_display_on' + expect(page).to have_select 'shipping_method_display_on' expect(page).to have_css 'div#shipping_method_zones_field' expect(page).to have_field 'shipping_method_require_ship_address_true', checked: true diff --git a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee index 4feff89868..d483bec6a8 100644 --- a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee +++ b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee @@ -903,8 +903,8 @@ describe "AdminProductEditCtrl", -> $scope.categoryFilter = "6" $scope.resetSelectFilters() expect($scope.query).toBe "" - expect($scope.producerFilter).toBe "0" - expect($scope.categoryFilter).toBe "0" + expect($scope.producerFilter).toBeUndefined + expect($scope.categoryFilter).toBeUndefined describe "converting arrays of objects with ids to an object with ids as keys", -> diff --git a/spec/javascripts/unit/admin/side_menu/services/side_menu.js.coffee b/spec/javascripts/unit/admin/side_menu/services/side_menu.js.coffee index 0840d69c28..74c802c7d4 100644 --- a/spec/javascripts/unit/admin/side_menu/services/side_menu.js.coffee +++ b/spec/javascripts/unit/admin/side_menu/services/side_menu.js.coffee @@ -69,25 +69,3 @@ describe "SideMenu service", -> it "returns null if no items are found", -> SideMenu.items = [ { name: "Name 1"}, { name: "Name 2"} ] expect(SideMenu.find_by_name("Name 3")).toBe null - - describe "hiding an item by name", -> - it "sets visible to false on the response from find_by_name", -> - mockItem = { visible: true } - spyOn(SideMenu, 'find_by_name').and.returnValue mockItem - SideMenu.hide_item_by_name() - expect(mockItem.visible).toBe false - - it "doesn't crash if null is returned from find_by_name", -> - spyOn(SideMenu, 'find_by_name').and.returnValue null - SideMenu.hide_item_by_name() - - describe "showing an item by name", -> - it "sets visible to false on the response from find_by_name", -> - mockItem = { visible: false } - spyOn(SideMenu, 'find_by_name').and.returnValue mockItem - SideMenu.show_item_by_name() - expect(mockItem.visible).toBe true - - it "doesn't crash if null is returned from find_by_name", -> - spyOn(SideMenu, 'find_by_name').and.returnValue null - SideMenu.show_item_by_name() diff --git a/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee index 82c26397ca..c95fbdf81b 100644 --- a/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee @@ -1,7 +1,7 @@ describe "Enterprises service", -> Enterprises = $rootScope = null CurrentHubMock = {} - Geo = + GmapsGeo = OK: 'ok' succeed: true geocode: (query, callback) -> @@ -31,7 +31,7 @@ describe "Enterprises service", -> module 'Darkswarm' module ($provide)-> $provide.value "CurrentHub", CurrentHubMock - $provide.value "Geo", Geo + $provide.value "GmapsGeo", GmapsGeo null angular.module('Darkswarm').value('enterprises', enterprises) angular.module('Darkswarm').value('taxons', taxons) @@ -118,12 +118,12 @@ describe "Enterprises service", -> spyOn(Enterprises, "setDistanceFrom") it "calculates distance for all enterprises when geocoding succeeds", -> - Geo.succeed = true + GmapsGeo.succeed = true Enterprises.calculateDistanceGeo('query') expect(Enterprises.setDistanceFrom).toHaveBeenCalledWith("location") it "resets distance when geocoding fails", -> - Geo.succeed = false + GmapsGeo.succeed = false spyOn(Enterprises, "resetDistance") Enterprises.calculateDistanceGeo('query') expect(Enterprises.setDistanceFrom).not.toHaveBeenCalled() diff --git a/spec/javascripts/unit/darkswarm/services/map_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/map_spec.js.coffee index fb4def8342..eed215dbe1 100644 --- a/spec/javascripts/unit/darkswarm/services/map_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/map_spec.js.coffee @@ -1,7 +1,7 @@ describe "Hubs service", -> OfnMap = null CurrentHubMock = {} - Geo = {} + GmapsGeo = {} enterprises = [ { id: 2 @@ -54,7 +54,7 @@ describe "Hubs service", -> angular.module('Darkswarm').value('enterprises', enterprises) module ($provide)-> $provide.value "CurrentHub", CurrentHubMock - $provide.value "Geo", Geo + $provide.value "GmapsGeo", GmapsGeo null inject ($injector)-> OfnMap = $injector.get("OfnMap") diff --git a/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee index 62c8c0a071..88ff585f00 100644 --- a/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee @@ -12,7 +12,7 @@ describe 'Products service', -> productWithImage = null properties = null taxons = null - Geo = {} + GmapsGeo = {} endpoint = "/api/order_cycles/1/products?distributor=1" beforeEach -> @@ -53,7 +53,7 @@ describe 'Products service', -> $provide.value "currentOrder", currentOrder $provide.value "taxons", taxons $provide.value "properties", properties - $provide.value "Geo", Geo + $provide.value "GmapsGeo", GmapsGeo $provide.value "OrderCycle", OrderCycle $provide.value "railsFlash", null null diff --git a/spec/models/order_cycle_spec.rb b/spec/models/order_cycle_spec.rb index 7f198e29ea..21cad530a9 100644 --- a/spec/models/order_cycle_spec.rb +++ b/spec/models/order_cycle_spec.rb @@ -65,8 +65,8 @@ describe OrderCycle do oc_received = create(:simple_order_cycle, distributors: [e2]) oc_not_accessible = create(:simple_order_cycle, coordinator: e1) - expect(OrderCycle.accessible_by(user)).to include(oc_coordinated, oc_sent, oc_received) - expect(OrderCycle.accessible_by(user)).not_to include(oc_not_accessible) + expect(OrderCycle.visible_by(user)).to include(oc_coordinated, oc_sent, oc_received) + expect(OrderCycle.visible_by(user)).not_to include(oc_not_accessible) end it "finds the most recently closed order cycles" do diff --git a/spec/models/spree/calculator/price_sack_spec.rb b/spec/models/spree/calculator/price_sack_spec.rb index 921b657f88..05c7a8cb8a 100644 --- a/spec/models/spree/calculator/price_sack_spec.rb +++ b/spec/models/spree/calculator/price_sack_spec.rb @@ -49,6 +49,32 @@ describe Spree::Calculator::PriceSack do end end + context "minimal amount is float" do + before do + calculator.preferred_minimal_amount = 16.5 + calculator.preferred_normal_amount = 5 + calculator.preferred_discount_amount = 1 + line_item.quantity = 2 + end + + context "with price bellow minimal amount" do + let(:price) { 8 } + + it "returns the correct value of cost" do + expect(calculator.compute(line_item)).to eq(5) + end + end + + context "with price above minimal amount" do + let(:price) { 8.5 } + + it "returns the correct value of cost" do + expect(calculator.compute(line_item)).to eq(1) + end + end + + end + context "extends LocalizedNumber" do it_behaves_like "a model using the LocalizedNumber module", [:preferred_minimal_amount, :preferred_normal_amount, :preferred_discount_amount] end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index cb6bf45f0f..4309d105c9 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -257,6 +257,37 @@ module Spree end end + describe "in_distributors" do + let!(:distributor1) { create(:distributor_enterprise) } + let!(:distributor2) { create(:distributor_enterprise) } + let!(:product1) { create(:product) } + let!(:product2) { create(:product) } + let!(:product3) { create(:product) } + let!(:product4) { create(:product) } + let!(:order_cycle1) { + create(:order_cycle, distributors: [distributor1], + variants: [product1.variants.first, product2.variants.first]) + } + let!(:order_cycle2) { + create(:order_cycle, distributors: [distributor2], + variants: [product3.variants.first]) + } + + it "returns distributed products for a given Enterprise AR relation" do + distributors = Enterprise.where(id: [distributor1.id, distributor2.id]).to_a + + expect(Product.in_distributors(distributors)).to include product1, product2, product3 + expect(Product.in_distributors(distributors)).to_not include product4 + end + + it "returns distributed products for a given array of enterprise ids" do + distributors_ids = [distributor1.id, distributor2.id] + + expect(Product.in_distributors(distributors_ids)).to include product1, product2, product3 + expect(Product.in_distributors(distributors_ids)).to_not include product4 + end + end + describe "in_supplier_or_distributor" do it "shows products in supplier" do s1 = create(:supplier_enterprise) @@ -579,57 +610,6 @@ module Spree end end - describe "stock filtering" do - it "considers products that are on_demand as being in stock" do - product = create(:simple_product, on_demand: true) - product.master.update_attribute(:on_hand, 0) - expect(product.has_stock?).to eq(true) - end - - describe "finding products in stock for a particular distribution" do - it "returns on-demand products" do - p = create(:simple_product, on_demand: true) - p.variants.first.update_attributes!(on_hand: 0, on_demand: true) - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - oc.exchanges.outgoing.first.variants << p.variants.first - - expect(p).to have_stock_for_distribution(oc, d) - end - - it "returns products with in-stock variants" do - p = create(:simple_product) - v = create(:variant, product: p) - v.update_attribute(:on_hand, 1) - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - oc.exchanges.outgoing.first.variants << v - - expect(p).to have_stock_for_distribution(oc, d) - end - - it "returns products with on-demand variants" do - p = create(:simple_product) - v = create(:variant, product: p, on_demand: true) - v.update_attribute(:on_hand, 0) - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - oc.exchanges.outgoing.first.variants << v - - expect(p).to have_stock_for_distribution(oc, d) - end - - it "does not return products that have stock not in the distribution" do - p = create(:simple_product) - p.master.update_attribute(:on_hand, 1) - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - - expect(p).not_to have_stock_for_distribution(oc, d) - end - end - end - describe "taxons" do let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } diff --git a/spec/services/bulk_invoice_service_spec.rb b/spec/services/bulk_invoice_service_spec.rb index 4056a1b88f..687e680bcc 100644 --- a/spec/services/bulk_invoice_service_spec.rb +++ b/spec/services/bulk_invoice_service_spec.rb @@ -47,4 +47,25 @@ describe BulkInvoiceService do expect(filepath).to eq 'tmp/invoices/1234567.pdf' end end + + describe "#orders_from" do + let(:renderer) { InvoiceRenderer.new } + + before do + allow(InvoiceRenderer).to receive(:new).and_return(renderer) + end + + it "orders with completed desc" do + order_old = create(:order_with_distributor, :completed, completed_at: 2.minutes.ago) + order_oldest = create(:order_with_distributor, :completed, completed_at: 4.minutes.ago) + order_older = create(:order_with_distributor, :completed, completed_at: 3.minutes.ago) + + expect(renderer).to receive(:render_to_string).with(order_old).ordered.and_return("") + expect(renderer).to receive(:render_to_string).with(order_older).ordered.and_return("") + expect(renderer).to receive(:render_to_string).with(order_oldest).ordered.and_return("") + + order_ids = [order_oldest, order_old, order_older].map(&:id) + service.start_pdf_job_without_delay(order_ids) + end + end end diff --git a/spec/services/order_cart_reset_spec.rb b/spec/services/order_cart_reset_spec.rb index 0b26977d6a..6c95c3ed81 100644 --- a/spec/services/order_cart_reset_spec.rb +++ b/spec/services/order_cart_reset_spec.rb @@ -10,7 +10,7 @@ describe OrderCartReset do let(:new_distributor) { create(:distributor_enterprise) } it "empties order" do - OrderCartReset.new(order, new_distributor.id.to_s, nil, nil).call + OrderCartReset.new(order, new_distributor.id.to_s).reset_distributor expect(order.line_items).to be_empty end @@ -28,7 +28,7 @@ describe OrderCartReset do it "empties order and makes order cycle nil" do expect(order_cycle_list).to receive(:call).and_return([]) - OrderCartReset.new(order, distributor.id.to_s, nil, nil).call + OrderCartReset.new(order, distributor.id.to_s).reset_other!(nil, nil) expect(order.line_items).to be_empty expect(order.order_cycle).to be_nil @@ -38,7 +38,7 @@ describe OrderCartReset do other_order_cycle = create(:simple_order_cycle, distributors: [distributor]) expect(order_cycle_list).to receive(:call).and_return([other_order_cycle]) - OrderCartReset.new(order, distributor.id.to_s, nil, nil).call + OrderCartReset.new(order, distributor.id.to_s).reset_other!(nil, nil) expect(order.order_cycle).to eq other_order_cycle end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4044a92992..3c60e24f65 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -44,7 +44,6 @@ WebMock.disable_net_connect!( # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } -require 'spree/testing_support/controller_requests' require 'spree/testing_support/capybara_ext' require 'spree/api/testing_support/setup' require 'spree/testing_support/authorization_helpers' @@ -156,8 +155,8 @@ RSpec.configure do |config| config.include Spree::UrlHelpers config.include Spree::CheckoutHelpers config.include Spree::MoneyHelper - config.include Spree::TestingSupport::ControllerRequests, type: :controller config.include Spree::TestingSupport::Preferences + config.include ControllerRequestsHelper, type: :controller config.include Devise::TestHelpers, type: :controller config.extend Spree::Api::TestingSupport::Setup, type: :controller config.include OpenFoodNetwork::ApiHelper, type: :controller diff --git a/spec/support/controller_hacks.rb b/spec/support/controller_hacks.rb deleted file mode 100644 index 8d23cb7483..0000000000 --- a/spec/support/controller_hacks.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'active_support/all' - -module ControllerHacks - def api_get(action, params = {}, session = nil, flash = nil) - api_process(action, params, session, flash, "GET") - end - - def api_post(action, params = {}, session = nil, flash = nil) - api_process(action, params, session, flash, "POST") - end - - def api_put(action, params = {}, session = nil, flash = nil) - api_process(action, params, session, flash, "PUT") - end - - def api_delete(action, params = {}, session = nil, flash = nil) - api_process(action, params, session, flash, "DELETE") - end - - def api_process(action, params = {}, session = nil, flash = nil, method = "get") - scoping = respond_to?(:resource_scoping) ? resource_scoping : {} - process(action, - method, - params. - merge(scoping). - reverse_merge!(use_route: :spree, format: :json), - session, - flash) - end -end - -RSpec.configure do |config| - config.include ControllerHacks, type: :controller -end diff --git a/spec/support/controller_requests_helper.rb b/spec/support/controller_requests_helper.rb new file mode 100644 index 0000000000..d9dee19e2f --- /dev/null +++ b/spec/support/controller_requests_helper.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require 'active_support/all' + +module ControllerRequestsHelper + def api_get(action, params = {}, session = nil, flash = nil) + process_json_action(action, params, session, flash, "GET") + end + + def api_post(action, params = {}, session = nil, flash = nil) + process_json_action(action, params, session, flash, "POST") + end + + def api_put(action, params = {}, session = nil, flash = nil) + process_json_action(action, params, session, flash, "PUT") + end + + def api_delete(action, params = {}, session = nil, flash = nil) + process_json_action(action, params, session, flash, "DELETE") + end + + def spree_get(action, params = {}, session = nil, flash = nil) + process_action_with_route(action, params, session, flash, "GET") + end + + def spree_post(action, params = {}, session = nil, flash = nil) + process_action_with_route(action, params, session, flash, "POST") + end + + def spree_put(action, params = {}, session = nil, flash = nil) + process_action_with_route(action, params, session, flash, "PUT") + end + + def spree_delete(action, params = {}, session = nil, flash = nil) + process_action_with_route(action, params, session, flash, "DELETE") + end + + private + + def process_json_action(action, params = {}, session = nil, flash = nil, method = "get") + process_action_with_route(action, + params.reverse_merge!(format: :json), + session, + flash, + method) + end + + def process_action_with_route(action, params = {}, session = nil, flash = nil, method = "GET") + process(action, + method, + params.reverse_merge!(use_route: :main_app), + session, + flash) + end +end diff --git a/vendor/assets/javascripts/autocomplete.min.js b/vendor/assets/javascripts/autocomplete.min.js new file mode 100644 index 0000000000..a86832e175 --- /dev/null +++ b/vendor/assets/javascripts/autocomplete.min.js @@ -0,0 +1 @@ +var Autocomplete=function(){"use strict";function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function e(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},a=u.search,l=u.autoSelect,r=void 0!==l&&l,d=u.setValue,c=void 0===d?function(){}:d,h=u.setAttribute,p=void 0===h?function(){}:h,f=u.onUpdate,b=void 0===f?function(){}:f,v=u.onSubmit,g=void 0===v?function(){}:v,L=u.onShow,y=void 0===L?function(){}:L,w=u.onHide,m=void 0===w?function(){}:w,S=u.onLoading,x=void 0===S?function(){}:S,R=u.onLoaded,A=void 0===R?function(){}:R;t(this,e),n(this,"value",""),n(this,"searchCounter",0),n(this,"results",[]),n(this,"selectedIndex",-1),n(this,"handleInput",(function(t){var e=t.target.value;i.updateResults(e),i.value=e})),n(this,"handleKeyDown",(function(t){var e=t.key;switch(e){case"Up":case"Down":case"ArrowUp":case"ArrowDown":var n="ArrowUp"===e||"Up"===e?i.selectedIndex-1:i.selectedIndex+1;t.preventDefault(),i.handleArrows(n);break;case"Tab":i.selectResult();break;case"Enter":var s=i.results[i.selectedIndex];i.selectResult(),i.onSubmit(s);break;case"Esc":case"Escape":i.hideResults(),i.setValue();break;default:return}})),n(this,"handleFocus",(function(t){var e=t.target.value;i.updateResults(e),i.value=e})),n(this,"handleBlur",(function(){i.hideResults()})),n(this,"handleResultMouseDown",(function(t){t.preventDefault()})),n(this,"handleResultClick",(function(t){var e=t.target,n=s(e,"[data-result-index]");if(n){i.selectedIndex=parseInt(n.dataset.resultIndex,10);var o=i.results[i.selectedIndex];i.selectResult(),i.onSubmit(o)}})),n(this,"handleArrows",(function(t){var e=i.results.length;i.selectedIndex=(t%e+e)%e,i.onUpdate(i.results,i.selectedIndex)})),n(this,"selectResult",(function(){var t=i.results[i.selectedIndex];t&&i.setValue(t),i.hideResults()})),n(this,"updateResults",(function(t){var e=++i.searchCounter;i.onLoading(),i.search(t).then((function(t){e===i.searchCounter&&(i.results=t,i.onLoaded(),0!==i.results.length?(i.selectedIndex=i.autoSelect?0:-1,i.onUpdate(i.results,i.selectedIndex),i.showResults()):i.hideResults())}))})),n(this,"showResults",(function(){i.setAttribute("aria-expanded",!0),i.onShow()})),n(this,"hideResults",(function(){i.selectedIndex=-1,i.results=[],i.setAttribute("aria-expanded",!1),i.setAttribute("aria-activedescendant",""),i.onUpdate(i.results,i.selectedIndex),i.onHide()})),n(this,"checkSelectedResultVisible",(function(t){var e=t.querySelector('[data-result-index="'.concat(i.selectedIndex,'"]'));if(e){var n=t.getBoundingClientRect(),s=e.getBoundingClientRect();s.topn.bottom&&(t.scrollTop+=s.bottom-n.bottom)}})),this.search=o(a)?a:function(t){return Promise.resolve(a(t))},this.autoSelect=r,this.setValue=c,this.setAttribute=p,this.onUpdate=b,this.onSubmit=g,this.onShow=y,this.onHide=m,this.onLoading=x,this.onLoaded=A},a=0,l=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return"".concat(t).concat(++a)},r=function(t,e){var n=t.getBoundingClientRect(),i=e.getBoundingClientRect();return n.bottom+i.height>window.innerHeight&&window.innerHeight-n.bottom0?"above":"below"},d=function(t,e,n){var i;return function(){var s=this,o=arguments,u=function(){i=null,n||t.apply(s,o)},a=n&&!i;clearTimeout(i),i=setTimeout(u,e),a&&t.apply(s,o)}},c=function(){function n(e,i,s){t(this,n),this.id="".concat(s,"-result-").concat(e),this.class="".concat(s,"-result"),this["data-result-index"]=e,this.role="option",e===i&&(this["aria-selected"]="true")}var i,s,o;return i=n,(s=[{key:"toString",value:function(){var t=this;return Object.keys(this).reduce((function(e,n){return"".concat(e," ").concat(n,'="').concat(t[n],'"')}),"")}}])&&e(i.prototype,s),o&&e(i,o),n}();return function e(i){var s=this,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=o.search,h=o.onSubmit,p=void 0===h?function(){}:h,f=o.baseClass,b=void 0===f?"autocomplete":f,v=o.autoSelect,g=o.getResultValue,L=void 0===g?function(t){return t}:g,y=o.renderResult,w=o.debounceTime,m=void 0===w?0:w;t(this,e),n(this,"expanded",!1),n(this,"loading",!1),n(this,"position",{}),n(this,"resetPosition",!0),n(this,"initialize",(function(){s.root.style.position="relative",s.input.setAttribute("role","combobox"),s.input.setAttribute("autocomplete","off"),s.input.setAttribute("autocapitalize","off"),s.input.setAttribute("autocorrect","off"),s.input.setAttribute("spellcheck","false"),s.input.setAttribute("aria-autocomplete","list"),s.input.setAttribute("aria-haspopup","listbox"),s.input.setAttribute("aria-expanded","false"),s.resultList.setAttribute("role","listbox"),s.resultList.style.position="absolute",s.resultList.style.zIndex="1",s.resultList.style.width="100%",s.resultList.style.boxSizing="border-box",s.resultList.id||(s.resultList.id=l("".concat(s.baseClass,"-result-list-"))),s.input.setAttribute("aria-owns",s.resultList.id),document.body.addEventListener("click",s.handleDocumentClick),s.input.addEventListener("input",s.core.handleInput),s.input.addEventListener("keydown",s.core.handleKeyDown),s.input.addEventListener("focus",s.core.handleFocus),s.input.addEventListener("blur",s.core.handleBlur),s.resultList.addEventListener("mousedown",s.core.handleResultMouseDown),s.resultList.addEventListener("click",s.core.handleResultClick),s.updateStyle()})),n(this,"setAttribute",(function(t,e){s.input.setAttribute(t,e)})),n(this,"setValue",(function(t){s.input.value=t?s.getResultValue(t):""})),n(this,"renderResult",(function(t,e){return"
  • ").concat(s.getResultValue(t),"
  • ")})),n(this,"handleUpdate",(function(t,e){s.resultList.innerHTML="",t.forEach((function(t,n){var i=new c(n,e,s.baseClass),o=s.renderResult(t,i);"string"==typeof o?s.resultList.insertAdjacentHTML("beforeend",o):s.resultList.insertAdjacentElement("beforeend",o)})),s.input.setAttribute("aria-activedescendant",e>-1?"".concat(s.baseClass,"-result-").concat(e):""),s.resetPosition&&(s.resetPosition=!1,s.position=r(s.input,s.resultList),s.updateStyle()),s.core.checkSelectedResultVisible(s.resultList)})),n(this,"handleShow",(function(){s.expanded=!0,s.updateStyle()})),n(this,"handleHide",(function(){s.expanded=!1,s.resetPosition=!0,s.updateStyle()})),n(this,"handleLoading",(function(){s.loading=!0,s.updateStyle()})),n(this,"handleLoaded",(function(){s.loading=!1,s.updateStyle()})),n(this,"handleDocumentClick",(function(t){s.root.contains(t.target)||s.core.hideResults()})),n(this,"updateStyle",(function(){s.root.dataset.expanded=s.expanded,s.root.dataset.loading=s.loading,s.root.dataset.position=s.position,s.resultList.style.visibility=s.expanded?"visible":"hidden",s.resultList.style.pointerEvents=s.expanded?"auto":"none","below"===s.position?(s.resultList.style.bottom=null,s.resultList.style.top="100%"):(s.resultList.style.top=null,s.resultList.style.bottom="100%")})),this.root="string"==typeof i?document.querySelector(i):i,this.input=this.root.querySelector("input"),this.resultList=this.root.querySelector("ul"),this.baseClass=b,this.getResultValue=L,"function"==typeof y&&(this.renderResult=y);var S=new u({search:a,autoSelect:v,setValue:this.setValue,setAttribute:this.setAttribute,onUpdate:this.handleUpdate,onSubmit:p,onShow:this.handleShow,onHide:this.handleHide,onLoading:this.handleLoading,onLoaded:this.handleLoaded});m>0&&(S.handleInput=d(S.handleInput,m)),this.core=S,this.initialize()}}(); diff --git a/vendor/assets/javascripts/leaflet-1.6.0.js b/vendor/assets/javascripts/leaflet-1.6.0.js new file mode 100644 index 0000000000..bc9ef0f551 --- /dev/null +++ b/vendor/assets/javascripts/leaflet-1.6.0.js @@ -0,0 +1,5 @@ +/* @preserve + * Leaflet 1.6.0+Detached: 0c81bdf904d864fd12a286e3d1979f47aba17991.0c81bdf, a JS library for interactive maps. http://leafletjs.com + * (c) 2010-2019 Vladimir Agafonkin, (c) 2010-2011 CloudMade + */ +!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";var i=Object.freeze;function h(t){var i,e,n,o;for(e=1,n=arguments.length;e=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=R(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=R(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.xi.y&&n.y=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=D(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=D(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lati.lng&&n.lng';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}();function Bt(t){return 0<=navigator.userAgent.toLowerCase().indexOf(t)}var At=(Object.freeze||Object)({ie:it,ielt9:et,edge:nt,webkit:ot,android:st,android23:rt,androidStock:ht,opera:ut,chrome:lt,gecko:ct,safari:_t,phantom:dt,opera12:pt,win:mt,ie3d:ft,webkit3d:gt,gecko3d:vt,any3d:yt,mobile:xt,mobileWebkit:wt,mobileWebkit3d:Pt,msPointer:Lt,pointer:bt,touch:Tt,mobileOpera:zt,mobileGecko:Mt,retina:Ct,passiveEvents:Et,canvas:St,svg:Zt,vml:kt}),It=Lt?"MSPointerDown":"pointerdown",Ot=Lt?"MSPointerMove":"pointermove",Rt=Lt?"MSPointerUp":"pointerup",Nt=Lt?"MSPointerCancel":"pointercancel",Dt=["INPUT","SELECT","OPTION"],jt={},Wt=!1,Ht=0;function Ft(t,i,e,n){return"touchstart"===i?function(t,i,e){var n=a(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(Dt.indexOf(t.target.tagName)<0))return;ji(t)}Gt(t,i)});t["_leaflet_touchstart"+e]=n,t.addEventListener(It,n,!1),Wt||(document.documentElement.addEventListener(It,Ut,!0),document.documentElement.addEventListener(Ot,Vt,!0),document.documentElement.addEventListener(Rt,qt,!0),document.documentElement.addEventListener(Nt,qt,!0),Wt=!0)}(t,e,n):"touchmove"===i?function(t,i,e){function n(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&Gt(t,i)}t["_leaflet_touchmove"+e]=n,t.addEventListener(Ot,n,!1)}(t,e,n):"touchend"===i&&function(t,i,e){function n(t){Gt(t,i)}t["_leaflet_touchend"+e]=n,t.addEventListener(Rt,n,!1),t.addEventListener(Nt,n,!1)}(t,e,n),this}function Ut(t){jt[t.pointerId]=t,Ht++}function Vt(t){jt[t.pointerId]&&(jt[t.pointerId]=t)}function qt(t){delete jt[t.pointerId],Ht--}function Gt(t,i){for(var e in t.touches=[],jt)t.touches.push(jt[e]);t.changedTouches=[t],i(t)}var Kt=Lt?"MSPointerDown":bt?"pointerdown":"touchstart",Yt=Lt?"MSPointerUp":bt?"pointerup":"touchend",Xt="_leaflet_";function Jt(t,o,i){var s,r,a=!1;function e(t){var i;if(bt){if(!nt||"mouse"===t.pointerType)return;i=Ht}else i=t.touches.length;if(!(1this.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,D(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},panInside:function(t,i){var e=I((i=i||{}).paddingTopLeft||i.padding||[0,0]),n=I(i.paddingBottomRight||i.padding||[0,0]),o=this.getCenter(),s=this.project(o),r=this.project(t),a=this.getPixelBounds(),h=a.getSize().divideBy(2),u=R([a.min.add(e),a.max.subtract(n)]);if(!u.contains(r)){this._enforcingBounds=!0;var l=s.subtract(r),c=I(r.x+l.x,r.y+l.y);(r.xu.max.x)&&(c.x=s.x-l.x,0u.max.y)&&(c.y=s.y-l.y,0=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,n=[],o="mouseout"===i||"mouseover"===i,s=t.target||t.srcElement,r=!1;s;){if((e=this._targets[u(s)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){r=!0;break}if(e&&e.listens(i,!0)){if(o&&!Yi(s,t))break;if(n.push(e),o)break}if(s===this._container)break;s=s.parentNode}return n.length||r||o||!Yi(s,t)||(n=[this]),n},_handleDOMEvent:function(t){if(this._loaded&&!Ki(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i&&"keyup"!==i&&"keydown"!==i||Mi(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,i,e){if("click"===t.type){var n=h({},t);n.type="preclick",this._fireDOMEvent(n,n.type,e)}if(!t._stopped&&(e=(e||[]).concat(this._findEventTargets(t,i))).length){var o=e[0];"contextmenu"===i&&o.listens(i,!0)&&ji(t);var s={originalEvent:t};if("keypress"!==t.type&&"keydown"!==t.type&&"keyup"!==t.type){var r=o.getLatLng&&(!o._radius||o._radius<=10);s.containerPoint=r?this.latLngToContainerPoint(o.getLatLng()):this.mouseEventToContainerPoint(t),s.layerPoint=this.containerPointToLayerPoint(s.containerPoint),s.latlng=r?o.getLatLng():this.layerPointToLatLng(s.layerPoint)}for(var a=0;athis.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(M(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,e,n){this._mapPane&&(e&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,mi(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:n}),setTimeout(a(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&fi(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),M(function(){this._moveEnd(!0)},this))}});function Qi(t){return new te(t)}var te=S.extend({options:{position:"topright"},initialize:function(t){p(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return mi(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this._map.on("unload",this.remove,this),this},remove:function(){return this._map&&(li(this._container),this.onRemove&&this.onRemove(this._map),this._map.off("unload",this.remove,this),this._map=null),this},_refocusOnMap:function(t){this._map&&t&&0",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),n=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=n):i=this._createRadioElement("leaflet-base-layers_"+u(this),n),this._layerControlInputs.push(i),i.layerId=u(t.layer),ki(i,"click",this._onInputClick,this);var o=document.createElement("span");o.innerHTML=" "+t.name;var s=document.createElement("div");return e.appendChild(s),s.appendChild(i),s.appendChild(o),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;0<=s;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;si.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),ee=te.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=ui("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=ui("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),Di(s),ki(s,"click",Wi),ki(s,"click",o,this),ki(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";fi(this._zoomInButton,i),fi(this._zoomOutButton,i),!this._disabled&&t._zoom!==t.getMinZoom()||mi(this._zoomOutButton,i),!this._disabled&&t._zoom!==t.getMaxZoom()||mi(this._zoomInButton,i)}});$i.mergeOptions({zoomControl:!0}),$i.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new ee,this.addControl(this.zoomControl))});var ne=te.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i="leaflet-control-scale",e=ui("div",i),n=this.options;return this._addScales(n,i+"-line",e),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),e},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=ui("div",i,e)),t.imperial&&(this._iScale=ui("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;5280Leaflet'},initialize:function(t){p(this,t),this._attributions={}},onAdd:function(t){for(var i in(t.attributionControl=this)._container=ui("div","leaflet-control-attribution"),Di(this._container),t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t&&(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update()),this},removeAttribution:function(t){return t&&this._attributions[t]&&(this._attributions[t]--,this._update()),this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});$i.mergeOptions({attributionControl:!0}),$i.addInitHook(function(){this.options.attributionControl&&(new oe).addTo(this)});te.Layers=ie,te.Zoom=ee,te.Scale=ne,te.Attribution=oe,Qi.layers=function(t,i,e){return new ie(t,i,e)},Qi.zoom=function(t){return new ee(t)},Qi.scale=function(t){return new ne(t)},Qi.attribution=function(t){return new oe(t)};var se=S.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled||(this._enabled=!0,this.addHooks()),this},disable:function(){return this._enabled&&(this._enabled=!1,this.removeHooks()),this},enabled:function(){return!!this._enabled}});se.addTo=function(t,i){return t.addHandler(i,this),this};var re,ae={Events:Z},he=Tt?"touchstart mousedown":"mousedown",ue={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},le={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},ce=k.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){p(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(ki(this._dragStartTarget,he,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(ce._dragging===this&&this.finishDrag(),Ai(this._dragStartTarget,he,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!pi(this._element,"leaflet-zoom-anim")&&!(ce._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||((ce._dragging=this)._preventOutline&&Mi(this._element),Ti(),Qt(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t,e=Ei(this._element);this._startPoint=new B(i.clientX,i.clientY),this._parentScale=Si(e),ki(document,le[t.type],this._onMove,this),ki(document,ue[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&1i.max.x&&(e|=2),t.yi.max.y&&(e|=8),e}function ge(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return 0this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()t.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||je.prototype._containsPoint.call(this,t,!0)}});var He=ke.extend({initialize:function(t,i){p(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=v(t)?t:t.features;if(o){for(i=0,e=o.length;iu.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Wi(t)},_getAnchor:function(){return I(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});$i.mergeOptions({closePopupOnClick:!0}),$i.include({openPopup:function(t,i,e){return t instanceof sn||(t=new sn(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),Se.include({bindPopup:function(t,i){return t instanceof sn?(p(t,i),(this._popup=t)._source=this):(this._popup&&!i||(this._popup=new sn(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){return this._popup&&this._map&&(i=this._popup._prepareOpen(this,t,i),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Wi(t),i instanceof Re?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var rn=on.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){on.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){on.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=on.prototype.getEvents.call(this);return Tt&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=ui("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=I(this.options.offset),u=this._getAnchor();t="top"===s?t.add(I(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t.subtract(I(r/2-h.x,-h.y,!0)):"center"===s?t.subtract(I(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.xthis.options.maxZoom||ethis.options.maxZoom||void 0!==this.options.minZoom&&oe.max.x)||!i.wrapLat&&(t.ye.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return D(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new N(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new B(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(li(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){mi(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=l,t.onmousemove=l,et&&this.options.opacity<1&&yi(t,this.options.opacity),st&&!rt&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var e=this._getTilePos(t),n=this._tileCoordsToKey(t),o=this.createTile(this._wrapCoords(t),a(this._tileReady,this,t));this._initTile(o),this.createTile.length<2&&M(a(this._tileReady,this,t,null,o)),Pi(o,e),this._tiles[n]={el:o,coords:t,current:!0},i.appendChild(o),this.fire("tileloadstart",{tile:o,coords:t})},_tileReady:function(t,i,e){i&&this.fire("tileerror",{error:i,tile:e,coords:t});var n=this._tileCoordsToKey(t);(e=this._tiles[n])&&(e.loaded=+new Date,this._map._fadeAnimated?(yi(e.el,0),C(this._fadeFrame),this._fadeFrame=M(this._updateOpacity,this)):(e.active=!0,this._pruneTiles()),i||(mi(e.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:e.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),et||!this._map._fadeAnimated?M(this._pruneTiles,this):setTimeout(a(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new B(this._wrapX?r(t.x,this._wrapX):t.x,this._wrapY?r(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new O(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}});var un=hn.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=p(this,i)).detectRetina&&Ct&&0')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),fn={_initContainer:function(){this._container=ui("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(_n.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=mn("shape");mi(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=mn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[u(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;li(i),t.removeInteractiveTarget(i),delete this._layers[u(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=mn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=v(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=mn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){_i(t._container)},_bringToBack:function(t){di(t._container)}},gn=kt?mn:$,vn=_n.extend({getEvents:function(){var t=_n.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=gn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=gn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){li(this._container),Ai(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){_n.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),Pi(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=gn("path");t.options.className&&mi(i,t.options.className),t.options.interactive&&mi(i,"leaflet-interactive"),this._updateStyle(t),this._layers[u(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){li(t._path),t.removeInteractiveTarget(t._path),delete this._layers[u(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,Q(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){_i(t._path)},_bringToBack:function(t){di(t._path)}});function yn(t){return Zt||kt?new vn(t):null}kt&&vn.include(fn),$i.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this._createRenderer()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=this._createRenderer({pane:t}),this._paneRenderers[t]=i),i},_createRenderer:function(t){return this.options.preferCanvas&&pn(t)||yn(t)}});var xn=We.extend({initialize:function(t,i){We.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return[(t=D(t)).getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});vn.create=gn,vn.pointsToPath=Q,He.geometryToLayer=Fe,He.coordsToLatLng=Ve,He.coordsToLatLngs=qe,He.latLngToCoords=Ge,He.latLngsToCoords=Ke,He.getFeature=Ye,He.asFeature=Xe,$i.mergeOptions({boxZoom:!0});var wn=se.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){ki(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){Ai(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){li(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),Qt(),Ti(),this._startPoint=this._map.mouseEventToContainerPoint(t),ki(document,{contextmenu:Wi,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=ui("div","leaflet-zoom-box",this._container),mi(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new O(this._point,this._startPoint),e=i.getSize();Pi(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(li(this._box),fi(this._container,"leaflet-crosshair")),ti(),zi(),Ai(document,{contextmenu:Wi,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(a(this._resetState,this),0);var i=new N(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});$i.addInitHook("addHandler","boxZoom",wn),$i.mergeOptions({doubleClickZoom:!0});var Pn=se.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});$i.addInitHook("addHandler","doubleClickZoom",Pn),$i.mergeOptions({dragging:!0,inertia:!rt,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var Ln=se.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new ce(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}mi(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){fi(this._map._container,"leaflet-grab"),fi(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=D(this._map.options.maxBounds);this._offsetLimit=R(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),this._prunePositions(i)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;1i.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)i.getMaxZoom()&&1OpenStreetMap contributors' + }, + variants: { + Mapnik: {}, + DE: { + url: 'https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', + options: { + maxZoom: 18 + } + }, + CH: { + url: 'https://tile.osm.ch/switzerland/{z}/{x}/{y}.png', + options: { + maxZoom: 18, + bounds: [[45, 5], [48, 11]] + } + }, + France: { + url: 'https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', + options: { + maxZoom: 20, + attribution: '© Openstreetmap France | {attribution.OpenStreetMap}' + } + }, + HOT: { + url: 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', + options: { + attribution: + '{attribution.OpenStreetMap}, ' + + 'Tiles style by Humanitarian OpenStreetMap Team ' + + 'hosted by OpenStreetMap France' + } + }, + BZH: { + url: 'https://tile.openstreetmap.bzh/br/{z}/{x}/{y}.png', + options: { + attribution: '{attribution.OpenStreetMap}, Tiles courtesy of Breton OpenStreetMap Team', + bounds: [[46.2, -5.5], [50, 0.7]] + } + } + } + }, + OpenSeaMap: { + url: 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', + options: { + attribution: 'Map data: © OpenSeaMap contributors' + } + }, + OpenPtMap: { + url: 'http://openptmap.org/tiles/{z}/{x}/{y}.png', + options: { + maxZoom: 17, + attribution: 'Map data: © OpenPtMap contributors' + } + }, + OpenTopoMap: { + url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', + options: { + maxZoom: 17, + attribution: 'Map data: {attribution.OpenStreetMap}, SRTM | Map style: © OpenTopoMap (CC-BY-SA)' + } + }, + OpenRailwayMap: { + url: 'https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © OpenRailwayMap (CC-BY-SA)' + } + }, + OpenFireMap: { + url: 'http://openfiremap.org/hytiles/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © OpenFireMap (CC-BY-SA)' + } + }, + SafeCast: { + url: 'https://s3.amazonaws.com/te512.safecast.org/{z}/{x}/{y}.png', + options: { + maxZoom: 16, + attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © SafeCast (CC-BY-SA)' + } + }, + Stadia: { + url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png', + options: { + maxZoom: 20, + attribution: '© Stadia Maps, © OpenMapTiles © OpenStreetMap contributors' + }, + variants: { + AlidadeSmooth: { + url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png' + }, + AlidadeSmoothDark: { + url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png' + }, + OSMBright: { + url: 'https://tiles.stadiamaps.com/tiles/osm_bright/{z}/{x}/{y}{r}.png' + }, + Outdoors: { + url: 'https://tiles.stadiamaps.com/tiles/outdoors/{z}/{x}/{y}{r}.png' + } + } + }, + Thunderforest: { + url: 'https://{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png?apikey={apikey}', + options: { + attribution: + '© Thunderforest, {attribution.OpenStreetMap}', + variant: 'cycle', + apikey: '', + maxZoom: 22 + }, + variants: { + OpenCycleMap: 'cycle', + Transport: { + options: { + variant: 'transport' + } + }, + TransportDark: { + options: { + variant: 'transport-dark' + } + }, + SpinalMap: { + options: { + variant: 'spinal-map' + } + }, + Landscape: 'landscape', + Outdoors: 'outdoors', + Pioneer: 'pioneer', + MobileAtlas: 'mobile-atlas', + Neighbourhood: 'neighbourhood' + } + }, + CyclOSM: { + url: 'https://dev.{s}.tile.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', + options: { + maxZoom: 20, + attribution: 'CyclOSM | Map data: {attribution.OpenStreetMap}' + } + }, + OpenMapSurfer: { + url: 'https://maps.heigit.org/openmapsurfer/tiles/{variant}/webmercator/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + variant: 'roads', + attribution: 'Imagery from GIScience Research Group @ University of Heidelberg | Map data ' + }, + variants: { + Roads: { + options: { + variant: 'roads', + attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' + } + }, + Hybrid: { + options: { + variant: 'hybrid', + attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' + } + }, + AdminBounds: { + options: { + variant: 'adminb', + maxZoom: 18, + attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' + } + }, + ContourLines: { + options: { + variant: 'asterc', + maxZoom: 18, + minZoom: 13, + attribution: '{attribution.OpenMapSurfer} ASTER GDEM' + } + }, + Hillshade: { + options: { + variant: 'asterh', + maxZoom: 18, + attribution: '{attribution.OpenMapSurfer} ASTER GDEM, SRTM' + } + }, + ElementsAtRisk: { + options: { + variant: 'elements_at_risk', + attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' + } + } + } + }, + Hydda: { + url: 'https://{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png', + options: { + maxZoom: 18, + variant: 'full', + attribution: 'Tiles courtesy of OpenStreetMap Sweden — Map data {attribution.OpenStreetMap}' + }, + variants: { + Full: 'full', + Base: 'base', + RoadsAndLabels: 'roads_and_labels' + } + }, + MapBox: { + url: 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}{r}.png?access_token={accessToken}', + options: { + attribution: + '© Mapbox ' + + '{attribution.OpenStreetMap} ' + + 'Improve this map', + subdomains: 'abcd', + id: 'mapbox.streets', + accessToken: '', + } + }, + Stamen: { + url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}{r}.{ext}', + options: { + attribution: + 'Map tiles by Stamen Design, ' + + 'CC BY 3.0 — ' + + 'Map data {attribution.OpenStreetMap}', + subdomains: 'abcd', + minZoom: 0, + maxZoom: 20, + variant: 'toner', + ext: 'png' + }, + variants: { + Toner: 'toner', + TonerBackground: 'toner-background', + TonerHybrid: 'toner-hybrid', + TonerLines: 'toner-lines', + TonerLabels: 'toner-labels', + TonerLite: 'toner-lite', + Watercolor: { + url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}', + options: { + variant: 'watercolor', + ext: 'jpg', + minZoom: 1, + maxZoom: 16 + } + }, + Terrain: { + options: { + variant: 'terrain', + minZoom: 0, + maxZoom: 18 + } + }, + TerrainBackground: { + options: { + variant: 'terrain-background', + minZoom: 0, + maxZoom: 18 + } + }, + TerrainLabels: { + options: { + variant: 'terrain-labels', + minZoom: 0, + maxZoom: 18 + } + }, + TopOSMRelief: { + url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}', + options: { + variant: 'toposm-color-relief', + ext: 'jpg', + bounds: [[22, -132], [51, -56]] + } + }, + TopOSMFeatures: { + options: { + variant: 'toposm-features', + bounds: [[22, -132], [51, -56]], + opacity: 0.9 + } + } + } + }, + TomTom: { + url: 'https://{s}.api.tomtom.com/map/1/tile/{variant}/{style}/{z}/{x}/{y}.{ext}?key={apikey}', + options: { + variant: 'basic', + maxZoom: 22, + attribution: + '© 1992 - ' + new Date().getFullYear() + ' TomTom. ', + subdomains: 'abcd', + style: 'main', + ext: 'png', + apikey: '', + }, + variants: { + Basic: 'basic', + Hybrid: 'hybrid', + Labels: 'labels' + } + }, + Esri: { + url: 'https://server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}', + options: { + variant: 'World_Street_Map', + attribution: 'Tiles © Esri' + }, + variants: { + WorldStreetMap: { + options: { + attribution: + '{attribution.Esri} — ' + + 'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012' + } + }, + DeLorme: { + options: { + variant: 'Specialty/DeLorme_World_Base_Map', + minZoom: 1, + maxZoom: 11, + attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme' + } + }, + WorldTopoMap: { + options: { + variant: 'World_Topo_Map', + attribution: + '{attribution.Esri} — ' + + 'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community' + } + }, + WorldImagery: { + options: { + variant: 'World_Imagery', + attribution: + '{attribution.Esri} — ' + + 'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' + } + }, + WorldTerrain: { + options: { + variant: 'World_Terrain_Base', + maxZoom: 13, + attribution: + '{attribution.Esri} — ' + + 'Source: USGS, Esri, TANA, DeLorme, and NPS' + } + }, + WorldShadedRelief: { + options: { + variant: 'World_Shaded_Relief', + maxZoom: 13, + attribution: '{attribution.Esri} — Source: Esri' + } + }, + WorldPhysical: { + options: { + variant: 'World_Physical_Map', + maxZoom: 8, + attribution: '{attribution.Esri} — Source: US National Park Service' + } + }, + OceanBasemap: { + options: { + variant: 'Ocean_Basemap', + maxZoom: 13, + attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri' + } + }, + NatGeoWorldMap: { + options: { + variant: 'NatGeo_World_Map', + maxZoom: 16, + attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC' + } + }, + WorldGrayCanvas: { + options: { + variant: 'Canvas/World_Light_Gray_Base', + maxZoom: 16, + attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ' + } + } + } + }, + OpenWeatherMap: { + url: 'http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png?appid={apiKey}', + options: { + maxZoom: 19, + attribution: 'Map data © OpenWeatherMap', + apiKey:'', + opacity: 0.5 + }, + variants: { + Clouds: 'clouds', + CloudsClassic: 'clouds_cls', + Precipitation: 'precipitation', + PrecipitationClassic: 'precipitation_cls', + Rain: 'rain', + RainClassic: 'rain_cls', + Pressure: 'pressure', + PressureContour: 'pressure_cntr', + Wind: 'wind', + Temperature: 'temp', + Snow: 'snow' + } + }, + HERE: { + /* + * HERE maps, formerly Nokia maps. + * These basemaps are free, but you need an api id and app key. Please sign up at + * https://developer.here.com/plans + */ + url: + 'https://{s}.{base}.maps.api.here.com/maptile/2.1/' + + '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' + + 'app_id={app_id}&app_code={app_code}&lg={language}', + options: { + attribution: + 'Map © 1987-' + new Date().getFullYear() + ' HERE', + subdomains: '1234', + mapID: 'newest', + 'app_id': '', + 'app_code': '', + base: 'base', + variant: 'normal.day', + maxZoom: 20, + type: 'maptile', + language: 'eng', + format: 'png8', + size: '256' + }, + variants: { + normalDay: 'normal.day', + normalDayCustom: 'normal.day.custom', + normalDayGrey: 'normal.day.grey', + normalDayMobile: 'normal.day.mobile', + normalDayGreyMobile: 'normal.day.grey.mobile', + normalDayTransit: 'normal.day.transit', + normalDayTransitMobile: 'normal.day.transit.mobile', + normalDayTraffic: { + options: { + variant: 'normal.traffic.day', + base: 'traffic', + type: 'traffictile' + } + }, + normalNight: 'normal.night', + normalNightMobile: 'normal.night.mobile', + normalNightGrey: 'normal.night.grey', + normalNightGreyMobile: 'normal.night.grey.mobile', + normalNightTransit: 'normal.night.transit', + normalNightTransitMobile: 'normal.night.transit.mobile', + reducedDay: 'reduced.day', + reducedNight: 'reduced.night', + basicMap: { + options: { + type: 'basetile' + } + }, + mapLabels: { + options: { + type: 'labeltile', + format: 'png' + } + }, + trafficFlow: { + options: { + base: 'traffic', + type: 'flowtile' + } + }, + carnavDayGrey: 'carnav.day.grey', + hybridDay: { + options: { + base: 'aerial', + variant: 'hybrid.day' + } + }, + hybridDayMobile: { + options: { + base: 'aerial', + variant: 'hybrid.day.mobile' + } + }, + hybridDayTransit: { + options: { + base: 'aerial', + variant: 'hybrid.day.transit' + } + }, + hybridDayGrey: { + options: { + base: 'aerial', + variant: 'hybrid.grey.day' + } + }, + hybridDayTraffic: { + options: { + variant: 'hybrid.traffic.day', + base: 'traffic', + type: 'traffictile' + } + }, + pedestrianDay: 'pedestrian.day', + pedestrianNight: 'pedestrian.night', + satelliteDay: { + options: { + base: 'aerial', + variant: 'satellite.day' + } + }, + terrainDay: { + options: { + base: 'aerial', + variant: 'terrain.day' + } + }, + terrainDayMobile: { + options: { + base: 'aerial', + variant: 'terrain.day.mobile' + } + } + } + }, + HEREv3: { + /* + * HERE maps API Version 3. + * These basemaps are free, but you need an API key. Please sign up at + * https://developer.here.com/plans + * Version 3 deprecates the app_id and app_code access in favor of apiKey + * + * Supported access methods as of 2019/12/21: + * @see https://developer.here.com/faqs#access-control-1--how-do-you-control-access-to-here-location-services + */ + url: + 'https://{s}.{base}.maps.ls.hereapi.com/maptile/2.1/' + + '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' + + 'apiKey={apiKey}&lg={language}', + options: { + attribution: + 'Map © 1987-' + new Date().getFullYear() + ' HERE', + subdomains: '1234', + mapID: 'newest', + apiKey: '', + base: 'base', + variant: 'normal.day', + maxZoom: 20, + type: 'maptile', + language: 'eng', + format: 'png8', + size: '256' + }, + variants: { + normalDay: 'normal.day', + normalDayCustom: 'normal.day.custom', + normalDayGrey: 'normal.day.grey', + normalDayMobile: 'normal.day.mobile', + normalDayGreyMobile: 'normal.day.grey.mobile', + normalDayTransit: 'normal.day.transit', + normalDayTransitMobile: 'normal.day.transit.mobile', + normalNight: 'normal.night', + normalNightMobile: 'normal.night.mobile', + normalNightGrey: 'normal.night.grey', + normalNightGreyMobile: 'normal.night.grey.mobile', + normalNightTransit: 'normal.night.transit', + normalNightTransitMobile: 'normal.night.transit.mobile', + reducedDay: 'reduced.day', + reducedNight: 'reduced.night', + basicMap: { + options: { + type: 'basetile' + } + }, + mapLabels: { + options: { + type: 'labeltile', + format: 'png' + } + }, + trafficFlow: { + options: { + base: 'traffic', + type: 'flowtile' + } + }, + carnavDayGrey: 'carnav.day.grey', + hybridDay: { + options: { + base: 'aerial', + variant: 'hybrid.day' + } + }, + hybridDayMobile: { + options: { + base: 'aerial', + variant: 'hybrid.day.mobile' + } + }, + hybridDayTransit: { + options: { + base: 'aerial', + variant: 'hybrid.day.transit' + } + }, + hybridDayGrey: { + options: { + base: 'aerial', + variant: 'hybrid.grey.day' + } + }, + pedestrianDay: 'pedestrian.day', + pedestrianNight: 'pedestrian.night', + satelliteDay: { + options: { + base: 'aerial', + variant: 'satellite.day' + } + }, + terrainDay: { + options: { + base: 'aerial', + variant: 'terrain.day' + } + }, + terrainDayMobile: { + options: { + base: 'aerial', + variant: 'terrain.day.mobile' + } + } + } + }, + FreeMapSK: { + url: 'http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg', + options: { + minZoom: 8, + maxZoom: 16, + subdomains: '1234', + bounds: [[47.204642, 15.996093], [49.830896, 22.576904]], + attribution: + '{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 Freemap.sk' + } + }, + MtbMap: { + url: 'http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png', + options: { + attribution: + '{attribution.OpenStreetMap} & USGS' + } + }, + CartoDB: { + url: 'https://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}{r}.png', + options: { + attribution: '{attribution.OpenStreetMap} © CARTO', + subdomains: 'abcd', + maxZoom: 19, + variant: 'light_all' + }, + variants: { + Positron: 'light_all', + PositronNoLabels: 'light_nolabels', + PositronOnlyLabels: 'light_only_labels', + DarkMatter: 'dark_all', + DarkMatterNoLabels: 'dark_nolabels', + DarkMatterOnlyLabels: 'dark_only_labels', + Voyager: 'rastertiles/voyager', + VoyagerNoLabels: 'rastertiles/voyager_nolabels', + VoyagerOnlyLabels: 'rastertiles/voyager_only_labels', + VoyagerLabelsUnder: 'rastertiles/voyager_labels_under' + } + }, + HikeBike: { + url: 'https://tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: '{attribution.OpenStreetMap}', + variant: 'hikebike' + }, + variants: { + HikeBike: {}, + HillShading: { + options: { + maxZoom: 15, + variant: 'hillshading' + } + } + } + }, + BasemapAT: { + url: 'https://maps{s}.wien.gv.at/basemap/{variant}/{type}/google3857/{z}/{y}/{x}.{format}', + options: { + maxZoom: 19, + attribution: 'Datenquelle: basemap.at', + subdomains: ['', '1', '2', '3', '4'], + type: 'normal', + format: 'png', + bounds: [[46.358770, 8.782379], [49.037872, 17.189532]], + variant: 'geolandbasemap' + }, + variants: { + basemap: { + options: { + maxZoom: 20, // currently only in Vienna + variant: 'geolandbasemap' + } + }, + grau: 'bmapgrau', + overlay: 'bmapoverlay', + terrain: { + options: { + variant: 'bmapgelaende', + type: 'grau', + format: 'jpeg' + } + }, + surface: { + options: { + variant: 'bmapoberflaeche', + type: 'grau', + format: 'jpeg' + } + }, + highdpi: { + options: { + variant: 'bmaphidpi', + format: 'jpeg' + } + }, + orthofoto: { + options: { + maxZoom: 20, // currently only in Vienna + variant: 'bmaporthofoto30cm', + format: 'jpeg' + } + } + } + }, + nlmaps: { + url: 'https://geodata.nationaalgeoregister.nl/tiles/service/wmts/{variant}/EPSG:3857/{z}/{x}/{y}.png', + options: { + minZoom: 6, + maxZoom: 19, + bounds: [[50.5, 3.25], [54, 7.6]], + attribution: 'Kaartgegevens © Kadaster' + }, + variants: { + 'standaard': 'brtachtergrondkaart', + 'pastel': 'brtachtergrondkaartpastel', + 'grijs': 'brtachtergrondkaartgrijs', + 'luchtfoto': { + 'url': 'https://geodata.nationaalgeoregister.nl/luchtfoto/rgb/wmts/2018_ortho25/EPSG:3857/{z}/{x}/{y}.png', + } + } + }, + NASAGIBS: { + url: 'https://map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}', + options: { + attribution: + 'Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System ' + + '(ESDIS) with funding provided by NASA/HQ.', + bounds: [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]], + minZoom: 1, + maxZoom: 9, + format: 'jpg', + time: '', + tilematrixset: 'GoogleMapsCompatible_Level' + }, + variants: { + ModisTerraTrueColorCR: 'MODIS_Terra_CorrectedReflectance_TrueColor', + ModisTerraBands367CR: 'MODIS_Terra_CorrectedReflectance_Bands367', + ViirsEarthAtNight2012: { + options: { + variant: 'VIIRS_CityLights_2012', + maxZoom: 8 + } + }, + ModisTerraLSTDay: { + options: { + variant: 'MODIS_Terra_Land_Surface_Temp_Day', + format: 'png', + maxZoom: 7, + opacity: 0.75 + } + }, + ModisTerraSnowCover: { + options: { + variant: 'MODIS_Terra_Snow_Cover', + format: 'png', + maxZoom: 8, + opacity: 0.75 + } + }, + ModisTerraAOD: { + options: { + variant: 'MODIS_Terra_Aerosol', + format: 'png', + maxZoom: 6, + opacity: 0.75 + } + }, + ModisTerraChlorophyll: { + options: { + variant: 'MODIS_Terra_Chlorophyll_A', + format: 'png', + maxZoom: 7, + opacity: 0.75 + } + } + } + }, + NLS: { + // NLS maps are copyright National library of Scotland. + // http://maps.nls.uk/projects/api/index.html + // Please contact NLS for anything other than non-commercial low volume usage + // + // Map sources: Ordnance Survey 1:1m to 1:63K, 1920s-1940s + // z0-9 - 1:1m + // z10-11 - quarter inch (1:253440) + // z12-18 - one inch (1:63360) + url: 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', + options: { + attribution: 'National Library of Scotland Historic Maps', + bounds: [[49.6, -12], [61.7, 3]], + minZoom: 1, + maxZoom: 18, + subdomains: '0123', + } + }, + JusticeMap: { + // Justice Map (http://www.justicemap.org/) + // Visualize race and income data for your community, county and country. + // Includes tools for data journalists, bloggers and community activists. + url: 'http://www.justicemap.org/tile/{size}/{variant}/{z}/{x}/{y}.png', + options: { + attribution: 'Justice Map', + // one of 'county', 'tract', 'block' + size: 'county', + // Bounds for USA, including Alaska and Hawaii + bounds: [[14, -180], [72, -56]] + }, + variants: { + income: 'income', + americanIndian: 'indian', + asian: 'asian', + black: 'black', + hispanic: 'hispanic', + multi: 'multi', + nonWhite: 'nonwhite', + white: 'white', + plurality: 'plural' + } + }, + Wikimedia: { + url: 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}{r}.png', + options: { + attribution: 'Wikimedia', + minZoom: 1, + maxZoom: 19 + } + }, + GeoportailFrance: { + url: 'https://wxs.ign.fr/{apikey}/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE={style}&TILEMATRIXSET=PM&FORMAT={format}&LAYER={variant}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}', + options: { + attribution: 'Geoportail France', + bounds: [[-75, -180], [81, 180]], + minZoom: 2, + maxZoom: 18, + // Get your own geoportail apikey here : http://professionnels.ign.fr/ign/contrats/ + // NB : 'choisirgeoportail' is a demonstration key that comes with no guarantee + apikey: 'choisirgeoportail', + format: 'image/jpeg', + style : 'normal', + variant: 'GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN-EXPRESS.STANDARD' + }, + variants: { + parcels: { + options : { + variant: 'CADASTRALPARCELS.PARCELS', + maxZoom: 20, + style : 'bdparcellaire', + format: 'image/png' + } + }, + ignMaps: 'GEOGRAPHICALGRIDSYSTEMS.MAPS', + maps: 'GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN-EXPRESS.STANDARD', + orthos: { + options: { + maxZoom: 19, + variant: 'ORTHOIMAGERY.ORTHOPHOTOS' + } + } + } + }, + OneMapSG: { + url: 'https://maps-{s}.onemap.sg/v3/{variant}/{z}/{x}/{y}.png', + options: { + variant: 'Default', + minZoom: 11, + maxZoom: 18, + bounds: [[1.56073, 104.11475], [1.16, 103.502]], + attribution: ' New OneMap | Map data © contributors, Singapore Land Authority' + }, + variants: { + Default: 'Default', + Night: 'Night', + Original: 'Original', + Grey: 'Grey', + LandLot: 'LandLot' + } + } + }; + + L.tileLayer.provider = function (provider, options) { + return new L.TileLayer.Provider(provider, options); + }; + + return L; +})); diff --git a/vendor/assets/stylesheets/autocomplete.css b/vendor/assets/stylesheets/autocomplete.css new file mode 100644 index 0000000000..2af8d808ba --- /dev/null +++ b/vendor/assets/stylesheets/autocomplete.css @@ -0,0 +1 @@ +.autocomplete-input{border:1px solid #eee;border-radius:8px;width:100%;padding:12px 12px 12px 48px;box-sizing:border-box;position:relative;font-size:16px;line-height:1.5;flex:1;background-color:#eee;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNjY2IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIvPjxwYXRoIGQ9Ik0yMSAyMWwtNC00Ii8+PC9zdmc+");background-repeat:no-repeat;background-position:12px}.autocomplete-input:focus,.autocomplete-input[aria-expanded=true]{border-color:rgba(0,0,0,.12);background-color:#fff;outline:none;box-shadow:0 2px 2px rgba(0,0,0,.16)}[data-position=below] .autocomplete-input[aria-expanded=true]{border-bottom-color:transparent;border-radius:8px 8px 0 0}[data-position=above] .autocomplete-input[aria-expanded=true]{border-top-color:transparent;border-radius:0 0 8px 8px;z-index:2}.autocomplete[data-loading=true]:after{content:"";border:3px solid rgba(0,0,0,.12);border-right-color:rgba(0,0,0,.48);border-radius:100%;width:20px;height:20px;position:absolute;right:12px;top:50%;transform:translateY(-50%);animation:rotate 1s linear infinite}.autocomplete-result-list{margin:0;border:1px solid rgba(0,0,0,.12);padding:0;box-sizing:border-box;max-height:296px;overflow-y:auto;background:#fff;list-style:none;box-shadow:0 2px 2px rgba(0,0,0,.16)}[data-position=below] .autocomplete-result-list{margin-top:-1px;border-top-color:transparent;border-radius:0 0 8px 8px;padding-bottom:8px}[data-position=above] .autocomplete-result-list{margin-bottom:-1px;border-bottom-color:transparent;border-radius:8px 8px 0 0;padding-top:8px}.autocomplete-result{cursor:default;padding:12px 12px 12px 48px;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjY2NjIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIvPjxwYXRoIGQ9Ik0yMSAyMWwtNC00Ii8+PC9zdmc+");background-repeat:no-repeat;background-position:12px}.autocomplete-result:hover,.autocomplete-result[aria-selected=true]{background-color:rgba(0,0,0,.06)}@keyframes rotate{0%{transform:translateY(-50%) rotate(0deg)}to{transform:translateY(-50%) rotate(359deg)}} \ No newline at end of file diff --git a/vendor/assets/stylesheets/leaflet.css b/vendor/assets/stylesheets/leaflet.css new file mode 100644 index 0000000000..983d60592b --- /dev/null +++ b/vendor/assets/stylesheets/leaflet.css @@ -0,0 +1,640 @@ +/* required styles */ + +.leaflet-pane, +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-tile-container, +.leaflet-pane > svg, +.leaflet-pane > canvas, +.leaflet-zoom-box, +.leaflet-image-layer, +.leaflet-layer { + position: absolute; + left: 0; + top: 0; + } +.leaflet-container { + overflow: hidden; + } +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + -webkit-user-drag: none; + } +/* Prevents IE11 from highlighting tiles in blue */ +.leaflet-tile::selection { + background: transparent; +} +/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ +.leaflet-safari .leaflet-tile { + image-rendering: -webkit-optimize-contrast; + } +/* hack that prevents hw layers "stretching" when loading new tiles */ +.leaflet-safari .leaflet-tile-container { + width: 1600px; + height: 1600px; + -webkit-transform-origin: 0 0; + } +.leaflet-marker-icon, +.leaflet-marker-shadow { + display: block; + } +/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ +/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ +.leaflet-container .leaflet-overlay-pane svg, +.leaflet-container .leaflet-marker-pane img, +.leaflet-container .leaflet-shadow-pane img, +.leaflet-container .leaflet-tile-pane img, +.leaflet-container img.leaflet-image-layer, +.leaflet-container .leaflet-tile { + max-width: none !important; + max-height: none !important; + } + +.leaflet-container.leaflet-touch-zoom { + -ms-touch-action: pan-x pan-y; + touch-action: pan-x pan-y; + } +.leaflet-container.leaflet-touch-drag { + -ms-touch-action: pinch-zoom; + /* Fallback for FF which doesn't support pinch-zoom */ + touch-action: none; + touch-action: pinch-zoom; +} +.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { + -ms-touch-action: none; + touch-action: none; +} +.leaflet-container { + -webkit-tap-highlight-color: transparent; +} +.leaflet-container a { + -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); +} +.leaflet-tile { + filter: inherit; + visibility: hidden; + } +.leaflet-tile-loaded { + visibility: inherit; + } +.leaflet-zoom-box { + width: 0; + height: 0; + -moz-box-sizing: border-box; + box-sizing: border-box; + z-index: 800; + } +/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ +.leaflet-overlay-pane svg { + -moz-user-select: none; + } + +.leaflet-pane { z-index: 400; } + +.leaflet-tile-pane { z-index: 200; } +.leaflet-overlay-pane { z-index: 400; } +.leaflet-shadow-pane { z-index: 500; } +.leaflet-marker-pane { z-index: 600; } +.leaflet-tooltip-pane { z-index: 650; } +.leaflet-popup-pane { z-index: 700; } + +.leaflet-map-pane canvas { z-index: 100; } +.leaflet-map-pane svg { z-index: 200; } + +.leaflet-vml-shape { + width: 1px; + height: 1px; + } +.lvml { + behavior: url(#default#VML); + display: inline-block; + position: absolute; + } + + +/* control positioning */ + +.leaflet-control { + position: relative; + z-index: 800; + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } +.leaflet-top, +.leaflet-bottom { + position: absolute; + z-index: 1000; + pointer-events: none; + } +.leaflet-top { + top: 0; + } +.leaflet-right { + right: 0; + } +.leaflet-bottom { + bottom: 0; + } +.leaflet-left { + left: 0; + } +.leaflet-control { + float: left; + clear: both; + } +.leaflet-right .leaflet-control { + float: right; + } +.leaflet-top .leaflet-control { + margin-top: 10px; + } +.leaflet-bottom .leaflet-control { + margin-bottom: 10px; + } +.leaflet-left .leaflet-control { + margin-left: 10px; + } +.leaflet-right .leaflet-control { + margin-right: 10px; + } + + +/* zoom and fade animations */ + +.leaflet-fade-anim .leaflet-tile { + will-change: opacity; + } +.leaflet-fade-anim .leaflet-popup { + opacity: 0; + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; + } +.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { + opacity: 1; + } +.leaflet-zoom-animated { + -webkit-transform-origin: 0 0; + -ms-transform-origin: 0 0; + transform-origin: 0 0; + } +.leaflet-zoom-anim .leaflet-zoom-animated { + will-change: transform; + } +.leaflet-zoom-anim .leaflet-zoom-animated { + -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); + -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); + transition: transform 0.25s cubic-bezier(0,0,0.25,1); + } +.leaflet-zoom-anim .leaflet-tile, +.leaflet-pan-anim .leaflet-tile { + -webkit-transition: none; + -moz-transition: none; + transition: none; + } + +.leaflet-zoom-anim .leaflet-zoom-hide { + visibility: hidden; + } + + +/* cursors */ + +.leaflet-interactive { + cursor: pointer; + } +.leaflet-grab { + cursor: -webkit-grab; + cursor: -moz-grab; + cursor: grab; + } +.leaflet-crosshair, +.leaflet-crosshair .leaflet-interactive { + cursor: crosshair; + } +.leaflet-popup-pane, +.leaflet-control { + cursor: auto; + } +.leaflet-dragging .leaflet-grab, +.leaflet-dragging .leaflet-grab .leaflet-interactive, +.leaflet-dragging .leaflet-marker-draggable { + cursor: move; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + cursor: grabbing; + } + +/* marker & overlays interactivity */ +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-image-layer, +.leaflet-pane > svg path, +.leaflet-tile-container { + pointer-events: none; + } + +.leaflet-marker-icon.leaflet-interactive, +.leaflet-image-layer.leaflet-interactive, +.leaflet-pane > svg path.leaflet-interactive, +svg.leaflet-image-layer.leaflet-interactive path { + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } + +/* visual tweaks */ + +.leaflet-container { + background: #ddd; + outline: 0; + } +.leaflet-container a { + color: #0078A8; + } +.leaflet-container a.leaflet-active { + outline: 2px solid orange; + } +.leaflet-zoom-box { + border: 2px dotted #38f; + background: rgba(255,255,255,0.5); + } + + +/* general typography */ +.leaflet-container { + font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; + } + + +/* general toolbar styles */ + +.leaflet-bar { + box-shadow: 0 1px 5px rgba(0,0,0,0.65); + border-radius: 4px; + } +.leaflet-bar a, +.leaflet-bar a:hover { + background-color: #fff; + border-bottom: 1px solid #ccc; + width: 26px; + height: 26px; + line-height: 26px; + display: block; + text-align: center; + text-decoration: none; + color: black; + } +.leaflet-bar a, +.leaflet-control-layers-toggle { + background-position: 50% 50%; + background-repeat: no-repeat; + display: block; + } +.leaflet-bar a:hover { + background-color: #f4f4f4; + } +.leaflet-bar a:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + } +.leaflet-bar a:last-child { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-bottom: none; + } +.leaflet-bar a.leaflet-disabled { + cursor: default; + background-color: #f4f4f4; + color: #bbb; + } + +.leaflet-touch .leaflet-bar a { + width: 30px; + height: 30px; + line-height: 30px; + } +.leaflet-touch .leaflet-bar a:first-child { + border-top-left-radius: 2px; + border-top-right-radius: 2px; + } +.leaflet-touch .leaflet-bar a:last-child { + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + } + +/* zoom control */ + +.leaflet-control-zoom-in, +.leaflet-control-zoom-out { + font: bold 18px 'Lucida Console', Monaco, monospace; + text-indent: 1px; + } + +.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { + font-size: 22px; + } + + +/* layers control */ + +.leaflet-control-layers { + box-shadow: 0 1px 5px rgba(0,0,0,0.4); + background: #fff; + border-radius: 5px; + } +.leaflet-control-layers-toggle { + background-image: url(images/layers.png); + width: 36px; + height: 36px; + } +.leaflet-retina .leaflet-control-layers-toggle { + background-image: url(images/layers-2x.png); + background-size: 26px 26px; + } +.leaflet-touch .leaflet-control-layers-toggle { + width: 44px; + height: 44px; + } +.leaflet-control-layers .leaflet-control-layers-list, +.leaflet-control-layers-expanded .leaflet-control-layers-toggle { + display: none; + } +.leaflet-control-layers-expanded .leaflet-control-layers-list { + display: block; + position: relative; + } +.leaflet-control-layers-expanded { + padding: 6px 10px 6px 6px; + color: #333; + background: #fff; + } +.leaflet-control-layers-scrollbar { + overflow-y: scroll; + overflow-x: hidden; + padding-right: 5px; + } +.leaflet-control-layers-selector { + margin-top: 2px; + position: relative; + top: 1px; + } +.leaflet-control-layers label { + display: block; + } +.leaflet-control-layers-separator { + height: 0; + border-top: 1px solid #ddd; + margin: 5px -10px 5px -6px; + } + +/* Default icon URLs */ +.leaflet-default-icon-path { + background-image: url(images/marker-icon.png); + } + + +/* attribution and scale controls */ + +.leaflet-container .leaflet-control-attribution { + background: #fff; + background: rgba(255, 255, 255, 0.7); + margin: 0; + } +.leaflet-control-attribution, +.leaflet-control-scale-line { + padding: 0 5px; + color: #333; + } +.leaflet-control-attribution a { + text-decoration: none; + } +.leaflet-control-attribution a:hover { + text-decoration: underline; + } +.leaflet-container .leaflet-control-attribution, +.leaflet-container .leaflet-control-scale { + font-size: 11px; + } +.leaflet-left .leaflet-control-scale { + margin-left: 5px; + } +.leaflet-bottom .leaflet-control-scale { + margin-bottom: 5px; + } +.leaflet-control-scale-line { + border: 2px solid #777; + border-top: none; + line-height: 1.1; + padding: 2px 5px 1px; + font-size: 11px; + white-space: nowrap; + overflow: hidden; + -moz-box-sizing: border-box; + box-sizing: border-box; + + background: #fff; + background: rgba(255, 255, 255, 0.5); + } +.leaflet-control-scale-line:not(:first-child) { + border-top: 2px solid #777; + border-bottom: none; + margin-top: -2px; + } +.leaflet-control-scale-line:not(:first-child):not(:last-child) { + border-bottom: 2px solid #777; + } + +.leaflet-touch .leaflet-control-attribution, +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + box-shadow: none; + } +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + border: 2px solid rgba(0,0,0,0.2); + background-clip: padding-box; + } + + +/* popup */ + +.leaflet-popup { + position: absolute; + text-align: center; + margin-bottom: 20px; + } +.leaflet-popup-content-wrapper { + padding: 1px; + text-align: left; + border-radius: 12px; + } +.leaflet-popup-content { + margin: 13px 19px; + line-height: 1.4; + } +.leaflet-popup-content p { + margin: 18px 0; + } +.leaflet-popup-tip-container { + width: 40px; + height: 20px; + position: absolute; + left: 50%; + margin-left: -20px; + overflow: hidden; + pointer-events: none; + } +.leaflet-popup-tip { + width: 17px; + height: 17px; + padding: 1px; + + margin: -10px auto 0; + + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + } +.leaflet-popup-content-wrapper, +.leaflet-popup-tip { + background: white; + color: #333; + box-shadow: 0 3px 14px rgba(0,0,0,0.4); + } +.leaflet-container a.leaflet-popup-close-button { + position: absolute; + top: 0; + right: 0; + padding: 4px 4px 0 0; + border: none; + text-align: center; + width: 18px; + height: 14px; + font: 16px/14px Tahoma, Verdana, sans-serif; + color: #c3c3c3; + text-decoration: none; + font-weight: bold; + background: transparent; + } +.leaflet-container a.leaflet-popup-close-button:hover { + color: #999; + } +.leaflet-popup-scrolled { + overflow: auto; + border-bottom: 1px solid #ddd; + border-top: 1px solid #ddd; + } + +.leaflet-oldie .leaflet-popup-content-wrapper { + zoom: 1; + } +.leaflet-oldie .leaflet-popup-tip { + width: 24px; + margin: 0 auto; + + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; + filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); + } +.leaflet-oldie .leaflet-popup-tip-container { + margin-top: -1px; + } + +.leaflet-oldie .leaflet-control-zoom, +.leaflet-oldie .leaflet-control-layers, +.leaflet-oldie .leaflet-popup-content-wrapper, +.leaflet-oldie .leaflet-popup-tip { + border: 1px solid #999; + } + + +/* div icon */ + +.leaflet-div-icon { + background: #fff; + border: 1px solid #666; + } + + +/* Tooltip */ +/* Base styles for the element that has a tooltip */ +.leaflet-tooltip { + position: absolute; + padding: 6px; + background-color: #fff; + border: 1px solid #fff; + border-radius: 3px; + color: #222; + white-space: nowrap; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + pointer-events: none; + box-shadow: 0 1px 3px rgba(0,0,0,0.4); + } +.leaflet-tooltip.leaflet-clickable { + cursor: pointer; + pointer-events: auto; + } +.leaflet-tooltip-top:before, +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + position: absolute; + pointer-events: none; + border: 6px solid transparent; + background: transparent; + content: ""; + } + +/* Directions */ + +.leaflet-tooltip-bottom { + margin-top: 6px; +} +.leaflet-tooltip-top { + margin-top: -6px; +} +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-top:before { + left: 50%; + margin-left: -6px; + } +.leaflet-tooltip-top:before { + bottom: 0; + margin-bottom: -12px; + border-top-color: #fff; + } +.leaflet-tooltip-bottom:before { + top: 0; + margin-top: -12px; + margin-left: -6px; + border-bottom-color: #fff; + } +.leaflet-tooltip-left { + margin-left: -6px; +} +.leaflet-tooltip-right { + margin-left: 6px; +} +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + top: 50%; + margin-top: -6px; + } +.leaflet-tooltip-left:before { + right: 0; + margin-right: -12px; + border-left-color: #fff; + } +.leaflet-tooltip-right:before { + left: 0; + margin-left: -12px; + border-right-color: #fff; + }