use SL::DBUtils;
use SL::IO;
use SL::MoreCommon;
+use SL::DB::ApGl;
use SL::DB::Default;
use SL::DB::Draft;
use SL::DB::Order;
SL::DB::Manager::Draft->delete_all(where => [ id => delete($form->{draft_id}) ]);
}
+ # hook for taxkey 94
+ $self->_reverse_charge($myconfig, $form);
# safety check datev export
if ($::instance_conf->get_datev_check_on_ap_transaction) {
my $datev = SL::DATEV->new(
return 1;
}
+sub _reverse_charge {
+ my ($self, $myconfig, $form) = @_;
+
+ # check taxkey settings or return
+ my $tax = SL::DB::Manager::Tax->get_first( where => [taxkey => 94 ]);
+ return unless ref $tax eq 'SL::DB::Tax';
+
+ # delete previous bookings, if they exists (repost)
+ my $ap_gl = SL::DB::Manager::ApGl->get_first(where => [ ap_id => $form->{id} ]);
+ my $gl_id = ref $ap_gl eq 'SL::DB::ApGl' ? $ap_gl->gl_id : undef;
+
+ SL::DB::Manager::GLTransaction->delete_all(where => [ id => $gl_id ]) if $gl_id;
+ SL::DB::Manager::ApGl-> delete_all(where => [ ap_id => $form->{id} ]) if $gl_id;
+ SL::DB::Manager::RecordLink-> delete_all(where => [ from_table => 'ap', to_table => 'gl', from_id => $form->{id} ]);
+
+ # gl booking
+ my ($credit, $debit);
+ $credit = SL::DB::Manager::Chart->find_by(id => $tax->chart_id);
+ $debit = SL::DB::Manager::Chart->find_by(id => $tax->reverse_charge_chart_id);
+
+ croak("No such Chart ID" . $tax->chart_id) unless ref $credit eq 'SL::DB::Chart';
+ croak("No such Chart ID" . $tax->reverse_chart_id) unless ref $debit eq 'SL::DB::Chart';
+
+ my ($i, $current_transaction);
+
+ for $i (1 .. $form->{rowcount}) {
+ next unless $form->{"taxkey_$i"} == 94;
+
+ my ($tmpnetamount, $tmptaxamount) = $form->calculate_tax($form->{"amount_$i"}, 0.19, $form->{taxincluded}, 2);
+ $current_transaction = SL::DB::GLTransaction->new(
+ employee_id => $form->{employee_id},
+ transdate => $form->{transdate},
+ description => $form->{notes} || $form->{invnumber},
+ reference => $form->{invnumber},
+ department_id => $form->{department_id} ? $form->{department_id} : undef,
+ imported => 0, # not imported
+ taxincluded => 0,
+ )->add_chart_booking(
+ chart => $tmptaxamount < 0 ? $credit : $debit,
+ credit => abs($tmptaxamount),
+ source => "Reverse Charge for " . $form->{invnumber},
+ )->add_chart_booking(
+ chart => $tmptaxamount < 0 ? $debit : $credit,
+ debit => abs($tmptaxamount),
+ source => "Reverse Charge for " . $form->{invnumber},
+ )->post;
+ # add a stable link from ap to gl
+ my %props_gl = (
+ ap_id => $form->{id},
+ gl_id => $current_transaction->id,
+ );
+ SL::DB::ApGl->new(%props_gl)->save;
+ # Record a record link from ap to gl
+ my %props_rl = (
+ from_table => 'ap',
+ from_id => $form->{id},
+ to_table => 'gl',
+ to_id => $current_transaction->id,
+ );
+ SL::DB::RecordLink->new(%props_rl)->save;
+ }
+}
+
sub delete_transaction {
$main::lxdebug->enter_sub();
my ($self, $myconfig, $form) = @_;
SL::DB->client->with_transaction(sub {
+
+ # if tax 94 reverse charge, clear all GL bookings and links
+ my $ap_gl = SL::DB::Manager::ApGl->get_first(where => [ ap_id => $form->{id} ]);
+ my $gl_id = ref $ap_gl eq 'SL::DB::ApGl' ? $ap_gl->gl_id : undef;
+
+ SL::DB::Manager::GLTransaction->delete_all(where => [ id => $gl_id ]) if $gl_id;
+ SL::DB::Manager::ApGl-> delete_all(where => [ ap_id => $form->{id} ]) if $gl_id;
+ SL::DB::Manager::RecordLink-> delete_all(where => [ from_table => 'ap', to_table => 'gl', from_id => $form->{id} ]);
+ # done gl delete for tax 94 case
+
+ # begin ap delete
my $query = qq|DELETE FROM ap WHERE id = ?|;
do_query($form, SL::DB->client->dbh, $query, $form->{id});
1;
my ($self, $myconfig, $form) = @_;
+ return unless ($::instance_conf->get_email_journal);
+
my ($table, $query, $dbh);
if ($form->{script} eq 'oe.pl') {
the middle by a single space and remove tailing line feed/carriage
return characters).
+=item C<save_email_status>
+
+Adds sending information to internal notes.
+Does nothing if the client config email_journal is enabled.
+
=back
=head1 BUGS
$::form->{id} = $self->order->id; # this is used in SL::Mailer to create a linked record to the mail
$::form->send_email(\%::myconfig, 'pdf');
- # internal notes
- my $intnotes = $self->order->intnotes;
- $intnotes .= "\n\n" if $self->order->intnotes;
- $intnotes .= t8('[email]') . "\n";
- $intnotes .= t8('Date') . ": " . $::locale->format_date_object(DateTime->now_local, precision => 'seconds') . "\n";
- $intnotes .= t8('To (email)') . ": " . $::form->{email} . "\n";
- $intnotes .= t8('Cc') . ": " . $::form->{cc} . "\n" if $::form->{cc};
- $intnotes .= t8('Bcc') . ": " . $::form->{bcc} . "\n" if $::form->{bcc};
- $intnotes .= t8('Subject') . ": " . $::form->{subject} . "\n\n";
- $intnotes .= t8('Message') . ": " . $::form->{message};
-
- $self->order->update_attributes(intnotes => $intnotes);
+ # internal notes unless no email journal
+ unless ($::instance_conf->get_email_journal) {
+
+ my $intnotes = $self->order->intnotes;
+ $intnotes .= "\n\n" if $self->order->intnotes;
+ $intnotes .= t8('[email]') . "\n";
+ $intnotes .= t8('Date') . ": " . $::locale->format_date_object(DateTime->now_local, precision => 'seconds') . "\n";
+ $intnotes .= t8('To (email)') . ": " . $::form->{email} . "\n";
+ $intnotes .= t8('Cc') . ": " . $::form->{cc} . "\n" if $::form->{cc};
+ $intnotes .= t8('Bcc') . ": " . $::form->{bcc} . "\n" if $::form->{bcc};
+ $intnotes .= t8('Subject') . ": " . $::form->{subject} . "\n\n";
+ $intnotes .= t8('Message') . ": " . $::form->{message};
+
+ $self->order->update_attributes(intnotes => $intnotes);
+ }
$self->save_history('MAILED');
$::form->{id} = $self->order->id; # this is used in SL::Mailer to create a linked record to the mail
$::form->send_email(\%::myconfig, $::form->{print_options}->{format});
- # internal notes
- my $intnotes = $self->order->intnotes;
- $intnotes .= "\n\n" if $self->order->intnotes;
- $intnotes .= t8('[email]') . "\n";
- $intnotes .= t8('Date') . ": " . $::locale->format_date_object(DateTime->now_local, precision => 'seconds') . "\n";
- $intnotes .= t8('To (email)') . ": " . $::form->{email} . "\n";
- $intnotes .= t8('Cc') . ": " . $::form->{cc} . "\n" if $::form->{cc};
- $intnotes .= t8('Bcc') . ": " . $::form->{bcc} . "\n" if $::form->{bcc};
- $intnotes .= t8('Subject') . ": " . $::form->{subject} . "\n\n";
- $intnotes .= t8('Message') . ": " . SL::HTML::Util->strip($::form->{message});
-
- $self->order->update_attributes(intnotes => $intnotes);
+ # internal notes unless no email journal
+ unless ($::instance_conf->get_email_journal) {
+ my $intnotes = $self->order->intnotes;
+ $intnotes .= "\n\n" if $self->order->intnotes;
+ $intnotes .= t8('[email]') . "\n";
+ $intnotes .= t8('Date') . ": " . $::locale->format_date_object(DateTime->now_local, precision => 'seconds') . "\n";
+ $intnotes .= t8('To (email)') . ": " . $::form->{email} . "\n";
+ $intnotes .= t8('Cc') . ": " . $::form->{cc} . "\n" if $::form->{cc};
+ $intnotes .= t8('Bcc') . ": " . $::form->{bcc} . "\n" if $::form->{bcc};
+ $intnotes .= t8('Subject') . ": " . $::form->{subject} . "\n\n";
+ $intnotes .= t8('Message') . ": " . SL::HTML::Util->strip($::form->{message});
+
+ $self->order->update_attributes(intnotes => $intnotes);
+ }
$self->save_history('MAILED');
# optional KOST1 - KOST2 ?
$department_name = $row->[36];
if ($department_name) {
- $department = SL::DB::Manager::Department->get_first(description => { like => $department_name . '%' });
+ $department = SL::DB::Manager::Department->get_first(where => [ description => { ilike => $department_name . '%' } ]);
}
my $amount = $::form->parse_amount({ numberformat => '1000,00' }, $row->[0]);
$gl_itime_filter
$gl_department_id_filter
$gl_imported
+ AND NOT EXISTS (SELECT gl_id from ap_gl where gl_id = gl.id)
$filter
ORDER BY trans_id, acc_trans_id|;
}
if ($transaction->[$i]->{'taxkey'}) {
$taxkey = $transaction->[$i]->{'taxkey'};
+ # $taxkey = 0 if $taxkey == 94; # taxbookings are in gl
}
if ($transaction->[$i]->{'charttax'}) {
$charttax = $transaction->[$i]->{'charttax'};
--- /dev/null
+# This file has been auto-generated only because it didn't exist.
+# Feel free to modify it at will; it will not be overwritten automatically.
+
+package SL::DB::ApGl;
+
+use strict;
+
+use SL::DB::MetaSetup::ApGl;
+use SL::DB::Manager::ApGl;
+
+__PACKAGE__->meta->initialize;
+
+1;
use SL::DB::AccTransaction;
use SL::DB::AdditionalBillingAddress;
+use SL::DB::ApGl;
use SL::DB::Assembly;
use SL::DB::AssortmentItem;
use SL::DB::AuthClient;
'auth.user_group' => 'auth_user_group',
ar => 'invoice',
ap => 'purchase_invoice',
+ ap_gl => 'ap_gl',
assembly => 'assembly',
assortment_items => 'assortment_item',
background_jobs => 'background_job',
--- /dev/null
+# This file has been auto-generated only because it didn't exist.
+# Feel free to modify it at will; it will not be overwritten automatically.
+
+package SL::DB::Manager::ApGl;
+
+use strict;
+
+use parent qw(SL::DB::Helper::Manager);
+
+sub object_class { 'SL::DB::ApGl' }
+
+__PACKAGE__->make_manager_methods;
+
+1;
--- /dev/null
+# This file has been auto-generated. Do not modify it; it will be overwritten
+# by rose_auto_create_model.pl automatically.
+package SL::DB::ApGl;
+
+use strict;
+
+use parent qw(SL::DB::Object);
+
+__PACKAGE__->meta->table('ap_gl');
+
+__PACKAGE__->meta->columns(
+ ap_id => { type => 'integer', not_null => 1 },
+ gl_id => { type => 'integer', not_null => 1 },
+ itime => { type => 'timestamp', default => 'now()' },
+ mtime => { type => 'timestamp' },
+);
+
+__PACKAGE__->meta->primary_key_columns([ 'ap_id', 'gl_id' ]);
+
+__PACKAGE__->meta->allow_inline_column_values(1);
+
+__PACKAGE__->meta->foreign_keys(
+ ap => {
+ class => 'SL::DB::PurchaseInvoice',
+ key_columns => { ap_id => 'id' },
+ },
+
+ gl => {
+ class => 'SL::DB::GLTransaction',
+ key_columns => { gl_id => 'id' },
+ },
+);
+
+1;
+;
price_factor_id => { type => 'integer' },
pricegroup_id => { type => 'integer' },
project_id => { type => 'integer' },
- qty => { type => 'float', precision => 4, scale => 4 },
+ qty => { type => 'numeric', precision => 25, scale => 5 },
sellprice => { type => 'numeric', precision => 15, scale => 5 },
serialnumber => { type => 'text' },
subtotal => { type => 'boolean', default => 'false' },
price_factor_id => { type => 'integer' },
pricegroup_id => { type => 'integer' },
project_id => { type => 'integer' },
- qty => { type => 'float', precision => 4, scale => 4 },
+ qty => { type => 'numeric', precision => 25, scale => 5 },
reqdate => { type => 'date' },
sellprice => { type => 'numeric', precision => 15, scale => 5 },
serialnumber => { type => 'text' },
itime => { type => 'timestamp', default => 'now()' },
mtime => { type => 'timestamp' },
rate => { type => 'numeric', default => '0', not_null => 1, precision => 15, scale => 5 },
+ reverse_charge_chart_id => { type => 'integer' },
skonto_purchase_chart_id => { type => 'integer' },
skonto_sales_chart_id => { type => 'integer' },
taxdescription => { type => 'text', not_null => 1 },
[ 'LTR', qr{^(?:l|liter|litre)$}i ],
# miscellaneous
- [ 'C62', qr{^(?:stck|stück|pieces?|pc|psch|pauschal)$}i ],
+ [ 'C62', qr{^(?:stck|stück|pieces?|pc|psch|pauschal|licenses?|lizenz(?:en)?)$}i ],
);
sub map_name_to_code {
$form->{"selected_taxchart_$i"} = $selected_taxchart;
$form->{"AP_amount_chart_id_$i"} = $amount_chart_id;
$form->{"taxcharts_$i"} = \@taxcharts;
+
+ # reverse charge hack for template, display two taxes
+ if ($taxchart_to_use->taxkey == 94) {
+ my $tmpnetamount;
+ ($tmpnetamount, $form->{"tax_reverse_$i"}) = $form->calculate_tax($form->parse_amount(\%myconfig, $form->{"amount_$i"}), 0.19, $form->{taxincluded},2);
+ $form->{"tax_charge_$i"} = $form->{"tax_reverse_$i"} * -1;
+ $form->{"tax_reverse_$i"} = $form->format_amount(\%myconfig, $form->{"tax_reverse_$i"}, 2);
+ $form->{"tax_charge_$i"} = $form->format_amount(\%myconfig, $form->{"tax_charge_$i"}, 2);
+ }
}
$form->{taxchart_value_title_sub} = sub {
$form->error($locale->text('Cannot post transaction for a closed period!')) if ($form->date_closed($form->{"transdate"}, \%myconfig));
my $zero_amount_posting = 1;
+ # no taxincluded for 94
+ my $tax = SL::DB::Manager::Tax->get_first( where => [taxkey => 94 ]);
+ my $tax_id = ref $tax eq 'SL::DB::Tax' ? $tax->id : undef;
for my $i (1 .. $form->{rowcount}) {
+ # no taxincluded for 94
+ if ($tax_id && $form->{"taxchart_$i"} =~ m/^$tax_id--/ && $form->{taxincluded}) {
+ $form->error($locale->text('Cannot Post AP transaction with tax included!'));
+ }
if ($form->parse_amount(\%myconfig, $form->{"amount_$i"})) {
$zero_amount_posting = 0;
- last;
}
}
$is_linked_bank_transaction = 1;
}
+ my $is_linked_gl_transaction;
+ if ($::form->{id} && SL::DB::Manager::ApGl->find_by(ap_id => $::form->{id})) {
+ $is_linked_gl_transaction = 1;
+ }
my $create_post_action = sub {
# $_[0]: description
: $is_storno ? t8('Reversal invoices cannot be canceled.')
: $::form->{totalpaid} ? t8('Invoices with payments cannot be canceled.')
: $has_sepa_exports ? t8('This invoice has been linked with a sepa export, undo this first.')
+ : $is_linked_gl_transaction ? t8('This transaction is linked with a gl transaction. Please delete the ap transaction booking if needed.')
: undef,
],
action => [ t8('Delete'),
confirm => t8('Do you really want to delete this object?'),
disabled => !$may_edit_create ? t8('You must not change this AP transaction.')
: !$::form->{id} ? t8('This invoice has not been posted yet.')
- : $change_never ? t8('Changing invoices has been disabled in the configuration.')
- : $change_on_same_day_only ? t8('Invoices can only be changed on the day they are posted.')
- : $has_storno ? t8('This invoice has been canceled already.')
: $is_closed ? t8('The billing period has already been locked.')
: $has_sepa_exports ? t8('This invoice has been linked with a sepa export, undo this first.')
: $is_linked_bank_transaction ? t8('This transaction is linked with a bank transaction. Please undo and redo the bank transaction booking if needed.')
+ : $is_linked_gl_transaction ? undef # linked transactions can be deleted, if period is not closed
+ : $change_never ? t8('Changing invoices has been disabled in the configuration.')
+ : $change_on_same_day_only ? t8('Invoices can only be changed on the day they are posted.')
+ : $has_storno ? t8('This invoice has been canceled already.')
: undef,
],
], # end of combobox "Storno"
use POSIX qw(strftime);
use List::Util qw(first sum);
+use SL::DB::ApGl;
use SL::DB::RecordTemplate;
use SL::DB::BankTransactionAccTrans;
use SL::DB::Tax;
my $form = $::form;
my $change_never = $::instance_conf->get_gl_changeable == 0;
my $change_on_same_day_only = $::instance_conf->get_gl_changeable == 2 && ($form->current_date(\%::myconfig) ne $form->{gldate});
- my $is_linked_bank_transaction;
+ my ($is_linked_bank_transaction, $is_linked_ap_transaction);
if ($form->{id} && SL::DB::Manager::BankTransactionAccTrans->find_by(gl_id => $form->{id})) {
$is_linked_bank_transaction = 1;
}
+ if ($form->{id} && SL::DB::Manager::ApGl->find_by(gl_id => $form->{id})) {
+ $is_linked_ap_transaction = 1;
+ }
+
my $create_post_action = sub {
# $_[0]: description
: ($form->{id} && $change_never) ? t8('Changing general ledger transaction has been disabled in the configuration.')
: ($form->{id} && $change_on_same_day_only) ? t8('General ledger transactions can only be changed on the day they are posted.')
: $is_linked_bank_transaction ? t8('This transaction is linked with a bank transaction. Please undo and redo the bank transaction booking if needed.')
- : undef,
+ : $is_linked_ap_transaction ? t8('This transaction is linked with a AP transaction. Please undo and redo the AP transaction booking if needed.')
+ : undef,
],
};
disabled => !$form->{id} ? t8('This general ledger transaction has not been posted yet.')
: $form->{storno} ? t8('A canceled general ledger transaction cannot be canceled again.')
: $is_linked_bank_transaction ? t8('This transaction is linked with a bank transaction. Please undo and redo the bank transaction booking if needed.')
+ : $is_linked_ap_transaction ? t8('This transaction is linked with a AP transaction. Please undo and redo the AP transaction booking if needed.')
: undef,
],
action => [ t8('Delete'),
: $change_never ? t8('Changing invoices has been disabled in the configuration.')
: $change_on_same_day_only ? t8('Invoices can only be changed on the day they are posted.')
: $is_linked_bank_transaction ? t8('This transaction is linked with a bank transaction. Please undo and redo the bank transaction booking if needed.')
+ : $is_linked_ap_transaction ? t8('This transaction is linked with a AP transaction. Please undo and redo the AP transaction booking if needed.')
: $form->{storno} ? t8('A canceled general ledger transaction cannot be deleted.')
- : undef,
+ : undef,
],
], # end of combobox "Storno"
call => [ 'kivi.Draft.popup', 'gl', 'unknown', $form->{draft_id}, $form->{draft_description} ],
disabled => $form->{id} ? t8('This invoice has already been posted.')
: $form->{locked} ? t8('The billing period has already been locked.')
- : undef,
+ : undef,
],
], # end of combobox "more"
);
# Veränderungen von kivitendo #
###############################
+2022-0x-xx - Release 3.6.1
+
+Größere neue Features:
+
+Mittelgroße neue Features:
+
+Kleinere neue Features und Detailverbesserungen:
+
+ - Die Protokollierung von E-Mails in interne Bemerkungen ist deaktiviert,
+ falls der Mandant sowieso das E-Mail-Journal aktiviert hat.
+ - Steuerschlüssel 94, Reverse Charge gleichzeitige Vor- und Mehrwertsteuer
+ kann in einem netto verbuchten Kreditorenbeleg verbucht werden, die Steuer
+ wird dann mit einer verknüpften Dialogbuchung verbucht.
+
2022-03-02 - Release 3.6.0
Größere neue Features:
'Cancel Accounts Payables Transaction' => 'Kreditorenbuchung stornieren',
'Cancel Accounts Receivables Transaction' => 'Debitorenbuchung stornieren',
'Cancelling is disallowed. Either undo or balance the current payments until the open amount matches the invoice amount' => 'Storno verboten, da Zahlungen zum Beleg vorhanden sind. Entweder die Zahlungen löschen oder mit umgekehrten Vorzeichen ausbuchen, sodass der offene Betrag dem Rechnungsbetrag entspricht.',
+ 'Cannot Post AP transaction with tax included!' => 'Kann diesen kreditorischen Beleg nicht mit "Steuer im Preis inbegriffen" verbuchen!',
'Cannot add Booking, reason: #1 DB: #2 ' => 'Kann die Buchung nicht hinzufügen, Grund: #1 DB: #2',
'Cannot allocate parts.' => 'Es sind nicht genügend Artikel vorhanden',
'Cannot change transaction in a closed period!' => 'In einem bereits abgeschlossenen Zeitraum kann keine Buchung verändert werden!',
'This sales order has an active configuration for periodic invoices. If you save then all subsequently created invoices will contain those changes as well, but not those that have already been created. Do you want to continue?' => 'Dieser Auftrag besitzt eine aktive Konfiguration für wiederkehrende Rechnungen. Wenn Sie jetzt speichern, so werden alle zukünftig hieraus erzeugten Rechnungen die Änderungen enthalten, nicht aber die bereits erzeugten Rechnungen. Möchten Sie speichern?',
'This status output will be refreshed every five seconds.' => 'Diese Statusausgabe wird alle fünf Sekunden aktualisiert.',
'This transaction has to be split into several transactions manually.' => 'Diese Buchung muss manuell in mehrere Buchungen aufgeteilt werden.',
+ 'This transaction is linked with a AP transaction. Please undo and redo the AP transaction booking if needed.' => 'Diese Buchung ist mit einer Kreditorenbuchung verknüpft. Bitte Löschen oder Ändern Sie die Kreditorenbuchung nötigenfalls.',
'This transaction is linked with a bank transaction. Please undo and redo the bank transaction booking if needed.' => 'Ein oder mehrere Zahlungen des Belegs sind über das Verbuchen von Kontoauszüge erstellt worden, falls notwendig kann eine Neuverbuchung über Zahlungsverkehr -> Bericht Bankbewegung möglich gemacht werden.',
+ 'This transaction is linked with a gl transaction. Please delete the ap transaction booking if needed.' => 'Diese Buchung ist mit einer Dialogbuchung verknüpft. Bitte Löschen oder Ändern Sie diese Kreditorenbuchung nötigenfalls.',
'This update will change the nature the onhand of goods is tracked.' => 'Dieses update ändert die Art und Weise wie Lagermengen gezält werden.',
'This user is a member in the following groups' => 'Dieser Benutzer ist Mitglied in den folgenden Gruppen',
'This user will have access to the following clients' => 'Dieser Benutzer wird Zugriff auf die folgenden Mandanten haben',
'Cancel Accounts Payables Transaction' => '',
'Cancel Accounts Receivables Transaction' => '',
'Cancelling is disallowed. Either undo or balance the current payments until the open amount matches the invoice amount' => '',
+ 'Cannot Post AP transaction with tax included!' => '',
'Cannot add Booking, reason: #1 DB: #2 ' => '',
'Cannot allocate parts.' => '',
'Cannot change transaction in a closed period!' => '',
'This sales order has an active configuration for periodic invoices. If you save then all subsequently created invoices will contain those changes as well, but not those that have already been created. Do you want to continue?' => '',
'This status output will be refreshed every five seconds.' => '',
'This transaction has to be split into several transactions manually.' => '',
+ 'This transaction is linked with a AP transaction. Please undo and redo the AP transaction booking if needed.' => '',
'This transaction is linked with a bank transaction. Please undo and redo the bank transaction booking if needed.' => '',
+ 'This transaction is linked with a gl transaction. Please delete the ap transaction booking if needed.' => '',
'This update will change the nature the onhand of goods is tracked.' => '',
'This user is a member in the following groups' => '',
'This user will have access to the following clients' => '',
--- /dev/null
+-- @tag: ap_gl
+-- @description: Hilfstabelle für automatische GL-Buchung nach Kreditorenbuchung
+-- @depends: release_3_5_0
+-- @ignore: 0
+ CREATE TABLE ap_gl (
+ ap_id integer,
+ gl_id integer,
+ itime TIMESTAMP DEFAULT now(),
+ mtime TIMESTAMP,
+ PRIMARY KEY (ap_id, gl_id),
+ FOREIGN KEY (ap_id) REFERENCES ap (id),
+ FOREIGN KEY (gl_id) REFERENCES gl (id) ON DELETE CASCADE);
+
+
+
+
--- /dev/null
+-- @tag: cape_remove_oids
+-- @description: OIDs von Tabellen entfernen
+-- @depends: release_3_5_6
+ALTER TABLE assembly SET WITHOUT OIDS;
+ALTER TABLE delivery_order_items SET WITHOUT OIDS;
+ALTER TABLE invoice SET WITHOUT OIDS;
+ALTER TABLE orderitems SET WITHOUT OIDS;
+ALTER TABLE parts SET WITHOUT OIDS;
+ALTER TABLE partsgroup SET WITHOUT OIDS;
--- /dev/null
+-- @tag: convert_real_qty
+-- @description: Spaltentyp auf Numeric anstelle von Real für qty
+-- @depends: release_3_6_0
+ALTER TABLE orderitems ALTER column qty type numeric(25,5);
+ALTER TABLE invoice ALTER column qty type numeric(25,5);
+
+
--- /dev/null
+-- @tag: remove_oids
+-- @description: OIDs von Tabellen entfernen
+-- @depends: release_3_6_0
+ALTER TABLE assembly SET WITHOUT OIDS;
+ALTER TABLE delivery_order_items SET WITHOUT OIDS;
+ALTER TABLE invoice SET WITHOUT OIDS;
+ALTER TABLE orderitems SET WITHOUT OIDS;
+ALTER TABLE parts SET WITHOUT OIDS;
+ALTER TABLE partsgroup SET WITHOUT OIDS;
--- /dev/null
+-- @tag: tax_reverse_charge
+-- @description: Reverse Charge für Kreditorenbelege
+-- @depends: release_3_6_0
+-- @ignore: 0
+
+ALTER TABLE tax add column reverse_charge_chart_id integer;
+
+INSERT INTO chart (
+ accno, description,
+ charttype, category, link,
+ taxkey_id
+ )
+SELECT
+ '1577','Abziehbare Vorst. nach §13b UstG 19%',
+ 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice',
+ 0
+WHERE EXISTS ( -- update only for SKR03
+ SELECT coa FROM defaults
+ WHERE defaults.coa='Germany-DATEV-SKR03EU' AND NOT EXISTS (SELECT id from chart where accno='1577')
+);
+
+INSERT INTO chart (
+ accno, description,
+ charttype, category, link,
+ taxkey_id
+ )
+SELECT
+ '1787','Umsatzsteuer nach §13b UStG 19%',
+ 'A', 'I', 'AR_tax:IC_taxpart:IC_taxservice',
+ 0
+WHERE EXISTS ( -- update only for SKR03
+ SELECT coa FROM defaults
+ WHERE defaults.coa='Germany-DATEV-SKR03EU' AND NOT EXISTS (SELECT id from chart where accno='1787')
+);
+
+
+INSERT INTO chart (
+ accno, description,
+ charttype, category, link,
+ taxkey_id
+ )
+SELECT
+ '1407','Abziehbare Vorst. nach §13b UstG 19%',
+ 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice',
+ 0
+WHERE EXISTS ( -- update only for SKR04
+ SELECT coa FROM defaults
+ WHERE defaults.coa='Germany-DATEV-SKR04EU' AND NOT EXISTS (SELECT id from chart where accno='1407')
+);
+
+INSERT INTO chart (
+ accno, description,
+ charttype, category, link,
+ taxkey_id
+ )
+SELECT
+ '3837','Umsatzsteuer nach §13b UStG 19%',
+ 'A', 'I', 'AR_tax:IC_taxpart:IC_taxservice',
+ 0
+WHERE EXISTS ( -- update only for SKR04
+ SELECT coa FROM defaults
+ WHERE defaults.coa='Germany-DATEV-SKR04EU' AND NOT EXISTS (SELECT id from chart where accno='3837')
+);
+
+
+
+INSERT INTO tax (
+ chart_id,
+ reverse_charge_chart_id,
+ rate,
+ taxkey,
+ taxdescription,
+ chart_categories
+ )
+ SELECT
+ (SELECT id FROM chart WHERE accno = '1577'),
+ (SELECT id FROM chart WHERE accno = '1787'), 0,
+ '94', '19% Vorsteuer und 19% Umsatzsteuer', 'EI'
+WHERE EXISTS ( -- update only for SKR03
+ SELECT coa FROM defaults
+ WHERE defaults.coa='Germany-DATEV-SKR03EU'
+);
+
+
+INSERT INTO tax (
+ chart_id,
+ reverse_charge_chart_id,
+ rate,
+ taxkey,
+ taxdescription,
+ chart_categories
+ )
+ SELECT
+ (SELECT id FROM chart WHERE accno = '1407'),
+ (SELECT id FROM chart WHERE accno = '3837'), 0,
+ '94', '19% Vorsteuer und 19% Umsatzsteuer', 'EI'
+WHERE EXISTS ( -- update only for SKR03
+ SELECT coa FROM defaults
+ WHERE defaults.coa='Germany-DATEV-SKR04EU'
+);
+
+-- if not defined
+insert into taxkeys(chart_id,tax_id,taxkey_id,startdate) SELECT (SELECT chart_id FROM tax WHERE taxkey = '94'),0,0,'1970-01-01' WHERE NOT EXISTS
+ (SELECT chart_id from taxkeys where chart_id = ( SELECT chart_id FROM tax WHERE taxkey = '94'));
+
+insert into taxkeys(chart_id,tax_id,taxkey_id,startdate) SELECT (SELECT reverse_charge_chart_id FROM tax WHERE taxkey = '94'),0,0,'1970-01-01' WHERE NOT EXISTS
+ (SELECT chart_id from taxkeys where chart_id = ( SELECT reverse_charge_chart_id FROM tax WHERE taxkey = '94'));
+
}
# and add department (KOST1 description)
+ SL::DB::Department->new(
+ description => 'Total falsche Abteilung, niemals zuordnen!'
+ )->save;
+
+ SL::DB::Department->new(
+ description => '2. Total falsche Abteilung, niemals zuordnen!'
+ )->save;
+
+ SL::DB::Department->new(
+ description => '3. Total falsche Abteilung, niemals zuordnen!'
+ )->save;
+
+ SL::DB::Department->new(
+ description => 'annahme stelle. Total falsche Abteilung, niemals zuordnen!'
+ )->save;
+
+
SL::DB::Department->new(
description => 'Wisavis'
)->save;
# gl
is ($current_row->[13], $booking->reference, "Buchungstext correct");
- if (ref $booking->department eq 'SL::DB::Department') {
+ if ($current_row->[36] eq 'wisavis') {
+ is(ref $booking->department eq 'SL::DB::Department', 1, "Department assigned");
is ($current_row->[36], 'wisavis', "Department correctly assigned"); # lowercase
is ('Wisavis', $booking->department->description, "Department correctly assigned"); # upper case
} else {
<input name="amount_[% i %]" size="10" value="[% temp = "amount_"_ i %][% $temp | html %]">
</td>
<td>
- [% temp = "tax_"_ i %][% $temp | html %]
+ [% IF "tax_reverse_"_ i %]
+ [% temp_r = "tax_reverse_"_ i %][% $temp_r | html %]
+
+ [% temp_c = "tax_charge_"_ i %][% $temp_c | html %]
+ [% ELSE %]
+ [% temp = "tax_"_ i %][% $temp | html %]
+ [% END %]
</td>
<td>
[% temp = 'selected_taxchart_'_ i %]