sub _create_sunit {
my ($editor, $sunit) = @_;
+ # The unique barcode constraint does not span asset.copy and serial.unit.
+ # ensure the barcode on the new unit does not collide with an existing
+ # asset.copy barcode.
+ my $existing = $editor->search_asset_copy(
+ {deleted => 'f', barcode => $sunit->barcode})->[0];
+
+ if (!$existing) {
+ # The DB will prevent duplicate serial.unit barcodes, but for
+ # consistency (and a more specific error message for the
+ # user), prevent creation attempts on serial unit barcode
+ # collisions as well.
+ $existing = $editor->search_serial_unit(
+ {deleted => 'f', barcode => $sunit->barcode})->[0];
+ }
+
+ if ($existing) {
+ $editor->rollback;
+ return new OpenILS::Event(
+ 'SERIAL_UNIT_BARCODE_COLLISION', note =>
+ 'Serial unit barcode collides with existing unit/copy barcode',
+ payload => {barcode => $sunit->barcode}
+ );
+ }
+
$logger->info("sunit-alter: new Unit ".OpenSRF::Utils::JSON->perl2JSON($sunit));
- return $editor->event unless $editor->create_serial_unit($sunit);
+ return $editor->die_event unless $editor->create_serial_unit($sunit);
return 0;
}
$user_unit->editor($user_id);
$user_unit->creator($user_id);
- return $e->die_event unless $e->create_serial_unit($user_unit);
+ $evt = _create_sunit($e, $user_unit);
+ return $evt if $evt;
# save reference to new unit
$item->unit($e->data->id);
batch_receive.missing_units=You have not provided barcodes and call numbers for all of the selected items. Choose OK to receive those items anyway, or choose Cancel to supply the missing information.
batch_receive.missing_cn=You cannot assign a barcode without selecting a call number. Please correct the non-conforming units.
batch_receive.print_routing_list_users=Print Routing List
+batch_receive.unit_barcode_collision=Serial unit barcode '%1$s' collides with an existing barcode.
pattern_wizard.enumeration.a=First level
pattern_wizard.enumeration.b=Second level
pattern_wizard.enumeration.c=Third level
"oncomplete": function(r) {
try {
var streams_for_printing = [];
- while (item_id = openils.Util.readResponse(r)) {
+
+ // first check for problems encountered during
+ // receive and exit early if any are found.
+ var item_ids = [];
+ while (item_id = openils.Util.readResponse(r, true)) {
+ if (typeof item_id == 'object') { // event
+ if (item_id.textcode ==
+ 'SERIAL_UNIT_BARCODE_COLLISION') {
+ alert(F(
+ 'unit_barcode_collision',
+ item_id.payload.barcode
+ ));
+ } else {
+ // unexpected event, rely on toString()
+ alert(item_id);
+ }
+ busy(false);
+ return;
+ }
+ item_ids.push(item_id);
+ }
+
+ while (item_id = item_ids.shift()) {
if (self._wants_print_routing[item_id]) {
streams_for_printing.push(
self.item_cache[item_id].stream()