use strict;
 use SL::PriceSource::Pricegroup;
 use SL::PriceSource::MasterData;
+use SL::PriceSource::Makemodel;
 
 my %price_sources_by_name = (
   master_data => 'SL::PriceSource::MasterData',
   pricegroup  => 'SL::PriceSource::Pricegroup',
+  makemodel   => 'SL::PriceSource::Makemodel',
 );
 
 my @price_sources_order = qw(
   master_data
   pricegroup
+  makemodel
 );
 
 sub all_price_sources {
 
--- /dev/null
+package SL::PriceSource::Makemodel;
+
+use strict;
+use parent qw(SL::PriceSource::Base);
+
+use SL::PriceSource::Price;
+use SL::Locale::String;
+use SL::DB::MakeModel;
+use List::UtilsBy qw(min_by);
+
+sub name { 'makemodel' }
+
+sub description { t8('Makemodel Price') }
+
+sub available_prices {
+  my ($self, %params) = @_;
+
+  return () if !$self->part;
+  return () if  $self->record->is_sales;
+
+  map { $self->make_price_from_makemodel($_) }
+  grep { $_->make == $self->record->vendor_id }
+  $self->part->makemodels;
+}
+
+sub price_from_source {
+  my ($self, $source, $spec) = @_;
+
+  my $makemodel = SL::DB::Manager::MakeModel->find_by(id => $spec);
+
+  # TODO: if someone deletes the prices entry, this fails. add a fallback
+  return $self->make_price_from_makemodel($makemodel);
+
+}
+
+sub best_price {
+  my ($self, %params) = @_;
+
+  return () if $self->record->is_sales;
+
+  min_by { $_->price } $self->available_prices;
+
+}
+
+sub make_price_from_makemodel {
+  my ($self, $makemodel) = @_;
+
+  return SL::PriceSource::Price->new(
+    price        => $makemodel->lastcost,
+    spec         => $makemodel->id,
+    description  => $makemodel->model,
+    price_source => $self,
+  );
+}
+
+
+1;
 
 sub available_prices {
   my ($self, %params) = @_;
 
-  my $part = $self->part;
+  return () unless $self->part;
 
-  return () unless $part;
-
-  # TODO: sellprice only in sales, lastcost in purchase
-  return $self->make_sellprice($part);
+  grep { $_->price > 0 } $self->record->is_sales
+    ? ($self->make_sellprice, $self->make_listprice)
+    : ($self->make_lastcost,  $self->make_listprice);
 }
 
 sub price_from_source {
   my ($self, $source, $spec) = @_;
 
-  if ($spec eq 'sellprice') {
-    return $self->make_sellprice($self->part);
-  }
+    $spec eq 'sellprice' ? $self->make_sellprice
+  : $spec eq 'lastcost'  ? $self->make_lastcost
+  : $spec eq 'listprice' ? $self->make_listprice
+  : do { die "unknown spec '$spec'" };
+}
+
+sub best_price {
+  $_[0]->record->is_sales
+  ? $_[0]->make_sellprice
+  : $_[0]->make_lastcost
 }
 
 sub make_sellprice {
-  my ($self, $part) = @_;
+  my ($self) = @_;
 
   return SL::PriceSource::Price->new(
-    price        => $part->sellprice,
+    price        => $self->part->sellprice,
     spec         => 'sellprice',
     description  => t8('Sellprice'),
     price_source => $self,
   );
 }
 
+sub make_listprice {
+  my ($self) = @_;
+
+  return SL::PriceSource::Price->new(
+    price        => $self->part->listprice,
+    spec         => 'listprice',
+    description  => t8('List Price'),
+    price_source => $self,
+  );
+}
+
+sub make_lastcost {
+  my ($self) = @_;
+
+  return SL::PriceSource::Price->new(
+    price        => $self->part->lastcost,
+    spec         => 'lastcost',
+    description  => t8('Lastcost'),
+    price_source => $self,
+  );
+}
+
 1;
 
   array => [ qw(depends_on) ]
 );
 
+use SL::DB::Helper::Attr;
+SL::DB::Helper::Attr::make(__PACKAGE__,
+  price => 'numeric(15,5)',
+);
+
 sub source {
   $_[0]->price_source
   ?  $_[0]->price_source->name . '/' . $_[0]->spec
     : $self->description
 }
 
+sub to_str {
+  "source: @{[ $_[0]->source ]}, price: @{[ $_[0]->price]}, description: @{[ $_[0]->description ]}"
+}
+
 1;
 
 use parent qw(SL::PriceSource::Base);
 
 use SL::PriceSource::Price;
+use SL::DB::Price;
 use SL::Locale::String;
 use List::UtilsBy qw(min_by);
 use List::Util qw(first);
 sub available_prices {
   my ($self, %params) = @_;
 
+  return () unless $self->record->is_sales;
+
   my $item = $self->record_item;
 
   my $prices = SL::DB::Manager::Price->get_all(
 sub price_from_source {
   my ($self, $source, $spec) = @_;
 
-  my $price = SL::DB::Manager::Price->find_by(id => $spec);
+  my $price = SL::DB::Manager::Price->find_by(pricegroup_id => $spec, parts_id => $self->part->id);
 
+  # TODO: if someone deletes the prices entry, this fails. add a fallback
   return $self->make_price($price);
 }
 
 sub best_price {
   my ($self, %params) = @_;
 
-  my @prices    = $self->availabe_prices;
+  return () unless $self->record->is_sales;
+
+  my @prices    = $self->available_prices;
   my $customer  = $self->record->customer;
-  my $min_price = min_by { $_->price } @prices;
 
-  return $min_price if !$customer || !$customer->cv_klass;
+  return () if !$customer || !$customer->klass;
 
-  my $best_price = first { $_->spec == $customer->cv_class } @prices;
+  my $best_price = first { $_->spec == $customer->klass } @prices;
 
-  return $best_price || $min_price;
+  return $best_price || ();
 }
 
 sub make_price {
 
   SL::PriceSource::Price->new(
     price        => $price_obj->price,
-    spec         => $price_obj->id,
+    spec         => $price_obj->pricegroup->id,
     description  => $price_obj->pricegroup->pricegroup,
     price_source => $self,
   )
 
       $form->{"sellprice_$i"} = $form->{"price_new_$i"};
     }
 
-    my $record_item = $record->items->[$i-1];
+    my $record_item = $record->id && $record->items ? $record->items->[$i-1] : _make_record_item($i);
 
 # unit begin
     $form->{"unit_old_$i"}      ||= $form->{"unit_$i"};
 
   map { $form->{"${_}_$i"} = $new_item->{$_} } @new_fields;
 
+  my $record       = _make_record();
+  my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record);
+  my $best_price   = $price_source->best_price;
+
+  if ($best_price) {
+    $::form->{"sellprice_$i"}           = $best_price->price;
+    $::form->{"active_price_source_$i"} = $best_price->source;
+  }
+
+
   $form->{"marge_price_factor_$i"} = $new_item->{price_factor};
 
   if ($form->{"part_payment_id_$i"} ne "") {
     purchase_oder           => 'Order',
     sales_quotation         => 'Order',
     request_quotation       => 'Order',
-    invoice                 => 'Invoice',
-    purchase_invoice        => 'PurchaseInvoice',
     purchase_delivery_order => 'DeliveryOrder',
     sales_delivery_order    => 'DeliveryOrder',
   }->{$::form->{type}};
 
+  if ($::form->{type} eq 'invoice') {
+    $class = $::form->{vc} eq 'customer' ? 'Invoice'
+           : $::form->{vc} eq 'vendor'   ? 'PurchaseInvoice'
+           : do { die 'unknown invoice type' };
+  }
+
   return unless $class;
 
   $class = 'SL::DB::' . $class;
     push @items, _make_record_item($i)
   }
 
-  $obj->orderitems(@items);
+  $obj->items(@items) if @items;
 
   return $obj;
 }
 
         if ($sellprice) {
           $form->{"sellprice_$i"} = $sellprice;
         } else {
+          my $record       = _make_record();
+          my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record);
+          my $best_price   = $price_source->best_price;
+
+          if ($best_price) {
+            $::form->{"sellprice_$i"}           = $best_price->price;
+            $::form->{"active_price_source_$i"} = $best_price->source;
+          }
+
           $form->{"sellprice_$i"} *= (1 - $form->{tradediscount});
           $form->{"sellprice_$i"} /= $exchangerate;   # if there is an exchange rate adjust sellprice
         }
 
   'Make (vendor\'s database ID, number or name; with X being a number)' => 'Lieferant (Datenbank-ID, Nummer oder Name des Lieferanten; X ist eine fortlaufende Zahl)',
   'Make compatible for import'  => 'Für den Import kompatibel machen',
   'Make default profile'        => 'Zu Standardprofil machen',
+  'Makemodel Price'             => 'Lieferantenpreis',
   'Manage Custom Variables'     => 'Benutzerdefinierte Variablen',
   'Mandantennummer'             => 'Mandantennummer',
   'Mandate Date of Signature'   => 'Mandat-Unterschriftsdatum',