# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1335, USA.
#======================================================================
#
# Order entry module
use SL::IC;
use SL::TransNumber;
use SL::Util qw(trim);
+use SL::DB;
use Text::ParseWords;
use strict;
qq|WHERE (o.quotation = ?) |;
push(@values, $quotation);
- my ($null, $split_department_id) = split /--/, $form->{department};
- my $department_id = $form->{department_id} || $split_department_id;
- if ($department_id) {
+ if ($form->{department_id}) {
$query .= qq| AND o.department_id = ?|;
- push(@values, $department_id);
+ push(@values, $form->{department_id});
}
if ($form->{"project_id"}) {
WHERE proi.projectnumber ILIKE ? AND oi.trans_id = o.id
))
SQL
- push @values, "%" . $form->{"projectnumber"} . "%", "%" . $form->{"projectnumber"} . "%" ;
+ push @values, like($form->{"projectnumber"}), like($form->{"projectnumber"});
}
if ($form->{"business_id"}) {
} elsif ($form->{$vc}) {
$query .= " AND ct.name ILIKE ?";
- push(@values, '%' . trim($form->{$vc}) . '%');
+ push(@values, like($form->{$vc}));
}
if ($form->{"cp_name"}) {
$query .= " AND (cp.cp_name ILIKE ? OR cp.cp_givenname ILIKE ?)";
- push(@values, ('%' . trim($form->{"cp_name"}) . '%')x2);
+ push(@values, (like($form->{"cp_name"}))x2);
}
if (!$main::auth->assert('sales_all_edit', 1)) {
if ($form->{$ordnumber}) {
$query .= qq| AND o.$ordnumber ILIKE ?|;
- push(@values, '%' . trim($form->{$ordnumber}) . '%');
+ push(@values, like($form->{$ordnumber}));
}
if ($form->{cusordnumber}) {
$query .= qq| AND o.cusordnumber ILIKE ?|;
- push(@values, '%' . trim($form->{cusordnumber}) . '%');
+ push(@values, like($form->{cusordnumber}));
}
if($form->{transdatefrom}) {
if ($form->{shippingpoint}) {
$query .= qq| AND o.shippingpoint ILIKE ?|;
- push(@values, '%' . trim($form->{shippingpoint}) . '%');
+ push(@values, like($form->{shippingpoint}));
}
if ($form->{taxzone_id} ne '') { # taxzone_id could be 0
if ($form->{transaction_description}) {
$query .= qq| AND o.transaction_description ILIKE ?|;
- push(@values, '%' . trim($form->{transaction_description}) . '%');
+ push(@values, like($form->{transaction_description}));
}
if ($form->{periodic_invoices_active} ne $form->{periodic_invoices_inactive}) {
push @values, conv_date($form->{expected_billing_date_to});
}
+ if ($form->{parts_partnumber}) {
+ $query .= <<SQL;
+ AND EXISTS (
+ SELECT orderitems.trans_id
+ FROM orderitems
+ LEFT JOIN parts ON (orderitems.parts_id = parts.id)
+ WHERE (orderitems.trans_id = o.id)
+ AND (parts.partnumber ILIKE ?)
+ LIMIT 1
+ )
+SQL
+ push @values, like($form->{parts_partnumber});
+ }
+
+ if ($form->{parts_description}) {
+ $query .= <<SQL;
+ AND EXISTS (
+ SELECT orderitems.trans_id
+ FROM orderitems
+ WHERE (orderitems.trans_id = o.id)
+ AND (orderitems.description ILIKE ?)
+ LIMIT 1
+ )
+SQL
+ push @values, like($form->{parts_description});
+ }
+
if ($form->{all}) {
my @tokens = parse_line('\s+', 0, $form->{all});
# ordnumber quonumber customer.name vendor.name transaction_description
ct.name ILIKE ? OR
o.transaction_description ILIKE ?
)| for @tokens;
- push @values, ("%$_%")x4 for @tokens;
+ push @values, (like($_))x4 for @tokens;
}
my ($cvar_where, @cvar_values) = CVar->build_filter_query('module' => 'CT',
}
sub save {
+ my ($self, $myconfig, $form) = @_;
+ $main::lxdebug->enter_sub();
+
+ my $rc = SL::DB->client->with_transaction(\&_save, $self, $myconfig, $form);
+
+ $::lxdebug->leave_sub;
+
+ return $rc;
+}
+
+sub _save {
$main::lxdebug->enter_sub();
my ($self, $myconfig, $form) = @_;
- # connect to database, turn off autocommit
- my $dbh = $form->get_standard_dbh;
+ my $dbh = SL::DB->client->dbh;
my $restricter = SL::HTML::Restrict->create;
my ($query, @values, $sth, $null);
dbh => $dbh);
# link previous items with orderitems
- foreach (qw(orderitems invoice)) {
- if (!$form->{saveasnew} && !$form->{useasnew} && $form->{"converted_from_${_}_id_$i"}) {
+ # assume we have a new workflow if we link from invoice or order to quotation
+ # unluckily orderitems are used for quotation and orders - therefore one more
+ # check to be sure NOT to link from order to quotation
+ foreach (qw(orderitems)) {
+ if (!$form->{saveasnew} && !$form->{useasnew} && $form->{"converted_from_${_}_id_$i"}
+ && $form->{type} !~ 'quotation') {
RecordLinks->create_links('dbh' => $dbh,
'mode' => 'ids',
'from_table' => $_,
my $quotation = $form->{type} =~ /_order$/ ? 'f' : 't';
- ($null, $form->{department_id}) = split(/--/, $form->{department}) if $form->{department};
-
# save OE record
$query =
qq|UPDATE oe SET
$form->save_status($dbh);
# Link this record to the records it was created from.
- # check every record type we may link. i am not happy with converting the string to array back
- # should be a array from the start (OE.pm -> retrieve).
- # and that i need the local array ref for close_quotation_rfqs. better ideas welcome
$form->{convert_from_oe_ids} =~ s/^\s+//;
$form->{convert_from_oe_ids} =~ s/\s+$//;
my @convert_from_oe_ids = split m/\s+/, $form->{convert_from_oe_ids};
delete $form->{convert_from_oe_ids};
- @{ $form->{convert_from_oe_ids} } = @convert_from_oe_ids;
- foreach (qw(ar oe)) {
- if (!$form->{useasnew} && $form->{"convert_from_${_}_ids"}) {
- RecordLinks->create_links('dbh' => $dbh,
- 'mode' => 'ids',
- 'from_table' => $_,
- 'from_ids' => $form->{"convert_from_${_}_ids"},
- 'to_table' => 'oe',
- 'to_id' => $form->{id},
- );
- delete $form->{"convert_from_${_}_ids"};
- }
+ if (!$form->{useasnew} && scalar @convert_from_oe_ids) {
+ RecordLinks->create_links('dbh' => $dbh,
+ 'mode' => 'ids',
+ 'from_table' => 'oe',
+ 'from_ids' => \@convert_from_oe_ids,
+ 'to_table' => 'oe',
+ 'to_id' => $form->{id},
+ );
$self->_close_quotations_rfqs('dbh' => $dbh,
'from_id' => \@convert_from_oe_ids,
- 'to_id' => $form->{id}) if $_ eq 'oe';
+ 'to_id' => $form->{id});
}
if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
Common::webdav_folder($form);
- my $rc = $dbh->commit;
-
$self->save_periodic_invoices_config(dbh => $dbh,
oe_id => $form->{id},
config_yaml => $form->{periodic_invoices_config})
$main::lxdebug->leave_sub();
- return $rc;
+ return 1;
}
sub save_periodic_invoices_config {
if ($config_obj) {
my $config = { map { $_ => $config_obj->$_ } qw(active terminated periodicity order_value_periodicity start_date_as_date end_date_as_date first_billing_date_as_date extend_automatically_by ar_chart_id
- print printer_id copies direct_debit) };
+ print printer_id copies direct_debit send_email email_recipient_contact_id email_recipient_address email_sender email_subject email_body) };
$form->{periodic_invoices_config} = YAML::Dump($config);
}
}
my $myconfig = \%main::myconfig;
my $form = $main::form;
- my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
+ my $dbh = $params{dbh} || SL::DB->client->dbh;
- my $query = qq|SELECT quotation FROM oe WHERE id = ?|;
- my $sth = prepare_query($form, $dbh, $query);
+ SL::DB->client->with_transaction(sub {
- do_statement($form, $sth, $query, conv_i($params{to_id}));
+ my $query = qq|SELECT quotation FROM oe WHERE id = ?|;
+ my $sth = prepare_query($form, $dbh, $query);
- my ($quotation) = $sth->fetchrow_array();
+ do_statement($form, $sth, $query, conv_i($params{to_id}));
- if ($quotation) {
- $main::lxdebug->leave_sub();
- return;
- }
+ my ($quotation) = $sth->fetchrow_array();
- my @close_ids;
+ if ($quotation) {
+ return 1;
+ }
- foreach my $from_id (@{ $params{from_id} }) {
- $from_id = conv_i($from_id);
- do_statement($form, $sth, $query, $from_id);
- ($quotation) = $sth->fetchrow_array();
- push @close_ids, $from_id if ($quotation);
- }
+ my @close_ids;
- $sth->finish();
+ foreach my $from_id (@{ $params{from_id} }) {
+ $from_id = conv_i($from_id);
+ do_statement($form, $sth, $query, $from_id);
+ ($quotation) = $sth->fetchrow_array();
+ push @close_ids, $from_id if ($quotation);
+ }
- if (scalar @close_ids) {
- $query = qq|UPDATE oe SET closed = TRUE WHERE id IN (| . join(', ', ('?') x scalar @close_ids) . qq|)|;
- do_query($form, $dbh, $query, @close_ids);
+ $sth->finish();
- $dbh->commit() unless ($params{dbh});
- }
+ if (scalar @close_ids) {
+ $query = qq|UPDATE oe SET closed = TRUE WHERE id IN (| . join(', ', ('?') x scalar @close_ids) . qq|)|;
+ do_query($form, $dbh, $query, @close_ids);
+ }
+ 1;
+ }) or do { die SL::DB->client->error };
$main::lxdebug->leave_sub();
}
unlink map { "$spool/$_" } @spoolfiles if $spool;
1;
- });
+ }) or do { die SL::DB->client->error };
$main::lxdebug->leave_sub();
}
sub retrieve {
+ my ($self, $myconfig, $form) = @_;
$main::lxdebug->enter_sub();
+ my $rc = SL::DB->client->with_transaction(\&_retrieve, $self, $myconfig, $form);
+
+ $::lxdebug->leave_sub;
+ return $rc;
+}
+
+sub _retrieve {
my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->get_standard_dbh;
+ my $dbh = SL::DB->client->dbh;
my ($query, $query_add, @values, @ids, $sth);
$sth = prepare_execute_query($form, $dbh, $query, $form->{id});
$ref = $sth->fetchrow_hashref("NAME_lc");
- delete($ref->{id});
- map { $form->{$_} = $ref->{$_} } keys %$ref;
+ $form->{$_} = $ref->{$_} for grep { m{^shipto(?!_id$)} } keys %$ref;
$sth->finish;
- if ($form->{shipto_id}) {
+ if ($ref->{shipto_id}) {
my $cvars = CVar->get_custom_variables(
dbh => $dbh,
module => 'ShipTo',
- trans_id => $form->{shipto_id},
+ trans_id => $ref->{shipto_id},
);
$form->{"shiptocvar_$_->{name}"} = $_->{value} for @{ $cvars };
}
c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid,
c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid,
oe.ordnumber AS ordnumber_oe, oe.transdate AS transdate_oe, oe.cusordnumber AS cusordnumber_oe,
- p.partnumber, p.assembly, p.listprice, o.description, o.qty,
- o.sellprice, o.parts_id AS id, o.unit, o.discount, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id,
+ p.partnumber, p.part_type, p.listprice, o.description, o.qty,
+ p.classification_id,
+ o.sellprice, o.parts_id AS id, o.unit, o.discount, p.notes AS partnotes, p.part_type,
o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost,
o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription,
o.price_factor_id, o.price_factor, o.marge_price_factor, o.active_price_source, o.active_discount_source,
map { $ref->{"ic_cvar_$_->{name}"} = $_->{value} } @{ $cvars };
# Handle accounts.
- if (!$ref->{"part_inventory_accno_id"}) {
+ if (!$ref->{"part_type"} eq 'part') {
map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid));
}
- delete($ref->{"part_inventory_accno_id"});
+ # delete($ref->{"part_inventory_accno_id"});
# in collective order, copy global ordnumber, transdate, cusordnumber into item scope
# unless already present there
$self->load_periodic_invoice_config($form);
- my $rc = $dbh->commit;
-
- $main::lxdebug->leave_sub();
-
- return $rc;
+ return 1;
}
sub retrieve_simple {
my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->get_standard_dbh;
+ my $dbh = SL::DB->client->dbh;
my $query;
my @values = ();
my $sth;
push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"});
- $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
- 'departments' => 'ALL_DEPARTMENTS');
+ $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS');
my %price_factors;
foreach my $pfac (@{ $form->{ALL_PRICE_FACTORS} }) {
$pfac->{formatted_factor} = $form->format_amount($myconfig, $pfac->{factor});
}
- # lookup department
- foreach my $dept (@{ $form->{ALL_DEPARTMENTS} }) {
- next unless $dept->{id} eq $form->{department_id};
- $form->{department} = $dept->{description};
- last;
- }
-
# sort items by partsgroup
for $i (1 .. $form->{rowcount}) {
$partsgroup = "";
# so that they can be sorted in later
my %prepared_template_arrays = IC->prepare_parts_for_printing(myconfig => $myconfig, form => $form);
my @prepared_arrays = keys %prepared_template_arrays;
+ my @separate_totals = qw(non_separate_subtotal);
$form->{TEMPLATE_ARRAYS} = { };
push @{ $form->{TEMPLATE_ARRAYS}->{discount_nofmt} }, ($discount != 0) ? $discount * -1 : '';
push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} }, $form->{"discount_$i"};
+ if ( $prepared_template_arrays{separate}[$i - 1] ) {
+ my $pabbr = $prepared_template_arrays{separate}[$i - 1];
+ if ( ! $form->{"separate_${pabbr}_subtotal"} ) {
+ push @separate_totals , "separate_${pabbr}_subtotal";
+ $form->{"separate_${pabbr}_subtotal"} = 0;
+ }
+ $form->{"separate_${pabbr}_subtotal"} += $linetotal;
+ } else {
+ $form->{non_separate_subtotal} += $linetotal;
+ }
+
$form->{ordtotal} += $linetotal;
$form->{nodiscount_total} += $nodiscount_linetotal;
$form->{discount_total} += $discount;
$tax_rate = $taxrate * 100;
push(@{ $form->{TEMPLATE_ARRAYS}->{tax_rate} }, qq|$tax_rate|);
- if ($form->{"assembly_$i"}) {
+ if ($form->{"part_type_$i"} eq 'assembly') {
$sameitem = "";
# get parts and push them onto the stack
$form->{subtotal_nofmt} = $form->{ordtotal};
}
- $form->{ordtotal} = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
+ my $grossamount = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
+ $form->{ordtotal} = $form->round_amount( $grossamount, 2, 1);
+ $form->{rounding} = $form->round_amount(
+ $form->{ordtotal} - $form->round_amount($grossamount, 2),
+ 2
+ );
# format amounts
+ $form->{rounding} = $form->format_amount($myconfig, $form->{rounding}, 2);
$form->{quototal} = $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
- if ($form->{type} =~ /_quotation/) {
- $form->set_payment_options($myconfig, $form->{quodate});
- } else {
- $form->set_payment_options($myconfig, $form->{orddate});
- }
+ $form->set_payment_options($myconfig, $form->{$form->{type} =~ /_quotation/ ? 'quodate' : 'orddate'}, $form->{type});
$form->{username} = $myconfig->{name};
- $dbh->disconnect;
-
+ $form->{department} = SL::DB::Manager::Department->find_by(id => $form->{department_id})->description if $form->{department_id};
$form->{delivery_term} = SL::DB::Manager::DeliveryTerm->find_by(id => $form->{delivery_term_id} || undef);
$form->{delivery_term}->description_long($form->{delivery_term}->translated_attribute('description_long', $form->{language_id})) if $form->{delivery_term} && $form->{language_id};
$form->{order} = SL::DB::Manager::Order->find_by(id => $form->{id}) if $form->{id};
+ $form->{$_} = $form->format_amount($myconfig, $form->{$_}, 2) for @separate_totals;
$main::lxdebug->leave_sub();
}