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_intake => 'auftragseingaenge',
22 sales_order => 'bestellungen',
23 request_quotation => 'anfragen',
24 purchase_quotation_intake => 'angebotseingaenge',
25 purchase_order => 'lieferantenbestellungen',
26 purchase_order_confirmation => 'lieferantenauftragsbestaetigungen',
27 sales_delivery_order => 'verkaufslieferscheine',
28 purchase_delivery_order => 'einkaufslieferscheine',
29 supplier_delivery_order => 'beistelllieferscheine',
30 rma_delivery_order => 'retourenlieferscheine',
31 purchase_reclamation => 'einkaufsreklamation',
32 sales_reclamation => 'verkaufsreklamation',
33 credit_note => 'gutschriften',
34 invoice => 'rechnungen',
35 invoice_for_advance_payment => 'rechnungen',
36 final_invoice => 'rechnungen',
37 purchase_invoice => 'einkaufsrechnungen',
39 service => 'dienstleistungen',
40 assembly => 'erzeugnisse',
42 general_ledger => 'dialogbuchungen',
43 accounts_payable => 'kreditorenbuchungen',
45 vendor => 'lieferanten',
46 dunning => 'mahnungen',
52 my @objects = $self->get_all_objects;
55 for my $obj (@objects) {
56 my $filename = join '.', grep $_, $obj->basename, $obj->extension;
58 my $file = $files_by_name{$filename} ||= SL::Webdav::File->new(filename => $filename, webdav => $self, loaded => 1);
59 $file->add_objects($obj);
62 return values %files_by_name;
68 my $path = $self->webdav_path;
71 my $base_path = $ENV{'SCRIPT_NAME'};
72 $base_path =~ s|[^/]+$||;
73 if (opendir my $dir, $path) {
74 foreach my $file (sort { lc $a cmp lc $b } map { decode("UTF-8", $_) } readdir $dir) {
75 next if (($file eq '.') || ($file eq '..'));
80 push @objects, SL::Webdav::Object->new(filename => $fname, webdav => $self);
92 my @files = $self->get_all_files;
93 map { ($_->versions)[-1] } @files;
96 sub _sanitized_number {
97 my $number = $_[0]->number;
98 $number =~ s|[/\\]|_|g;
105 die "No client set in \$::auth" unless $::auth->client;
106 die "Need number" unless $self->number;
108 my $type = $type_to_path{$self->type};
110 die "Unknown type" unless $type;
112 my $path = File::Spec->catdir("webdav", $::auth->client->{id}, $type, $self->_sanitized_number);
115 Common::mkdir_with_parents($path);
121 sub init_version_scheme {
122 SL::Webdav::VersionScheme::Timestamp->new;
133 SL::Webdav - Webdav manipulation
137 # get list of all documents for this record
140 my $webdav = SL::Webdav->new(
145 # gives you SL::Webdav::File instances
146 my $webdav_files = $webdav->get_all_files;
148 # gives you the objects instead
149 my $webdav_objects = $webdav->get_all_objects;
151 # gives you only the latest objects
152 my $webdav_objects = $webdav->get_all_latest;
154 # physical path to this dir
155 my $path = $webdav->webdav_path;
159 This module is a wrapper around the webdav storage mechanism with some simple
160 document management functionality.
162 This is not a replacement for real document management, mostly because the
163 underlying webdav storage is not fully under our control. It's common practice
164 to allow people direct samba access to the webdav, so all versioning
165 information needs to be encoded into the filename of a file, and nonsensical
166 filenames must not break assumptions.
168 This module is intended to be used if you need to scan the folder for
169 previously saved files and need to build a list in order to display it.
171 If you need to manipulate the versions of a file, see L<SL::Webdav::File>
173 If you need to access a file directly for download or metadata, see L<SL::Webdav::Object>
179 =item C<get_all_objects>
181 Returns all L<SL::Webdav::Objects> found.
183 =item C<get_all_files>
185 Returns all objects sorted into L<SL::Webdav::File>s.
187 =item C<get_all_latest>
189 Returns only the latest object of each L<SL::Webdav::File> found.
193 Returns the physical path to this webdav object.
197 =head1 VERSIONING SCHEME
199 You may register a versioning scheme object to handle versioning. It is
200 expected to implement the following methods:
206 Must return a string that will be used to separate the basename and version part of
207 filenames when generating and parsing.
209 =item C<extract_regexp>
211 Must return a regexp that will match a versioning string at the end of a
212 filename after the extension has been stripped off. It will be surrounded by
217 Must return a comparison function that will be invoked with two
218 L<SL::Webdav::Object> instances.
220 =item C<first_version>
222 Must return a string representing the version of the first of a series of objects.
226 =item C<next_version>
228 Will be called with the latest L<SL::Webdav::Object> and must return a new version string.
230 =item C<keep_last_version>
232 Will be called with the latest L<SL::Webdav::Object>. Truish return value will
233 cause the latest object to be overwritten instead of creating a new version.
237 =head1 BUGS AND CAVEATS
243 File operations are inconsistently L<File::Spec>ed.
249 L<SL::Webdav::File>, L<SL::Webdav::Object>
253 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>