Revision 96670fe8
Von Moritz Bunkus vor fast 9 Jahren hinzugefügt
SL/BackgroundJob/CreatePeriodicInvoices.pm | ||
---|---|---|
|
||
my $order = $config->order;
|
||
my $invoice;
|
||
if (!$self->{db_obj}->db->do_transaction(sub {
|
||
if (!$self->{db_obj}->db->with_transaction(sub {
|
||
1; # make Emacs happy
|
||
|
||
$invoice = SL::DB::Invoice->new_from($order);
|
||
... | ... | |
_log_msg("_create_invoice created for period start date $period_start_date id " . $invoice->id . " number " . $invoice->invnumber . " netamount " . $invoice->netamount . " amount " . $invoice->amount);
|
||
|
||
# die $invoice->transaction_description;
|
||
|
||
1;
|
||
})) {
|
||
$::lxdebug->message(LXDebug->WARN(), "_create_invoice failed: " . join("\n", (split(/\n/, $self->{db_obj}->db->error))[0..2]));
|
||
return undef;
|
SL/Controller/Buchungsgruppen.pm | ||
---|---|---|
# allow deletion of unused Buchungsgruppen. Will fail, due to database
|
||
# constraint, if Buchungsgruppe is connected to a part
|
||
|
||
my $db = $self->{config}->db;
|
||
$db->do_transaction(sub {
|
||
my $taxzone_charts = SL::DB::Manager::TaxzoneChart->get_all(where => [ buchungsgruppen_id => $self->config->id ]);
|
||
foreach my $taxzonechart ( @{$taxzone_charts} ) { $taxzonechart->delete };
|
||
$self->config->delete();
|
||
flash_later('info', $::locale->text('The booking group has been deleted.'));
|
||
$self->{config}->db->with_transaction(sub {
|
||
my $taxzone_charts = SL::DB::Manager::TaxzoneChart->get_all(where => [ buchungsgruppen_id => $self->config->id ]);
|
||
foreach my $taxzonechart ( @{$taxzone_charts} ) { $taxzonechart->delete };
|
||
$self->config->delete();
|
||
flash_later('info', $::locale->text('The booking group has been deleted.'));
|
||
|
||
1;
|
||
}) || flash_later('error', $::locale->text('The booking group is in use and cannot be deleted.'));
|
||
|
||
$self->redirect_to(action => 'list');
|
||
... | ... | |
my @errors;
|
||
|
||
my $db = $self->config->db;
|
||
$db->do_transaction( sub {
|
||
if (!$db->with_transaction(sub {
|
||
|
||
$self->config->assign_attributes(%{ $params }); # assign description and inventory_accno_id
|
||
|
||
... | ... | |
$taxzone_chart->save;
|
||
}
|
||
}
|
||
} ) || die @errors ? join("\n", @errors) . "\n" : $db->error . "\n";
|
||
# die with rollback of taxzone save if saving of any of the taxzone_charts fails
|
||
# only show the $db->error if we haven't already identified the likely error ourselves
|
||
|
||
1;
|
||
})) {
|
||
die @errors ? join("\n", @errors) . "\n" : $db->error . "\n";
|
||
# die with rollback of taxzone save if saving of any of the taxzone_charts fails
|
||
# only show the $db->error if we haven't already identified the likely error ourselves
|
||
}
|
||
|
||
flash_later('info', $is_new ? t8('The booking group has been created.') : t8('The booking group has been saved.'));
|
||
$self->redirect_to(action => 'list');
|
SL/Controller/CustomerVendor.pm | ||
---|---|---|
|
||
my $db = $self->{cv}->db;
|
||
|
||
$db->do_transaction(sub {
|
||
$db->with_transaction(sub {
|
||
my $cvs_by_nr;
|
||
if ( $self->is_vendor() ) {
|
||
if ( $self->{cv}->vendornumber ) {
|
||
... | ... | |
$note->delete(cascade => 'delete');
|
||
}
|
||
}
|
||
|
||
1;
|
||
}) || die($db->error);
|
||
|
||
}
|
||
... | ... | |
$self->action_edit();
|
||
} else {
|
||
|
||
$db->do_transaction(sub {
|
||
$db->with_transaction(sub {
|
||
$self->{cv}->delete(cascade => 1);
|
||
|
||
my $snumbers = $self->is_vendor() ? 'vendornumber_'. $self->{cv}->vendornumber : 'customernumber_'. $self->{cv}->customernumber;
|
||
... | ... | |
SL::Helper::Flash::flash('error', $::locale->text('No contact selected to delete'));
|
||
} else {
|
||
|
||
$db->do_transaction(sub {
|
||
$db->with_transaction(sub {
|
||
if ( $self->{contact}->used ) {
|
||
$self->{contact}->detach();
|
||
$self->{contact}->save();
|
||
... | ... | |
$self->{contact}->delete(cascade => 1);
|
||
SL::Helper::Flash::flash('info', $::locale->text('Contact deleted.'));
|
||
}
|
||
|
||
1;
|
||
}) || die($db->error);
|
||
|
||
$self->{contact} = $self->_new_contact_object;
|
||
... | ... | |
SL::Helper::Flash::flash('error', $::locale->text('No shipto selected to delete'));
|
||
} else {
|
||
|
||
$db->do_transaction(sub {
|
||
$db->with_transaction(sub {
|
||
if ( $self->{shipto}->used ) {
|
||
$self->{shipto}->detach();
|
||
$self->{shipto}->save(cascade => 1);
|
||
... | ... | |
$self->{shipto}->delete(cascade => 1);
|
||
SL::Helper::Flash::flash('info', $::locale->text('Shipto deleted.'));
|
||
}
|
||
|
||
1;
|
||
}) || die($db->error);
|
||
|
||
$self->{shipto} = SL::DB::Shipto->new();
|
SL/Controller/MassInvoiceCreatePrint.pm | ||
---|---|---|
}
|
||
|
||
my $db = SL::DB::Invoice->new->db;
|
||
my @invoices;
|
||
|
||
if (!$db->do_transaction(sub {
|
||
my @invoices;
|
||
if (!$db->with_transaction(sub {
|
||
foreach my $id (@sales_delivery_order_ids) {
|
||
my $delivery_order = SL::DB::DeliveryOrder->new(id => $id)->load;
|
||
|
||
... | ... | |
push @invoices, $invoice;
|
||
}
|
||
|
||
my $key = sprintf('%d-%d', Time::HiRes::gettimeofday());
|
||
$::auth->set_session_value("MassInvoiceCreatePrint::ids-${key}" => [ map { $_->id } @invoices ]);
|
||
|
||
flash_later('info', t8('The invoices have been created. They\'re pre-selected below.'));
|
||
$self->redirect_to(action => 'list_invoices', ids => $key);
|
||
|
||
1;
|
||
})) {
|
||
$::lxdebug->message(LXDebug::WARN(), "Error: " . $db->error);
|
||
$::form->error($db->error);
|
||
}
|
||
|
||
my $key = sprintf('%d-%d', Time::HiRes::gettimeofday());
|
||
$::auth->set_session_value("MassInvoiceCreatePrint::ids-${key}" => [ map { $_->id } @invoices ]);
|
||
|
||
flash_later('info', t8('The invoices have been created. They\'re pre-selected below.'));
|
||
$self->redirect_to(action => 'list_invoices', ids => $key);
|
||
}
|
||
|
||
sub action_list_invoices {
|
SL/Controller/Order.pm | ||
---|---|---|
my ($self) = @_;
|
||
|
||
my $errors = [];
|
||
my $db = $self->order->db;
|
||
my $db = $self->order->db;
|
||
|
||
$db->do_transaction(
|
||
$db->with_transaction(
|
||
sub {
|
||
my @spoolfiles = grep { $_ } map { $_->spoolfile } @{ SL::DB::Manager::Status->get_all(where => [ trans_id => $self->order->id ]) };
|
||
$self->order->delete;
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
my $errors = [];
|
||
my $db = $self->order->db;
|
||
my $db = $self->order->db;
|
||
|
||
$db->do_transaction(
|
||
sub {
|
||
SL::DB::OrderItem->new(id => $_)->delete for @{$self->item_ids_to_delete};
|
||
$self->order->save(cascade => 1);
|
||
$db->with_transaction(sub {
|
||
SL::DB::OrderItem->new(id => $_)->delete for @{$self->item_ids_to_delete};
|
||
$self->order->save(cascade => 1);
|
||
}) || push(@{$errors}, $db->error);
|
||
|
||
return $errors;
|
SL/Controller/RequirementSpec.pm | ||
---|---|---|
sub action_ajax_save_time_and_cost_estimate {
|
||
my ($self) = @_;
|
||
|
||
$self->requirement_spec->db->do_transaction(sub {
|
||
$self->requirement_spec->db->with_transaction(sub {
|
||
# Make Emacs happy
|
||
1;
|
||
foreach my $attributes (@{ $::form->{requirement_spec_items} || [] }) {
|
||
... | ... | |
}
|
||
|
||
my $db = $self->requirement_spec->db;
|
||
if (!$db->do_transaction(sub {
|
||
if (!$db->with_transaction(sub {
|
||
if ($self->copy_source) {
|
||
$self->requirement_spec($self->copy_source->create_copy(%{ $params }));
|
||
} else {
|
||
$self->requirement_spec->save(cascade => 1);
|
||
}
|
||
1;
|
||
})) {
|
||
$::lxdebug->message(LXDebug::WARN(), "Error: " . $db->error);
|
||
@errors = ($::locale->text('Saving failed. Error message from the database: #1', $db->error));
|
||
... | ... | |
return $self->js->error(@errors)->render if @errors;
|
||
|
||
my $db = $self->requirement_spec->db;
|
||
if (!$db->do_transaction(sub {
|
||
if (!$db->with_transaction(sub {
|
||
$project->save;
|
||
$self->requirement_spec->update_attributes(project_id => $project->id);
|
||
|
SL/Controller/RequirementSpecItem.pm | ||
---|---|---|
my $old_type = $self->item->item_type;
|
||
my $new_type = !$dropped_item ? 'section' : $position =~ m/before|after/ ? $dropped_item->item_type : $dropped_item->child_type;
|
||
|
||
$self->item->db->do_transaction(sub {
|
||
$self->item->db->with_transaction(sub {
|
||
$self->item->remove_from_list;
|
||
$self->item->parent_id($position =~ m/before|after/ ? $dropped_item->parent_id : $dropped_item->id) if $dropped_item;
|
||
$self->item->item_type($new_type);
|
SL/Controller/RequirementSpecPart.pm | ||
---|---|---|
my ($self) = @_;
|
||
|
||
my $db = $self->requirement_spec->db;
|
||
$db->do_transaction(sub {
|
||
$db->with_transaction(sub {
|
||
# Make Emacs happy
|
||
1;
|
||
my $parts = $::form->{additional_parts} || [];
|
||
... | ... | |
$_->{position} = $position++ for @{ $parts };
|
||
|
||
$self->requirement_spec->update_attributes(parts => $parts)->load;
|
||
|
||
1;
|
||
}) or do {
|
||
return $self->js->error(t8('Saving failed. Error message from the database: #1', $db->error))->render;
|
||
};
|
SL/Controller/RequirementSpecTextBlock.pm | ||
---|---|---|
my $dropped_type = $position ne 'last' ? undef : $::form->{dropped_type} =~ m/^ text-blocks- (?:front|back) $/x ? $::form->{dropped_type} : die "Unknown 'dropped_type' parameter";
|
||
my $old_where = $self->text_block->output_position;
|
||
|
||
$self->text_block->db->do_transaction(sub {
|
||
$self->text_block->db->with_transaction(sub {
|
||
1;
|
||
$self->text_block->remove_from_list;
|
||
$self->text_block->output_position($position =~ m/before|after/ ? $dropped_text_block->output_position : $::form->{dropped_type} eq 'text-blocks-front' ? 0 : 1);
|
||
... | ... | |
sub paste_picture {
|
||
my ($self, $copied) = @_;
|
||
|
||
if (!$self->text_block->db->do_transaction(sub {
|
||
if (!$self->text_block->db->with_transaction(sub {
|
||
1;
|
||
$self->picture($copied->to_object)->save; # Create new picture from copied data and save
|
||
$self->text_block->add_pictures($self->picture); # Add new picture to text block
|
SL/Controller/Taxzones.pm | ||
---|---|---|
# allow deletion of unused tax zones. Will fail, due to database
|
||
# constraints, if tax zone is used anywhere
|
||
|
||
my $db = $self->{config}->db;
|
||
$db->do_transaction(sub {
|
||
my $taxzone_charts = SL::DB::Manager::TaxzoneChart->get_all(where => [ taxzone_id => $self->config->id ]);
|
||
foreach my $taxzonechart ( @{$taxzone_charts} ) { $taxzonechart->delete };
|
||
$self->config->delete();
|
||
flash_later('info', $::locale->text('The tax zone has been deleted.'));
|
||
$self->{config}->db->with_transaction(sub {
|
||
my $taxzone_charts = SL::DB::Manager::TaxzoneChart->get_all(where => [ taxzone_id => $self->config->id ]);
|
||
foreach my $taxzonechart ( @{$taxzone_charts} ) { $taxzonechart->delete };
|
||
$self->config->delete();
|
||
flash_later('info', $::locale->text('The tax zone has been deleted.'));
|
||
|
||
1;
|
||
}) || flash_later('error', $::locale->text('The tax zone is in use and cannot be deleted.'));
|
||
|
||
$self->redirect_to(action => 'list');
|
||
... | ... | |
my @errors;
|
||
|
||
my $db = $self->config->db;
|
||
$db->do_transaction( sub {
|
||
if (!$db->with_transaction(sub {
|
||
|
||
# always allow editing of description and obsolete
|
||
$self->config->assign_attributes( %{$params} ) ;
|
||
... | ... | |
$taxzone_chart->save;
|
||
}
|
||
}
|
||
} ) || die @errors ? join("\n", @errors) . "\n" : $db->error . "\n";
|
||
# die with rollback of taxzone save if saving of any of the taxzone_charts fails
|
||
# only show the $db->error if we haven't already identified the likely error ourselves
|
||
|
||
1;
|
||
})) {
|
||
die @errors ? join("\n", @errors) . "\n" : $db->error . "\n";
|
||
# die with rollback of taxzone save if saving of any of the taxzone_charts fails
|
||
# only show the $db->error if we haven't already identified the likely error ourselves
|
||
}
|
||
|
||
flash_later('info', $is_new ? t8('The taxzone has been created.') : t8('The taxzone has been saved.'));
|
||
$self->redirect_to(action => 'list');
|
SL/DB/Helper/ActsAsList.pm | ||
---|---|---|
sub remove_from_list {
|
||
my ($self) = @_;
|
||
|
||
my $worker = sub {
|
||
return $self->db->with_transaction(sub {
|
||
remove_position($self);
|
||
|
||
# Set to -1 manually because $self->update_attributes() would
|
||
... | ... | |
SQL
|
||
$self->db->dbh->do($sql, undef, $self->$primary_key_col);
|
||
$self->$column(undef);
|
||
};
|
||
|
||
return $self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker);
|
||
});
|
||
}
|
||
|
||
sub add_to_list {
|
||
... | ... | |
${group_by}
|
||
SQL
|
||
|
||
my $worker = sub {
|
||
return $self->db->with_transaction(sub {
|
||
$self->db->dbh->do($query, undef, $new_position - 1, @values);
|
||
$self->update_attributes($column => $new_position);
|
||
};
|
||
|
||
return $self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker);
|
||
});
|
||
}
|
||
|
||
sub get_next_in_list {
|
||
... | ... | |
|
||
my $self = ref($class_or_self) ? $class_or_self : $class_or_self->new;
|
||
my $column = column_name($self);
|
||
my $result = $self->db->do_transaction(sub {
|
||
my $result = $self->db->with_transaction(sub {
|
||
my $query = qq|UPDATE | . $self->meta->table . qq| SET ${column} = ? WHERE id = ?|;
|
||
my $sth = $self->db->dbh->prepare($query) || die $self->db->dbh->errstr;
|
||
|
||
... | ... | |
}
|
||
|
||
$sth->finish;
|
||
|
||
1;
|
||
});
|
||
|
||
return $result;
|
SL/DB/Invoice.pm | ||
---|---|---|
$params{ar_id} = $chart->id;
|
||
}
|
||
|
||
my $worker = sub {
|
||
if (!$self->db->with_transaction(sub {
|
||
my %data = $self->calculate_prices_and_taxes;
|
||
|
||
$self->_post_create_assemblyitem_entries($data{assembly_items});
|
||
... | ... | |
$self->_post_update_allocated($data{allocated});
|
||
|
||
$self->_post_book_rounding($data{rounding});
|
||
};
|
||
|
||
if ($self->db->in_transaction) {
|
||
$worker->();
|
||
} elsif (!$self->db->do_transaction($worker)) {
|
||
1;
|
||
})) {
|
||
$::lxdebug->message(LXDebug->WARN(), "convert_to_invoice failed: " . join("\n", (split(/\n/, $self->db->error))[0..2]));
|
||
return undef;
|
||
}
|
SL/DB/Object.pm | ||
---|---|---|
sub save {
|
||
my ($self, @args) = @_;
|
||
|
||
my ($result, $exception);
|
||
my $worker = sub {
|
||
$exception = $EVAL_ERROR unless eval {
|
||
SL::DB::Object::Hooks::run_hooks($self, 'before_save');
|
||
$result = $self->SUPER::save(@args);
|
||
SL::DB::Object::Hooks::run_hooks($self, 'after_save', $result);
|
||
1;
|
||
};
|
||
my $result;
|
||
|
||
return $result;
|
||
};
|
||
$self->db->with_transaction(sub {
|
||
SL::DB::Object::Hooks::run_hooks($self, 'before_save');
|
||
$result = $self->SUPER::save(@args);
|
||
SL::DB::Object::Hooks::run_hooks($self, 'after_save', $result);
|
||
|
||
$self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker);
|
||
|
||
die $exception if $exception;
|
||
1;
|
||
}) || die $self->error;
|
||
|
||
return $result;
|
||
}
|
||
... | ... | |
sub delete {
|
||
my ($self, @args) = @_;
|
||
|
||
my ($result, $exception);
|
||
my $worker = sub {
|
||
$exception = $EVAL_ERROR unless eval {
|
||
SL::DB::Object::Hooks::run_hooks($self, 'before_delete');
|
||
$result = $self->SUPER::delete(@args);
|
||
SL::DB::Object::Hooks::run_hooks($self, 'after_delete', $result);
|
||
1;
|
||
};
|
||
|
||
return $result;
|
||
};
|
||
my $result;
|
||
|
||
$self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker);
|
||
$self->db->with_transaction(sub {
|
||
SL::DB::Object::Hooks::run_hooks($self, 'before_delete');
|
||
$result = $self->SUPER::delete(@args);
|
||
SL::DB::Object::Hooks::run_hooks($self, 'after_delete', $result);
|
||
|
||
die $exception if $exception;
|
||
1;
|
||
}) || die $self->error;
|
||
|
||
return $result;
|
||
}
|
SL/DB/RequirementSpec.pm | ||
---|---|---|
return $self->_create_copy(%params) if $self->db->in_transaction;
|
||
|
||
my $copy;
|
||
if (!$self->db->do_transaction(sub { $copy = $self->_create_copy(%params) })) {
|
||
if (!$self->db->with_transaction(sub { $copy = $self->_create_copy(%params) })) {
|
||
$::lxdebug->message(LXDebug->WARN(), "create_copy failed: " . join("\n", (split(/\n/, $self->db->error))[0..2]));
|
||
return undef;
|
||
}
|
t/ar/ar.t | ||
---|---|---|
|
||
my $db = $invoice->db;
|
||
|
||
$db->do_transaction( sub {
|
||
$db->with_transaction( sub {
|
||
|
||
my $tax = SL::DB::Manager::Tax->find_by(taxkey => 0, rate => 0);
|
||
|
||
... | ... | |
|
||
_save_and_pay_and_check(invoice => $invoice, bank => $bank, pay => 1, check => 1);
|
||
|
||
1;
|
||
|
||
}) || die "something went wrong: " . $db->error;
|
||
return $invoice->invnumber;
|
||
};
|
||
... | ... | |
|
||
my $db = $invoice->db;
|
||
|
||
$db->do_transaction( sub {
|
||
$db->with_transaction( sub {
|
||
|
||
# TODO: check for currency and exchange rate
|
||
|
||
... | ... | |
$invoice->create_ar_row( chart => $ar_chart );
|
||
_save_and_pay_and_check(invoice => $invoice, bank => $bank, pay => 1, check => 1);
|
||
|
||
1;
|
||
}) || die "something went wrong: " . $db->error;
|
||
return $invoice->invnumber;
|
||
};
|
Auch abrufbar als: Unified diff
»with_transaction« anstelle von »do_transaction« verwenden
Es sollte so selten wie möglich »do_transaction« verwndet werden, damit
man sich immer angewöhnt, »with_transaction« zu nutzen.
Hintergründe und Unterschiede zwischen den beiden Funktionen sind in der
Dokumentation von SL/DB.pm beschrieben.