accept changesfrom upstream and resolve merge conflict ~ automatic go invoices
1
.gitignore
vendored
|
@ -7,6 +7,7 @@ tmp
|
||||||
public/assets
|
public/assets
|
||||||
public/system
|
public/system
|
||||||
public/uploads
|
public/uploads
|
||||||
|
storage
|
||||||
vendor/bundle
|
vendor/bundle
|
||||||
|
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2.6.6
|
2.6.9
|
||||||
|
|
|
@ -39,6 +39,7 @@ RUN export DATABASE_URL=mysql2://localhost/temp?encoding=utf8 && \
|
||||||
mariadb -e "CREATE DATABASE temp" && \
|
mariadb -e "CREATE DATABASE temp" && \
|
||||||
cp config/app_config.yml.SAMPLE config/app_config.yml && \
|
cp config/app_config.yml.SAMPLE config/app_config.yml && \
|
||||||
cp config/database.yml.MySQL_SAMPLE config/database.yml && \
|
cp config/database.yml.MySQL_SAMPLE config/database.yml && \
|
||||||
|
cp config/storage.yml.SAMPLE config/storage.yml && \
|
||||||
bundle exec rake db:setup assets:precompile && \
|
bundle exec rake db:setup assets:precompile && \
|
||||||
rm -Rf tmp/* && \
|
rm -Rf tmp/* && \
|
||||||
/etc/init.d/mysql stop && \
|
/etc/init.d/mysql stop && \
|
||||||
|
@ -56,6 +57,8 @@ USER nobody
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
|
VOLUME /usr/src/app/storage
|
||||||
|
|
||||||
# cleanup, and by default start web process from Procfile
|
# cleanup, and by default start web process from Procfile
|
||||||
ENTRYPOINT ["./docker-entrypoint.sh"]
|
ENTRYPOINT ["./docker-entrypoint.sh"]
|
||||||
CMD ["./proc-start", "web"]
|
CMD ["./proc-start", "web"]
|
||||||
|
|
|
@ -28,7 +28,7 @@ Deploying
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Setup foodsoft to [run in production](doc/SETUP_PRODUCTION.md), or join an existing
|
Setup foodsoft to [run in production](doc/SETUP_PRODUCTION.md), or join an existing
|
||||||
[hosting platform](https://foodcoops.github.io/foodsoft-hosting/).
|
[hosting platform](https://foodcoops.net/foodsoft-hosting/).
|
||||||
|
|
||||||
|
|
||||||
License
|
License
|
||||||
|
@ -52,7 +52,7 @@ files are marked as public domain in the file header.
|
||||||
|
|
||||||
If you have any remaining questions, please
|
If you have any remaining questions, please
|
||||||
[open an issue](https://github.com/foodcoops/foodsoft/issues/new) or contact
|
[open an issue](https://github.com/foodcoops/foodsoft/issues/new) or contact
|
||||||
the [mailing list](http://foodsoft.51229.x6.nabble.com/foodsoft-discuss-f5.html).
|
the [mailing list](http://foodsoft.274.s1.nabble.com/foodsoft-discuss-f5.html).
|
||||||
|
|
||||||
Please see [LICENSE](LICENSE.md) for the full and authoritative text. Some
|
Please see [LICENSE](LICENSE.md) for the full and authoritative text. Some
|
||||||
bundled third-party components have [other licenses](vendor/README.md).
|
bundled third-party components have [other licenses](vendor/README.md).
|
||||||
|
|
|
@ -115,7 +115,7 @@ class Mailer < ActionMailer::Base
|
||||||
@user = user
|
@user = user
|
||||||
@feedback = feedback
|
@feedback = feedback
|
||||||
|
|
||||||
mail to: FoodsoftConfig[:notification][:error_recipients],
|
mail to: feedback_recipients,
|
||||||
from: user,
|
from: user,
|
||||||
subject: I18n.t('mailer.feedback.subject')
|
subject: I18n.t('mailer.feedback.subject')
|
||||||
end
|
end
|
||||||
|
@ -196,4 +196,9 @@ class Mailer < ActionMailer::Base
|
||||||
address.display_name = name
|
address.display_name = name
|
||||||
address.format
|
address.format
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# use the (new) feedback_recipients option, but fallback to error_recipients for backwards compatibility
|
||||||
|
def feedback_recipients
|
||||||
|
FoodsoftConfig[:notification][:feedback_recipients] || FoodsoftConfig[:notification][:error_recipients]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -62,6 +62,10 @@ class Article < ApplicationRecord
|
||||||
validates_presence_of :name, :unit, :price, :tax, :deposit, :unit_quantity, :supplier_id, :article_category
|
validates_presence_of :name, :unit, :price, :tax, :deposit, :unit_quantity, :supplier_id, :article_category
|
||||||
validates_length_of :name, :in => 4..60
|
validates_length_of :name, :in => 4..60
|
||||||
validates_length_of :unit, :in => 1..15
|
validates_length_of :unit, :in => 1..15
|
||||||
|
validates_length_of :note, :maximum => 255
|
||||||
|
validates_length_of :origin, :maximum => 255
|
||||||
|
validates_length_of :manufacturer, :maximum => 255
|
||||||
|
validates_length_of :order_number, :maximum => 255
|
||||||
validates_numericality_of :price, :greater_than_or_equal_to => 0
|
validates_numericality_of :price, :greater_than_or_equal_to => 0
|
||||||
validates_numericality_of :unit_quantity, :greater_than => 0
|
validates_numericality_of :unit_quantity, :greater_than => 0
|
||||||
validates_numericality_of :deposit, :tax
|
validates_numericality_of :deposit, :tax
|
||||||
|
|
|
@ -118,9 +118,9 @@ default: &defaults
|
||||||
# label: Birthday
|
# label: Birthday
|
||||||
# as: date_picker
|
# as: date_picker
|
||||||
|
|
||||||
# Uncomment to add tracking code for web statistics, e.g. for Piwik. (Added to bottom of page)
|
# Uncomment to add tracking code for web statistics, e.g. for Matomo. (Added to bottom of page)
|
||||||
#webstats_tracking_code: |
|
#webstats_tracking_code: |
|
||||||
# <!-- Piwik -->
|
# <!-- Matomo -->
|
||||||
# ......
|
# ......
|
||||||
|
|
||||||
# email address to be used as sender
|
# email address to be used as sender
|
||||||
|
@ -137,6 +137,8 @@ default: &defaults
|
||||||
notification:
|
notification:
|
||||||
error_recipients:
|
error_recipients:
|
||||||
- admin@foodcoop.test
|
- admin@foodcoop.test
|
||||||
|
feedback_recipients:
|
||||||
|
- support@foodcoop.test
|
||||||
sender_address: "\"Foodsoft Error\" <foodsoft@foodcoop.test>"
|
sender_address: "\"Foodsoft Error\" <foodsoft@foodcoop.test>"
|
||||||
email_prefix: "[Foodsoft]"
|
email_prefix: "[Foodsoft]"
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,9 @@ Rails.application.configure do
|
||||||
config.cache_store = :null_store
|
config.cache_store = :null_store
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Store uploaded files on the local file system (see config/storage.yml for options)
|
||||||
|
config.active_storage.service = :local
|
||||||
|
|
||||||
# Don't care if the mailer can't send.
|
# Don't care if the mailer can't send.
|
||||||
config.action_mailer.raise_delivery_errors = false
|
config.action_mailer.raise_delivery_errors = false
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,9 @@ Rails.application.configure do
|
||||||
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
|
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
|
||||||
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
||||||
|
|
||||||
|
# Store uploaded files on the local file system (see config/storage.yml for options)
|
||||||
|
config.active_storage.service = :local
|
||||||
|
|
||||||
# Mount Action Cable outside main process or domain
|
# Mount Action Cable outside main process or domain
|
||||||
# config.action_cable.mount_path = nil
|
# config.action_cable.mount_path = nil
|
||||||
# config.action_cable.url = 'wss://example.com/cable'
|
# config.action_cable.url = 'wss://example.com/cable'
|
||||||
|
|
|
@ -31,6 +31,10 @@ Rails.application.configure do
|
||||||
|
|
||||||
# Disable request forgery protection in test environment.
|
# Disable request forgery protection in test environment.
|
||||||
config.action_controller.allow_forgery_protection = false
|
config.action_controller.allow_forgery_protection = false
|
||||||
|
|
||||||
|
# Store uploaded files on the local file system in a temporary directory
|
||||||
|
config.active_storage.service = :test
|
||||||
|
|
||||||
config.action_mailer.perform_caching = false
|
config.action_mailer.perform_caching = false
|
||||||
|
|
||||||
# Tell Action Mailer not to deliver emails to the real world.
|
# Tell Action Mailer not to deliver emails to the real world.
|
||||||
|
|
15
config/initializers/active_storage_foodcoop_path.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require 'active_storage/service/disk_service'
|
||||||
|
|
||||||
|
module FoodsoftActiveStorageDiskService
|
||||||
|
def self.included(base) # :nodoc:
|
||||||
|
base.class_eval do
|
||||||
|
def path_for(key)
|
||||||
|
File.join root, FoodsoftConfig.scope, folder_for(key), key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ActiveSupport.on_load(:after_initialize) do
|
||||||
|
ActiveStorage::Service::DiskService.include FoodsoftActiveStorageDiskService
|
||||||
|
end
|
34
config/storage.yml.SAMPLE
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
test:
|
||||||
|
service: Disk
|
||||||
|
root: <%= Rails.root.join("tmp/storage") %>
|
||||||
|
|
||||||
|
local:
|
||||||
|
service: Disk
|
||||||
|
root: <%= Rails.root.join("storage") %>
|
||||||
|
|
||||||
|
# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
|
||||||
|
# amazon:
|
||||||
|
# service: S3
|
||||||
|
# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
|
||||||
|
# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
|
||||||
|
# region: us-east-1
|
||||||
|
# bucket: your_own_bucket
|
||||||
|
|
||||||
|
# Remember not to checkin your GCS keyfile to a repository
|
||||||
|
# google:
|
||||||
|
# service: GCS
|
||||||
|
# project: your_project
|
||||||
|
# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
|
||||||
|
# bucket: your_own_bucket
|
||||||
|
|
||||||
|
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
|
||||||
|
# microsoft:
|
||||||
|
# service: AzureStorage
|
||||||
|
# storage_account_name: your_account_name
|
||||||
|
# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
|
||||||
|
# container: your_container_name
|
||||||
|
|
||||||
|
# mirror:
|
||||||
|
# service: Mirror
|
||||||
|
# primary: local
|
||||||
|
# mirrors: [ amazon, google, microsoft ]
|
|
@ -0,0 +1,27 @@
|
||||||
|
# This migration comes from active_storage (originally 20170806125915)
|
||||||
|
class CreateActiveStorageTables < ActiveRecord::Migration[4.2][5.2]
|
||||||
|
def change
|
||||||
|
create_table :active_storage_blobs do |t|
|
||||||
|
t.string :key, null: false
|
||||||
|
t.string :filename, null: false
|
||||||
|
t.string :content_type
|
||||||
|
t.text :metadata
|
||||||
|
t.bigint :byte_size, null: false
|
||||||
|
t.string :checksum, null: false
|
||||||
|
t.datetime :created_at, null: false
|
||||||
|
|
||||||
|
t.index [:key], unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table :active_storage_attachments do |t|
|
||||||
|
t.string :name, null: false
|
||||||
|
t.references :record, null: false, polymorphic: true, index: false
|
||||||
|
t.references :blob, null: false
|
||||||
|
|
||||||
|
t.datetime :created_at, null: false
|
||||||
|
|
||||||
|
t.index [:record_type, :record_id, :name, :blob_id], name: "index_active_storage_attachments_uniqueness", unique: true
|
||||||
|
t.foreign_key :active_storage_blobs, column: :blob_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
119
db/schema.rb
|
@ -10,15 +10,36 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
ActiveRecord::Schema.define(version: 2021_02_05_090257) do
|
||||||
|
|
||||||
create_table "article_categories", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "active_storage_attachments", id: :integer, force: :cascade do |t|
|
||||||
|
t.string "name", null: false
|
||||||
|
t.string "record_type", null: false
|
||||||
|
t.bigint "record_id", null: false
|
||||||
|
t.bigint "blob_id", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
|
||||||
|
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "active_storage_blobs", id: :integer, force: :cascade do |t|
|
||||||
|
t.string "key", null: false
|
||||||
|
t.string "filename", null: false
|
||||||
|
t.string "content_type"
|
||||||
|
t.text "metadata"
|
||||||
|
t.bigint "byte_size", null: false
|
||||||
|
t.string "checksum", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "article_categories", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", default: "", null: false
|
t.string "name", default: "", null: false
|
||||||
t.string "description"
|
t.string "description"
|
||||||
t.index ["name"], name: "index_article_categories_on_name", unique: true
|
t.index ["name"], name: "index_article_categories_on_name", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "article_prices", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "article_prices", id: :integer, force: :cascade do |t|
|
||||||
t.integer "article_id", null: false
|
t.integer "article_id", null: false
|
||||||
t.decimal "price", precision: 8, scale: 2, default: "0.0", null: false
|
t.decimal "price", precision: 8, scale: 2, default: "0.0", null: false
|
||||||
t.decimal "tax", precision: 8, scale: 2, default: "0.0", null: false
|
t.decimal "tax", precision: 8, scale: 2, default: "0.0", null: false
|
||||||
|
@ -28,7 +49,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["article_id"], name: "index_article_prices_on_article_id"
|
t.index ["article_id"], name: "index_article_prices_on_article_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "articles", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "articles", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", default: "", null: false
|
t.string "name", default: "", null: false
|
||||||
t.integer "supplier_id", default: 0, null: false
|
t.integer "supplier_id", default: 0, null: false
|
||||||
t.integer "article_category_id", default: 0, null: false
|
t.integer "article_category_id", default: 0, null: false
|
||||||
|
@ -54,14 +75,14 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["type"], name: "index_articles_on_type"
|
t.index ["type"], name: "index_articles_on_type"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "assignments", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "assignments", id: :integer, force: :cascade do |t|
|
||||||
t.integer "user_id", default: 0, null: false
|
t.integer "user_id", default: 0, null: false
|
||||||
t.integer "task_id", default: 0, null: false
|
t.integer "task_id", default: 0, null: false
|
||||||
t.boolean "accepted", default: false
|
t.boolean "accepted", default: false
|
||||||
t.index ["user_id", "task_id"], name: "index_assignments_on_user_id_and_task_id", unique: true
|
t.index ["user_id", "task_id"], name: "index_assignments_on_user_id_and_task_id", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "bank_accounts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "bank_accounts", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.string "iban"
|
t.string "iban"
|
||||||
t.string "description"
|
t.string "description"
|
||||||
|
@ -70,7 +91,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.string "import_continuation_point"
|
t.string "import_continuation_point"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "bank_transactions", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "bank_transactions", id: :integer, force: :cascade do |t|
|
||||||
t.integer "bank_account_id", null: false
|
t.integer "bank_account_id", null: false
|
||||||
t.string "external_id"
|
t.string "external_id"
|
||||||
t.date "date"
|
t.date "date"
|
||||||
|
@ -84,7 +105,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["financial_link_id"], name: "index_bank_transactions_on_financial_link_id"
|
t.index ["financial_link_id"], name: "index_bank_transactions_on_financial_link_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "documents", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "documents", id: :integer, force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "mime"
|
t.string "mime"
|
||||||
t.binary "data", limit: 4294967295
|
t.binary "data", limit: 4294967295
|
||||||
|
@ -95,16 +116,16 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["parent_id"], name: "index_documents_on_parent_id"
|
t.index ["parent_id"], name: "index_documents_on_parent_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "financial_links", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "financial_links", id: :integer, force: :cascade do |t|
|
||||||
t.text "note"
|
t.text "note"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "financial_transaction_classes", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "financial_transaction_classes", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.boolean "ignore_for_account_balance", default: false, null: false
|
t.boolean "ignore_for_account_balance", default: false, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "financial_transaction_types", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "financial_transaction_types", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.integer "financial_transaction_class_id", null: false
|
t.integer "financial_transaction_class_id", null: false
|
||||||
t.string "name_short"
|
t.string "name_short"
|
||||||
|
@ -112,7 +133,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["name_short"], name: "index_financial_transaction_types_on_name_short"
|
t.index ["name_short"], name: "index_financial_transaction_types_on_name_short"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "financial_transactions", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "financial_transactions", id: :integer, force: :cascade do |t|
|
||||||
t.integer "ordergroup_id"
|
t.integer "ordergroup_id"
|
||||||
t.decimal "amount", precision: 8, scale: 2, default: "0.0", null: false
|
t.decimal "amount", precision: 8, scale: 2, default: "0.0", null: false
|
||||||
t.text "note", null: false
|
t.text "note", null: false
|
||||||
|
@ -126,7 +147,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["reverts_id"], name: "index_financial_transactions_on_reverts_id", unique: true
|
t.index ["reverts_id"], name: "index_financial_transactions_on_reverts_id", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "group_order_article_quantities", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "group_order_article_quantities", id: :integer, force: :cascade do |t|
|
||||||
t.integer "group_order_article_id", default: 0, null: false
|
t.integer "group_order_article_id", default: 0, null: false
|
||||||
t.integer "quantity", default: 0
|
t.integer "quantity", default: 0
|
||||||
t.integer "tolerance", default: 0
|
t.integer "tolerance", default: 0
|
||||||
|
@ -134,7 +155,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["group_order_article_id"], name: "index_group_order_article_quantities_on_group_order_article_id"
|
t.index ["group_order_article_id"], name: "index_group_order_article_quantities_on_group_order_article_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "group_order_articles", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "group_order_articles", id: :integer, force: :cascade do |t|
|
||||||
t.integer "group_order_id", default: 0, null: false
|
t.integer "group_order_id", default: 0, null: false
|
||||||
t.integer "order_article_id", default: 0, null: false
|
t.integer "order_article_id", default: 0, null: false
|
||||||
t.integer "quantity", default: 0, null: false
|
t.integer "quantity", default: 0, null: false
|
||||||
|
@ -147,17 +168,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["order_article_id"], name: "index_group_order_articles_on_order_article_id"
|
t.index ["order_article_id"], name: "index_group_order_articles_on_order_article_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "group_order_invoices", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "group_orders", id: :integer, force: :cascade do |t|
|
||||||
t.integer "group_order_id"
|
|
||||||
t.bigint "invoice_number"
|
|
||||||
t.date "invoice_date"
|
|
||||||
t.string "payment_method"
|
|
||||||
t.datetime "created_at", null: false
|
|
||||||
t.datetime "updated_at", null: false
|
|
||||||
t.index ["group_order_id"], name: "index_group_order_invoices_on_group_order_id", unique: true
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "group_orders", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
|
||||||
t.integer "ordergroup_id"
|
t.integer "ordergroup_id"
|
||||||
t.integer "order_id", default: 0, null: false
|
t.integer "order_id", default: 0, null: false
|
||||||
t.decimal "price", precision: 8, scale: 2, default: "0.0", null: false
|
t.decimal "price", precision: 8, scale: 2, default: "0.0", null: false
|
||||||
|
@ -170,7 +181,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["ordergroup_id"], name: "index_group_orders_on_ordergroup_id"
|
t.index ["ordergroup_id"], name: "index_group_orders_on_ordergroup_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "groups", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "groups", id: :integer, force: :cascade do |t|
|
||||||
t.string "type", default: "", null: false
|
t.string "type", default: "", null: false
|
||||||
t.string "name", default: "", null: false
|
t.string "name", default: "", null: false
|
||||||
t.string "description"
|
t.string "description"
|
||||||
|
@ -195,7 +206,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["name"], name: "index_groups_on_name", unique: true
|
t.index ["name"], name: "index_groups_on_name", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "invites", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "invites", id: :integer, force: :cascade do |t|
|
||||||
t.string "token", default: "", null: false
|
t.string "token", default: "", null: false
|
||||||
t.datetime "expires_at", null: false
|
t.datetime "expires_at", null: false
|
||||||
t.integer "group_id", default: 0, null: false
|
t.integer "group_id", default: 0, null: false
|
||||||
|
@ -204,7 +215,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["token"], name: "index_invites_on_token"
|
t.index ["token"], name: "index_invites_on_token"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "invoices", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "invoices", id: :integer, force: :cascade do |t|
|
||||||
t.integer "supplier_id"
|
t.integer "supplier_id"
|
||||||
t.string "number"
|
t.string "number"
|
||||||
t.date "date"
|
t.date "date"
|
||||||
|
@ -222,7 +233,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["supplier_id"], name: "index_invoices_on_supplier_id"
|
t.index ["supplier_id"], name: "index_invoices_on_supplier_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "links", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "links", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.string "url", null: false
|
t.string "url", null: false
|
||||||
t.integer "workgroup_id"
|
t.integer "workgroup_id"
|
||||||
|
@ -230,7 +241,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.string "authorization"
|
t.string "authorization"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "mail_delivery_status", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "mail_delivery_status", id: :integer, force: :cascade do |t|
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.string "email", null: false
|
t.string "email", null: false
|
||||||
t.string "message", null: false
|
t.string "message", null: false
|
||||||
|
@ -239,13 +250,13 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["email"], name: "index_mail_delivery_status_on_email"
|
t.index ["email"], name: "index_mail_delivery_status_on_email"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "memberships", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "memberships", id: :integer, force: :cascade do |t|
|
||||||
t.integer "group_id", default: 0, null: false
|
t.integer "group_id", default: 0, null: false
|
||||||
t.integer "user_id", default: 0, null: false
|
t.integer "user_id", default: 0, null: false
|
||||||
t.index ["user_id", "group_id"], name: "index_memberships_on_user_id_and_group_id", unique: true
|
t.index ["user_id", "group_id"], name: "index_memberships_on_user_id_and_group_id", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "message_recipients", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "message_recipients", id: :integer, force: :cascade do |t|
|
||||||
t.integer "message_id", null: false
|
t.integer "message_id", null: false
|
||||||
t.integer "user_id", null: false
|
t.integer "user_id", null: false
|
||||||
t.integer "email_state", default: 0, null: false
|
t.integer "email_state", default: 0, null: false
|
||||||
|
@ -254,7 +265,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["user_id", "read_at"], name: "index_message_recipients_on_user_id_and_read_at"
|
t.index ["user_id", "read_at"], name: "index_message_recipients_on_user_id_and_read_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "messages", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "messages", id: :integer, force: :cascade do |t|
|
||||||
t.integer "sender_id"
|
t.integer "sender_id"
|
||||||
t.string "subject", null: false
|
t.string "subject", null: false
|
||||||
t.text "body"
|
t.text "body"
|
||||||
|
@ -266,7 +277,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.binary "received_email", limit: 16777215
|
t.binary "received_email", limit: 16777215
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "oauth_access_grants", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "oauth_access_grants", id: :integer, force: :cascade do |t|
|
||||||
t.integer "resource_owner_id", null: false
|
t.integer "resource_owner_id", null: false
|
||||||
t.integer "application_id", null: false
|
t.integer "application_id", null: false
|
||||||
t.string "token", null: false
|
t.string "token", null: false
|
||||||
|
@ -278,7 +289,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true
|
t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "oauth_access_tokens", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "oauth_access_tokens", id: :integer, force: :cascade do |t|
|
||||||
t.integer "resource_owner_id"
|
t.integer "resource_owner_id"
|
||||||
t.integer "application_id"
|
t.integer "application_id"
|
||||||
t.string "token", null: false
|
t.string "token", null: false
|
||||||
|
@ -292,7 +303,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true
|
t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "oauth_applications", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "oauth_applications", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.string "uid", null: false
|
t.string "uid", null: false
|
||||||
t.string "secret", null: false
|
t.string "secret", null: false
|
||||||
|
@ -304,7 +315,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true
|
t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "order_articles", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "order_articles", id: :integer, force: :cascade do |t|
|
||||||
t.integer "order_id", default: 0, null: false
|
t.integer "order_id", default: 0, null: false
|
||||||
t.integer "article_id", default: 0, null: false
|
t.integer "article_id", default: 0, null: false
|
||||||
t.integer "quantity", default: 0, null: false
|
t.integer "quantity", default: 0, null: false
|
||||||
|
@ -318,7 +329,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["order_id"], name: "index_order_articles_on_order_id"
|
t.index ["order_id"], name: "index_order_articles_on_order_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "order_comments", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "order_comments", id: :integer, force: :cascade do |t|
|
||||||
t.integer "order_id"
|
t.integer "order_id"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.text "text"
|
t.text "text"
|
||||||
|
@ -326,7 +337,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["order_id"], name: "index_order_comments_on_order_id"
|
t.index ["order_id"], name: "index_order_comments_on_order_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "orders", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "orders", id: :integer, force: :cascade do |t|
|
||||||
t.integer "supplier_id"
|
t.integer "supplier_id"
|
||||||
t.text "note"
|
t.text "note"
|
||||||
t.datetime "starts"
|
t.datetime "starts"
|
||||||
|
@ -345,7 +356,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["state"], name: "index_orders_on_state"
|
t.index ["state"], name: "index_orders_on_state"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "page_versions", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "page_versions", id: :integer, force: :cascade do |t|
|
||||||
t.integer "page_id"
|
t.integer "page_id"
|
||||||
t.integer "lock_version"
|
t.integer "lock_version"
|
||||||
t.text "body"
|
t.text "body"
|
||||||
|
@ -356,7 +367,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["page_id"], name: "index_page_versions_on_page_id"
|
t.index ["page_id"], name: "index_page_versions_on_page_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "pages", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "pages", id: :integer, force: :cascade do |t|
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.text "body"
|
t.text "body"
|
||||||
t.string "permalink"
|
t.string "permalink"
|
||||||
|
@ -370,20 +381,20 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["title"], name: "index_pages_on_title"
|
t.index ["title"], name: "index_pages_on_title"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "periodic_task_groups", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "periodic_task_groups", id: :integer, force: :cascade do |t|
|
||||||
t.date "next_task_date"
|
t.date "next_task_date"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "poll_choices", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "poll_choices", id: :integer, force: :cascade do |t|
|
||||||
t.integer "poll_vote_id", null: false
|
t.integer "poll_vote_id", null: false
|
||||||
t.integer "choice", null: false
|
t.integer "choice", null: false
|
||||||
t.integer "value", null: false
|
t.integer "value", null: false
|
||||||
t.index ["poll_vote_id", "choice"], name: "index_poll_choices_on_poll_vote_id_and_choice", unique: true
|
t.index ["poll_vote_id", "choice"], name: "index_poll_choices_on_poll_vote_id_and_choice", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "poll_votes", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "poll_votes", id: :integer, force: :cascade do |t|
|
||||||
t.integer "poll_id", null: false
|
t.integer "poll_id", null: false
|
||||||
t.integer "user_id", null: false
|
t.integer "user_id", null: false
|
||||||
t.integer "ordergroup_id"
|
t.integer "ordergroup_id"
|
||||||
|
@ -393,7 +404,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["poll_id", "user_id", "ordergroup_id"], name: "index_poll_votes_on_poll_id_and_user_id_and_ordergroup_id", unique: true
|
t.index ["poll_id", "user_id", "ordergroup_id"], name: "index_poll_votes_on_poll_id_and_user_id_and_ordergroup_id", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "polls", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "polls", id: :integer, force: :cascade do |t|
|
||||||
t.integer "created_by_user_id", null: false
|
t.integer "created_by_user_id", null: false
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.text "description"
|
t.text "description"
|
||||||
|
@ -413,7 +424,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["final_choice"], name: "index_polls_on_final_choice"
|
t.index ["final_choice"], name: "index_polls_on_final_choice"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "printer_job_updates", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "printer_job_updates", id: :integer, force: :cascade do |t|
|
||||||
t.integer "printer_job_id", null: false
|
t.integer "printer_job_id", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.string "state", null: false
|
t.string "state", null: false
|
||||||
|
@ -421,7 +432,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["printer_job_id", "created_at"], name: "index_printer_job_updates_on_printer_job_id_and_created_at"
|
t.index ["printer_job_id", "created_at"], name: "index_printer_job_updates_on_printer_job_id_and_created_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "printer_jobs", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "printer_jobs", id: :integer, force: :cascade do |t|
|
||||||
t.integer "order_id"
|
t.integer "order_id"
|
||||||
t.string "document", null: false
|
t.string "document", null: false
|
||||||
t.integer "created_by_user_id", null: false
|
t.integer "created_by_user_id", null: false
|
||||||
|
@ -430,7 +441,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["finished_at"], name: "index_printer_jobs_on_finished_at"
|
t.index ["finished_at"], name: "index_printer_jobs_on_finished_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "settings", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "settings", id: :integer, force: :cascade do |t|
|
||||||
t.string "var", null: false
|
t.string "var", null: false
|
||||||
t.text "value"
|
t.text "value"
|
||||||
t.integer "thing_id"
|
t.integer "thing_id"
|
||||||
|
@ -440,7 +451,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["thing_type", "thing_id", "var"], name: "index_settings_on_thing_type_and_thing_id_and_var", unique: true
|
t.index ["thing_type", "thing_id", "var"], name: "index_settings_on_thing_type_and_thing_id_and_var", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "stock_changes", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "stock_changes", id: :integer, force: :cascade do |t|
|
||||||
t.integer "stock_event_id"
|
t.integer "stock_event_id"
|
||||||
t.integer "order_id"
|
t.integer "order_id"
|
||||||
t.integer "stock_article_id"
|
t.integer "stock_article_id"
|
||||||
|
@ -450,7 +461,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["stock_event_id"], name: "index_stock_changes_on_stock_event_id"
|
t.index ["stock_event_id"], name: "index_stock_changes_on_stock_event_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "stock_events", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "stock_events", id: :integer, force: :cascade do |t|
|
||||||
t.integer "supplier_id"
|
t.integer "supplier_id"
|
||||||
t.date "date"
|
t.date "date"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
|
@ -460,13 +471,13 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["supplier_id"], name: "index_stock_events_on_supplier_id"
|
t.index ["supplier_id"], name: "index_stock_events_on_supplier_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "supplier_categories", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "supplier_categories", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.string "description"
|
t.string "description"
|
||||||
t.integer "financial_transaction_class_id"
|
t.integer "financial_transaction_class_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "suppliers", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "suppliers", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", default: "", null: false
|
t.string "name", default: "", null: false
|
||||||
t.string "address", default: "", null: false
|
t.string "address", default: "", null: false
|
||||||
t.string "phone", default: "", null: false
|
t.string "phone", default: "", null: false
|
||||||
|
@ -488,7 +499,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["name"], name: "index_suppliers_on_name", unique: true
|
t.index ["name"], name: "index_suppliers_on_name", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "tasks", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "tasks", id: :integer, force: :cascade do |t|
|
||||||
t.string "name", default: "", null: false
|
t.string "name", default: "", null: false
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.date "due_date"
|
t.date "due_date"
|
||||||
|
@ -505,7 +516,7 @@ ActiveRecord::Schema.define(version: 2021_12_08_142719) do
|
||||||
t.index ["workgroup_id"], name: "index_tasks_on_workgroup_id"
|
t.index ["workgroup_id"], name: "index_tasks_on_workgroup_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
create_table "users", id: :integer, force: :cascade do |t|
|
||||||
t.string "nick"
|
t.string "nick"
|
||||||
t.string "password_hash", default: "", null: false
|
t.string "password_hash", default: "", null: false
|
||||||
t.string "password_salt", default: "", null: false
|
t.string "password_salt", default: "", null: false
|
||||||
|
|
|
@ -11,107 +11,100 @@ If instead you just want to run Foodsoft without changing its code, please refer
|
||||||
[deployment](https://github.com/foodcoops/foodsoft/wiki/Deployment-notes).
|
[deployment](https://github.com/foodcoops/foodsoft/wiki/Deployment-notes).
|
||||||
|
|
||||||
**System requirements**:
|
**System requirements**:
|
||||||
[RVM](https://rvm.io/rvm/install),
|
[rbenv](https://github.com/rbenv/rbenv),
|
||||||
[Ruby 2+](https://www.ruby-lang.org/en/downloads/),
|
[Ruby 2.6+](https://www.ruby-lang.org/en/downloads/),
|
||||||
[Bundler](http://bundler.io/),
|
[Bundler](http://bundler.io/),
|
||||||
[MySQL](http://mysql.com/)/[PostgreSQL](http://www.postgresql.org/)/[SQLite](http://sqlite.org/).
|
[MySQL](http://mysql.com/) / [SQLite](http://sqlite.org/),
|
||||||
|
[Redis](http://redis.io/) (optional).
|
||||||
**Optional**:
|
|
||||||
[Redis](http://redis.io/).
|
|
||||||
|
|
||||||
### Getting started
|
### Getting started
|
||||||
|
|
||||||
0. Clone the repository from GitHub:
|
1. Clone the repository from GitHub:
|
||||||
|
|
||||||
git clone https://github.com/foodcoops/foodsoft.git
|
git clone https://github.com/foodcoops/foodsoft.git
|
||||||
|
|
||||||
This brings up the bleeding-edge development version, which might contain some
|
This brings up the bleeding-edge development version, which might contain some unfinished parts.
|
||||||
unfinished parts. If you want to be safe, choose the last release:
|
If you want to be safe, choose the last release:
|
||||||
`git checkout $(git tag -l | grep ^v | sort -rn | head -n1)`
|
|
||||||
|
|
||||||
*Note:* When developing on Windows you might run into issues with shell scripts
|
git checkout $(git tag -l | grep ^v | sort -rn | head -n1)
|
||||||
because of Git auto-crlf. Have a look how to avoid that in the
|
|
||||||
[Docker Development Setup](./SETUP_DEVELOPMENT_DOCKER.md#prerequisites-windows-only)
|
*Note:* When developing on Windows you might run into issues with shell scripts because of Git auto-crlf.
|
||||||
|
Have a look how to avoid that in the [Docker Development Setup](./SETUP_DEVELOPMENT_DOCKER.md#prerequisites-windows-only)
|
||||||
instructions.
|
instructions.
|
||||||
|
|
||||||
1. Install RVM and Ruby 2.6+ (if you have not done so before):
|
1. Install and setup rbenv and Bundler. For Debian/Ubuntu:
|
||||||
|
|
||||||
\curl -L https://get.rvm.io | bash
|
sudo apt install rbenv
|
||||||
source ~/.rvm/scripts/rvm
|
|
||||||
rvm install 2.6
|
|
||||||
|
|
||||||
We try to keep Foodsoft compatible with Ruby 2.6 as well as any later versions,
|
For other distributions have a look at the rbenv [documentation](https://github.com/rbenv/rbenv).
|
||||||
so if you use this and don't want to use RVM, that might actually work.
|
|
||||||
|
|
||||||
2. Install system dependencies.
|
Add the following line to your `.bashrc`:
|
||||||
|
|
||||||
For Debian/Ubuntu, that's
|
eval "$(rbenv init -)"
|
||||||
[libv8-dev](https://packages.debian.org/stable/libv8-dev)
|
|
||||||
[libmysqlclient-dev](https://packages.debian.org/stable/libmysqlclient-dev)
|
|
||||||
[libxml2-dev](https://packages.debian.org/stable/libxml2-dev)
|
|
||||||
[libxslt1-dev](https://packages.debian.org/stable/libxslt1-dev)
|
|
||||||
[libffi-dev](https://packages.debian.org/stable/libffi-dev)
|
|
||||||
[libreadline-dev](https://packages.debian.org/stable/libreadline-dev)
|
|
||||||
[libmagic-dev](https://packages.debian.org/stable/libmagic-dev):
|
|
||||||
|
|
||||||
# Debian/Ubuntu
|
Install [ruby-build](https://github.com/rbenv/ruby-build):
|
||||||
sudo apt-get install libv8-dev libmysqlclient-dev libxml2-dev libxslt1-dev libffi-dev libreadline-dev libmagic-dev
|
|
||||||
|
|
||||||
For CentOS/Redhat you need
|
mkdir -p "$(rbenv root)"/plugins
|
||||||
[v8](https://apps.fedoraproject.org/packages/v8)
|
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
|
||||||
[community-mysql-devel](https://apps.fedoraproject.org/packages/community-mysql-devel)
|
|
||||||
[libxml2-devel](https://apps.fedoraproject.org/packages/libxml2-devel)
|
Change to the Foodsoft directory and install the [recommended](https://github.com/foodcoops/foodsoft/blob/master/.ruby-version)
|
||||||
[libxslt-devel](https://apps.fedoraproject.org/packages/libxslt-devel)
|
Ruby version:
|
||||||
[libffi-devel](https://apps.fedoraproject.org/packages/libffi-devel)
|
|
||||||
[readline-devel](https://apps.fedoraproject.org/packages/readline-devel)
|
rbenv install "$(cat .ruby-version)"
|
||||||
[file-devel](https://apps.fedoraproject.org/packages/file-devel):
|
|
||||||
|
Now you can install [Bundler](https://bundler.io/):
|
||||||
|
|
||||||
|
rbenv exec gem install bundler
|
||||||
|
|
||||||
|
1. Install system dependencies.
|
||||||
|
|
||||||
|
For Debian/Ubuntu, that's:
|
||||||
|
|
||||||
|
sudo apt install libv8-dev default-libmysqlclient-dev libxml2-dev libxslt1-dev libffi-dev libreadline-dev libmagic-dev
|
||||||
|
|
||||||
|
For CentOS/Redhat you need:
|
||||||
|
|
||||||
# CentOS/Redhat
|
|
||||||
sudo yum install v8 community-mysql-devel libxml2-devel libxslt-devel libffi-devel readline-devel file-devel
|
sudo yum install v8 community-mysql-devel libxml2-devel libxslt-devel libffi-devel readline-devel file-devel
|
||||||
|
|
||||||
3. Install Ruby dependencies:
|
1. Install Ruby dependencies:
|
||||||
|
|
||||||
bundle install
|
rbenv exec bundle install
|
||||||
|
|
||||||
4. Setup your development environment:
|
1. Setup your development environment:
|
||||||
|
|
||||||
rake foodsoft:setup_development
|
rbenv exec rails foodsoft:setup_development
|
||||||
|
|
||||||
This will interactively prompt with several questions relating to your
|
This will interactively prompt with several questions relating to your
|
||||||
required environment.
|
required environment.
|
||||||
|
|
||||||
**Important**: After selecting your database type, `rake` will create the file `config/database.yml`,
|
**Important**: After selecting your database type, `rails` will create the file `config/database.yml`,
|
||||||
which then then be edited with working `username` and `password` credentials for the database. These fields
|
which then then be edited with working `username` and `password` credentials for the database. These fields
|
||||||
must be added for *development* AND (temporary) *test* databases. Then continue with confirmation in rake dialogue.
|
must be added for *development* AND (temporary) *test* databases. Then continue with confirmation in rails dialogue.
|
||||||
|
|
||||||
5. Start rails by running:
|
1. Start rails by running:
|
||||||
|
|
||||||
bundle exec rails s
|
rbenv exec rails s
|
||||||
|
|
||||||
6. Open your favorite browser and open the web application at:
|
1. Open your favorite browser and open the web browser at:
|
||||||
|
|
||||||
http://localhost:3000/
|
http://localhost:3000/
|
||||||
|
|
||||||
You might want to watch a
|
You might want to watch a [kitten video](https://www.youtube.com/watch?v=9Iq5yCoHp4o) while it's loading.
|
||||||
[kitten video](https://www.youtube.com/watch?v=9Iq5yCoHp4o)
|
|
||||||
while it's loading.
|
|
||||||
|
|
||||||
7. Login using the default credentials: `admin/secret`
|
1. Login using the default credentials: `admin/secret`
|
||||||
|
|
||||||
8. Change the admin password, just in case.
|
1. Change the admin password, just in case.
|
||||||
|
|
||||||
9. Have phun!
|
1. Have phun!
|
||||||
|
|
||||||
For running integration tests, you also need the Chromium/Chrome web browser.
|
For running integration tests, you also need the Chromium/Chrome web browser.
|
||||||
On Debian that would be `sudo apt-get install chromium`, on Ubuntu
|
On Debian that would be `apt-get install chromium`, on Ubuntu
|
||||||
`sudo apt-get install chromium-browser`.
|
`sudo apt-get install chromium-browser`.
|
||||||
|
|
||||||
### Manual configuration
|
### Manual configuration
|
||||||
|
|
||||||
The rake task `foodsoft:setup_development` helps you to setup foodsoft.
|
The rails task `foodsoft:setup_development` helps you to setup foodsoft.
|
||||||
If you want to have more control, you can do these steps manually as
|
If you want to have more control, you can do these steps manually as explained here.
|
||||||
explained here.
|
|
||||||
|
|
||||||
|
|
||||||
1. **Configure database**
|
1. **Configure database**
|
||||||
|
|
||||||
|
@ -120,23 +113,19 @@ explained here.
|
||||||
cp config/database.yml.SQLite_SAMPLE config/database.yml
|
cp config/database.yml.SQLite_SAMPLE config/database.yml
|
||||||
|
|
||||||
If you are fine with using a file-based sqlite database you are all set.
|
If you are fine with using a file-based sqlite database you are all set.
|
||||||
The sqlite files (`development/test/production`) will reside in the `db`
|
The sqlite files (`development/test/production`) will reside in the `db` directory. Otherwise you would want to copy one
|
||||||
directory. Otherwise you would want to copy one of the other
|
of the other `database.yml.*_SAMPLE` files and edit `database.yml` to suit your needs.
|
||||||
`database.yml.*_SAMPLE` files and edit `database.yml` to suit your needs.
|
|
||||||
|
|
||||||
|
1. **Configure development environment**
|
||||||
2. **Configure development environment**
|
|
||||||
|
|
||||||
Again, you need to create your own copy of the default configuration:
|
Again, you need to create your own copy of the default configuration:
|
||||||
|
|
||||||
cp config/environments/development.rb.SAMPLE config/environments/development.rb
|
cp config/environments/development.rb.SAMPLE config/environments/development.rb
|
||||||
|
|
||||||
Edit development.rb to specify your settings (at least the ActionMailer SMTP
|
Edit development.rb to specify your settings (at least the ActionMailer SMTP settings). If you just leave the file as is,
|
||||||
settings). If you just leave the file as is, emails will not work but
|
emails will not work but everything else should be okay.
|
||||||
everything else should be okay.
|
|
||||||
|
|
||||||
|
1. **Foodsoft settings**
|
||||||
3. **Foodsoft settings**
|
|
||||||
|
|
||||||
You need to create your own copy of the foodsoft configuration settings:
|
You need to create your own copy of the foodsoft configuration settings:
|
||||||
|
|
||||||
|
@ -144,37 +133,36 @@ explained here.
|
||||||
|
|
||||||
Edit `app_config.yml` to suit your needs or just keep the defaults for now.
|
Edit `app_config.yml` to suit your needs or just keep the defaults for now.
|
||||||
|
|
||||||
|
1. **Create database (schema) and load defaults**
|
||||||
|
|
||||||
4. **Create database (schema) and load defaults**
|
rbenv exec rails db:setup
|
||||||
|
|
||||||
rake db:setup
|
With this, you also get a ready to go user with username 'admin' and password 'secret'.
|
||||||
|
|
||||||
With this, you also get a ready to go user with username 'admin' and
|
1. (optional) Get **background jobs** done
|
||||||
password 'secret'.
|
|
||||||
|
|
||||||
|
Time intensive tasks may block the web request. To run these in a separate task, you can install Redis and enable Resque:
|
||||||
5. (optional) Get **background jobs** done
|
|
||||||
|
|
||||||
Time intensive tasks may block the web request. To run these in a separate
|
|
||||||
task, you can install Redis and enable Resque:
|
|
||||||
|
|
||||||
* Comment `Resque.inline = true` in `config/environments/development.rb`
|
* Comment `Resque.inline = true` in `config/environments/development.rb`
|
||||||
* Install [Redis](http://redis.io/) (Ubuntu package `redis-server`)
|
* Install [Redis](http://redis.io/) (Debian/Ubuntu package `redis-server`)
|
||||||
* Run the worker: `rake resque:work QUEUE=foodsoft_notifier`
|
* Run the worker:
|
||||||
|
|
||||||
|
```
|
||||||
|
rbenv exec rails resque:work QUEUE=*
|
||||||
|
```
|
||||||
|
|
||||||
To have look on the current queue, failed jobs etc start the resque server with
|
To have look on the current queue, failed jobs etc start the resque server with
|
||||||
`resque-web`.
|
`resque-web`.
|
||||||
|
|
||||||
|
1. (optional) **View mails in browser** instead in your logs
|
||||||
6. (optional) **View mails in browser** instead in your logs
|
|
||||||
|
|
||||||
We use mailcatcher in development mode to view all delivered mails in a
|
We use mailcatcher in development mode to view all delivered mails in a
|
||||||
browser interface. Just install mailcatcher with gem install mailcatcher
|
browser interface. Just install mailcatcher with `rbenv exec gem install mailcatcher`
|
||||||
and start the service with
|
and start the service with:
|
||||||
|
|
||||||
mailcatcher
|
mailcatcher
|
||||||
|
|
||||||
From now on you have a smtp server listening on 1025. To see the emails go to
|
From now on you have a smtp server listening on 1025. To see the emails go to:
|
||||||
|
|
||||||
http://localhost:1080
|
http://localhost:1080
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
The recommended way to run Foodsoft in production is using docker. Alternative options are
|
The recommended way to run Foodsoft in production is using docker. Alternative options are
|
||||||
discussed [in the wiki](https://github.com/foodcoops/foodsoft/wiki/Deployment-notes). If you
|
discussed [in the wiki](https://github.com/foodcoops/foodsoft/wiki/Deployment-notes). If you
|
||||||
have any questions, please contact the mailing list [foodsoft-discuss](http://foodsoft.51229.x6.nabble.com/foodsoft-discuss-f5.html).
|
have any questions, please contact the mailing list [foodsoft-discuss](http://foodsoft.274.s1.nabble.com/foodsoft-discuss-f5.html).
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,7 @@ class FoodsoftConfig
|
||||||
use_apple_points: true,
|
use_apple_points: true,
|
||||||
# English is the default language, and this makes it show up as default.
|
# English is the default language, and this makes it show up as default.
|
||||||
default_locale: 'en',
|
default_locale: 'en',
|
||||||
|
time_zone: 'Berlin',
|
||||||
currency_unit: '€',
|
currency_unit: '€',
|
||||||
currency_space: true,
|
currency_space: true,
|
||||||
foodsoft_url: 'https://github.com/foodcoops/foodsoft',
|
foodsoft_url: 'https://github.com/foodcoops/foodsoft',
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace :foodsoft do
|
||||||
setup_app_config
|
setup_app_config
|
||||||
setup_development
|
setup_development
|
||||||
setup_database
|
setup_database
|
||||||
|
setup_storage
|
||||||
start_mailcatcher
|
start_mailcatcher
|
||||||
puts yellow "All done! Your foodsoft setup should be running smoothly."
|
puts yellow "All done! Your foodsoft setup should be running smoothly."
|
||||||
start_server
|
start_server
|
||||||
|
@ -43,6 +44,7 @@ namespace :foodsoft do
|
||||||
puts yellow "This task will help you get your foodcoop running in development via docker."
|
puts yellow "This task will help you get your foodcoop running in development via docker."
|
||||||
setup_app_config
|
setup_app_config
|
||||||
setup_development
|
setup_development
|
||||||
|
setup_storage
|
||||||
setup_run_rake_db_setup
|
setup_run_rake_db_setup
|
||||||
puts yellow "All done! Your foodsoft setup should be running smoothly via docker."
|
puts yellow "All done! Your foodsoft setup should be running smoothly via docker."
|
||||||
end
|
end
|
||||||
|
@ -112,6 +114,15 @@ def setup_development
|
||||||
reminder(file)
|
reminder(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def setup_storage
|
||||||
|
file = 'config/storage.yml'
|
||||||
|
return nil if skip?(file)
|
||||||
|
|
||||||
|
puts yellow "Copying #{file}..."
|
||||||
|
%x(cp -p #{Rails.root.join("#{file}.SAMPLE")} #{Rails.root.join(file)})
|
||||||
|
reminder(file)
|
||||||
|
end
|
||||||
|
|
||||||
def start_mailcatcher
|
def start_mailcatcher
|
||||||
return nil if ENV['MAILCATCHER_PORT'] # skip when it has an existing Docker container
|
return nil if ENV['MAILCATCHER_PORT'] # skip when it has an existing Docker container
|
||||||
|
|
||||||
|
|
BIN
public/apple-touch-icon-114x114.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
public/apple-touch-icon-120x120.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
public/apple-touch-icon-144x144.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
public/apple-touch-icon-152x152.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
public/apple-touch-icon-180x180.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
public/apple-touch-icon-57x57.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
public/apple-touch-icon-72x72.png
Normal file
After Width: | Height: | Size: 9 KiB |
BIN
public/apple-touch-icon-76x76.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
public/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 5.9 KiB |