+ $main::lxdebug->leave_sub();
+}
+
+sub _update_custom_variables {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+
+ $form->{CVAR_CONFIGS} = { } unless ref $form->{CVAR_CONFIGS} eq 'HASH';
+ $form->{CVAR_CONFIGS}->{IC} ||= CVar->get_configs(module => 'IC');
+
+ $main::lxdebug->leave_sub();
+}
+
+sub _render_custom_variables_inputs {
+ $main::lxdebug->enter_sub(2);
+
+ my $form = $main::form;
+
+ my %params = @_;
+
+ if (!$form->{CVAR_CONFIGS}->{IC}) {
+ $main::lxdebug->leave_sub();
+ return;
+ }
+
+ my $valid = CVar->custom_variables_validity_by_trans_id(trans_id => $params{part_id});
+
+ # get partsgroup_id from part
+ my $partsgroup_id;
+ if ($params{part_id}) {
+ $partsgroup_id = SL::DB::Part->new(id => $params{part_id})->load->partsgroup_id;
+ }
+
+ my $num_visible_cvars = 0;
+ foreach my $cvar (@{ $form->{CVAR_CONFIGS}->{IC} }) {
+ $cvar->{valid} = $params{part_id} && $valid->($cvar->{id});
+
+ # set partsgroup filter
+ my $partsgroup_filtered = 0;
+ if ($cvar->{flag_partsgroup_filter}) {
+ if (!$partsgroup_id || (!grep {$partsgroup_id == $_} @{ $cvar->{partsgroups} })) {
+ $partsgroup_filtered = 1;
+ }
+ }
+
+ my $hide_non_editable = 1;
+
+ my $show = 0;
+ my $description = '';
+ if (( ($cvar->{flag_editable} || !$hide_non_editable) && $cvar->{valid}) && !$partsgroup_filtered) {
+ $num_visible_cvars++;
+ $description = $cvar->{description} . ' ';
+ $show = 1;
+ }
+
+ my $form_key = "ic_cvar_" . $cvar->{name} . "_$params{row}";
+
+ push @{ $params{ROW2} }, {
+ line_break => $show && !(($num_visible_cvars - 1) % ($::myconfig{form_cvars_nr_cols}*1 || 3)),
+ description => $description,
+ cvar => 1,
+ render_options => {
+ hide_non_editable => $hide_non_editable,
+ var => $cvar,
+ name_prefix => 'ic_',
+ name_postfix => "_$params{row}",
+ valid => $cvar->{valid},
+ value => CVar->parse($::form->{$form_key}, $cvar),
+ partsgroup_filtered => $partsgroup_filtered,
+ }
+ };
+ }
+
+ $main::lxdebug->leave_sub(2);
+}
+
+sub _remove_billed_or_delivered_rows {
+ my (%params) = @_;
+
+ croak "Missing parameter 'quantities'" if !$params{quantities};
+
+ my @fields = map { s/_1$//; $_ } grep { m/_1$/ } keys %{ $::form };
+ my @new_rows;
+
+ my $make_key = sub {
+ my ($row) = @_;
+ return $::form->{"id_${row}"} unless $::form->{"serialnumber_${row}"};
+ my $key = $::form->{"id_${row}"} . ':' . $::form->{"serialnumber_${row}"};
+ return exists $params{quantities}->{$key} ? $key : $::form->{"id_${row}"};
+ };
+
+ my $removed_rows = 0;
+ my $row = 0;
+ while ($row < $::form->{rowcount}) {
+ $row++;
+ next unless $::form->{"id_$row"};
+
+ my $parts_id = $::form->{"id_$row"};
+ my $base_qty = $::form->parse_amount(\%::myconfig, $::form->{"qty_$row"}) * SL::DB::Manager::Unit->find_by(name => $::form->{"unit_$row"})->base_factor;
+
+ my $key = $make_key->($row);
+ my $sub_qty = min($base_qty, $params{quantities}->{$key});
+ $params{quantities}->{$key} -= $sub_qty;
+
+ if (!$sub_qty || ($sub_qty != $base_qty)) {
+ $::form->{"qty_${row}"} = $::form->format_amount(\%::myconfig, ($base_qty - $sub_qty) / SL::DB::Manager::Unit->find_by(name => $::form->{"unit_$row"})->base_factor);
+ push @new_rows, { map { $_ => $::form->{"${_}_${row}"} } @fields };
+
+ } else {
+ $removed_rows++;
+ }
+ }
+
+ $::form->redo_rows(\@fields, \@new_rows, scalar(@new_rows), $::form->{rowcount});
+ $::form->{rowcount} -= $removed_rows;