+use SL::DB::Manager::Project;
+
+use SL::DB::Helper::CustomVariables(
+  module      => 'Projects',
+  cvars_alias => 1,
+);
+
+__PACKAGE__->meta->add_relationship(
+  employee_invoice_permissions  => {
+    type       => 'many to many',
+    map_class  => 'SL::DB::EmployeeProjectInvoices',
+  },
+);
+
+__PACKAGE__->meta->initialize;
+
+sub validate {
+  my ($self) = @_;
+
+  my @errors;
+  push @errors, $::locale->text('The project number is missing.')        if !$self->projectnumber;
+  push @errors, $::locale->text('The project number is already in use.') if !$self->is_projectnumber_unique;
+  push @errors, $::locale->text('The description is missing.')           if !$self->description;
+
+  return @errors;
+}
+
+sub is_used {
+  my ($self) = @_;
+
+  # Unsaved projects are never referenced.
+  return 0 unless $self->id;
+
+  return any {
+    my $column = $SL::DB::Manager::Project::project_id_column_prefixes{$_} . 'project_id';
+    $self->db->dbh->selectrow_arrayref(qq|SELECT EXISTS(SELECT * FROM ${_} WHERE ${column} = ?)|, undef, $self->id)->[0]
+  } @SL::DB::Manager::Project::tables_with_project_id_cols;
+}
+
+sub is_projectnumber_unique {
+  my ($self) = @_;
+
+  return 1 unless $self->projectnumber;
+
+  my @filter = (projectnumber => $self->projectnumber);
+  @filter    = (and => [ @filter, '!id' => $self->id ]) if $self->id;
+
+  return !SL::DB::Manager::Project->get_first(where => \@filter);
+}
+
+sub displayable_name {
+  my ($self) = @_;
+
+  return join ' ', grep $_, $self->projectnumber, $self->description;
+}
+
+sub full_description {
+  my ($self, %params) = @_;
+
+  $params{style} ||= 'both';
+  my $description;
+
+  if ($params{style} =~ m/number/) {
+    $description = $self->projectnumber;
+
+  } elsif ($params{style} =~ m/description/) {
+    $description = $self->description;
+
+  } elsif (($params{style} =~ m/full/) && $self->customer) {
+    $description = $self->projectnumber;
+    if ($self->description && do { my $desc = quotemeta $self->description; $self->projectnumber !~ m/$desc/ }) {
+      $description .= ' ' . $self->description;
+    }
+
+    $description = $self->customer->name . " (${description})";
+
+  } else {
+    $description = $self->projectnumber;
+    if ($self->description && do { my $desc = quotemeta $self->description; $self->projectnumber !~ m/$desc/ }) {
+      $description .= ' (' . $self->description . ')';
+    }
+  }
+
+  return $description;
+}
+
+sub may_employee_view_project_invoices {
+  my ($self, $employee) = @_;