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 invoice_for_advance_payment => 'rechnungen',
29 final_invoice => 'rechnungen',
30 purchase_invoice => 'einkaufsrechnungen',
32 service => 'dienstleistungen',
33 assembly => 'erzeugnisse',
35 general_ledger => 'dialogbuchungen',
36 accounts_payable => 'kreditorenbuchungen',
38 vendor => 'lieferanten',
39 dunning => 'mahnungen',
45 my @objects = $self->get_all_objects;
48 for my $obj (@objects) {
49 my $filename = join '.', grep $_, $obj->basename, $obj->extension;
51 my $file = $files_by_name{$filename} ||= SL::Webdav::File->new(filename => $filename, webdav => $self, loaded => 1);
52 $file->add_objects($obj);
55 return values %files_by_name;
61 my $path = $self->webdav_path;
64 my $base_path = $ENV{'SCRIPT_NAME'};
65 $base_path =~ s|[^/]+$||;
66 if (opendir my $dir, $path) {
67 foreach my $file (sort { lc $a cmp lc $b } map { decode("UTF-8", $_) } readdir $dir) {
68 next if (($file eq '.') || ($file eq '..'));
73 push @objects, SL::Webdav::Object->new(filename => $fname, webdav => $self);
85 my @files = $self->get_all_files;
86 map { ($_->versions)[-1] } @files;
89 sub _sanitized_number {
90 my $number = $_[0]->number;
91 $number =~ s|[/\\]|_|g;
98 die "No client set in \$::auth" unless $::auth->client;
99 die "Need number" unless $self->number;
101 my $type = $type_to_path{$self->type};
103 die "Unknown type" unless $type;
105 my $path = File::Spec->catdir("webdav", $::auth->client->{id}, $type, $self->_sanitized_number);
108 Common::mkdir_with_parents($path);
114 sub init_version_scheme {
115 SL::Webdav::VersionScheme::Timestamp->new;
126 SL::Webdav - Webdav manipulation
130 # get list of all documents for this record
133 my $webdav = SL::Webdav->new(
138 # gives you SL::Webdav::File instances
139 my $webdav_files = $webdav->get_all_files;
141 # gives you the objects instead
142 my $webdav_objects = $webdav->get_all_objects;
144 # gives you only the latest objects
145 my $webdav_objects = $webdav->get_all_latest;
147 # physical path to this dir
148 my $path = $webdav->webdav_path;
152 This module is a wrapper around the webdav storage mechanism with some simple
153 document management functionality.
155 This is not a replacement for real document management, mostly because the
156 underlying webdav storage is not fully under our control. It's common practice
157 to allow people direct samba access to the webdav, so all versioning
158 information needs to be encoded into the filename of a file, and nonsensical
159 filenames must not break assumptions.
161 This module is intended to be used if you need to scan the folder for
162 previously saved files and need to build a list in order to display it.
164 If you need to manipulate the versions of a file, see L<SL::Webdav::File>
166 If you need to access a file directly for download or metadata, see L<SL::Webdav::Object>
172 =item C<get_all_objects>
174 Returns all L<SL::Webdav::Objects> found.
176 =item C<get_all_files>
178 Returns all objects sorted into L<SL::Webdav::File>s.
180 =item C<get_all_latest>
182 Returns only the latest object of each L<SL::Webdav::File> found.
186 Returns the physical path to this webdav object.
190 =head1 VERSIONING SCHEME
192 You may register a versioning scheme object to handle versioning. It is
193 expected to implement the following methods:
199 Must return a string that will be used to separate the basename and version part of
200 filenames when generating and parsing.
202 =item C<extract_regexp>
204 Must return a regexp that will match a versioning string at the end of a
205 filename after the extension has been stripped off. It will be surrounded by
210 Must return a comparison function that will be invoked with two
211 L<SL::Webdav::Object> instances.
213 =item C<first_version>
215 Must return a string representing the version of the first of a series of objects.
219 =item C<next_version>
221 Will be called with the latest L<SL::Webdav::Object> and must return a new version string.
223 =item C<keep_last_version>
225 Will be called with the latest L<SL::Webdav::Object>. Truish return value will
226 cause the latest object to be overwritten instead of creating a new version.
230 =head1 BUGS AND CAVEATS
236 File operations are inconsistently L<File::Spec>ed.
242 L<SL::Webdav::File>, L<SL::Webdav::Object>
246 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>