From 6f7c057a47132d98b17eeb8a08d8bc9a9cea6b56 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 11 Aug 2023 15:01:22 +0200 Subject: [PATCH] make explicit deposit in invoices work --- app/documents/group_order_invoice_pdf.rb | 138 ++++++++++++++---- app/models/concerns/price_calculation.rb | 16 ++ app/models/group_order_article.rb | 12 ++ app/models/order.rb | 14 +- .../admin/configs/_tab_payment.html.haml | 1 + app/views/admin/ordergroups/_form.html.haml | 1 + app/views/finance/balancing/_summary.haml | 10 ++ app/views/ordergroups/edit.html.haml | 4 + app/views/shared/_group.html.haml | 2 + config/locales/de.yml | 8 +- config/locales/en.yml | 3 + ...0822120005_add_customer_number_to_group.rb | 5 + db/schema.rb | 109 +++++++------- spec/integration/group_order_invoices_spec.rb | 3 +- 14 files changed, 242 insertions(+), 84 deletions(-) create mode 100644 db/migrate/20230822120005_add_customer_number_to_group.rb diff --git a/app/documents/group_order_invoice_pdf.rb b/app/documents/group_order_invoice_pdf.rb index 31ee4384..07fd7eb5 100644 --- a/app/documents/group_order_invoice_pdf.rb +++ b/app/documents/group_order_invoice_pdf.rb @@ -21,13 +21,11 @@ class GroupOrderInvoicePdf < RenderPdf move_down 5 text "#{contact[:zip_code]} #{contact[:city]}", size: fontsize(9), align: :left move_down 5 - unless contact[:phone].blank? + if contact[:phone].present? text "#{Supplier.human_attribute_name :phone}: #{contact[:phone]}", size: fontsize(9), align: :left move_down 5 end - unless contact[:email].blank? - text "#{Supplier.human_attribute_name :email}: #{contact[:email]}", size: fontsize(9), align: :left - end + text "#{Supplier.human_attribute_name :email}: #{contact[:email]}", size: fontsize(9), align: :left if contact[:email].present? move_down 5 text I18n.t('documents.group_order_invoice_pdf.tax_number', :number => @options[:tax_number]), size: fontsize(9), align: :left end @@ -38,14 +36,18 @@ class GroupOrderInvoicePdf < RenderPdf move_down 7 text I18n.t('documents.group_order_invoice_pdf.ordergroup.name', ordergroup: ordergroup.name.to_s), size: fontsize(9) move_down 5 - if ordergroup.contact_address + if ordergroup.contact_address.present? text I18n.t('documents.group_order_invoice_pdf.ordergroup.contact_address', contact_address: ordergroup.contact_address.to_s), size: fontsize(9) move_down 5 end - if ordergroup.contact_phone + if ordergroup.contact_phone.present? text I18n.t('documents.group_order_invoice_pdf.ordergroup.contact_phone', contact_phone: ordergroup.contact_phone.to_s), size: fontsize(9) move_down 5 end + if ordergroup.customer_number.present? + text I18n.t('documents.group_order_invoice_pdf.ordergroup.customer_number', customer_number: ordergroup.customer_number.to_s), size: fontsize(9) + move_down 5 + end end # invoice Date and nnvoice number @@ -66,6 +68,7 @@ class GroupOrderInvoicePdf < RenderPdf #------------- Table Data ----------------------- @group_order = GroupOrder.find(@options[:group_order].id) + if FoodsoftConfig[:group_order_invoices][:vat_exempt] body_for_vat_exempt else @@ -78,15 +81,25 @@ class GroupOrderInvoicePdf < RenderPdf data = [I18n.t('documents.group_order_invoice_pdf.vat_exempt_rows')] move_down 10 group_order_articles = GroupOrderArticle.where(group_order_id: @group_order.id) + separate_deposits = FoodsoftConfig[:group_order_invoices]&.[](:separate_deposits) group_order_articles.each do |goa| # if no unit is received, nothing is to be charged next if goa.result.to_i == 0 - goa_total_gross = goa.result * goa.order_article.price.gross_price + + goa_total_price = separate_deposits ? goa.total_price_without_deposit : goa.total_price data << [goa.order_article.article.name, goa.result.to_i, - number_to_currency(goa.order_article.price.gross_price), - number_to_currency(goa.total_price)] - total_gross += goa_total_gross + number_to_currency(goa.order_article.price.fc_price_without_deposit), + number_to_currency(goa_total_price)] + total_gross += goa_total_price + next unless separate_deposits && goa.order_article.price.deposit > 0.0 + + goa_total_deposit = goa.result * goa.order_article.price.fc_deposit_price + data << ["zzgl. Pfand", + goa.result.to_i, + number_to_currency(goa.order_article.article.fc_deposit_price), + number_to_currency(goa_total_deposit)] + total_gross += goa_total_deposit end table data, position: :left, cell_style: { size: fontsize(8), overflow: :shrink_to_fit } do |table| @@ -122,6 +135,7 @@ class GroupOrderInvoicePdf < RenderPdf end def body_with_vat + separate_deposits = FoodsoftConfig[:group_order_invoices]&.[](:separate_deposits) total_gross = 0 total_net = 0 # Articles @@ -129,6 +143,14 @@ class GroupOrderInvoicePdf < RenderPdf tax_hash_net = Hash.new(0) # for summing up article net prices grouped into vat percentage tax_hash_gross = Hash.new(0) # same here with gross prices + if separate_deposits + total_deposit = 0 + total_deposit_gross = 0 + + tax_hash_deposit_gross = Hash.new(0) # for summing up deposit gross prices grouped into vat percentage + tax_hash_deposit_net = Hash.new(0) # same here with gross prices + end + marge = FoodsoftConfig[:price_markup] # data table looks different when price_markup > 0 @@ -145,15 +167,37 @@ class GroupOrderInvoicePdf < RenderPdf order_article = goa.order_article goa_total_net = goa.result * order_article.price.price - goa_total_gross = goa.result * order_article.price.gross_price + + goa_total_gross = separate_deposits ? goa.total_price_without_deposit : goa.total_price + data << [order_article.article.name, goa.result.to_i, number_to_currency(order_article.price.price), number_to_currency(goa_total_net), tax.to_s + '%', - number_to_currency(goa.total_price)] + number_to_currency(goa_total_gross)] + + if separate_deposits && order_article.price.deposit > 0.0 + goa_deposit = goa.result * order_article.price.deposit + goa_total_deposit = goa.result * order_article.price.fc_deposit_price + + data << ["zzgl. Pfand", + goa.result.to_i, + number_to_currency(order_article.price.deposit), + number_to_currency(goa_deposit), + tax.to_s + '%', + number_to_currency(goa_total_deposit)] + + total_deposit += goa_deposit + total_deposit_gross += goa_total_deposit + + tax_hash_deposit_net[tax.to_i] += goa_deposit + tax_hash_deposit_gross[tax.to_i] += goa_total_deposit + end + tax_hash_net[tax.to_i] += goa_total_net tax_hash_gross[tax.to_i] += goa_total_gross + total_net += goa_total_net total_gross += goa_total_gross end @@ -166,34 +210,66 @@ class GroupOrderInvoicePdf < RenderPdf table.position = :center table.cells.border_width = 1 table.cells.border_color = '666666' - - table.row(0).column(1).width = 40 + table.row(0).columns(0..6).style(background_color: 'cccccc', font_style: :bold) + table.rows(0..-1).columns(0..6).width = 80 table.row(0).border_bottom_width = 2 table.columns(1).align = :right table.columns(1..6).align = :right end - sum = [] - sum << [nil, nil, nil, nil, I18n.t('documents.group_order_invoice_pdf.sum_to_pay_net'), number_to_currency(total_net)] - tax_hash_net.each_key.each do |tax| - sum << [nil, nil, nil, nil, I18n.t('documents.group_order_invoice_pdf.tax_included', tax: tax), number_to_currency(tax_hash_gross[tax] - tax_hash_net[tax])] + # 4 spalten Netto, MwSt, Brutto + # Produkte mit 7% MwSt + # Pfand mit 7% MwSt + # Produkte mit 19% MwSt + # Pfand mit 19% MwSt + # + # x,x,GESAMT; SUMME + + sum = [[nil, nil, nil, "Netto", "MwSt", "Brutto"]] + [7, 19].each do |key| + sum << [nil, nil, "Produkte mit #{key}%", number_to_currency(tax_hash_net[key]), number_to_currency(tax_hash_gross[key] - tax_hash_net[key]), number_to_currency(tax_hash_gross[key])] + sum << [nil, nil, "Pfand mit #{key}%", number_to_currency(tax_hash_deposit_net[key]), number_to_currency(tax_hash_deposit_gross[key] - tax_hash_deposit_net[key]), number_to_currency(tax_hash_deposit_gross[key])] if separate_deposits end - unless marge == 0 - sum << [nil, nil, nil, nil, I18n.t('documents.group_order_invoice_pdf.markup_included', marge: marge), number_to_currency(total_gross * marge / 100.0)] - end - end_sum = total_gross * (1 + marge / 100.0) - sum << [nil, nil, nil, nil, I18n.t('documents.group_order_invoice_pdf.sum_to_pay_gross'), number_to_currency(end_sum)] + total_deposit_gross ||= 0 + sum << [nil, nil, nil, nil, I18n.t('documents.group_order_invoice_pdf.sum_to_pay_gross'), number_to_currency(total_gross + total_deposit_gross)] + # tax_hash_net.each_key.each do |tax| + # sum << [nil, nil, nil, nil, I18n.t('documents.group_order_invoice_pdf.tax_included', tax: tax), number_to_currency(tax_hash_gross[tax] - tax_hash_net[tax])] + # end + # unless marge == 0 + # sum << [nil, nil, nil, nil, I18n.t('documents.group_order_invoice_pdf.markup_included', marge: marge), number_to_currency(total_gross * marge / 100.0)] + # end + # end_sum = total_gross * (1 + marge / 100.0) + # sum << [nil, nil, nil, nil, I18n.t('documents.group_order_invoice_pdf.sum_to_pay_gross'), number_to_currency(end_sum)] # table for sum - table sum, position: :right, cell_style: { size: fontsize(8), overflow: :shrink_to_fit } do |table| - sum.length.times do |count| - table.row(count).columns(0..5).borders = [] - end - table.row(sum.length - 1).columns(0..4).borders = [] - table.row(sum.length - 1).border_bottom_width = 2 - table.row(sum.length - 1).columns(5).borders = [:bottom] + # table sum, position: :right, cell_style: { size: fontsize(8), overflow: :shrink_to_fit } do |table| + # sum.length.times do |count| + # table.row(count).columns(0..5).borders = [] + # end + # table.row(sum.length - 1).columns(0..4).borders = [] + # table.row(sum.length - 1).border_bottom_width = 2 + # table.row(sum.length - 1).columns(5).borders = [:bottom] + # end + move_down 10 + table sum, cell_style: { size: fontsize(8), overflow: :shrink_to_fit } do |table| + table.header = true + table.position = :center + table.cells.border_width = 1 + table.cells.border_color = '666666' + table.row(0).columns(2..6).style(align: :bottom) + table.row(0).border_bottom_width = 2 + table.row(0..-1).columns(0..1).border_width = 0 + + table.rows(0..-1).columns(0..6).width = 80 + table.row(-1).column(-1).style(font_style: :bold) + table.row(-1).column(-2).style(font_style: :bold) + table.row(-1).column(-1).size = fontsize(10) + table.row(-1).column(-2).size = fontsize(10) + + table.columns(1).align = :right + table.columns(1..6).align = :right end - if(FoodsoftConfig[:group_order_invoices][:vat_exempt]) + if FoodsoftConfig[:group_order_invoices][:vat_exempt] move_down 15 text I18n.t('documents.group_order_invoice_pdf.small_business_regulation') end diff --git a/app/models/concerns/price_calculation.rb b/app/models/concerns/price_calculation.rb index 8d56d671..47c28bc6 100644 --- a/app/models/concerns/price_calculation.rb +++ b/app/models/concerns/price_calculation.rb @@ -7,11 +7,27 @@ module PriceCalculation add_percent(price + deposit, tax) end + def gross_price_without_deposit + add_percent(price, tax) + end + + def gross_deposit_price + add_percent(deposit, tax) + end + # @return [Number] Price for the foodcoop-member. def fc_price add_percent(gross_price, FoodsoftConfig[:price_markup].to_i) end + def fc_price_without_deposit + add_percent(gross_price_without_deposit, FoodsoftConfig[:price_markup].to_i) + end + + def fc_deposit_price + add_percent(gross_deposit_price, FoodsoftConfig[:price_markup].to_i) + end + private def add_percent(value, percent) diff --git a/app/models/group_order_article.rb b/app/models/group_order_article.rb index 7b95d462..f5f42789 100644 --- a/app/models/group_order_article.rb +++ b/app/models/group_order_article.rb @@ -208,6 +208,18 @@ class GroupOrderArticle < ApplicationRecord end end + def total_price_without_deposit(order_article = self.order_article) + if order_article.order.open? + if FoodsoftConfig[:tolerance_is_costly] + order_article.price.fc_price_without_deposit * (quantity + tolerance) + else + order_article.price.fc_price_without_deposit * quantity + end + else + order_article.price.fc_price_without_deposit * result + end + end + # Check if the result deviates from the result_computed def result_manually_changed? result != result_computed unless result.nil? diff --git a/app/models/order.rb b/app/models/order.rb index ada62e59..e275519b 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -207,7 +207,7 @@ class Order < ApplicationRecord # :fc, guess what... def sum(type = :gross) total = 0 - if %i[net gross fc].include?(type) + if %i[net gross gross_deposit fc_deposit deposit fc].include?(type) for oa in order_articles.ordered.includes(:article, :article_price) quantity = oa.units * oa.price.unit_quantity case type @@ -217,6 +217,12 @@ class Order < ApplicationRecord total += quantity * oa.price.gross_price when :fc total += quantity * oa.price.fc_price + when :gross_deposit + total += quantity * oa.price.gross_deposit_price + when :fc_deposit + total += quantity * oa.price.fc_deposit_price + when :deposit + total += quantity * oa.price.deposit end end elsif %i[groups groups_without_markup].include?(type) @@ -224,7 +230,11 @@ class Order < ApplicationRecord for goa in go.group_order_articles case type when :groups - total += goa.result * goa.order_article.price.fc_price + total += if FoodsoftConfig[:group_order_invoices]&.[](:separate_deposits) + goa.result * (goa.order_article.price.fc_price + goa.order_article.price.fc_deposit_price) + else + goa.result * goa.order_article.price.fc_price + end when :groups_without_markup total += goa.result * goa.order_article.price.gross_price end diff --git a/app/views/admin/configs/_tab_payment.html.haml b/app/views/admin/configs/_tab_payment.html.haml index 70502c90..70291110 100644 --- a/app/views/admin/configs/_tab_payment.html.haml +++ b/app/views/admin/configs/_tab_payment.html.haml @@ -16,6 +16,7 @@ %h4= t '.group_order_invoices' = form.fields_for :group_order_invoices do |field| = config_input field, :use_automatic_invoices, as: :boolean + = config_input field, :separate_deposits, as: :boolean = config_input field, :vat_exempt, as: :boolean = config_input field, :payment_method, as: :string, input_html: {class: 'input-medium'} diff --git a/app/views/admin/ordergroups/_form.html.haml b/app/views/admin/ordergroups/_form.html.haml index 3eb3a9f5..128338bb 100644 --- a/app/views/admin/ordergroups/_form.html.haml +++ b/app/views/admin/ordergroups/_form.html.haml @@ -2,6 +2,7 @@ %p= t('.first_paragraph', url: link_to(t('.here'), new_invite_path(id: @ordergroup.id), remote: true)).html_safe = simple_form_for [:admin, @ordergroup] do |f| - captured = capture do + = f.input :customer_number = f.input :contact_person = f.input :contact_phone = f.input :contact_address diff --git a/app/views/finance/balancing/_summary.haml b/app/views/finance/balancing/_summary.haml index e466727f..6516aa69 100644 --- a/app/views/finance/balancing/_summary.haml +++ b/app/views/finance/balancing/_summary.haml @@ -12,6 +12,16 @@ %tr %td= t('.fc_amount') %td.numeric= number_to_currency(order.sum(:fc)) + - if FoodsoftConfig[:group_order_invoices]&.[](:separate_deposits) + %tr + %td= t('.deposit') + %td.numeric= number_to_currency(order.sum(:deposit)) + %tr + %td= t('.gross_deposit') + %td.numeric= number_to_currency(order.sum(:gross_deposit)) + %tr + %td= t('.fc_deposit') + %td.numeric= number_to_currency(order.sum(:fc_deposit)) %tr %td= t('.groups_amount') %td.numeric= number_to_currency(order.sum(:groups)) diff --git a/app/views/ordergroups/edit.html.haml b/app/views/ordergroups/edit.html.haml index 1cba43e6..9e964c89 100644 --- a/app/views/ordergroups/edit.html.haml +++ b/app/views/ordergroups/edit.html.haml @@ -57,6 +57,10 @@ = f.label :contact_person %br/ = f.text_field :contact_person + %p + = f.label :customer_number + %br/ + = f.text_field :customer_number %p = f.label :contact_phone %br/ diff --git a/app/views/shared/_group.html.haml b/app/views/shared/_group.html.haml index 3386aaab..c4d00679 100644 --- a/app/views/shared/_group.html.haml +++ b/app/views/shared/_group.html.haml @@ -6,6 +6,8 @@ %dd=h group.contact %dt= heading_helper(Ordergroup, :contact_address) + ':' %dd= link_to_gmaps group.contact_address + %dt= heading_helper(Ordergroup, :customer_number) + ':' + %dd=h group.customer_number - if group.break_start? or group.break_end? %dt= heading_helper(Ordergroup, :break) + ':' %dd= raw t '.break', start: format_date(group.break_start), end: format_date(group.break_end) diff --git a/config/locales/de.yml b/config/locales/de.yml index 502d8412..1ee73275 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -169,6 +169,7 @@ de: contact_address: Adresse contact_person: Kontaktperson contact_phone: Telefon + customer_number: Kundennummer description: Beschreibung ignore_apple_restriction: Bestellstop bei zu wenig Äpfeln ignorieren last_order: Zuletzt bestellt @@ -678,6 +679,7 @@ de: email_sender: Senderadresse group_order_invoices: use_automatic_invoices: Automatisch bei Abrechnung per Mail versenden + separate_deposits: Pfand getrennt abrechnen payment_method: Zahlungsart vat_exempt: Diese Foodcoop ist MwSt. befreit help_url: URL Dokumentation @@ -775,11 +777,12 @@ de: ordergroup: contact_phone: 'Telefonnummer: %{contact_phone}' contact_address: 'Adresse : %{contact_address}' + customer_number: 'Kundennummer: %{customer_number}' name: Bestellgruppe %{ordergroup} payment_method: 'Zahlungsart: %{payment_method}' sum_to_pay: Zu zahlen gesamt sum_to_pay_net: Zu zahlen gesamt (netto) - sum_to_pay_gross: Zu zahlen gesamt (brutto) + sum_to_pay_gross: Gesamt small_business_regulation: Als Kleinunternehmer*in im Sinne von §19 Abs. 1 Umsatzsteuergesetz (UStG) wird keine Umsatzsteuer berechnet. table_headline: 'Für die Bestellung fallen folgende Posten an:' tax_excluded: exkl. MwSt. @@ -924,6 +927,9 @@ de: changed: Daten wurden verändert! duration: von %{starts} bis %{ends} fc_amount: 'FC-Betrag:' + deposit: 'Pfand netto:' + gross_deposit: 'Pfand brutto:' + fc_deposit: 'Pfand FC-Betrag:' fc_profit: FC Gewinn gross_amount: 'Bruttobetrag:' groups_amount: 'Gruppenbeträge:' diff --git a/config/locales/en.yml b/config/locales/en.yml index 12ac7743..08d34061 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -168,6 +168,7 @@ en: contact_address: Address contact_person: Contact person contact_phone: Phone + customer_number: Customer number description: Description ignore_apple_restriction: Ignore order stop by apple points restriction last_order: Last order @@ -709,6 +710,7 @@ en: group_order_invoices: use_automatic_invoices: Send automatically via mail after oder settlement payment_method: Payment method + separate_deposits: Separate deposits on invoice vat_exempt: This foodcoopis VAT exempt use_boxfill: Box-fill phase use_iban: Use IBAN @@ -771,6 +773,7 @@ en: ordergroup: contact_phone: 'Phone: %{contact_phone}' contact_address: 'Adress : %{contact_address}' + customer_number: 'Customer number: %{customer_number}' name: 'Ordergroup: %{ordergroup}' filename: Invoice%{number} invoicee: Invoicee diff --git a/db/migrate/20230822120005_add_customer_number_to_group.rb b/db/migrate/20230822120005_add_customer_number_to_group.rb new file mode 100644 index 00000000..9b4c2278 --- /dev/null +++ b/db/migrate/20230822120005_add_customer_number_to_group.rb @@ -0,0 +1,5 @@ +class AddCustomerNumberToGroup < ActiveRecord::Migration[7.0] + def change + add_column :groups, :customer_number, :string, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 4c853039..e024426f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,8 +10,8 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do - create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| +ActiveRecord::Schema[7.0].define(version: 2023_08_22_120005) do + create_table "action_text_rich_texts", charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.text "body", size: :long t.string "record_type", null: false @@ -21,7 +21,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true end - create_table "active_storage_attachments", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "active_storage_attachments", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false t.bigint "record_id", null: false @@ -31,7 +31,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do 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, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "active_storage_blobs", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "key", null: false t.string "filename", null: false t.string "content_type" @@ -43,19 +43,19 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end - create_table "active_storage_variant_records", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "active_storage_variant_records", charset: "utf8mb4", force: :cascade do |t| t.integer "blob_id", null: false t.string "variation_digest", null: false t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true end - create_table "article_categories", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "article_categories", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", default: "", null: false t.string "description" t.index ["name"], name: "index_article_categories_on_name", unique: true end - create_table "article_prices", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "article_prices", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "article_id", 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 @@ -65,7 +65,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["article_id"], name: "index_article_prices_on_article_id" end - create_table "articles", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "articles", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", default: "", null: false t.integer "supplier_id", default: 0, null: false t.integer "article_category_id", default: 0, null: false @@ -91,14 +91,14 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["type"], name: "index_articles_on_type" end - create_table "assignments", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "assignments", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "user_id", default: 0, null: false t.integer "task_id", default: 0, null: false t.boolean "accepted", default: false t.index ["user_id", "task_id"], name: "index_assignments_on_user_id_and_task_id", unique: true end - create_table "bank_accounts", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "bank_accounts", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.string "iban" t.string "description" @@ -108,14 +108,14 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.integer "bank_gateway_id" end - create_table "bank_gateways", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "bank_gateways", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.string "url", null: false t.string "authorization" t.integer "unattended_user_id" end - create_table "bank_transactions", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "bank_transactions", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "bank_account_id", null: false t.string "external_id" t.date "date" @@ -129,7 +129,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["financial_link_id"], name: "index_bank_transactions_on_financial_link_id" end - create_table "documents", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "documents", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name" t.string "mime" t.binary "data", size: :long @@ -140,16 +140,16 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["parent_id"], name: "index_documents_on_parent_id" end - create_table "financial_links", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "financial_links", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.text "note" end - create_table "financial_transaction_classes", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "financial_transaction_classes", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.boolean "ignore_for_account_balance", default: false, null: false end - create_table "financial_transaction_types", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "financial_transaction_types", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.integer "financial_transaction_class_id", null: false t.string "name_short" @@ -157,7 +157,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["name_short"], name: "index_financial_transaction_types_on_name_short" end - create_table "financial_transactions", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "financial_transactions", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "ordergroup_id" t.decimal "amount", precision: 8, scale: 2, default: "0.0", null: false t.text "note", null: false @@ -171,7 +171,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["reverts_id"], name: "index_financial_transactions_on_reverts_id", unique: true end - create_table "group_order_article_quantities", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "group_order_article_quantities", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "group_order_article_id", default: 0, null: false t.integer "quantity", default: 0 t.integer "tolerance", default: 0 @@ -179,7 +179,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["group_order_article_id"], name: "index_group_order_article_quantities_on_group_order_article_id" end - create_table "group_order_articles", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "group_order_articles", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "group_order_id", default: 0, null: false t.integer "order_article_id", default: 0, null: false t.integer "quantity", default: 0, null: false @@ -192,7 +192,17 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["order_article_id"], name: "index_group_order_articles_on_order_article_id" end - create_table "group_orders", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "group_order_invoices", charset: "utf8mb4", 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", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["group_order_id"], name: "index_group_order_invoices_on_group_order_id", unique: true + end + + create_table "group_orders", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "ordergroup_id" t.integer "order_id", default: 0, null: false t.decimal "price", precision: 8, scale: 2, default: "0.0", null: false @@ -205,7 +215,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["ordergroup_id"], name: "index_group_orders_on_ordergroup_id" end - create_table "groups", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "groups", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "type", default: "", null: false t.string "name", default: "", null: false t.string "description" @@ -227,10 +237,11 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.date "break_end" t.boolean "role_invoices", default: false, null: false t.boolean "role_pickups", default: false, null: false + t.string "customer_number" t.index ["name"], name: "index_groups_on_name", unique: true end - create_table "invites", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "invites", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "token", default: "", null: false t.datetime "expires_at", precision: nil, null: false t.integer "group_id", default: 0, null: false @@ -239,7 +250,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["token"], name: "index_invites_on_token" end - create_table "invoices", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "invoices", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "supplier_id" t.string "number" t.date "date" @@ -257,7 +268,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["supplier_id"], name: "index_invoices_on_supplier_id" end - create_table "links", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "links", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.string "url", null: false t.integer "workgroup_id" @@ -265,7 +276,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.string "authorization" end - create_table "mail_delivery_status", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "mail_delivery_status", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.datetime "created_at", precision: nil t.string "email", null: false t.string "message", null: false @@ -274,13 +285,13 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["email"], name: "index_mail_delivery_status_on_email" end - create_table "memberships", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "memberships", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "group_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 end - create_table "message_recipients", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "message_recipients", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "message_id", null: false t.integer "user_id", null: false t.integer "email_state", default: 0, null: false @@ -289,7 +300,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["user_id", "read_at"], name: "index_message_recipients_on_user_id_and_read_at" end - create_table "messages", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "messages", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "sender_id" t.string "subject", null: false t.boolean "private", default: false @@ -300,7 +311,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.binary "received_email", size: :medium end - create_table "oauth_access_grants", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "oauth_access_grants", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "resource_owner_id", null: false t.integer "application_id", null: false t.string "token", null: false @@ -312,7 +323,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true end - create_table "oauth_access_tokens", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "oauth_access_tokens", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "resource_owner_id" t.integer "application_id" t.string "token", null: false @@ -326,7 +337,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true end - create_table "oauth_applications", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "oauth_applications", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.string "uid", null: false t.string "secret", null: false @@ -338,7 +349,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true end - create_table "order_articles", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "order_articles", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "order_id", default: 0, null: false t.integer "article_id", default: 0, null: false t.integer "quantity", default: 0, null: false @@ -352,7 +363,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["order_id"], name: "index_order_articles_on_order_id" end - create_table "order_comments", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "order_comments", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "order_id" t.integer "user_id" t.text "text" @@ -360,7 +371,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["order_id"], name: "index_order_comments_on_order_id" end - create_table "orders", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "orders", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "supplier_id" t.text "note" t.datetime "starts", precision: nil @@ -379,7 +390,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["state"], name: "index_orders_on_state" end - create_table "page_versions", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "page_versions", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "page_id" t.integer "lock_version" t.text "body" @@ -390,7 +401,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["page_id"], name: "index_page_versions_on_page_id" end - create_table "pages", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "pages", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "title" t.text "body" t.string "permalink" @@ -404,20 +415,20 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["title"], name: "index_pages_on_title" end - create_table "periodic_task_groups", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "periodic_task_groups", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.date "next_task_date" t.datetime "created_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false end - create_table "poll_choices", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "poll_choices", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "poll_vote_id", null: false t.integer "choice", 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 end - create_table "poll_votes", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "poll_votes", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "poll_id", null: false t.integer "user_id", null: false t.integer "ordergroup_id" @@ -427,7 +438,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["poll_id", "user_id", "ordergroup_id"], name: "index_poll_votes_on_poll_id_and_user_id_and_ordergroup_id", unique: true end - create_table "polls", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "polls", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "created_by_user_id", null: false t.string "name", null: false t.text "description" @@ -447,7 +458,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["final_choice"], name: "index_polls_on_final_choice" end - create_table "printer_job_updates", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "printer_job_updates", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "printer_job_id", null: false t.datetime "created_at", precision: nil, null: false t.string "state", null: false @@ -455,7 +466,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["printer_job_id", "created_at"], name: "index_printer_job_updates_on_printer_job_id_and_created_at" end - create_table "printer_jobs", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "printer_jobs", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "order_id" t.string "document", null: false t.integer "created_by_user_id", null: false @@ -464,7 +475,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["finished_at"], name: "index_printer_jobs_on_finished_at" end - create_table "settings", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "settings", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "var", null: false t.text "value" t.integer "thing_id" @@ -474,7 +485,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["thing_type", "thing_id", "var"], name: "index_settings_on_thing_type_and_thing_id_and_var", unique: true end - create_table "stock_changes", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "stock_changes", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "stock_event_id" t.integer "order_id" t.integer "stock_article_id" @@ -484,7 +495,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["stock_event_id"], name: "index_stock_changes_on_stock_event_id" end - create_table "stock_events", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "stock_events", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.integer "supplier_id" t.date "date" t.datetime "created_at", precision: nil @@ -494,14 +505,14 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["supplier_id"], name: "index_stock_events_on_supplier_id" end - create_table "supplier_categories", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "supplier_categories", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", null: false t.string "description" t.integer "financial_transaction_class_id" t.integer "bank_account_id" end - create_table "suppliers", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "suppliers", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", default: "", null: false t.string "address", default: "", null: false t.string "phone", default: "", null: false @@ -523,7 +534,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["name"], name: "index_suppliers_on_name", unique: true end - create_table "tasks", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "tasks", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "name", default: "", null: false t.text "description" t.date "due_date" @@ -540,7 +551,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do t.index ["workgroup_id"], name: "index_tasks_on_workgroup_id" end - create_table "users", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + create_table "users", id: :integer, charset: "utf8mb4", force: :cascade do |t| t.string "nick" t.string "password_hash", default: "", null: false t.string "password_salt", default: "", null: false diff --git a/spec/integration/group_order_invoices_spec.rb b/spec/integration/group_order_invoices_spec.rb index a84d9bc7..f6ece77d 100644 --- a/spec/integration/group_order_invoices_spec.rb +++ b/spec/integration/group_order_invoices_spec.rb @@ -41,13 +41,14 @@ feature GroupOrderInvoice, js: true do oa.update_results! FoodsoftConfig[:contact][:tax_number] = 12_345_678 order.update!(state: 'closed') + go.reload order.reload visit finance_order_index_path expect(page).to have_selector(:link_or_button, I18n.t('activerecord.attributes.group_order_invoice.links.generate')) click_link_or_button I18n.t('activerecord.attributes.group_order_invoice.links.generate') expect(GroupOrderInvoice.all.count).to eq(1) end - + it 'generates multiple Group Order Invoice for order when order is closed if tax_number is set' do goa.update_quantities 2, 0 oa.update_results!