From: Moritz Bunkus Date: Fri, 15 Sep 2017 12:35:16 +0000 (+0200) Subject: _make_record(_item): Zahlenattribute nicht mit leeren Strings setzen X-Git-Tag: release-3.5.6.1~245^2~40 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=2ae70bd488265cab4a7cef8243b3660f7d35e83e;p=kivitendo-erp.git _make_record(_item): Zahlenattribute nicht mit leeren Strings setzen Wir übergeben diverse Zahlenfelder als hidden inputs, ohne dass wir prüfen, ob die überhaupt gesetzt sind: 1. Im Aufruf 1 ist z.B. `$::form->{customer_id} = undef`, oder es gibt sogar nicht mal ein `$::form->{customer_id}`. 2. Dies wird ohne Prüfung auf den tatsächlichen Wert als Hidden ausgegeben, und endet damit als ``. 3. In Aufruf 2 kommt das dann als `$::form->{customer_id} = ''` an, also als leerer String, egal, ob der Wert vorher `undef`, ein leerer String war oder gar nicht existiert hat. Wenn man nun, wie `_make_record_item`, über alle Schlüssel aus `$::form` iteriert, und die korrespondierenden Attributs-Setter-Funktionen einer RDBO-Instanz mit ihnen aufruft, so werden somit Zahlen-Setter-Funktionen mit leeren Strings aufgerufen. Das sorgt dafür, dass später bei einem Aufruf von `$invoice->customer` versucht wird, ein Customer-Objekt aus der DB zu laden (da ja durch den Aufruf von `…->customer_id(…)`, also das Setzen des Relationship-Attributs, signalisiert wurde, dass die Relationship aktiv ist). Allerdings ist der Wert des Primärschlüsselattributes nun der leere String, also im Perl-Sinne `false`. Das wiederum wertet Rose als Versuch, ein Objekt ohne Angabe eines Primärschlüsselattributs zu laden, was wiederum zu einer Fehlermeldung führt. Kurz: Zahlenattribute aus RDBO-Instanzen dürfen gar nicht erst auf leere Strings gesetzt werden. Sie dürfen nur gesetzt werden, wenn sie auch tatsächliche Zahlenwerte enthalten sollen. Fix #57. --- diff --git a/bin/mozilla/io.pl b/bin/mozilla/io.pl index eff922e18..9fe058a91 100644 --- a/bin/mozilla/io.pl +++ b/bin/mozilla/io.pl @@ -1896,9 +1896,11 @@ sub _make_record_item { if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) { $obj->${\"$method\_as_date"}($value); } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) { - $obj->${\"$method\_as_number"}($value); + $obj->${\"$method\_as_number"}(($value // '') eq '' ? undef : $value); } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) { $obj->$method(!!$value); + } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Big)?(?:Int(?:eger)?|Serial)$/) { + $obj->$method(($value // '') eq '' ? undef : $value * 1); } else { $obj->$method($value); } @@ -1947,9 +1949,11 @@ sub _make_record { if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) { $obj->${\"$method\_as_date"}($::form->{$method}); } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) { - $obj->${\"$method\_as_number"}($::form->{$method}); + $obj->${\"$method\_as_number"}(($::form->{$method} // '') eq '' ? undef : $::form->{$method}); } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) { $obj->$method(!!$::form->{$method}); + } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Big)?(?:Int(?:eger)?|Serial)$/) { + $obj->$method(($::form->{$method} // '') eq '' ? undef : $::form->{$method} * 1); } else { $obj->$method($::form->{$method}); }