+           ->render;
+}
+
+sub action_update {
+  my ($self)   = @_;
+
+  my $order    = $self->rs_order->order;
+  my $sections = $self->requirement_spec->sections_sorted;
+
+  if (!$::auth->assert($order->quotation ? 'sales_quotation_edit' : 'sales_order_edit', 1)) {
+    return $self->js->flash('error', t8("You do not have the permissions to access this function."))->render;
+  }
+
+  my (@orderitems, %sections_seen);
+  foreach my $item (@{ $order->items_sorted }) {
+    my $section = first { my $num = $_->fb_number; $item->description =~ m{\b\Q${num}\E\b} && !$sections_seen{ $_->id } } @{ $sections };
+
+    $sections_seen{ $section->id } = 1 if $section;
+
+    push @orderitems, { item => $item, section => $section };
+  }
+
+  my $html = $self->render(
+    'requirement_spec_order/update', { output => 0 },
+    orderitems         => \@orderitems,
+    sections           => $sections,
+    make_section_title => sub { $_[0]->fb_number . ' ' . $_[0]->title },
+  );
+
+  $self->js->hide(LIST_SELECTOR())
+           ->after(LIST_SELECTOR(), $html)
+           ->render;
+}
+
+sub action_do_update {
+  my ($self)         = @_;
+
+  my $order          = $self->rs_order->order;
+  my @new_orderitems =  $self->do_update_sections;
+  push @new_orderitems, $self->do_update_additional_parts;
+
+  $order->add_orderitems(\@new_orderitems) if @new_orderitems;
+
+  $order->calculate_prices_and_taxes;
+
+  $order->db->with_transaction(sub {
+    $order->save;
+    $self->requirement_spec->link_to_record($order);
+  }) or do {
+    $::lxdebug->message(LXDebug::WARN(), "Error updating the order object: $@");
+  };
+
+  $self->init_requirement_spec;
+
+  my $html = $self->render('requirement_spec_order/list', { output => 0 });
+  $self->js->replaceWith(LIST_SELECTOR(), $html)
+           ->remove(FORMS_SELECTOR())
+           ->flash('info', $::form->{quotation} ? t8('Sales quotation #1 has been updated.', $order->quonumber) : t8('Sales order #1 has been updated.', $order->ordnumber))
+           ->render;