+sub _calculate_part_item {
+ my ($self, $data, $part, $total_qty, $base_factor) = @_;
+
+ _dbg("cpsi tq " . $total_qty);
+
+ return 0 if $::instance_conf->get_inventory_system eq 'periodic' || !$data->{is_invoice} || !$total_qty;
+
+ my ($entry);
+ $base_factor ||= 1;
+ my $remaining_qty = $total_qty;
+ my $expense_income_chart = $part->get_chart(type => $data->{is_sales} ? 'expense' : 'income', taxzone => $self->taxzone_id);
+ my $inventory_chart = $part->get_chart(type => 'inventory', taxzone => $self->taxzone_id);
+
+ my $iterator = SL::DB::Manager::InvoiceItem->get_all_iterator(query => [ and => [ parts_id => $part->id,
+ \'(base_qty + allocated) < 0' ] ]);
+
+ while (($remaining_qty > 0) && ($entry = $iterator->next)) {
+ my $qty = min($remaining_qty, $entry->base_qty * -1 - $entry->allocated - $data->{allocated}->{ $entry->id });
+ _dbg("qty $qty");
+
+ next unless $qty;
+
+ my $linetotal = _round(($entry->sellprice * $qty) / $base_factor, 2);
+
+ $data->{amounts_cogs}->{ $expense_income_chart->id } -= $linetotal;
+ $data->{amounts_cogs}->{ $inventory_chart->id } += $linetotal;
+
+ $data->{allocated}->{ $entry->id } ||= 0;
+ $data->{allocated}->{ $entry->id } += $qty;
+ $remaining_qty -= $qty;
+ }
+
+ $iterator->finish;
+
+ return $remaining_qty - $total_qty;
+}
+
+sub _round {