6ea2be9b1f05ff664554cb4164a8fce443d319c1
[kivitendo-erp.git] / SL / DB / Part.pm
1 package SL::DB::Part;
2
3 use strict;
4
5 use Carp;
6 use SL::DBUtils;
7 use SL::DB::MetaSetup::Part;
8 use SL::DB::Manager::Part;
9
10 __PACKAGE__->attr_number('lastcost',  places => -2);
11 __PACKAGE__->attr_number('listprice', places => -2);
12 __PACKAGE__->attr_number('sellprice', places => -2);
13
14 __PACKAGE__->meta->add_relationships(
15   unit_obj                     => {
16     type         => 'one to one',
17     class        => 'SL::DB::Unit',
18     column_map   => { unit => 'name' },
19   },
20   assemblies                     => {
21     type         => 'one to many',
22     class        => 'SL::DB::Assembly',
23     column_map   => { id => 'id' },
24   },
25 );
26
27 __PACKAGE__->meta->initialize;
28
29 sub is_type {
30   my $self = shift;
31   my $type  = lc(shift || '');
32
33   if ($type =~ m/^part/) {
34     return !$self->assembly && $self->inventory_accno_id  ? 1 : 0;
35
36   } elsif ($type =~ m/^service/) {
37     return !$self->inventory_accno_id && !$self->assembly ? 1 : 0;
38
39   } elsif ($type =~ m/^assembl/) {
40     return $self->assembly                                ? 1 : 0;
41
42   }
43
44   confess "Unknown type parameter '$type'";
45 }
46
47 sub get_sellprice_info {
48   my $self   = shift;
49   my %params = @_;
50
51   confess "Missing part id" unless $self->id;
52
53   my $object = $self->load;
54
55   return { sellprice       => $object->sellprice,
56            price_factor_id => $object->price_factor_id };
57 }
58
59 sub get_ordered_qty {
60   my $self   = shift;
61   my %result = SL::DB::Manager::Part->get_ordered_qty($self->id);
62
63   return $result{ $self->id };
64 }
65
66 sub get_uncommissioned_qty {
67   my $self   = shift;
68   my %params = @_;
69
70   confess "Missing part id" unless $self->id;
71
72   my $query = <<SQL;
73     SELECT
74       COALESCE((SELECT SUM(oi.qty)
75                 FROM orderitems oi
76                 LEFT JOIN oe ON (oi.trans_id = oe.id)
77                 WHERE (oi.parts_id = ?)
78                   AND (NOT COALESCE(oe.quotation, FALSE))
79                   AND (NOT COALESCE(oe.closed,    FALSE))
80                   AND (NOT COALESCE(oe.delivered, FALSE))
81                   AND (COALESCE(oe.customer_id, 0) <> 0)),
82                0)
83       -
84       COALESCE((SELECT SUM(i.qty) AS qty
85                 FROM inventory i
86                 LEFT JOIN warehouse wh ON (i.warehouse_id = wh.id)
87                 WHERE (i.parts_id = ?)
88                   AND COALESCE(wh.commission)),
89                0)
90       AS qty
91 SQL
92
93   my $result = selectfirst_hashref_query($::form, $self->dbh, $query, $self->id, $self->id);
94   return $result ? $result->{qty} : 0;
95 }
96
97 sub available_units {
98   shift->unit_obj->convertible_units;
99 }
100
101 1;
102
103 __END__
104
105 =pod
106
107 =head1 NAME
108
109 SL::DB::Part: Model for the 'parts' table
110
111 =head1 SYNOPSIS
112
113 This is a standard Rose::DB::Object based model and can be used as one.
114
115 =head1 FUNCTIONS
116
117 =over 4
118
119 =item is_type $type
120
121 Tests if the current object is a part, a service or an
122 assembly. C<$type> must be one of the words 'part', 'service' or
123 'assembly' (their plurals are ok, too).
124
125 Returns 1 if the requested type matches, 0 if it doesn't and
126 C<confess>es if an unknown C<$type> parameter is encountered.
127
128 =item get_sellprice_info %params
129
130 Retrieves the C<sellprice> and C<price_factor_id> for a part under
131 different conditions and returns a hash reference with those two keys.
132
133 If C<%params> contains a key C<project_id> then a project price list
134 will be consulted if one exists for that project. In this case the
135 parameter C<country_id> is evaluated as well: if a price list entry
136 has been created for this country then it will be used. Otherwise an
137 entry without a country set will be used.
138
139 If none of the above conditions is met then the information from
140 C<$self> is used.
141
142 =item get_ordered_qty %params
143
144 Retrieves the quantity that has been ordered from a vendor but that
145 has not been delivered yet. Only open purchase orders are considered.
146
147 =item get_uncommissioned_qty %params
148
149 Retrieves the quantity that has been ordered by a customer but that
150 has not been commissioned yet. Only open sales orders are considered.
151
152 =back
153
154 =head1 AUTHOR
155
156 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
157
158 =cut