|
#=====================================================================
|
|
# kivitendo ERP
|
|
# Copyright (c) 2004
|
|
#
|
|
# Author: Philip Reetz
|
|
# Email: p.reetz@linet-services.de
|
|
# Web: http://www.lx-office.org
|
|
#
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
# MA 02110-1335, USA.
|
|
#======================================================================
|
|
#
|
|
# Datev export module
|
|
#======================================================================
|
|
|
|
package SL::DATEV;
|
|
|
|
use utf8;
|
|
use strict;
|
|
|
|
use SL::DBUtils;
|
|
use SL::DATEV::CSV;
|
|
use SL::DB;
|
|
use SL::HTML::Util ();
|
|
use SL::Iconv;
|
|
use SL::Locale::String qw(t8);
|
|
use SL::VATIDNr;
|
|
|
|
use Archive::Zip;
|
|
use Data::Dumper;
|
|
use DateTime;
|
|
use Exporter qw(import);
|
|
use File::Path;
|
|
use IO::File;
|
|
use List::MoreUtils qw(any);
|
|
use List::Util qw(min max sum);
|
|
use List::UtilsBy qw(partition_by sort_by);
|
|
use Text::CSV_XS;
|
|
use Time::HiRes qw(gettimeofday);
|
|
use XML::LibXML;
|
|
|
|
{
|
|
my $i = 0;
|
|
use constant {
|
|
DATEV_ET_BUCHUNGEN => $i++,
|
|
DATEV_ET_STAMM => $i++,
|
|
DATEV_ET_CSV => $i++,
|
|
|
|
DATEV_FORMAT_KNE => $i++,
|
|
DATEV_FORMAT_OBE => $i++,
|
|
DATEV_FORMAT_CSV => $i++,
|
|
};
|
|
}
|
|
|
|
my @export_constants = qw(DATEV_ET_BUCHUNGEN DATEV_ET_STAMM DATEV_ET_CSV DATEV_FORMAT_KNE DATEV_FORMAT_OBE DATEV_FORMAT_CSV);
|
|
our @EXPORT_OK = (@export_constants);
|
|
our %EXPORT_TAGS = (CONSTANTS => [ @export_constants ]);
|
|
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my %data = @_;
|
|
|
|
my $obj = bless {}, $class;
|
|
|
|
$obj->$_($data{$_}) for keys %data;
|
|
|
|
$obj;
|
|
}
|
|
|
|
sub exporttype {
|
|
my $self = shift;
|
|
$self->{exporttype} = $_[0] if @_;
|
|
return $self->{exporttype};
|
|
}
|
|
|
|
sub has_exporttype {
|
|
defined $_[0]->{exporttype};
|
|
}
|
|
|
|
sub format {
|
|
my $self = shift;
|
|
$self->{format} = $_[0] if @_;
|
|
return $self->{format};
|
|
}
|
|
|
|
sub has_format {
|
|
defined $_[0]->{format};
|
|
}
|
|
|
|
sub _get_export_path {
|
|
$main::lxdebug->enter_sub();
|
|
|
|
my ($a, $b) = gettimeofday();
|
|
my $path = _get_path_for_download_token("${a}-${b}-${$}");
|
|
|
|
mkpath($path) unless (-d $path);
|
|
|
|
$main::lxdebug->leave_sub();
|
|
|
|
return $path;
|
|
}
|
|
|
|
sub _get_path_for_download_token {
|
|
$main::lxdebug->enter_sub();
|
|
|
|
my $token = shift || '';
|
|
my $path;
|
|
|
|
if ($token =~ m|^(\d+)-(\d+)-(\d+)$|) {
|
|
$path = $::lx_office_conf{paths}->{userspath} . "/datev-export-${1}-${2}-${3}/";
|
|
}
|
|
|
|
$main::lxdebug->leave_sub();
|
|
|
|
return $path;
|
|
}
|
|
|
|
sub _get_download_token_for_path {
|
|
$main::lxdebug->enter_sub();
|
|
|
|
my $path = shift;
|
|
my $token;
|
|
|
|
if ($path =~ m|.*datev-export-(\d+)-(\d+)-(\d+)/?$|) {
|
|
$token = "${1}-${2}-${3}";
|
|
}
|
|
|
|
$main::lxdebug->leave_sub();
|
|
|
|
return $token;
|
|
}
|
|
|
|
sub download_token {
|
|
my $self = shift;
|
|
$self->{download_token} = $_[0] if @_;
|
|
return $self->{download_token} ||= _get_download_token_for_path($self->export_path);
|
|
}
|
|
|
|
sub export_path {
|
|
my ($self) = @_;
|
|
|
|
return $self->{export_path} ||= _get_path_for_download_token($self->{download_token}) || _get_export_path();
|
|
}
|
|
|
|
sub add_filenames {
|
|
my $self = shift;
|
|
push @{ $self->{filenames} ||= [] }, @_;
|
|
}
|
|
|
|
sub filenames {
|
|
return @{ $_[0]{filenames} || [] };
|
|
}
|
|
|
|
sub add_error {
|
|
my $self = shift;
|
|
push @{ $self->{errors} ||= [] }, @_;
|
|
}
|
|
|
|
sub errors {
|
|
return @{ $_[0]{errors} || [] };
|
|
}
|
|
|
|
sub add_net_gross_differences {
|
|
my $self = shift;
|
|
push @{ $self->{net_gross_differences} ||= [] }, @_;
|
|
}
|
|
|
|
sub net_gross_differences {
|
|
return @{ $_[0]{net_gross_differences} || [] };
|
|
}
|
|
|
|
sub sum_net_gross_differences {
|
|
return sum $_[0]->net_gross_differences;
|
|
}
|
|
|
|
sub from {
|
|
my $self = shift;
|
|
|
|
if (@_) {
|
|
$self->{from} = $_[0];
|
|
}
|
|
|
|
return $self->{from};
|
|
}
|
|
|
|
sub to {
|
|
my $self = shift;
|
|
|
|
if (@_) {
|
|
$self->{to} = $_[0];
|
|
}
|
|
|
|
return $self->{to};
|
|
}
|
|
|
|
sub trans_id {
|
|
my $self = shift;
|
|
|
|
if (@_) {
|
|
$self->{trans_id} = $_[0];
|
|
}
|
|
|
|
die "illegal trans_id passed for DATEV export: " . $self->{trans_id} . "\n" unless $self->{trans_id} =~ m/^\d+$/;
|
|
|
|
return $self->{trans_id};
|
|