Merge current master

This commit is contained in:
Steve Pettitt
2016-02-20 17:24:57 +00:00
39 changed files with 265 additions and 106 deletions

13
.codeclimate.yml Normal file
View File

@@ -0,0 +1,13 @@
engines:
rubocop:
enabled: true
scss-lint:
enabled: true
ratings:
paths:
- app/**
- lib/**
- "**.rb"
exclude_paths:
- spec/**/*
- vendor/**/*

29
.rubocop.yml Normal file
View File

@@ -0,0 +1,29 @@
AllCops:
Include:
- '**/Rakefile'
- '**/config.ru'
Exclude:
- 'db/**/*'
- 'config/**/*'
- 'script/**/*'
- 'spec/**/*'
- !ruby/regexp /old_and_unused\.rb$/
Documentation:
Enabled: false
Style/EmptyLinesAroundClassBody:
Enabled: false
Style/BracesAroundHashParameters:
Enabled: false
Metrics/LineLength:
Enabled: false
Max: 120
MethodLength:
Enabled: false
StringLiterals:
Enabled: false

3
.scss-lint.yml Normal file
View File

@@ -0,0 +1,3 @@
scss_files: 'app/assets/stylesheets/**/*.css.scss'
exclude: 'app/assets/stylesheets/shared/**'

View File

@@ -1,7 +1,7 @@
# Contributing
We love pull requests from everyone. Here are some instructions for
contributing code to Open Food Network.
contributing code to Open Food Network. See the [developer wiki](https://github.com/openfoodfoundation/openfoodnetwork/wiki) for more information.
Fork, then clone the repo:

View File

@@ -1,3 +1,4 @@
[![Build Status](https://travis-ci.org/openfoodfoundation/openfoodnetwork.svg?branch=master)](https://travis-ci.org/openfoodfoundation/openfoodnetwork)
[![Code Climate](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork.png)](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork)
# Open Food Network
@@ -14,10 +15,12 @@ We're part of global movement - get involved!
## Getting started
Below are instructions for setting up a development environment for Open Food Network. If you're interested in provisioning a server, see [the project's Ansible playbooks](https://github.com/openfoodfoundation/ofn_deployment).
Below are instructions for setting up a development environment for Open Food Network. More information is in the [developer wiki](https://github.com/openfoodfoundation/openfoodnetwork/wiki).
If you're interested in provisioning a server, see [the project's Ansible playbooks](https://github.com/openfoodfoundation/ofn_deployment).
## Dependencies
### Dependencies
* Rails 3.2.x
* Ruby 2.1.5
@@ -26,7 +29,7 @@ Below are instructions for setting up a development environment for Open Food Ne
* See Gemfile for a list of gems required
## Get it
### Get it
The source code is managed with Git (a version control system) and
hosted at GitHub.
@@ -40,7 +43,7 @@ You can download the source with the command:
git clone https://github.com/openfoodfoundation/openfoodnetwork.git
## Get it running
### Get it running
For those new to Rails, the following tutorial will help get you up to speed with configuring a Rails environment: http://guides.rubyonrails.org/getting_started.html .
@@ -58,6 +61,15 @@ Configure the site:
cp config/application.yml.example config/application.yml
edit config/application.yml
Create a PostgreSQL user:
* Login as your system postrgresql priviledged user: `sudo -i -u postgres` (this may vary on your OS). Now your prompt looks like: `[postgres@your_host ~]$`
* Create the `ofn` database superuser and give it the password `f00d`:
```
createuser -s -P ofn
```
Create the development and test databases, using the settings specified in `config/database.yml`, and populate them with a schema and seed data:
rake db:setup
@@ -71,7 +83,7 @@ At long last, your dreams of spinning up a development server can be realised:
rails server
## Testing
### Testing
Tests, both unit and integration, are based on RSpec. To run the test suite, first prepare the test database:
@@ -97,6 +109,10 @@ usage instructions.
* Will Marshall (http://soundcloud.com/willmarshall)
* Laura Summers (https://github.com/summerscope)
* Maikel Linke (https://github.com/mkllnk)
* Lynne Davis (https://github.com/lin-d-hop)
* Paul Mackay (https://github.com/pmackay)
* Steve Petitt (https://github.com/stveep)
## Licence

View File

@@ -1,9 +1,7 @@
Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, Enterprises, Search, $document, HashNavigation, FilterSelectorsService, EnterpriseModal, enterpriseMatchesNameQueryFilter, distanceWithinKmFilter) ->
$scope.Enterprises = Enterprises
$scope.totalActive = FilterSelectorsService.totalActive
$scope.clearAll = FilterSelectorsService.clearAll
$scope.filterText = FilterSelectorsService.filterText
$scope.FilterSelectorsService = FilterSelectorsService
$scope.producers_to_filter = Enterprises.producers
$scope.filterSelectors = FilterSelectorsService.createSelectors()
$scope.query = Search.search()
$scope.openModal = EnterpriseModal.open
$scope.activeTaxons = []

View File

@@ -1,8 +1,5 @@
Darkswarm.controller "GroupEnterprisesCtrl", ($scope, Search, FilterSelectorsService, EnterpriseModal) ->
$scope.totalActive = FilterSelectorsService.totalActive
$scope.clearAll = FilterSelectorsService.clearAll
$scope.filterText = FilterSelectorsService.filterText
$scope.FilterSelectorsService = FilterSelectorsService
$scope.filterSelectors = FilterSelectorsService.createSelectors()
$scope.query = Search.search()
$scope.openModal = EnterpriseModal.open
$scope.activeTaxons = []

View File

@@ -15,6 +15,8 @@ Darkswarm.controller "GroupPageCtrl", ($scope, group_enterprises, Enterprises, M
$scope.group_hubs = visible_enterprises.filter (enterprise) ->
enterprise.category in ["hub", "hub_profile", "producer_hub", "producer_shop"]
$scope.producers_to_filter = $scope.group_producers
$scope.map = angular.copy MapConfiguration.options
$scope.mapMarkers = OfnMap.enterprise_markers visible_enterprises

View File

@@ -1,10 +1,8 @@
Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Products, OrderCycle, FilterSelectorsService, Cart, Taxons, Properties) ->
$scope.Products = Products
$scope.Cart = Cart
$scope.totalActive = FilterSelectorsService.totalActive
$scope.clearAll = FilterSelectorsService.clearAll
$scope.filterText = FilterSelectorsService.filterText
$scope.FilterSelectorsService = FilterSelectorsService
$scope.taxonSelectors = FilterSelectorsService.createSelectors()
$scope.propertySelectors = FilterSelectorsService.createSelectors()
$scope.filtersActive = true
$scope.limit = 3
$scope.order_cycle = OrderCycle.order_cycle
@@ -33,4 +31,5 @@ Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Products, OrderCycle,
$scope.clearAll = ->
$scope.query = ""
FilterSelectorsService.clearAll()
$scope.taxonSelectors.clearAll()
$scope.propertySelectors.clearAll()

View File

@@ -1,9 +1,10 @@
Darkswarm.directive "filterSelector", (FilterSelectorsService)->
Darkswarm.directive "filterSelector", ->
# Automatically builds activeSelectors for taxons
# Lots of magic here
restrict: 'E'
replace: true
scope:
selectorSet: '='
objects: "&"
activeSelectors: "=?"
allSelectors: "=?" # Optional
@@ -36,7 +37,7 @@ Darkswarm.directive "filterSelector", (FilterSelectorsService)->
if selector = selectors_by_id[id]
selectors.push selector
else
selector = selectors_by_id[id] = FilterSelectorsService.new
selector = selectors_by_id[id] = scope.selectorSet.new
object: object
selectors.push selector
selectors

View File

@@ -1,4 +1,4 @@
Darkswarm.directive "shippingTypeSelector", (FilterSelectorsService)->
Darkswarm.directive "shippingTypeSelector", ->
# Builds selector for shipping types
restrict: 'E'
replace: true
@@ -8,10 +8,10 @@ Darkswarm.directive "shippingTypeSelector", (FilterSelectorsService)->
pickup: false
delivery: false
scope.selectors =
delivery: FilterSelectorsService.new
scope.selectors =
delivery: scope.filterSelectors.new
icon: "ofn-i_039-delivery"
pickup: FilterSelectorsService.new
pickup: scope.filterSelectors.new
icon: "ofn-i_038-takeaway"
scope.emit = ->

View File

@@ -2,6 +2,7 @@ Darkswarm.directive 'singleLineSelectors', ($timeout, $filter) ->
restrict: 'E'
templateUrl: "single_line_selectors.html"
scope:
selectors: "="
objects: "&"
activeSelectors: "="
selectorName: "@activeSelectors"

View File

@@ -1,8 +1,11 @@
# Returns a factory with the only function `createSelectors()`.
# That function creates objects managing a list of filter selectors.
Darkswarm.factory "FilterSelectorsService", ->
# This stores all filters so we can access in-use counts etc
# Accessed via activeSelector Directive
new class FilterSelectorsService
selectors: []
class FilterSelectors
constructor: ->
@selectors = []
new: (obj = {})->
obj.active = false
@selectors.push obj
@@ -26,3 +29,8 @@ Darkswarm.factory "FilterSelectorsService", ->
for selector in @selectors
selector.active = false
selector.emit()
# Creates instances of `FilterSelectors`
new class FilterSelectorsService
createSelectors: ->
new FilterSelectors

View File

@@ -1,3 +1,4 @@
%active-selector{"ng-repeat" => "(name, selector) in selectors"}
%i{"ng-class" => "selector.icon"}
{{ name | capitalize }}
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-2
%active-selector{"ng-repeat" => "(name, selector) in selectors"}
%i{"ng-class" => "selector.icon"}
{{ name | capitalize }}

View File

@@ -1,5 +1,5 @@
-# In order for the single-line-selector scope to have access to the available selectors,
%filter-selector{objects: "objects()", "active-selectors" => "activeSelectors", "all-selectors" => "allSelectors" }
%filter-selector{"selector-set" => "selectors", objects: "objects()", "active-selectors" => "activeSelectors", "all-selectors" => "allSelectors" }
%ul{ ng: { if: "overFlowSelectors().length > 0 || fitting" } }
%li.more

View File

@@ -11,6 +11,10 @@
background-size: 922px 922px
@include sidepaddingSm
@include panepadding
h1, p.text
font-weight: 300
h1
font-size: 350%
a > .group-name
&:hover, &:focus, &:active
text-decoration: underline
@@ -97,11 +101,13 @@
// Producers tab
.producers
background-image: none
background-color: initial
.active_table .active_table_node a.is_distributor, .active_table .active_table_node a.is_distributor i.ofn-i_059-producer
color: $clr-turquoise
padding: 0
// Hubs tab
.hubs
background-image: none
padding-top: 0
padding-bottom: 0

View File

@@ -48,3 +48,7 @@ dialog .close-reveal-modal, .reveal-modal .close-reveal-modal
&:hover, &:active, &:focus
background-color: rgba(205,205,205,1)
color: #333
// Prevent body from scrolling when a modal is open
body.modal-open
overflow: hidden

View File

@@ -6,7 +6,7 @@ module InjectionHelper
end
def inject_group_enterprises
inject_json_ams "group_enterprises", @group.enterprises, Api::EnterpriseSerializer, enterprise_injection_data
inject_json_ams "group_enterprises", @group.enterprises.activated.all, Api::EnterpriseSerializer, enterprise_injection_data
end
def inject_current_hub

View File

@@ -16,7 +16,7 @@ class OrderCycle < ActiveRecord::Base
scope :inactive, lambda { where('order_cycles.orders_open_at > ? OR order_cycles.orders_close_at < ?', Time.zone.now, Time.zone.now) }
scope :upcoming, lambda { where('order_cycles.orders_open_at > ?', Time.zone.now) }
scope :closed, lambda { where('order_cycles.orders_close_at < ?', Time.zone.now).order("order_cycles.orders_close_at DESC") }
scope :undated, where(orders_open_at: nil, orders_close_at: nil)
scope :undated, where('order_cycles.orders_open_at IS NULL OR orders_close_at IS NULL')
scope :soonest_closing, lambda { active.order('order_cycles.orders_close_at ASC') }
# TODO This method returns all the closed orders. So maybe we can replace it with :recently_closed.
@@ -182,7 +182,7 @@ class OrderCycle < ActiveRecord::Base
end
def undated?
self.orders_open_at.nil? && self.orders_close_at.nil?
self.orders_open_at.nil? || self.orders_close_at.nil?
end
def upcoming?

View File

@@ -0,0 +1,21 @@
.row
= render partial: 'shared/components/filter_controls'
= render partial: 'shared/components/show_profiles'
.row.animate-show{"ng-show" => "filtersActive"}
.small-12.columns
.row.filter-box
.small-12.large-9.columns
%h5.tdhead
.light
= t :hubs_filter_by
= t :hubs_filter_type
%filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-5{"selector-set" => "filterSelectors", objects: "group_hubs | searchEnterprises:query | shipping:shippingTypes | showHubProfiles:show_profiles | taxonsOf", "active-selectors" => "activeTaxons"}
.small-12.large-3.columns
%h5.tdhead
.light
= t :hubs_filter_by
= t :hubs_filter_delivery
%shipping-type-selector
= render partial: 'shared/components/filter_box'

View File

@@ -7,10 +7,14 @@
angular.module('Darkswarm').value('groups', #{render partial: "json/groups", object: @groups})
#groups.pad-top.footer-pad{"ng-controller" => "GroupsCtrl"}
#active-table-search.row.pad-top
.small-12.columns
.row
.small-12.medium-6.medium-offset-3.columns.text-center
%h1
= t :groups_headline
%p.text
= t :groups_text
#active-table-search.row.pad-top
.small-12.columns
%p
%input{type: :text,
"ng-model" => "query",

View File

@@ -59,14 +59,13 @@
%h1
= t :groups_producers
= render partial: "shared/components/enterprise_search"
-# TODO: find out why this is not working
-#= render partial: "producers/filters"
= render partial: "producers/filters"
.row{bindonce: true}
.small-12.columns
.active_table
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
"ng-repeat" => "producer in filteredEnterprises = (group_producers | visible | searchEnterprises:query | taxons:activeTaxons)",
"ng-repeat" => "producer in filteredEnterprises = (group_producers | searchEnterprises:query | taxons:activeTaxons)",
"ng-controller" => "GroupEnterpriseNodeCtrl",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",
id: "{{producer.hash}}"}
@@ -87,17 +86,13 @@
= t :groups_hubs
= render partial: "shared/components/enterprise_search"
-# TODO: find out why this is not working
-#= render partial: "home/filters"
.small-12.medium-6.columns
%span &nbsp;
= render partial: 'shared/components/show_profiles'
= render partial: "hub_filters"
.row{bindonce: true}
.small-12.columns
.active_table
%hub.active_table_node.row.animate-repeat{id: "{{hub.hash}}",
"ng-repeat" => "hub in filteredEnterprises = (group_hubs | visible | searchEnterprises:query | taxons:activeTaxons | shipping:shippingTypes | showHubProfiles:show_profiles | orderBy:['-active', '+orders_close_at'])",
"ng-repeat" => "hub in filteredEnterprises = (group_hubs | searchEnterprises:query | taxons:activeTaxons | shipping:shippingTypes | showHubProfiles:show_profiles | orderBy:['-active', '+orders_close_at'])",
"ng-class" => "{'is_profile' : hub.category == 'hub_profile', 'closed' : !open(), 'open' : open(), 'inactive' : !hub.active, 'current' : current()}",
"ng-controller" => "GroupEnterpriseNodeCtrl"}
.small-12.columns

View File

@@ -11,13 +11,12 @@
.light
= t :hubs_filter_by
= t :hubs_filter_type
%filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-5{ objects: "visibleMatches | visible | taxonsOf", "active-selectors" => "activeTaxons" }
%filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-5{ "selector-set" => "filterSelectors", objects: "visibleMatches | visible | taxonsOf", "active-selectors" => "activeTaxons" }
.small-12.large-3.columns
%h5.tdhead
.light
= t :hubs_filter_by
= t :hubs_filter_delivery
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-2
%shipping-type-selector{results: "shippingTypes"}
%shipping-type-selector
= render partial: 'shared/components/filter_box'

View File

@@ -3,7 +3,7 @@
%meta{charset: 'utf-8'}/
%meta{name: 'viewport', content: "width=device-width,initial-scale=1.0"}/
%meta{property: "og:title", content: content_for?(:title) ? yield(:title) : t(:title)}
%meta{property: "og:description", content: content_for?(:description) ? yield(:description) : t(:description)}
%meta{property: "og:description", content: content_for?(:description) ? yield(:description) : t(:site_meta_description)}
%meta{property: "og:image", content: content_for?(:image) ? yield(:image) : ContentConfig.logo.url}
%title= content_for?(:title) ? "#{yield(:title)} - #{t(:title)}".html_safe : "#{t(:welcome_to)} #{t(:title)}"
- if Rails.env.production?

View File

@@ -11,5 +11,5 @@
.light
= t :producers_filter
= t :producers_filter_type
%filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-6{objects: "Enterprises.producers | searchEnterprises:query | taxonsOf", "active-selectors" => "activeTaxons"}
%filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-6{"selector-set" => "filterSelectors", objects: "producers_to_filter | searchEnterprises:query | taxonsOf", "active-selectors" => "activeTaxons"}
= render partial: 'shared/components/filter_box'

View File

@@ -150,7 +150,7 @@
= t :footer_legal_tos
&#124;
= t :footer_legal_visit
%a{href:"https://github.com/openfoodfoundation/openfoodnetwork", target: "_blank"} Github
%a{href:"https://github.com/openfoodfoundation/openfoodnetwork", target: "_blank"} GitHub
%p.text-small
= t :footer_legal_text_html, {content_license: link_to('CC BY-SA 3.0', 'https://creativecommons.org/licenses/by-sa/3.0/'), code_license: link_to('AGPL 3', 'https://tldrlegal.com/license/gnu-affero-general-public-license-v3-(agpl-3.0)')}

View File

@@ -1,5 +1,5 @@
.row.filter-box.clear-filters.animate-show{"ng-show" => "filtersActive && totalActive() > 0"}
.row.filter-box.clear-filters.animate-show{"ng-show" => "filtersActive && filterSelectors.totalActive() > 0"}
.small-12.columns
%a.button.secondary.small.expand{"ng-click" => "clearAll()"}
%a.button.secondary.small.expand{"ng-click" => "filterSelectors.clearAll()"}
%i.ofn-i_009-close
= t :components_filters_clearfilters

View File

@@ -1,4 +0,0 @@
%span.animate-show{"ng-show" => "filtersActive && totalActive() > 0"}
%a.button.secondary.tiny{"ng-click" => "clearAll()"}
%i.ofn-i_009-close
= t :components_filters_clearfilters

View File

@@ -1,9 +1,9 @@
.small-12.medium-6.columns
%a.button.success.tiny.filterbtn{"ng-click" => "filtersActive = !filtersActive",
"ng-show" => "FilterSelectorsService.selectors.length > 0"}
{{ filterText(filtersActive) }}
"ng-show" => "filterSelectors.selectors.length > 0"}
{{ filterSelectors.filterText(filtersActive) }}
%i.ofn-i_005-caret-down{"ng-show" => "!filtersActive"}
%i.ofn-i_006-caret-up{"ng-show" => "filtersActive"}
%a.button.secondary.tiny.filterbtn.disabled{"ng-show" => "FilterSelectorsService.selectors.length == 0"}
%a.button.secondary.tiny.filterbtn.disabled{"ng-show" => "filterSelectors.selectors.length == 0"}
= t :components_filters_nofilters

View File

@@ -1,8 +0,0 @@
%a.button.success.tiny.filterbtn{"ng-click" => "filtersActive = !filtersActive",
"ng-show" => "FilterSelectorsService.selectors.length > 0"}
{{ filterText(filtersActive) }}
%i.ofn-i_005-caret-down{"ng-show" => "!filtersActive"}
%i.ofn-i_006-caret-up{"ng-show" => "filtersActive"}
%a.button.secondary.tiny.filterbtn.disabled{"ng-show" => "FilterSelectorsService.selectors.length == 0"}
= t :components_filters_nofilters

View File

@@ -7,20 +7,23 @@
%td
%h5
= t :email_social
%p
%a.soc-btn.fb{:href => "https://www.facebook.com/OpenFoodNet", :target => "_blank"}
Facebook
%a.soc-btn.tw{:href => "https://twitter.com/OpenFoodNet", :target => "_blank"}
Twitter
%a.soc-btn.li{:href => "http://www.linkedin.com/groups/Open-Food-Foundation-4743336", :target => "_blank"}
LinkedIn
%p.social-icons
- if ContentConfig.footer_facebook_url.present?
%a.soc-btn.fb{href: ContentConfig.footer_facebook_url}
Facebook
- if ContentConfig.footer_twitter_url.present?
%a.soc-btn.tw{href: ContentConfig.footer_twitter_url}
Twitter
- if ContentConfig.footer_linkedin_url.present?
%a.soc-btn.li{href: ContentConfig.footer_linkedin_url}
LinkedIn
%table.column{:align => "left"}
%tr
%td
%h5
= t :email_contact
%p
- if ContentConfig.footer_email.present?
%h5
= t :email_contact
%strong
%a{:href => "mailto:hello@openfoodnetwork.org"}
hello@openfoodnetwork.org
%a{href: ContentConfig.footer_email.reverse, mailto: true, target: '_blank'}
#{ContentConfig.footer_email}
%span.clear

View File

@@ -1,5 +1,5 @@
.filter-shopfront.taxon-selectors.text-right
%single-line-selectors{ objects: "Products.products | products:query | properties: activeProperties | taxonsOf", "active-selectors" => "activeTaxons"}
%single-line-selectors{ selectors: "taxonSelectors", objects: "Products.products | products:query | properties: activeProperties | taxonsOf", "active-selectors" => "activeTaxons"}
.filter-shopfront.property-selectors.text-right
%single-line-selectors{ objects: "Products.products | products:query | taxons:activeTaxons | propertiesOf", "active-selectors" => "activeProperties"}
%single-line-selectors{ selectors: "propertySelectors", objects: "Products.products | products:query | taxons:activeTaxons | propertiesOf", "active-selectors" => "activeProperties"}

View File

@@ -18,7 +18,7 @@
- if @order.ship_address
%h4
= t :email_shipping_delivery_time
= t :email_shipping_delivery_address
%p
#{@order.ship_address.full_name}
%br

View File

@@ -129,7 +129,7 @@ en-GB:
footer_join_partners: "Food systems partners"
footer_legal_call: "Read our"
footer_legal_tos: "Terms & conditions"
footer_legal_tos: "Terms and conditions"
footer_legal_visit: "Find us on"
footer_legal_text_html: "Open Food Network is a free and open source software platform. Our content is licensed with %{content_license} and our code with %{code_license}."
@@ -355,7 +355,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
modal_how: "How it works"
modal_how_shop: Shop the Open Food Network
modal_how_shop_explained: Search for a food hub near you to start shopping! You can expand each food hub to see what kinds of goodies are available, and click through to start shopping. (You can only shop one food hub at a time.)
modal_how_pickup: Pick-ups, delivery & shipping costs
modal_how_pickup: Pick-ups, delivery and shipping costs
modal_how_pickup_explained: Some food hubs deliver to your door, while others require you to pick-up your purchases. You can see which options are available on the homepage, and select which you'd like at the shopping and check-out pages. Delivery will cost more, and pricing differs from hub-to-hub. Each food hub is a sales point with independent business operations and logisitics - so variations between hubs are to be expected.
modal_how_more: Learn more
modal_how_more_explained: "If you want to learn more about the Open Food Network, how it works, and get involved, check out:"
@@ -432,7 +432,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
orders_edit_checkout: Checkout
orders_form_empty_cart: "Empty cart"
orders_form_subtotal: Produce subtotal
orders_form_admin: Admin & handling
orders_form_admin: Admin and handling
orders_form_total: Total
orders_oc_expired_headline: Orders have closed for this order cycle
orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders."

View File

@@ -29,7 +29,7 @@ en:
home: "OFN"
title: Open Food Network
welcome_to: 'Welcome to '
description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can…"
site_meta_description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can…"
search_by_name: Search by name or suburb...
producers: Aussie Producers
producers_join: Australian producers are now welcome to join the Open Food Network.
@@ -168,7 +168,7 @@ en:
footer_join_partners: "Food systems partners"
footer_legal_call: "Read our"
footer_legal_tos: "Terms & conditions"
footer_legal_tos: "Terms and conditions"
footer_legal_visit: "Find us on"
footer_legal_text_html: "Open Food Network is a free and open source software platform. Our content is licensed with %{content_license} and our code with %{code_license}."
@@ -351,6 +351,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
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_search: "Search name or keyword"
groups_no_groups: "No groups found"
groups_about: "About Us"
@@ -395,7 +396,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
modal_how: "How it works"
modal_how_shop: Shop the Open Food Network
modal_how_shop_explained: Search for a food hub near you to start shopping! You can expand each food hub to see what kinds of goodies are available, and click through to start shopping. (You can only shop one food hub at a time.)
modal_how_pickup: Pick-ups, delivery & shipping costs
modal_how_pickup: Pick-ups, delivery and shipping costs
modal_how_pickup_explained: Some food hubs deliver to your door, while others require you to pick-up your purchases. You can see which options are available on the homepage, and select which you'd like at the shopping and check-out pages. Delivery will cost more, and pricing differs from hub-to-hub. Each food hub is a sales point with independent business operations and logisitics - so variations between hubs are to be expected.
modal_how_more: Learn more
modal_how_more_explained: "If you want to learn more about the Open Food Network, how it works, and get involved, check out:"
@@ -472,7 +473,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
orders_edit_checkout: Checkout
orders_form_empty_cart: "Empty cart"
orders_form_subtotal: Produce subtotal
orders_form_admin: Admin & handling
orders_form_admin: Admin and handling
orders_form_total: Total
orders_oc_expired_headline: Orders have closed for this order cycle
orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders."
@@ -630,7 +631,7 @@ Please follow the instructions there to make your enterprise visible on the Open
registration_type_producer: "Yes, I'm a producer"
registration_type_no_producer: "No, I'm not a producer"
registration_type_error: "Please choose one. Are you are producer?"
registration_type_producer_help: "Producers make yummy things to eat &/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it."
registration_type_producer_help: "Producers make yummy things to eat and/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it."
registration_type_no_producer_help: "If youre not a producer, youre probably someone who sells and distributes food. You might be a hub, coop, buying group, retailer, wholesaler or other."
create_profile: "Create Profile"
registration_images_headline: "Thanks!"

View File

@@ -14,10 +14,33 @@ fr:
title: Open Food France
welcome_to: 'Bienvenue sur '
search_by_name: Recherche pas nom ou région...
producers: Producteurs & hubs
producers: Producteurs et hubs
producers_join: Les producteurs et autres hubs basés en France sont invités à rejoindre Open Food France.
charges_sales_tax: Soumis à la TVA?
print: "Imprimer"
print_invoice: "Imprimer la facture"
send_invoice: "Envoyer la facture"
resend_confirmation: "Renvoyer la confirmation"
view_order: "Voir la commande"
edit_order: "Editer la commande"
ship_order: "Envoyer la commande"
cancel_order: "Annuler la commande"
confirm_send_invoice: "La facture de cette commande va être transmise au client. Etes-vous sûr de vouloir continuer ?"
confirm_resend_order_confirmation: "Etes-vous sûr de vouloir renvoyer le mail de confirmation de commande ?"
must_have_valid_business_number: "%{enterprise_name} doit avoir un SIRET valide avant que les factures puissent être envoyées."
invoice: "Facture"
percentage_of_sales: "%{percentage} des ventes"
percentage_of_turnover: "Pourcentage du chiffre d'affaire"
monthly_cap_excl_tax: "Cumul mensuel (sans TVA)"
capped_at_cap: "plafonné à %{cap}"
per_month: "par mois"
free: "gratuit"
plus_tax: "plus TVA"
total_monthly_bill_incl_tax: "Facture mensuelle totale (taxes incluses)"
sort_order_cycles_on_shopfront_by: "Trier les cycles de vente par"
invoice_column_item: "Produit"
invoice_column_qty: "Qté"
invoice_column_tax: "TVA"
invoice_column_price: "Prix"
logo: "Logo (640x130)"
logo_mobile: "Logo smartphone (75x26)"
logo_mobile_svg: "Logo smartphone (SVG)"
@@ -34,7 +57,6 @@ fr:
footer_links_md: "Liens"
footer_about_url: "A propos URL"
footer_tos_url: "Conditions d'utilisation URL"
invoice: "Facture"
name: Nom
first_name: Prénom
last_name: Nom de famille
@@ -111,7 +133,7 @@ fr:
footer_join_groups: "Inscription groupes"
footer_join_partners: "Partenaires"
footer_legal_call: "Lire nos"
footer_legal_tos: "Termes & conditions"
footer_legal_tos: "Termes et conditions"
footer_legal_visit: "Nous trouver sur"
footer_legal_text_html: "Open Food Network est une plateforme logicielle open source, libre et gratuite. Nos données sont protégées sous licence %{content_license} et notre code sous %{code_license}."
home_shop: Faire mes courses
@@ -210,7 +232,7 @@ fr:
email_payment_paid: RÉGLÉ
email_payment_not_paid: NON RÉGLÉ
email_payment_summary: Résumé du paiement
email_payment_method: "Payé via:"
email_payment_method: "Payer via :"
email_shipping_delivery_details: Détails de livraison
email_shipping_delivery_time: "Livré le:"
email_shipping_delivery_address: "Adresse de livraison:"
@@ -379,7 +401,7 @@ fr:
orders_edit_checkout: Régler ma commande
orders_form_empty_cart: "Vider le panier"
orders_form_subtotal: Sous-total
orders_form_admin: Admin & opérations
orders_form_admin: Admin et opérations
orders_form_total: Total
orders_oc_expired_headline: Les commandes ne sont plus possibles pour ce cycle de vente.
orders_oc_expired_text: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}! Veuillez contacter directement le hub pour voir s'il accepte les commandes tardives."
@@ -576,4 +598,4 @@ fr:
fundraising_fee: "Frais recherche de financement"
price_graph: "Légende détail du prix"
included_tax: "Inclut TVA"
remove_tax: "Afficher prix HT"
remove_tax: "Retirer TVA"

View File

@@ -17,7 +17,30 @@ nb:
producers: Norske Produsenter
producers_join: Norske produsenter er nå velkommen til å bli med i Open Food Network.
charges_sales_tax: MVA-pliktig?
print: "Print"
print_invoice: "Skriv ut Faktura"
send_invoice: "Send Faktura"
resend_confirmation: "Send Bekreftelse på nytt"
view_order: "Se Bestilling"
edit_order: "Rediger Bestilling"
ship_order: "Send Bestilling"
cancel_order: "Avbryt Bestilling"
confirm_send_invoice: "En faktura for denne bestillingen vil bli sendt til kunden. Er du sikker på at du vil fortsette?"
confirm_resend_order_confirmation: "Er du sikker på at du vil sende ordrebekreftelse via epost på nytt?"
must_have_valid_business_number: "%{enterprise_name} må ha et gyldig ORG nr. før fakturaer kan sendes."
invoice: "Faktura"
percentage_of_sales: "%{percentage} av handel"
percentage_of_turnover: "Prosent av omsetning"
monthly_cap_excl_tax: "månedlig tak (eks. MVA)"
capped_at_cap: "tak på %{cap}"
per_month: "pr. måned"
free: "gratis"
plus_tax: "pluss MVA"
total_monthly_bill_incl_tax: "Total månedlig regning (Inkl. Avgift)"
sort_order_cycles_on_shopfront_by: "Sorter Bestillingsrunder i Nettbutikk etter"
invoice_column_item: "Vare"
invoice_column_qty: "Mengde"
invoice_column_tax: "MVA"
invoice_column_price: "Pris"
logo: "Logo (640x130)"
logo_mobile: "Mobil logo (75x26)"
logo_mobile_svg: "Mobil logo (SVG)"
@@ -34,7 +57,6 @@ nb:
footer_links_md: "Linker"
footer_about_url: "Om URL"
footer_tos_url: "Vilkår URL"
invoice: "Faktura"
name: Navn
first_name: Fornavn
last_name: Etternavn
@@ -111,7 +133,7 @@ nb:
footer_join_groups: "Bli med som Gruppe"
footer_join_partners: "Samarbeidspartnere"
footer_legal_call: "Les våre"
footer_legal_tos: "Vilkår & betingelser"
footer_legal_tos: "Vilkår og betingelser"
footer_legal_visit: "Finn oss på"
footer_legal_text_html: "Open Food Network er en plattform med fri og åpen kildekode. Vårt innhold er lisensiert med %{content_license} og vår kode med %{code_license}."
home_shop: Handle nå
@@ -575,4 +597,4 @@ nb:
fundraising_fee: "Pengeinnsamlingsgebyr"
price_graph: "Prisgraf"
included_tax: "inkludert avgift"
remove_tax: "Fjern MVA"
remove_tax: "Fjern avgift"

View File

@@ -15,5 +15,11 @@ echo "--- Checking environment variables"
require_env_vars OFN_COMMIT BUILDKITE_REPO
echo "--- Checking GitHub status"
if [ -n "$1" ]; then
REQUIRED_STATUS="$1"
else
REQUIRED_STATUS="success"
fi
echo "Require status '$REQUIRED_STATUS'"
echo "Visiting $GITHUB_API_URL"
curl -s "$GITHUB_API_URL" | head -n 2 | grep '^ *"state": "success",$'
curl -s "$GITHUB_API_URL" | head -n 2 | grep '^ *"state":' | egrep "\"$REQUIRED_STATUS\",\$"

View File

@@ -35,12 +35,14 @@ describe OrderCycle do
oc_not_yet_open = create(:simple_order_cycle, orders_open_at: 1.week.from_now, orders_close_at: 2.weeks.from_now)
oc_already_closed = create(:simple_order_cycle, orders_open_at: 2.weeks.ago, orders_close_at: 1.week.ago)
oc_undated = create(:simple_order_cycle, orders_open_at: nil, orders_close_at: nil)
oc_undated_open = create(:simple_order_cycle, orders_open_at: 1.week.ago, orders_close_at: nil)
oc_undated_close = create(:simple_order_cycle, orders_open_at: nil, orders_close_at: 1.week.from_now)
OrderCycle.active.should == [oc_active]
OrderCycle.inactive.should match_array [oc_not_yet_open, oc_already_closed]
OrderCycle.upcoming.should == [oc_not_yet_open]
OrderCycle.closed.should == [oc_already_closed]
OrderCycle.undated.should == [oc_undated]
OrderCycle.undated.should == [oc_undated, oc_undated_open, oc_undated_close]
end
it "finds order cycles accessible by a user" do
@@ -356,6 +358,24 @@ describe OrderCycle do
oc.should_not be_open
oc.should_not be_closed
end
it "reports status when an order cycle is partially dated - opening time only" do
oc.update_attributes!(orders_close_at: nil)
oc.should be_undated
oc.should_not be_upcoming
oc.should_not be_open
oc.should_not be_closed
end
it "reports status when an order cycle is partially dated - closing time only" do
oc.update_attributes!(orders_open_at: nil)
oc.should be_undated
oc.should_not be_upcoming
oc.should_not be_open
oc.should_not be_closed
end
end
it "clones itself" do