self.server.move_booking(id_, up=toks[2] == 'up')
                 self.redirect(Path(self.pagename).joinpath(f'#{id_}'))
                 return
+            for key in self.postvars.keys_prefixed('copy_'):
+                id_ = int(key.split('_')[1])
+                self.server.copy_booking(id_)
+                self.redirect(Path('/bookings').joinpath(f'{id_}'))
+                return
         elif self.pagename == 'edit_structured':
             if self.postvars.first('apply'):
                 line_keys = self.postvars.keys_prefixed('line_')
             DatLine(line)
             for line in self._path_dat.read_text(encoding='utf8').splitlines()]
         self.last_save_hash = self._hash_dat_lines()
-        self.load_bookings()
+        self._load_bookings()
 
     def _hash_dat_lines(self) -> int:
         return hash(tuple(dl.raw for dl in self.dat_lines))
         """If .dat_lines different to those of last .load()."""
         return self._hash_dat_lines() != self.last_save_hash
 
-    def load_bookings(self) -> None:
-        """Read .dat_lines into Bookings / full ledger."""
+    def _load_bookings(self) -> None:
         self.bookings = []
         booking_lines: list[DatLine] = []
         last_date = ''
         self.dat_lines = (self.dat_lines[:start_idx]
                           + new_lines
                           + self.dat_lines[end_idx+1:])
-        self.load_bookings()
+        self._load_bookings()
 
     def move_booking(self, id_: int, up: bool) -> None:
         """Move Booking of id_ one step up or downwards"""
         self._replace_from_to(*self._margin_indices(self.bookings[id_]),
                               new_dat_lines)
 
+    def copy_booking(self, id_: int) -> None:
+        """Append copy of Booking of id_ to end of ledger."""
+        self.dat_lines += [DatLine('')] + [DatLine(dat_line.raw) for dat_line
+                                           in self.bookings[id_].dat_lines]
+        self._load_bookings()
+
     @property
     def dat_lines_sans_empty(self) -> list[DatLine]:
         """Return only those .data_lines with .code or .comment."""
 
     <td id="{{dat_line.booking_id}}"><a href="#{{dat_line.booking_id}}">[#]</a><input type="submit" name="move_{{dat_line.booking_id}}_up" value="^"{% if dat_line.booking_id == 0 %} disabled{% endif %}/></td>
   {% elif dat_line.booking_line.idx == 1 %}
     <td><a href="/balance?up_incl={{dat_line.booking_id}}">[b]</a><input type="submit" name="move_{{dat_line.booking_id}}_down" value="v"{% if dat_line.booking_id == max_id %} disabled{% endif %}/></td>
+  {% elif dat_line.booking_line.idx == 2 %}
+    <td><input type="submit" name="copy_{{dat_line.booking_id}}" value="c" /></td>
   {% else %}
     <td></td>
   {% endif %}