diff --git a/lib/NGCP/Panel/Controller/Contract.pm b/lib/NGCP/Panel/Controller/Contract.pm
new file mode 100644
index 0000000000..45186dbeb6
--- /dev/null
+++ b/lib/NGCP/Panel/Controller/Contract.pm
@@ -0,0 +1,129 @@
+package NGCP::Panel::Controller::Contract;
+use Moose;
+use namespace::autoclean;
+use Data::Dumper;
+
+BEGIN { extends 'Catalyst::Controller'; }
+
+use NGCP::Panel::Form::Contract;
+
+=head1 NAME
+
+NGCP::Panel::Controller::Contract - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+sub list :Chained('/') :PathPart('contract') :CaptureArgs(0) {
+    my ($self, $c) = @_;
+
+    my $contracts = [
+        {id => 1, contact_id => 1, billing_profile_id => 1, status => 'active'},
+        {id => 2, contact_id => 2, billing_profile_id => 2, status => 'pending'},
+        {id => 3, contact_id => 3, billing_profile_id => 3, status => 'active'},
+        {id => 4, contact_id => 4, billing_profile_id => 4, status => 'terminated'},
+        {id => 5, contact_id => 5, billing_profile_id => 5, status => 'locked'},
+        {id => 6, contact_id => 6, billing_profile_id => 6, status => 'active'},
+    ];
+    $c->stash(contracts => $contracts);
+    $c->stash(template => 'contract/list.tt');
+}
+
+sub root :Chained('list') :PathPart('') :Args(0) {
+    my ($self, $c) = @_;
+}
+
+sub create :Chained('list') :PathPart('create') :Args(0) {
+    my ($self, $c) = @_;
+
+    my $form = NGCP::Panel::Form::Contract->new;
+    $form->process(
+        posted => ($c->request->method eq 'POST'),
+        params => $c->request->params,
+        action => $c->uri_for('create'),
+    );
+    if($form->validated) {
+        $c->flash(messages => [{type => 'success', text => 'Contract successfully created!'}]);
+        if($c->session->{redirect_target}) {
+            # TODO: post back to redirect-target, so we can continue processing their form?
+            $c->response->redirect($c->session->{redirect_target});
+            return;
+        }
+        $c->response->redirect($c->uri_for());
+        return;
+    }
+
+    $c->stash(create_flag => 1);
+    $c->stash(form => $form);
+}
+
+sub search :Chained('list') :PathPart('search') Args(0) {
+    my ($self, $c) = @_;
+
+    $c->flash(messages => [{type => 'info', text => 'Contract search not implemented!'}]);
+    $c->response->redirect($c->uri_for());
+}
+
+sub base :Chained('/contract/list') :PathPart('') :CaptureArgs(1) {
+    my ($self, $c, $contract_id) = @_;
+
+    unless($contract_id && $contract_id =~ /^\d+$/) {
+        $c->flash(messages => [{type => 'error', text => 'Invalid contract id detected!'}]);
+        $c->response->redirect($c->uri_for());
+        return;
+    }
+
+    # TODO: fetch details of contract from model
+    my @rfilter = grep { $_->{id} == $contract_id } @{ $c->stash->{contracts} };
+    $c->stash(contract =>  shift @rfilter);
+}
+
+sub edit :Chained('base') :PathPart('edit') :Args(0) {
+    my ($self, $c) = @_;
+
+    my $posted = ($c->request->method eq 'POST');
+    my $form = NGCP::Panel::Form::Contract->new;
+    $form->process(
+        posted => 1,
+        params => $posted ? $c->request->params : $c->stash->{contract},
+        action => $c->uri_for($c->stash->{contract}->{id}, 'edit'),
+    );
+    if($posted && $form->validated) {
+        $c->flash(messages => [{type => 'success', text => 'Contract successfully changed!'}]);
+        $c->response->redirect($c->uri_for());
+        return;
+    }
+
+    $c->stash(form => $form);
+}
+
+sub delete :Chained('base') :PathPart('delete') :Args(0) {
+    my ($self, $c) = @_;
+
+    # $c->model('Provisioning')->contract($c->stash->{contract}->{id})->delete;
+    $c->flash(messages => [{type => 'info', text => 'Contract delete not implemented!'}]);
+    $c->response->redirect($c->uri_for());
+}
+
+
+=head1 AUTHOR
+
+Andreas Granig,,,
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
+# vim: set tabstop=4 expandtab:
diff --git a/lib/NGCP/Panel/Controller/Reseller.pm b/lib/NGCP/Panel/Controller/Reseller.pm
index ab7e818d71..d75841a01e 100644
--- a/lib/NGCP/Panel/Controller/Reseller.pm
+++ b/lib/NGCP/Panel/Controller/Reseller.pm
@@ -23,12 +23,12 @@ sub list :Chained('/') :PathPart('reseller') :CaptureArgs(0) {
     my ($self, $c) = @_;
 
     my $resellers = [
-        {id => 1, contract_id => 1, name => 'reseller 1', status => 'active'},
-        {id => 2, contract_id => 2, name => 'reseller 2', status => 'active'},
-        {id => 3, contract_id => 3, name => 'reseller 3', status => 'active'},
-        {id => 4, contract_id => 4, name => 'reseller 4', status => 'locked'},
-        {id => 5, contract_id => 5, name => 'reseller 5', status => 'terminated'},
-        {id => 6, contract_id => 6, name => 'reseller 6', status => 'active'},
+        {id => 1, contract => 1, name => 'reseller 1', status => 'active'},
+        {id => 2, contract => 2, name => 'reseller 2', status => 'active'},
+        {id => 3, contract => 3, name => 'reseller 3', status => 'active'},
+        {id => 4, contract => 4, name => 'reseller 4', status => 'locked'},
+        {id => 5, contract => 5, name => 'reseller 5', status => 'terminated'},
+        {id => 6, contract => 6, name => 'reseller 6', status => 'active'},
     ];
     $c->stash(resellers => $resellers);
     $c->stash(template => 'reseller/list.tt');
@@ -41,6 +41,12 @@ sub root :Chained('list') :PathPart('') :Args(0) {
 sub create :Chained('list') :PathPart('create') :Args(0) {
     my ($self, $c) = @_;
 
+    # TODO: check if some create-button is clicked, then set
+    # $c->session(redirect_target => $c->uri_for()); # <-- redirect back to here
+    # somehow save form in session(?) so we can continue from here,
+    # or maybe post from the redirect_target back here, with all values filled in already?
+
+
     my $form = NGCP::Panel::Form::Reseller->new;
     $form->process(
         posted => ($c->request->method eq 'POST'),
diff --git a/lib/NGCP/Panel/Field/BillingProfile.pm b/lib/NGCP/Panel/Field/BillingProfile.pm
new file mode 100644
index 0000000000..dab1a9b367
--- /dev/null
+++ b/lib/NGCP/Panel/Field/BillingProfile.pm
@@ -0,0 +1,21 @@
+package NGCP::Panel::Field::BillingProfile;
+use HTML::FormHandler::Moose;
+extends 'HTML::FormHandler::Field::Compound';
+
+has_field 'foo' => (
+    type => '+NGCP::Panel::Field::BillingProfileSelect',
+    label => 'Billing Profile',
+    required => 1,
+);
+
+has_field 'create' => (
+    type => 'Button',
+    label => 'or',
+    value => 'Create Billing Profile',
+    element_attr => { onclick => 'window.location=\'/billingprofile/create\'' },
+    element_class => [qw/btn btn-tertiary/],
+);
+
+1;
+
+# vim: set tabstop=4 expandtab:
diff --git a/lib/NGCP/Panel/Field/BillingProfileSelect.pm b/lib/NGCP/Panel/Field/BillingProfileSelect.pm
new file mode 100644
index 0000000000..9b3905bdf6
--- /dev/null
+++ b/lib/NGCP/Panel/Field/BillingProfileSelect.pm
@@ -0,0 +1,21 @@
+package NGCP::Panel::Field::BillingProfileSelect;
+use Moose;
+extends 'HTML::FormHandler::Field::Select';
+
+sub build_options {
+    my ($self) = @_;
+
+    return [ 
+        { label => 'Select...', value => '' },
+        { label => '1', value => 1 },
+        { label => '2', value => 2 },
+        { label => '3', value => 3 },
+        { label => '4', value => 4 },
+        { label => '5', value => 5 },
+        { label => '6', value => 6 },
+    ];
+}
+
+1;
+
+# vim: set tabstop=4 expandtab:
diff --git a/lib/NGCP/Panel/Field/Contact.pm b/lib/NGCP/Panel/Field/Contact.pm
new file mode 100644
index 0000000000..5f555ae630
--- /dev/null
+++ b/lib/NGCP/Panel/Field/Contact.pm
@@ -0,0 +1,21 @@
+package NGCP::Panel::Field::Contact;
+use HTML::FormHandler::Moose;
+extends 'HTML::FormHandler::Field::Compound';
+
+has_field 'foo' => (
+    type => '+NGCP::Panel::Field::ContactSelect',
+    label => 'Contact',
+    required => 1,
+);
+
+has_field 'create' => (
+    type => 'Button',
+    label => 'or',
+    value => 'Create Contact',
+    element_attr => { onclick => 'window.location=\'/contact/create\'' },
+    element_class => [qw/btn btn-tertiary/],
+);
+
+1;
+
+# vim: set tabstop=4 expandtab:
diff --git a/lib/NGCP/Panel/Field/ContactSelect.pm b/lib/NGCP/Panel/Field/ContactSelect.pm
new file mode 100644
index 0000000000..0321f4baca
--- /dev/null
+++ b/lib/NGCP/Panel/Field/ContactSelect.pm
@@ -0,0 +1,21 @@
+package NGCP::Panel::Field::ContactSelect;
+use Moose;
+extends 'HTML::FormHandler::Field::Select';
+
+sub build_options {
+    my ($self) = @_;
+
+    return [ 
+        { label => 'Select...', value => '' },
+        { label => '1', value => 1 },
+        { label => '2', value => 2 },
+        { label => '3', value => 3 },
+        { label => '4', value => 4 },
+        { label => '5', value => 5 },
+        { label => '6', value => 6 },
+    ];
+}
+
+1;
+
+# vim: set tabstop=4 expandtab:
diff --git a/lib/NGCP/Panel/Field/Contract.pm b/lib/NGCP/Panel/Field/Contract.pm
index 8bcf3702d3..dbdbb30cdb 100644
--- a/lib/NGCP/Panel/Field/Contract.pm
+++ b/lib/NGCP/Panel/Field/Contract.pm
@@ -2,7 +2,7 @@ package NGCP::Panel::Field::Contract;
 use HTML::FormHandler::Moose;
 extends 'HTML::FormHandler::Field::Compound';
 
-has_field 'foo' => (
+has_field 'contract' => (
     type => '+NGCP::Panel::Field::ContractSelect',
     label => 'Contract',
     required => 1,
@@ -12,7 +12,7 @@ has_field 'create' => (
     type => 'Button',
     label => 'or',
     value => 'Create Contract',
-    element_attr => { onclick => 'window.location=\'/contract/create\'' },
+    #element_attr => { onclick => 'window.location=\'/contract/create\'' },
     element_class => [qw/btn btn-tertiary/],
 );
 
diff --git a/lib/NGCP/Panel/Form/Contract.pm b/lib/NGCP/Panel/Form/Contract.pm
new file mode 100644
index 0000000000..c8000ded10
--- /dev/null
+++ b/lib/NGCP/Panel/Form/Contract.pm
@@ -0,0 +1,50 @@
+package NGCP::Panel::Form::Contract;
+
+use HTML::FormHandler::Moose;
+extends 'HTML::FormHandler';
+use Moose::Util::TypeConstraints;
+
+use HTML::FormHandler::Widget::Block::Bootstrap;
+
+has '+widget_wrapper' => ( default => 'Bootstrap' );
+sub build_render_list {[qw/fields actions/]}
+sub build_form_element_class { [qw/form-horizontal/] }
+
+has_field 'contact' => (
+    type => '+NGCP::Panel::Field::Contact',
+    label => 'Contact',
+    not_nullable => 1,
+);
+
+has_field 'billing_profile' => (
+    type => '+NGCP::Panel::Field::BillingProfile',
+    not_nullable => 1,
+);
+
+
+has_field 'status' => (
+    type => 'Text',
+    required => 1,
+);
+
+has_field 'save' => (
+    type => 'Submit',
+    value => 'Save',
+    element_class => [qw/btn btn-primary/],
+    label => '',
+);
+
+has_block 'fields' => (
+    tag => 'div',
+    class => [qw/modal-body/],
+    render_list => [qw/contact billing_profile status/],
+);
+
+has_block 'actions' => (
+    tag => 'div',
+    class => [qw/modal-footer/],
+    render_list => [qw/save/],
+);
+
+1;
+# vim: set tabstop=4 expandtab:
diff --git a/share/templates/contract/list.tt b/share/templates/contract/list.tt
new file mode 100644
index 0000000000..3f88f9e30c
--- /dev/null
+++ b/share/templates/contract/list.tt
@@ -0,0 +1,15 @@
+[% META title = 'Contracts' -%]
+[%
+    helper.name = 'Contract';
+    helper.data = contracts;
+    helper.messages = messages;
+    helper.column_titles = [ '#', 'Contact #', 'Billing Profile #', 'Status' ];
+    helper.column_fields = [ 'id', 'contact_id', 'billing_profile_id', 'status' ];
+
+    helper.create_flag = create_flag;
+    helper.edit_object = contract;
+    helper.form_object = form;
+
+    PROCESS 'helpers/table_form.tt';
+-%]
+[% # vim: set tabstop=4 syntax=html expandtab: -%]
diff --git a/share/templates/helpers/table_form.tt b/share/templates/helpers/table_form.tt
index 9030e39342..f32bcbe050 100644
--- a/share/templates/helpers/table_form.tt
+++ b/share/templates/helpers/table_form.tt
@@ -52,6 +52,7 @@
             window.location.href="[% c.uri_for() %]";
         });
 
+        $('button').trigger('submit');
     });
 </script>
 [% END -%]