+# this is designed to ignore chargenumbers, expiration dates and just give a list of how much <-> where
+sub get_simple_stock {
+ my ($self, %params) = @_;
+
+ return [] unless $self->id;
+
+ my $query = <<'';
+ SELECT sum(qty), warehouse_id, bin_id FROM inventory WHERE parts_id = ?
+ GROUP BY warehouse_id, bin_id
+
+ my $stock_info = selectall_hashref_query($::form, $::form->get_standard_dbh, $query, $self->id);
+ [ map { bless $_, 'SL::DB::Part::SimpleStock'} @$stock_info ];
+}
+# helper class to have bin/warehouse accessors in stock result
+{ package SL::DB::Part::SimpleStock;
+ sub warehouse { require SL::DB::Warehouse; SL::DB::Manager::Warehouse->find_by_or_create(id => $_[0]->{warehouse_id}) }
+ sub bin { require SL::DB::Bin; SL::DB::Manager::Bin ->find_by_or_create(id => $_[0]->{bin_id}) }
+}
+
+sub displayable_name {
+ join ' ', grep $_, map $_[0]->$_, qw(partnumber description);
+}
+
+sub clone_and_reset_deep {
+ my ($self) = @_;
+
+ my $clone = $self->clone_and_reset; # resets id and partnumber (primary key and unique constraint)
+ $clone->makemodels( map { $_->clone_and_reset } @{$self->makemodels});
+ $clone->translations( map { $_->clone_and_reset } @{$self->translations});
+
+ if ( $self->is_assortment ) {
+ $clone->assortment_items( map { $_->clone } @{$self->assortment_items} );
+ foreach my $ai ( @{ $clone->assortment_items } ) {
+ $ai->assortment_id(undef);
+ };
+ };
+
+ if ( $self->is_assembly ) {
+ $clone->assemblies( map { $_->clone_and_reset } @{$self->assemblies});
+ };
+
+ if ( $self->prices ) {
+ $clone->prices( map { $_->clone } @{$self->prices}); # pricegroup_id gets reset here because it is part of a unique contraint
+ if ( $clone->prices ) {
+ foreach my $price ( @{$clone->prices} ) {
+ $price->id(undef);
+ $price->parts_id(undef);
+ };
+ };
+ };
+
+ return $clone;
+}
+
+sub assembly_sellprice_sum {
+ my ($self) = @_;
+
+ return unless $self->is_assembly;
+ sum map { $_->linetotal_sellprice } @{$self->assemblies};
+};
+
+sub assembly_lastcost_sum {
+ my ($self) = @_;
+
+ return unless $self->is_assembly;
+ sum map { $_->linetotal_lastcost } @{$self->assemblies};
+};
+
+sub assortment_sellprice_sum {
+ my ($self) = @_;
+
+ return unless $self->is_assortment;
+ sum map { $_->linetotal_sellprice } @{$self->assortment_items};
+};
+
+sub assortment_lastcost_sum {
+ my ($self) = @_;
+
+ return unless $self->is_assortment;
+ sum map { $_->linetotal_lastcost } @{$self->assortment_items};
+};
+