4 use parent qw(Rose::Object);
 
  10 use SL::Webdav::Object;
 
  11 use SL::Webdav::VersionScheme::Serial;
 
  12 use SL::Webdav::VersionScheme::Timestamp;
 
  14 use Rose::Object::MakeMethods::Generic (
 
  15   scalar => [ qw(type number) ],
 
  16   'scalar --get_set_init' => [ qw(version_scheme) ],
 
  20   sales_quotation         => 'angebote',
 
  21   sales_order             => 'bestellungen',
 
  22   request_quotation       => 'anfragen',
 
  23   purchase_order          => 'lieferantenbestellungen',
 
  24   sales_delivery_order    => 'verkaufslieferscheine',
 
  25   purchase_delivery_order => 'einkaufslieferscheine',
 
  26   credit_note             => 'gutschriften',
 
  27   invoice                 => 'rechnungen',
 
  28   purchase_invoice        => 'einkaufsrechnungen',
 
  30   service                 => 'dienstleistungen',
 
  31   assembly                => 'erzeugnisse',
 
  37   my @objects = $self->get_all_objects;
 
  40   for my $obj (@objects) {
 
  41     my $filename = join '.', grep $_, $obj->basename, $obj->extension;
 
  43     my $file = $files_by_name{$filename} ||= SL::Webdav::File->new(filename => $filename, webdav => $self, loaded => 1);
 
  44     $file->add_objects($obj);
 
  47   return values %files_by_name;
 
  53   my $path = $self->webdav_path;
 
  56   my $base_path = $ENV{'SCRIPT_NAME'};
 
  57   $base_path =~ s|[^/]+$||;
 
  58   if (opendir my $dir, $path) {
 
  59     foreach my $file (sort { lc $a cmp lc $b } map { decode("UTF-8", $_) } readdir $dir) {
 
  60       next if (($file eq '.') || ($file eq '..'));
 
  65       push @objects, SL::Webdav::Object->new(filename => $fname, webdav => $self);
 
  77   my @files = $self->get_all_files;
 
  78   map { ($_->versions)[-1] } @files;
 
  81 sub _sanitized_number {
 
  82   my $number = $_[0]->number;
 
  83   $number =~ s|[/\\]|_|g;
 
  90   die "No client set in \$::auth" unless $::auth->client;
 
  91   die "Need number"               unless $self->number;
 
  93   my $type = $type_to_path{$self->type};
 
  95   die "Unknown type"              unless $type;
 
  97   my $path = File::Spec->catdir("webdav", $::auth->client->{id}, $type, $self->_sanitized_number);
 
 100     Common::mkdir_with_parents($path);
 
 106 sub init_version_scheme {
 
 107   SL::Webdav::VersionScheme::Timestamp->new;
 
 118 SL::Webdav - Webdav manipulation
 
 122   # get list of all documents for this record
 
 125   my $webdav = SL::Webdav->new(
 
 130   # gives you SL::Webdav::File instances
 
 131   my $webdav_files = $webdav->get_all_files;
 
 133   # gives you the objects instead
 
 134   my $webdav_objects = $webdav->get_all_objects;
 
 136   # gives you only the latest objects
 
 137   my $webdav_objects = $webdav->get_all_latest;
 
 139   # physical path to this dir
 
 140   my $path = $webdav->webdav_path;
 
 144 This module is a wrapper around the webdav storage mechanism with some simple
 
 145 document management functionality.
 
 147 This is not a replacement for real document management, mostly because the
 
 148 underlying webdav storage ist not fully under our control. It's common practice
 
 149 to allow people direct samba access to the webdav, so all versioning
 
 150 information need to be encoded into the filename of a file, and nonsensical
 
 151 filenames must not break assumptions.
 
 153 This module is intended to be used if you need to scan the folder for
 
 154 previously saved files and need to build a list to display for it.
 
 156 If you need to manipulate the versions of a file, see L<SL::Webdav::File>
 
 158 If you need to access a file directly for download or metadata, see L<SL::Webdav::Object>
 
 164 =item C<get_all_objects>
 
 166 Returns all L<SL::Webdav::Objects> found.
 
 168 =item C<get_all_files>
 
 170 Returns all objects sorted into L<SL::Webdav::File>s.
 
 172 =item C<get_all_latest>
 
 174 Returns only the latest object of each L<SL::Webdav::File> found.
 
 178 Returns the physical path to this webdav object.
 
 182 =head1 VERSIONING SCHEME
 
 184 You may register a versioning scheme object to hangdle versioning. It is
 
 185 expected to implement the following methods:
 
 191 Must return a string that will be used to separate basename and version part of
 
 192 filenames in generating and parsing.
 
 194 =item C<extract_regexp>
 
 196 Must return a regexp that will match a versioning string at the end of a
 
 197 filename after the extension has been stripped off. It will be surrounded by
 
 202 Must return a comparison function that will be invoked with two
 
 203 L<SL::Webdav::Object> instances.
 
 205 =item C<first_version>
 
 207 Must return a string representing the version of the first of a series of objects.
 
 211 =item C<next_version>
 
 213 Will be called with the latest L<SL::Webdav::Object> and must return a new version string.
 
 215 =item C<keep_last_version>
 
 217 Will be called with the latest L<SL::Webdav::Object>. Truish return value will
 
 218 cause the latest object to be overwritten instead of creating a new version.
 
 222 =head1 BUGS AND CAVEATS
 
 228 File operations are inconsistently L<File::Spec>ed.
 
 234 L<SL::Webdav::File>, L<SL::Webdav::Object>
 
 238 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>