Verwaltung von Abteilungen auf Controller umgestellt
authorMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 16 Jun 2011 13:23:03 +0000 (15:23 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 16 Jun 2011 13:23:03 +0000 (15:23 +0200)
SL/AM.pm
SL/Controller/Department.pm [new file with mode: 0644]
SL/DB/Department.pm
SL/DB/Manager/Department.pm [new file with mode: 0644]
bin/mozilla/am.pl
locale/de/all
menu.ini
templates/webpages/department/form.html [new file with mode: 0644]
templates/webpages/department/list.html [new file with mode: 0644]

index 4f5b971..ff9fc46 100644 (file)
--- a/SL/AM.pm
+++ b/SL/AM.pm
@@ -250,7 +250,7 @@ sub save_account {
 
     # if charttype is heading make sure certain values are empty
     # specifically, if charttype is changed from an existing account, empty the
-    # fields unnecessary for headings, so that e.g. heading doesn't appear in 
+    # fields unnecessary for headings, so that e.g. heading doesn't appear in
     # drop-down menues due to still having a valid "link" entry
 
     if ( $form->{charttype} eq 'H' ) {
@@ -474,110 +474,6 @@ sub delete_account {
   return $rc;
 }
 
-sub departments {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  # connect to database
-  my $dbh = $form->dbconnect($myconfig);
-
-  my $query = qq|SELECT d.id, d.description, d.role
-                 FROM department d
-                 ORDER BY 2|;
-
-  my $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
-
-  $form->{ALL} = [];
-  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
-    push @{ $form->{ALL} }, $ref;
-  }
-
-  $sth->finish;
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub get_department {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  # connect to database
-  my $dbh = $form->dbconnect($myconfig);
-
-  my $query = qq|SELECT d.description, d.role
-                 FROM department d
-                 WHERE d.id = ?|;
-  my $sth = $dbh->prepare($query);
-  $sth->execute($form->{id}) || $form->dberror($query . " ($form->{id})");
-
-  my $ref = $sth->fetchrow_hashref("NAME_lc");
-
-  map { $form->{$_} = $ref->{$_} } keys %$ref;
-
-  $sth->finish;
-
-  # see if it is in use
-  $query = qq|SELECT count(*) FROM dpt_trans d
-              WHERE d.department_id = ?|;
-  ($form->{orphaned}) = selectrow_query($form, $dbh, $query, $form->{id});
-
-  $form->{orphaned} = !$form->{orphaned};
-  $sth->finish;
-
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub save_department {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-  my ($query);
-
-  # connect to database
-  my $dbh = $form->dbconnect($myconfig);
-
-  my @values = ($form->{description}, $form->{role});
-  if ($form->{id}) {
-    $query = qq|UPDATE department SET
-                description = ?, role = ?
-                WHERE id = ?|;
-    push(@values, $form->{id});
-  } else {
-    $query = qq|INSERT INTO department
-                (description, role)
-                VALUES (?, ?)|;
-  }
-  do_query($form, $dbh, $query, @values);
-
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub delete_department {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-  my ($query);
-
-  # connect to database
-  my $dbh = $form->dbconnect($myconfig);
-
-  $query = qq|DELETE FROM department
-              WHERE id = ?|;
-  do_query($form, $dbh, $query, $form->{id});
-
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-}
-
 sub lead {
   $main::lxdebug->enter_sub();
 
diff --git a/SL/Controller/Department.pm b/SL/Controller/Department.pm
new file mode 100644 (file)
index 0000000..d1ba942
--- /dev/null
@@ -0,0 +1,104 @@
+package SL::Controller::Department;
+
+use strict;
+
+use parent qw(SL::Controller::Base);
+
+use SL::DB::Department;
+use SL::Helper::Flash;
+
+use Rose::Object::MakeMethods::Generic
+(
+ scalar => [ qw(department) ],
+);
+
+__PACKAGE__->run_before('check_auth');
+__PACKAGE__->run_before('load_department', only => [ qw(edit update destroy) ]);
+
+#
+# actions
+#
+
+sub action_list {
+  my ($self) = @_;
+
+  $self->render('department/list',
+                title       => $::locale->text('Departments'),
+                DEPARTMENTS => SL::DB::Manager::Department->get_all_sorted);
+}
+
+sub action_new {
+  my ($self) = @_;
+
+  $self->{department} = SL::DB::Department->new(role => 'P');
+  $self->render('department/form', title => $::locale->text('Create a new department'));
+}
+
+sub action_edit {
+  my ($self) = @_;
+  $self->render('department/form', title => $::locale->text('Edit department'));
+}
+
+sub action_create {
+  my ($self) = @_;
+
+  $self->{department} = SL::DB::Department->new;
+  $self->create_or_update;
+}
+
+sub action_update {
+  my ($self) = @_;
+  $self->create_or_update;
+}
+
+sub action_destroy {
+  my ($self) = @_;
+
+  if (eval { $self->{department}->delete; 1; }) {
+    flash_later('info',  $::locale->text('The department has been deleted.'));
+  } else {
+    flash_later('error', $::locale->text('The department is in use and cannot be deleted.'));
+  }
+
+  $self->redirect_to(action => 'list');
+}
+
+#
+# filters
+#
+
+sub check_auth {
+  $::auth->assert('config');
+}
+
+#
+# helpers
+#
+
+sub create_or_update {
+  my $self   = shift;
+  my $is_new = !$self->{department}->id;
+  my $params = delete($::form->{department}) || { };
+
+  $self->{department}->assign_attributes(%{ $params });
+
+  my @errors = $self->{department}->validate;
+
+  if (@errors) {
+    flash('error', @errors);
+    $self->render('department/form', title => $is_new ? $::locale->text('Create a new department') : $::locale->text('Edit department'));
+    return;
+  }
+
+  $self->{department}->save;
+
+  flash_later('info', $is_new ? $::locale->text('The department has been created.') : $::locale->text('The department has been saved.'));
+  $self->redirect_to(action => 'list');
+}
+
+sub load_department {
+  my ($self) = @_;
+  $self->{department} = SL::DB::Department->new(id => $::form->{id})->load;
+}
+
+1;
index ea62791..133886c 100644 (file)
@@ -1,13 +1,27 @@
-# This file has been auto-generated only because it didn't exist.
-# Feel free to modify it at will; it will not be overwritten automatically.
-
 package SL::DB::Department;
 
 use strict;
 
 use SL::DB::MetaSetup::Department;
+use SL::DB::Manager::Department;
+
+use SL::DB::DptTrans;
+
+sub validate {
+  my ($self) = @_;
+
+  my @errors;
+  push @errors, $::locale->text('The description is missing.') if !$self->description;
+
+  return @errors;
+}
+
+sub is_used {
+  my ($self) = @_;
 
-# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
-__PACKAGE__->meta->make_manager_class;
+  return undef if !$self->id;
+  my $is_used = SL::DB::Manager::DptTrans->find_by(department_id => $self->id);
+  return !!$is_used;
+}
 
 1;
diff --git a/SL/DB/Manager/Department.pm b/SL/DB/Manager/Department.pm
new file mode 100644 (file)
index 0000000..c237530
--- /dev/null
@@ -0,0 +1,21 @@
+package SL::DB::Manager::Department;
+
+use strict;
+
+use SL::DB::Helper::Manager;
+use base qw(SL::DB::Helper::Manager);
+
+use SL::DB::Helper::Sorted;
+
+sub object_class { 'SL::DB::Department' }
+
+__PACKAGE__->make_manager_methods;
+
+sub _sort_spec {
+  return ( default => [ 'description', 1 ],
+           columns => { SIMPLE => 'ALL',
+                        map { ( $_ => "lower(department.$_)" ) } qw(description)
+                      });
+}
+
+1;
index c6bb8e4..0030eb5 100644 (file)
@@ -620,242 +620,6 @@ sub delete_account {
   $main::lxdebug->leave_sub();
 }
 
-sub add_department {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-
-  $main::auth->assert('config');
-
-  $form->{title} = "Add";
-  $form->{role}  = "P";
-
-  $form->{callback} = "am.pl?action=add_department" unless $form->{callback};
-
-  &department_header;
-  &form_footer;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub edit_department {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-
-  $main::auth->assert('config');
-
-  $form->{title} = "Edit";
-
-  AM->get_department(\%myconfig, \%$form);
-
-  &department_header;
-  &form_footer;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub list_department {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-  my $locale   = $main::locale;
-
-  $main::auth->assert('config');
-
-  AM->departments(\%myconfig, \%$form);
-
-  $form->{callback} = "am.pl?action=list_department";
-
-  my $callback = $form->escape($form->{callback});
-
-  $form->{title} = $locale->text('Departments');
-
-  my @column_index = qw(description cost profit);
-  my %column_header;
-  $column_header{description} =
-      qq|<th class=listheading width=90%>|
-    . $locale->text('Description')
-    . qq|</th>|;
-  $column_header{cost} =
-      qq|<th class=listheading nowrap>|
-    . $locale->text('Cost Center')
-    . qq|</th>|;
-  $column_header{profit} =
-      qq|<th class=listheading nowrap>|
-    . $locale->text('Profit Center')
-    . qq|</th>|;
-
-  $form->header;
-
-  print qq|
-<body>
-
-<table width=100%>
-  <tr>
-    <th class=listtop>$form->{title}</th>
-  </tr>
-  <tr height="5"></tr>
-  <tr>
-    <td>
-      <table width=100%>
-        <tr class=listheading>
-|;
-
-  map { print "$column_header{$_}\n" } @column_index;
-
-  print qq|
-        </tr>
-|;
-
-  my ($i, %column_data);
-  foreach my $ref (@{ $form->{ALL} }) {
-
-    $i++;
-    $i %= 2;
-
-    print qq|
-        <tr valign=top class=listrow$i>
-|;
-
-    my $costcenter   = ($ref->{role} eq "C") ? "X" : "";
-    my $profitcenter = ($ref->{role} eq "P") ? "X" : "";
-
-    $column_data{description} =
-      qq|<td><a href="am.pl?action=edit_department&id=$ref->{id}&callback=$callback">$ref->{description}</td>|;
-    $column_data{cost}   = qq|<td align=center>$costcenter</td>|;
-    $column_data{profit} = qq|<td align=center>$profitcenter</td>|;
-
-    map { print "$column_data{$_}\n" } @column_index;
-
-    print qq|
-        </tr>
-|;
-  }
-
-  print qq|
-      </table>
-    </td>
-  </tr>
-  <tr>
-  <td><hr size=3 noshade></td>
-  </tr>
-</table>
-
-<br>
-<form method=post action=am.pl>
-
-<input name=callback type=hidden value="$form->{callback}">
-
-<input type=hidden name=type value=department>
-
-<input class=submit type=submit name=action value="|
-    . $locale->text('Add') . qq|">
-
-  </form>
-
-  </body>
-  </html>
-|;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub department_header {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
-
-  $main::auth->assert('config');
-
-  $form->{title} = $locale->text("$form->{title} Department");
-
-  # $locale->text('Add Department')
-  # $locale->text('Edit Department')
-
-  $form->{description} =~ s/\"/&quot;/g;
-
-  my ($rows, $description);
-  if (($rows = $form->numtextrows($form->{description}, 60)) > 1) {
-    $description =
-      qq|<textarea name="description" rows=$rows cols=60 wrap=soft>$form->{description}</textarea>|;
-  } else {
-    $description =
-      qq|<input name=description size=60 value="$form->{description}">|;
-  }
-
-  my $costcenter   = "checked" if $form->{role} eq "C";
-  my $profitcenter = "checked" if $form->{role} eq "P";
-
-  $form->header;
-
-  print qq|
-<body>
-
-<form method=post action=am.pl>
-
-<input type=hidden name=id value=$form->{id}>
-<input type=hidden name=type value=department>
-
-<table width=100%>
-  <tr>
-    <th class=listtop colspan=2>$form->{title}</th>
-  </tr>
-  <tr height="5"></tr>
-  <tr>
-    <th align=right>| . $locale->text('Description') . qq|</th>
-    <td>$description</td>
-  </tr>
-  <tr>
-    <td></td>
-    <td><input type=radio style=radio name=role value="C" $costcenter> |
-    . $locale->text('Cost Center') . qq|
-        <input type=radio style=radio name=role value="P" $profitcenter> |
-    . $locale->text('Profit Center') . qq|
-    </td>
-  <tr>
-    <td colspan=2><hr size=3 noshade></td>
-  </tr>
-</table>
-|;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub save_department {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-  my $locale   = $main::locale;
-
-  $main::auth->assert('config');
-
-  $form->isblank("description", $locale->text('Description missing!'));
-  AM->save_department(\%myconfig, \%$form);
-  $form->redirect($locale->text('Department saved!'));
-
-  $main::lxdebug->leave_sub();
-}
-
-sub delete_department {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-  my $locale   = $main::locale;
-
-  $main::auth->assert('config');
-
-  AM->delete_department(\%myconfig, \%$form);
-  $form->redirect($locale->text('Department deleted!'));
-
-  $main::lxdebug->leave_sub();
-}
-
 sub add_lead {
   $main::lxdebug->enter_sub();
 
index 8659da8..b89e04c 100644 (file)
@@ -196,6 +196,7 @@ $self->{texts} = {
   'Are you sure you want to delete Order Number' => 'Soll der Auftrag mit folgender Nummer wirklich gelöscht werden:',
   'Are you sure you want to delete Quotation Number' => 'Sind Sie sicher, dass Angebotnummer gelöscht werden soll?',
   'Are you sure you want to delete Transaction' => 'Buchung wirklich löschen?',
+  'Are you sure you want to delete this department?' => 'Sind Sie sicher, dass Sie diese Abteilung löschen wollen?',
   'Are you sure you want to delete this payment term?' => 'Wollen Sie diese Zahlungsbedingungen wirklich löschen?',
   'Are you sure you want to remove the marked entries from the queue?' => 'Sind Sie sicher, dass die markierten Einträge von der Warteschlange gelöscht werden sollen?',
   'Are you sure you want to update the prices' => 'Sind Sie sicher, dass Sie die Preise aktualisieren wollen?',
@@ -430,6 +431,7 @@ $self->{texts} = {
   'Create Chart of Accounts'    => 'Zu verwendender Kontenplan',
   'Create Dataset'              => 'Neue Datenbank anlegen',
   'Create Date'                 => 'Erstelldatum',
+  'Create a new department'     => 'Eine neue Abteilung erfassen',
   'Create a new payment term'   => 'Neue Zahlungsbedingungen anlegen',
   'Create a standard group'     => 'Eine Standard-Benutzergruppe anlegen',
   'Create and edit RFQs'        => 'Lieferantenanfragen erfassen und bearbeiten',
@@ -450,6 +452,7 @@ $self->{texts} = {
   'Create bank transfer via SEPA XML' => 'Überweisung via SEPA XML erzeugen',
   'Create invoice?'             => 'Rechnung erstellen?',
   'Create new'                  => 'Neu erfassen',
+  'Create new department'       => 'Neue Abteilung erfassen',
   'Create new payment term'     => 'Neue Zahlungsbedingung anlegen',
   'Create tables'               => 'Tabellen anlegen',
   'Created by'                  => 'Erstellt von',
@@ -570,8 +573,6 @@ $self->{texts} = {
   'Department 1'                => 'Abteilung (1)',
   'Department 2'                => 'Abteilung (2)',
   'Department Id'               => 'Reservierung',
-  'Department deleted!'         => 'Abteilung gelöscht.',
-  'Department saved!'           => 'Abteilung gespeichert.',
   'Departments'                 => 'Abteilungen',
   'Dependency loop detected:'   => 'Schleife in den Abh&auml;ngigkeiten entdeckt:',
   'Deposit'                     => 'Gutschrift',
@@ -672,7 +673,6 @@ $self->{texts} = {
   'Edit Business'               => 'Kunden-/Lieferantentyp bearbeiten',
   'Edit Credit Note'            => 'Gutschrift bearbeiten',
   'Edit Customer'               => 'Kunde editieren',
-  'Edit Department'             => 'Abteilung bearbeiten',
   'Edit Dunning'                => 'Mahnungen konfigurieren',
   'Edit Dunning Process Config' => 'Mahnwesenkonfiguration bearbeiten',
   'Edit Follow-Up'              => 'Wiedervorlage bearbeiten',
@@ -705,6 +705,7 @@ $self->{texts} = {
   'Edit and delete a group'     => 'Gruppen bearbeiten und l&ouml;schen',
   'Edit bank account'           => 'Bankkonto bearbeiten',
   'Edit custom variable'        => 'Benutzerdefinierte Variable bearbeiten',
+  'Edit department'             => 'Abteilung bearbeiten',
   'Edit file'                   => 'Datei bearbeiten',
   'Edit greetings'              => 'Anreden bearbeiten',
   'Edit group '                 => 'Gruppe bearbeiten',
@@ -1161,6 +1162,7 @@ $self->{texts} = {
   'No data was found.'          => 'Es wurden keine Daten gefunden.',
   'No databases have been found on this server.' => 'Auf diesem Server wurden keine Datenbanken gefunden.',
   'No datasets have been selected.' => 'Es wurden keine Datenbanken ausgew&auml;hlt.',
+  'No department has been created yet.' => 'Es wurde noch keine Abteilung erfasst.',
   'No dunnings have been selected for printing.' => 'Es wurden keine Mahnungen zum Drucken ausgew&auml;hlt.',
   'No entries were found which had no unit assigned to them.' => 'Es wurden keine Eintr&auml;ge gefunden, denen keine Einheit zugeordnet war.',
   'No file has been uploaded yet.' => 'Es wurde noch keine Datei hochgeladen.',
@@ -1746,6 +1748,10 @@ $self->{texts} = {
   'The deductible amount'       => 'Der abziehbare Skontobetrag',
   'The default value depends on the variable type:' => 'Die Bedeutung des Standardwertes h&auml;ngt vom Variablentypen ab:',
   'The delivery order has not been marked as delivered. The warehouse contents have not changed.' => 'Der Lieferschein wurde nicht als geliefert markiert. Der Lagerinhalt wurde nicht verändert.',
+  'The department has been created.' => 'Die Abteilung wurde angelegt.',
+  'The department has been deleted.' => 'Die Abteiltung wurde gelöscht.',
+  'The department has been saved.' => 'Die abteilung wurde gespeichert.',
+  'The department is in use and cannot be deleted.' => 'Die Abteilung wird benutzt und kann nicht gelöscht werden.',
   'The description is missing.' => 'Die Beschreibung fehlt.',
   'The description is shown on the form. Chose something short and descriptive.' => 'Die Beschreibung wird in der jeweiligen Maske angezeigt. Sie sollte kurz und pr&auml;gnant sein.',
   'The directory "%s" could not be created:\n%s' => 'Das Verzeichnis "%s" konnte nicht erstellt werden:\n%s',
index de5ca68..46292a0 100644 (file)
--- a/menu.ini
+++ b/menu.ini
@@ -633,12 +633,12 @@ target=acc_menu
 submenu=1
 
 [System--Departments--Add Department]
-module=am.pl
-action=add_department
+module=controller.pl
+action=Department/new
 
 [System--Departments--List Departments]
-module=am.pl
-action=list_department
+module=controller.pl
+action=Department/list
 
 [System--Type of Business]
 module=menu.pl
diff --git a/templates/webpages/department/form.html b/templates/webpages/department/form.html
new file mode 100644 (file)
index 0000000..f95836d
--- /dev/null
@@ -0,0 +1,42 @@
+[% USE HTML %][% USE T8 %][% USE L %][% USE LxERP %]
+[% SET is_used = SELF.department.is_used %]
+<body>
+
+ <form method="post" action="controller.pl">
+  <div class="listtop">[% FORM.title %]</div>
+
+[%- INCLUDE 'common/flash.html' %]
+
+  <table>
+   <tr>
+    <td>[%- 'Description' | $T8 %]</td>
+    <td>[% L.input_tag("department.description", SELF.department.description) %]</td>
+   </tr>
+
+   <tr>
+    <td valign="top">[%- 'Type' | $T8 %]</td>
+    <td valign="top">
+     [%- IF is_used %]
+      [% L.hidden_tag("role", SELF.department.role) %]
+      [%- IF SELF.department.role == "C" %][%- LxERP.t8('Cost Center') %][%- ELSE %][%- LxERP.t8('Profit Center') %][%- END %]
+     [%- ELSE %]
+      [% L.radio_button_tag("department.role", "value", "C", "label", LxERP.t8("Cost Center"), "checked", SELF.department.role == "C") %]
+      <br>
+      [% L.radio_button_tag("department.role", "value", "P", "label", LxERP.t8("Profit Center"), "checked", SELF.department.role == "P") %]
+     [%- END %]
+    </td>
+   </tr>
+  </table>
+
+  <p>
+   [% L.hidden_tag("id", SELF.department.id) %]
+   [% L.hidden_tag("action", "Department/dispatch") %]
+   <input type="submit" class="submit" name="action_[% IF SELF.department.id %]update[% ELSE %]create[% END %]" value="[% 'Save' | $T8 %]">
+   [%- IF SELF.department.id && !is_used %]
+    [% L.submit_tag("action_destroy", LxERP.t8("Delete"), "confirm", LxERP.t8("Are you sure you want to delete this department?")) %]
+   [%- END %]
+   <a href="[% SELF.url_for(action => 'list') %]">[%- 'Abort' | $T8 %]</a>
+  </p>
+ </form>
+</body>
+</html>
diff --git a/templates/webpages/department/list.html b/templates/webpages/department/list.html
new file mode 100644 (file)
index 0000000..059aa33
--- /dev/null
@@ -0,0 +1,47 @@
+[% USE HTML %][% USE T8 %][% USE L %][% USE LxERP %]
+
+<body>
+ <div class="listtop">[% FORM.title %]</div>
+
+[%- INCLUDE 'common/flash.html' %]
+
+ <form method="post" action="controller.pl">
+  [% IF !DEPARTMENTS.size %]
+   <p>
+    [%- 'No department has been created yet.' | $T8 %]
+   </p>
+
+  [%- ELSE %]
+   <table id="department_list" width="100%">
+    <thead>
+    <tr class="listheading">
+     <th width="100%">[%- 'Description' | $T8 %]</th>
+     <th>[%- 'Cost Center' | $T8 %]</th>
+     <th>[%- 'Profit Center' | $T8 %]</th>
+    </tr>
+    </thead>
+
+    <tbody>
+    [%- FOREACH department = DEPARTMENTS %]
+    <tr class="listrow[% loop.count % 2 %]" id="department_id_[% department.id %]">
+     <td>
+      <a href="[% SELF.url_for(action => 'edit', id => department.id) %]">
+       [%- HTML.escape(department.description) %]
+      </a>
+     </td>
+     <td align="center">[%- IF department.role == 'C' %]X[%- END %]</td>
+     <td align="center">[%- IF department.role == 'P' %]X[%- END %]</td>
+    </tr>
+    [%- END %]
+    </tbody>
+   </table>
+  [%- END %]
+
+  <hr size="3" noshade>
+
+  <p>
+   <a href="[% SELF.url_for(action => 'new') %]">[%- 'Create new department' | $T8 %]</a>
+  </p>
+ </form>
+</body>
+</html>