add vat exempt option in payment_tab ~ refs #automatic_go_invoices
add option vor vat_exempt inoices ~ refs automatic go invoices fix order.ordergroup nil pointer error ~ automatic go invoices fix nil pointer~ refs automatic go invoice rubocop styling ~ refs automatic go invoice
This commit is contained in:
parent
bafa163ce5
commit
81a5194023
8 changed files with 122 additions and 35 deletions
|
@ -84,7 +84,7 @@ class Finance::BalancingController < Finance::BaseController
|
|||
note = t('finance.balancing.close.notice')
|
||||
if @order.closed?
|
||||
alert = t('finance.balancing.close.alert')
|
||||
if FoodsoftConfig[:group_order_invoices]&.[](:use)
|
||||
if FoodsoftConfig[:group_order_invoices]&.[](:use_automatic_invoices)
|
||||
@order.group_orders.each do |go|
|
||||
alert = t('finance.balancing.close.settings_not_set')
|
||||
goi = GroupOrderInvoice.find_or_create_by!(group_order_id: go.id)
|
||||
|
|
|
@ -64,6 +64,64 @@ class GroupOrderInvoicePdf < RenderPDF
|
|||
move_down 5
|
||||
|
||||
#------------- Table Data -----------------------
|
||||
|
||||
@group_order = GroupOrder.find(@options[:group_order].id)
|
||||
if FoodsoftConfig[:group_order_invoices][:vat_exempt]
|
||||
body_for_vat_exempt
|
||||
else
|
||||
body_with_vat
|
||||
end
|
||||
end
|
||||
|
||||
def body_for_vat_exempt
|
||||
total_gross = 0
|
||||
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)
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
table data, position: :left, 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).column(1).width = 40
|
||||
table.row(0).border_bottom_width = 2
|
||||
table.columns(1).align = :right
|
||||
table.columns(1..6).align = :right
|
||||
end
|
||||
|
||||
move_down 5
|
||||
sum = []
|
||||
sum << [nil, nil, I18n.t('documents.group_order_invoice_pdf.sum_to_pay'), number_to_currency(total_gross)]
|
||||
# table for sum
|
||||
indent(200) do
|
||||
table sum, position: :center, cell_style: { size: fontsize(8), overflow: :shrink_to_fit } do |table|
|
||||
sum.length.times do |count|
|
||||
table.row(count).columns(0..3).borders = []
|
||||
end
|
||||
table.row(sum.length - 1).columns(0..2).borders = []
|
||||
table.row(sum.length - 1).border_bottom_width = 2
|
||||
table.row(sum.length - 1).columns(3).borders = [:bottom]
|
||||
end
|
||||
end
|
||||
|
||||
move_down 25
|
||||
text I18n.t('documents.group_order_invoice_pdf.small_business_regulation')
|
||||
move_down 10
|
||||
end
|
||||
|
||||
def body_with_vat
|
||||
total_gross = 0
|
||||
total_net = 0
|
||||
# Articles
|
||||
|
@ -71,7 +129,6 @@ 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
|
||||
|
||||
group_order = GroupOrder.find(@options[:group_order].id)
|
||||
marge = FoodsoftConfig[:price_markup]
|
||||
|
||||
# data table looks different when price_markup > 0
|
||||
|
@ -80,7 +137,7 @@ class GroupOrderInvoicePdf < RenderPDF
|
|||
else
|
||||
[I18n.t('documents.group_order_invoice_pdf.price_markup_rows', marge: marge)]
|
||||
end
|
||||
goa_tax_hash = GroupOrderArticle.where(group_order_id: group_order.id).find_each.group_by { |oat| oat.order_article.price.tax }
|
||||
goa_tax_hash = GroupOrderArticle.where(group_order_id: @group_order.id).find_each.group_by { |oat| oat.order_article.price.tax }
|
||||
goa_tax_hash.each do |tax, group_order_articles|
|
||||
group_order_articles.each do |goa|
|
||||
# if no unit is received, nothing is to be charged
|
||||
|
@ -136,6 +193,10 @@ class GroupOrderInvoicePdf < RenderPDF
|
|||
table.row(sum.length - 1).columns(5).borders = [:bottom]
|
||||
end
|
||||
|
||||
move_down 15
|
||||
if(FoodsoftConfig[:group_order_invoices][:vat_exempt])
|
||||
move_down 15
|
||||
text I18n.t('documents.group_order_invoice_pdf.small_business_regulation')
|
||||
end
|
||||
move_down 10
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
= config_input form, :charge_members_manually, as: :boolean
|
||||
= config_input form, :use_iban, as: :boolean
|
||||
= config_input form, :use_self_service, as: :boolean
|
||||
%h4= t '.group_order_invoices'
|
||||
= form.fields_for :group_order_invoices do |field|
|
||||
= config_input field, :use, as: :boolean
|
||||
= config_input field, :payment_method, as: :string, input_html: {class: 'input-mini'}
|
||||
= config_input field, :use_automatic_invoices, as: :boolean
|
||||
= config_input field, :vat_exempt, as: :boolean
|
||||
= config_input field, :payment_method, as: :string, input_html: {class: 'input-medium'}
|
||||
|
||||
%h4= t '.schedule_title'
|
||||
= form.simple_fields_for :order_schedule do |fields|
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
%td= show_user(order.updated_by)
|
||||
%td{id: "generate-invoice#{order.id}"}
|
||||
- if order.closed?
|
||||
-if FoodsoftConfig[:contact][:tax_number]
|
||||
-if FoodsoftConfig[:contact][:tax_number] && order.ordergroups.present?
|
||||
= render :partial => 'group_order_invoices/links', locals:{order: order}
|
||||
-else
|
||||
= I18n.t('activerecord.attributes.group_order_invoice.tax_number_not_set')
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
.row
|
||||
- order.group_orders.includes([:group_order_invoice, :ordergroup]).each do |go|
|
||||
.row
|
||||
- order.group_orders.includes([:group_order_invoice, :ordergroup]).each do |go|
|
||||
.row
|
||||
.column.small-3
|
||||
= label_tag go.ordergroup.name
|
||||
- if go.group_order_invoice
|
||||
- if go.group_order_invoice
|
||||
.column.small-3
|
||||
= link_to I18n.t('activerecord.attributes.group_order_invoice.links.download'), group_order_invoice_path(go.group_order_invoice, :format => 'pdf'), class: 'btn btn-small'
|
||||
.column.small-3
|
||||
= link_to I18n.t('activerecord.attributes.group_order_invoice.links.delete'), go.group_order_invoice, method: :delete, class: 'btn btn-danger btn-small', remote: true
|
||||
- else
|
||||
= button_to I18n.t('activerecord.attributes.group_order_invoice.links.generate'), group_order_invoices_path(:method => :post, group_order: go) ,class: 'btn btn-small', params: {id: order.id}, remote: true
|
||||
%br
|
||||
- else
|
||||
= button_to I18n.t('activerecord.attributes.group_order_invoice.links.generate'), group_order_invoices_path(:method => :post, group_order: go) ,class: 'btn btn-small', params: {id: order.id}, remote: true
|
||||
|
||||
|
|
|
@ -304,6 +304,7 @@ de:
|
|||
emails_title: E-Mails versenden
|
||||
tab_payment:
|
||||
schedule_title: Bestellschema
|
||||
group_order_invoices: Bestellgruppenrechnungen
|
||||
tab_security:
|
||||
default_roles_title: Zugriff auf
|
||||
default_roles_paragraph: Jedes Mitglied der Foodcoop hat automatisch Zugriff auf folgende Bereiche.
|
||||
|
@ -581,6 +582,10 @@ de:
|
|||
email_from: E-Mails werden so aussehen, als ob sie von dieser Adresse gesendet wurden. Kann leer gelassen werden, um die Kontaktadresse der Foodcoop zu benutzen.
|
||||
email_replyto: Setze diese Adresse, wenn Du Antworten auf Foodsoft E-Mails auf eine andere, als die oben angegebene Absenderadresse bekommen möchtest.
|
||||
email_sender: E-Mails werden so aussehen, als ob sie von dieser Adresse versendet wurden. Um zu vermeiden, dass E-Mails dadurch als Spam eingeordnet werden, muss der Webserver möglicherweise im SPF Eintrag der Domain der E-Mail Adresse eingetragen werden.
|
||||
group_order_invoices:
|
||||
use_automativ_go_invoices: Es werden auf die Bestellgruppen zugeschnittene Rechnungen für die jeweilige Bestellung beim Klicken auf "abrechnen" an alle Bestellgruppenmitglieder per Mail versendet.
|
||||
payment_method: Zahlungsart wird auf der Bestellgruppenrechnung deklariert
|
||||
vat_exempt: Eine Auflistung der Rechnungsartikel erfolgt ohne explizite Ausweisung der MwSt. und die Rechnung erhält den notwendigen Zusatz bzgl. der Kleinunternehmerregelung §19 (FoodCoop Marge ebenfalls nicht in Rechnung enthalten)
|
||||
help_url: Link zur Dokumentationsseite
|
||||
homepage: Webseite der Foodcoop
|
||||
ignore_browser_locale: Ignoriere die Sprache des Computers des Anwenders, wenn der Anwender noch keine Sprache gewählt hat.
|
||||
|
@ -608,8 +613,6 @@ de:
|
|||
tolerance_is_costly: Eine möglichst große Menge im Rahmen der Tolerenz bestellen. Wenn dies nicht aktiviert ist, wird im Rahmen der Toleranz nur so viel bestellt, dass damit komplette Einheiten (Boxen) bestellt werden können. Die Option wirkt sich auch auf die Toleranz des Gesamtpreises einer offenen Mitgliederbestellung aus.
|
||||
distribution_strategy: Wie bei der Verteilung von Artikeln nach dem Empfangen einer Bestellung vorgegangen werden soll.
|
||||
use_apple_points: Wenn das Apfel Punktesystem aktiviert ist, ist es erforderlich, dass Mitglieder Aufgaben erledigen um bestellen zu können.
|
||||
use_automatic_invoices: Bei der Abrechnung einer Bestellung werden Rechnungen für die einzelnen Bestellgruppenautomatisch per Mail versandt
|
||||
payment_method: Zahlungsart für Bestellgruppenrechnungen
|
||||
use_boxfill: Wenn aktiviert, können Benutzer nahe am Ende der Bestellung diese nur mehr so verändern, dass sich die Gesamtsumme erhöht. Dies hilft beim auffüllen der verbleibenden Kisten. Es muss trotzdem noch das Kistenauffülldatum bei der Bestellung gesetzt werden.
|
||||
use_iban: Zusätzlich Feld für die internationale Kontonummer bei Benutzern und Lieferanten anzeigen
|
||||
use_nick: Benutzernamen anstatt reale Namen zeigen und verwenden, jeder Benutzer muss dazu einen Benutzernamen (Spitznamen) haben.
|
||||
|
@ -640,6 +643,10 @@ de:
|
|||
email_from: Absenderadresse
|
||||
email_replyto: Antwortadresse
|
||||
email_sender: Senderadresse
|
||||
group_order_invoices:
|
||||
use_automatic_invoices: Automatisch bei Abrechnung per Mail versenden
|
||||
payment_method: Zahlungsart
|
||||
vat_exempt: Diese Foodcoop ist MwSt. befreit
|
||||
help_url: URL Dokumentation
|
||||
homepage: Webseite
|
||||
ignore_browser_locale: Browsersprache ignorieren
|
||||
|
@ -669,9 +676,6 @@ de:
|
|||
first_order_first_serve: Zuerst an die verteilen, die zuerst bestellt haben
|
||||
no_automatic_distribution: Keine automatische Verteilung
|
||||
use_apple_points: Apfelpunkte verwenden
|
||||
group_order_invoices:
|
||||
use: Bestellgruppen Rechnungen automatisch bei Abrechnung einer Bestellung versenden
|
||||
payment_method: Zahlungsart für Bestellgruppenrechnungen
|
||||
use_boxfill: Kistenauffüllphase
|
||||
use_iban: IBAN verwenden
|
||||
use_nick: Benutzernamen verwenden
|
||||
|
@ -740,13 +744,20 @@ de:
|
|||
contact_address: 'Adresse : %{contact_address}'
|
||||
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)
|
||||
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.
|
||||
tax_included: zzgl. Gesamtsumme MwSt. %{tax}%
|
||||
tax_number: 'Steuernummer: %{number}'
|
||||
title: Rechnung für die Bestellung bei %{supplier}
|
||||
vat_exempt_rows:
|
||||
- Name
|
||||
- Anzahl
|
||||
- Einzelpreis
|
||||
- Artikel Gesamtpreis
|
||||
no_price_markup_rows:
|
||||
- Name
|
||||
- Anzahl
|
||||
|
|
|
@ -304,6 +304,7 @@ en:
|
|||
emails_title: Sending email
|
||||
tab_payment:
|
||||
schedule_title: Ordering schedule
|
||||
group_order_invoices: Group order invoices
|
||||
tab_security:
|
||||
default_roles_title: Access to
|
||||
default_roles_paragraph: By default every member of the foodcoop has access to the following areas.
|
||||
|
@ -582,6 +583,9 @@ en:
|
|||
email_from: Emails will appear to be from this email address. Leave empty to use the foodcoop's contact address.
|
||||
email_replyto: Set this when you want to receive replies from emails sent by Foodsoft on a different address than the above.
|
||||
email_sender: Emails will appear to be sent from this email address. To avoid emails sent being classified as spam, the webserver may need to be registered in the SPF record of the email address's domain.
|
||||
use_automatic_invoices: A listing of the invoice items is made without explicit display of VAT and the invoice receives the necessary addition regarding the small business regulation §19 (applies to Germany)
|
||||
payment_method: Payment type is declared on the order group invoice
|
||||
vat_exempt: A listing of the invoice items is made without explicit display of VAT and the invoice contains the necessary addition regarding the German Kleinunternehmerregelung §19 UStG (attention! FoodCoop marge not included in nvoice).
|
||||
help_url: Documentation website.
|
||||
homepage: Website of your foodcoop.
|
||||
ignore_browser_locale: Ignore the language of user's computer when the user has not chosen a language yet.
|
||||
|
@ -671,8 +675,9 @@ en:
|
|||
no_automatic_distribution: No automatic distribution
|
||||
use_apple_points: Apple points
|
||||
group_order_invoices:
|
||||
use: Automatically send group order invoices when an order is settled
|
||||
payment_method: Payment method for group order invoices
|
||||
use_automatic_invoices: Send automatically via mail after oder settlement
|
||||
payment_method: Payment method
|
||||
vat_exempt: This foodcoopis VAT exempt
|
||||
use_boxfill: Box-fill phase
|
||||
use_iban: Use IBAN
|
||||
use_nick: Use nicknames
|
||||
|
@ -742,6 +747,8 @@ en:
|
|||
invoice_number: 'Invoice number: %{invoice_number}'
|
||||
markup_included: incl Foodcoop Marge on gross price %{marge}%
|
||||
payment_method: 'Payment_method: %{payment_method}'
|
||||
small_business_regulation: As a small entrepreneur in the sense of §19 para. 1 of the Umsatzsteuergesetz (UStG), no value added tax is charged.
|
||||
sum_to_pay: Total sum
|
||||
sum_to_pay_net: Total sum (net)
|
||||
sum_to_pay_gross: Total sum (gross)
|
||||
table_headline: 'The following items will be charged for the order:'
|
||||
|
@ -749,16 +756,21 @@ en:
|
|||
tax_included: incl. VAT %{tax}%
|
||||
tax_number: 'Tax number: %{number}'
|
||||
title: Invoice for order at %{supplier}
|
||||
vat_exempt_rows:
|
||||
- Name
|
||||
- Quantity
|
||||
- Unit price
|
||||
- Total price
|
||||
no_price_markup_rows:
|
||||
- Name
|
||||
- Amount
|
||||
- Quantity
|
||||
- Unit price (net)
|
||||
- Total price (net)
|
||||
- VAT
|
||||
- Total price (gross)
|
||||
price_markup_rows:
|
||||
- Name
|
||||
- Amount
|
||||
- Quantity
|
||||
- Unit price (net)
|
||||
- Total price (net)
|
||||
- VAT
|
||||
|
|
|
@ -4,7 +4,7 @@ feature GroupOrderInvoice, js: true do
|
|||
let(:admin) { create :user, groups: [create(:workgroup, role_finance: true)] }
|
||||
let(:article) { create :article, unit_quantity: 1 }
|
||||
let(:order) { create :order, supplier: article.supplier, article_ids: [article.id], ends: Time.now } # need to ref article
|
||||
let(:go) { create :group_order, order: order }
|
||||
let(:go) { create :group_order, order: order}
|
||||
let(:oa) { order.order_articles.find_by_article_id(article.id) }
|
||||
let(:ftt) { create :financial_transaction_type }
|
||||
let(:goa) { create :group_order_article, group_order: go, order_article: oa }
|
||||
|
@ -27,23 +27,14 @@ feature GroupOrderInvoice, js: true do
|
|||
goa.update_quantities 2, 0
|
||||
oa.update_results!
|
||||
order.reload
|
||||
FoodsoftConfig[:group_order_invoices] = { use: true }
|
||||
FoodsoftConfig[:group_order_invoices] = { use_automatic_invoices: true }
|
||||
FoodsoftConfig[:contact][:tax_number] = 12_345_678
|
||||
visit confirm_finance_order_path(id: order.id, type: ftt)
|
||||
expect(page).to have_selector(:link_or_button, I18n.t('finance.balancing.confirm.clear'))
|
||||
click_link_or_button I18n.t('finance.balancing.confirm.clear')
|
||||
expect(NotifyGroupOrderInvoiceJob).to have_been_enqueued
|
||||
end
|
||||
|
||||
it 'does not generate Group Order Invoice when order is closed if tax_number not set' do
|
||||
goa.update_quantities 2, 0
|
||||
oa.update_results!
|
||||
order.update!(state: 'closed')
|
||||
order.reload
|
||||
visit finance_order_index_path
|
||||
expect(page).to have_content(I18n.t('activerecord.attributes.group_order_invoice.tax_number_not_set'))
|
||||
end
|
||||
|
||||
|
||||
it 'generates Group Order Invoice when order is closed if tax_number is set' do
|
||||
goa.update_quantities 2, 0
|
||||
oa.update_results!
|
||||
|
@ -54,4 +45,13 @@ feature GroupOrderInvoice, js: true do
|
|||
click_link_or_button I18n.t('activerecord.attributes.group_order_invoice.links.generate')
|
||||
expect(GroupOrderInvoice.all.count).to eq(1)
|
||||
end
|
||||
|
||||
it 'does not generate Group Order Invoice when order is closed if tax_number not set' do
|
||||
goa.update_quantities 2, 0
|
||||
oa.update_results!
|
||||
order.update!(state: 'closed')
|
||||
order.reload
|
||||
visit finance_order_index_path
|
||||
expect(page).to have_content(I18n.t('activerecord.attributes.group_order_invoice.tax_number_not_set'))
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue