epic-ts
[kivitendo-erp.git] / SL / DB / Unit.pm
1 package SL::DB::Unit;
2
3 use List::MoreUtils qw(any);
4
5
6 use strict;
7
8 use SL::DB::MetaSetup::Unit;
9 use SL::DB::Manager::Unit;
10 use SL::DB::Helper::ActsAsList;
11
12 __PACKAGE__->meta->add_relationships(
13   base => {
14     type         => 'many to one',
15     class        => 'SL::DB::Unit',
16     column_map   => { base_unit => 'name' },
17   },
18 );
19
20 __PACKAGE__->meta->initialize;
21
22 #methods
23
24 sub unit_class {
25   my $self   = shift;
26
27   return $self if !$self->base_unit || $self->name eq $self->base_unit;
28   return $self->base->unit_class;
29 }
30
31 sub convertible_units {
32   my $self = shift;
33   my $all_units = scalar(@_) && (ref($_[0]) eq 'ARRAY') ? $_[0] : [ @_ ];
34   $all_units    = SL::DB::Manager::Unit->all_units if ! @{ $all_units };
35   return [
36     sort { $a->sortkey <=> $b->sortkey }
37     grep { $_->unit_class->name eq $self->unit_class->name }
38     @{ $all_units }
39   ];
40 }
41
42 sub base_factor {
43   my ($self) = @_;
44
45   my $cache = $::request->cache('base_factor');
46
47   if (!defined $cache->{$self->id}) {
48     $cache->{$self->id} = !$self->base_unit || !$self->factor || ($self->name eq $self->base_unit) ? 1 : $self->factor * $self->base->base_factor;
49   }
50
51   return $cache->{$self->id};
52 }
53
54 sub convert_to {
55   my ($self, $qty, $other_unit) = @_;
56
57   my $my_base_factor    = $self->base_factor       || 1;
58   my $other_base_factor = $other_unit->base_factor || 1;
59
60   return $qty * $my_base_factor / $other_base_factor;
61 }
62
63 sub is_time_based {
64   my ($self) = @_;
65
66   return any { $_->id == $self->id } @{ SL::DB::Manager::Unit->time_based_units };
67 }
68
69 1;