package OE;
-use List::Util qw(max);
+use List::Util qw(max first);
+use YAML;
use SL::AM;
use SL::Common;
+use SL::CVar;
+use SL::DB::PeriodicInvoicesConfig;
use SL::DBUtils;
+use SL::IC;
+
+use strict;
sub transactions {
$main::lxdebug->enter_sub();
my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->dbconnect($myconfig);
+ my $dbh = $form->get_standard_dbh;
my $query;
my $ordnumber = 'ordnumber';
my @values;
my $where;
+ my ($periodic_invoices_columns, $periodic_invoices_joins);
+
my $rate = ($form->{vc} eq 'customer') ? 'buy' : 'sell';
if ($form->{type} =~ /_quotation$/) {
$quotation = '1';
$ordnumber = 'quonumber';
+
+ } elsif ($form->{type} eq 'sales_order') {
+ $periodic_invoices_columns = qq| , COALESCE(pcfg.active, 'f') AS periodic_invoices |;
+ $periodic_invoices_joins = qq| LEFT JOIN periodic_invoices_configs pcfg ON (o.id = pcfg.oe_id) |;
}
my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";
qq| o.marge_total, o.marge_percent, | .
qq| ex.$rate AS exchangerate, | .
qq| pr.projectnumber AS globalprojectnumber, | .
- qq| e.name AS employee, s.name AS salesman | .
+ qq| e.name AS employee, s.name AS salesman, | .
+ qq| ct.${vc}number AS vcnumber, ct.country, ct.ustid | .
+ $periodic_invoices_columns .
qq|FROM oe o | .
qq|JOIN $vc ct ON (o.${vc}_id = ct.id) | .
qq|LEFT JOIN employee e ON (o.employee_id = e.id) | .
qq|LEFT JOIN exchangerate ex ON (ex.curr = o.curr | .
qq| AND ex.transdate = o.transdate) | .
qq|LEFT JOIN project pr ON (o.globalproject_id = pr.id) | .
+ qq|$periodic_invoices_joins | .
qq|WHERE (o.quotation = ?) |;
push(@values, $quotation);
- my ($null, $department_id) = split /--/, $form->{department};
+ my ($null, $split_department_id) = split /--/, $form->{department};
+ my $department_id = $form->{department_id} || $split_department_id;
if ($department_id) {
$query .= qq| AND o.department_id = ?|;
push(@values, $department_id);
qq|AND ((globalproject_id = ?) OR EXISTS | .
qq| (SELECT * FROM orderitems oi | .
qq| WHERE oi.project_id = ? AND oi.trans_id = o.id))|;
- push(@values, $form->{"project_id"}, $form->{"project_id"});
+ push(@values, conv_i($form->{"project_id"}), conv_i($form->{"project_id"}));
+ }
+
+ if ($form->{"projectnumber"}) {
+ $query .= <<SQL;
+ AND (pr.projectnumber ILIKE ?) OR EXISTS (
+ SELECT * FROM orderitems oi
+ LEFT JOIN project proi ON proi.id = oi.project_id
+ WHERE proi.projectnumber ILIKE ? AND oi.trans_id = o.id
+ )
+SQL
+ push @values, "%" . $form->{"projectnumber"} . "%", "%" . $form->{"projectnumber"} . "%" ;
}
if ($form->{"${vc}_id"}) {
push(@values, '%' . $form->{$vc} . '%');
}
+ if (!$main::auth->assert('sales_all_edit', 1)) {
+ $query .= " AND o.employee_id = (select id from employee where login= ?)";
+ push @values, $form->{login};
+ }
if ($form->{employee_id}) {
$query .= " AND o.employee_id = ?";
push @values, conv_i($form->{employee_id});
}
-
+
if ($form->{salesman_id}) {
$query .= " AND o.salesman_id = ?";
push @values, conv_i($form->{salesman_id});
push(@values, conv_date($form->{transdateto}));
}
+ if($form->{reqdatefrom}) {
+ $query .= qq| AND o.reqdate >= ?|;
+ push(@values, conv_date($form->{reqdatefrom}));
+ }
+
+ if($form->{reqdateto}) {
+ $query .= qq| AND o.reqdate <= ?|;
+ push(@values, conv_date($form->{reqdateto}));
+ }
+
if ($form->{transaction_description}) {
$query .= qq| AND o.transaction_description ILIKE ?|;
push(@values, '%' . $form->{transaction_description} . '%');
}
- my $sortdir = $form->{sortdir} ? 'ASC' : 'DESC';
+ if ($form->{periodic_invoices_active} ne $form->{periodic_invoices_inactive}) {
+ my $not = $form->{periodic_invoices_inactive} ? 'NOT' : '';
+ $query .= qq| AND ${not} COALESCE(pcfg.active, 'f')|;
+ }
+
+ my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
my $sortorder = join(', ', map { "${_} ${sortdir} " } ("o.id", $form->sort_columns("transdate", $ordnumber, "name")));
my %allowed_sort_columns = (
"transdate" => "o.transdate",
my %id = ();
$form->{OE} = [];
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
$ref->{exchangerate} = 1 unless $ref->{exchangerate};
push @{ $form->{OE} }, $ref if $ref->{id} != $id{ $ref->{id} };
$id{ $ref->{id} } = $ref->{id};
}
$sth->finish;
- $dbh->disconnect;
$main::lxdebug->leave_sub();
}
$query =
qq|SELECT oe.id, oe.transdate, oe.reqdate, oe.quonumber, oe.transaction_description, oe.amount,
+ CASE WHEN (COALESCE(oe.customer_id, 0) = 0) THEN 'vendor' ELSE 'customer' END AS vc,
c.name AS customer,
+ v.name AS vendor,
e.name AS employee
FROM oe
LEFT JOIN customer c ON (oe.customer_id = c.id)
+ LEFT JOIN vendor v ON (oe.vendor_id = v.id)
LEFT JOIN employee e ON (oe.employee_id = e.id)
WHERE (COALESCE(quotation, FALSE) = TRUE)
AND (COALESCE(closed, FALSE) = FALSE)
my ($self, $myconfig, $form) = @_;
# connect to database, turn off autocommit
- my $dbh = $form->dbconnect_noauto($myconfig);
+ my $dbh = $form->get_standard_dbh;
my ($query, @values, $sth, $null);
my $exchangerate = 0;
my $all_units = AM->retrieve_units($myconfig, $form);
$form->{all_units} = $all_units;
+ my $ic_cvar_configs = CVar->get_configs(module => 'IC',
+ dbh => $dbh);
+
$form->{employee_id} = (split /--/, $form->{employee})[1] if !$form->{employee_id};
unless ($form->{employee_id}) {
$form->get_employee($dbh);
my $ml = ($form->{type} eq 'sales_order') ? 1 : -1;
if ($form->{id}) {
+ $query = qq|DELETE FROM custom_variables
+ WHERE (config_id IN (SELECT id FROM custom_variable_configs WHERE module = 'IC'))
+ AND (sub_module = 'orderitems')
+ AND (trans_id IN (SELECT id FROM orderitems WHERE trans_id = ?))|;
+ do_query($form, $dbh, $query, $form->{id});
$query = qq|DELETE FROM orderitems WHERE trans_id = ?|;
do_query($form, $dbh, $query, $form->{id});
my $project_id;
my $reqdate;
my $taxrate;
+ my $taxbase;
+ my $taxdiff;
my $taxamount = 0;
my $fxsellprice;
my %taxbase;
my $baseqty = $form->{"qty_$i"} * $basefactor;
$form->{"marge_percent_$i"} = $form->parse_amount($myconfig, $form->{"marge_percent_$i"}) * 1;
- $form->{"marge_total_$i"} = $form->parse_amount($myconfig, $form->{"marge_total_$i"}) * 1;
- $form->{"lastcost_$i"} = $form->{"lastcost_$i"} * 1;
+ $form->{"marge_absolut_$i"} = $form->parse_amount($myconfig, $form->{"marge_absolut_$i"}) * 1;
+
+ $form->{"lastcost_$i"} = $form->parse_amount($myconfig, $form->{"lastcost_$i"});
# set values to 0 if nothing entered
$form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
if ($form->round_amount($taxrate, 7) == 0) {
if ($form->{taxincluded}) {
- foreach $item (@taxaccounts) {
+ foreach my $item (@taxaccounts) {
$taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
$taxaccounts{$item} += $taxamount;
$taxdiff += $taxamount;
}
$taxaccounts{ $taxaccounts[0] } += $taxdiff;
} else {
- foreach $item (@taxaccounts) {
+ foreach my $item (@taxaccounts) {
$taxaccounts{$item} += $linetotal * $form->{"${item}_rate"};
$taxbase{$item} += $taxbase;
}
}
} else {
- foreach $item (@taxaccounts) {
+ foreach my $item (@taxaccounts) {
$taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
$taxbase{$item} += $taxbase;
}
$pricegroup_id *= 1;
# save detail record in orderitems table
+ my $orderitems_id = $form->{"orderitems_id_$i"};
+ ($orderitems_id) = selectfirst_array_query($form, $dbh, qq|SELECT nextval('orderitemsid')|) if (!$orderitems_id);
+
@values = ();
- $query = qq|INSERT INTO orderitems (|;
- if ($form->{"orderitems_id_$i"}) {
- $query .= "id, ";
- }
- $query .= qq|trans_id, parts_id, description, longdescription, qty, base_qty, | .
- qq|sellprice, discount, unit, reqdate, project_id, serialnumber, ship, | .
- qq|pricegroup_id, ordnumber, transdate, cusordnumber, subtotal, | .
- qq|marge_percent, marge_total, lastcost, price_factor_id, price_factor, marge_price_factor) | .
- qq|VALUES (|;
- if($form->{"orderitems_id_$i"}) {
- $query .= qq|?,|;
- push(@values, $form->{"orderitems_id_$i"});
- }
- $query .= qq|?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
- (SELECT factor FROM price_factors WHERE id = ?), ?)|;
+ $query = qq|INSERT INTO orderitems (
+ id, trans_id, parts_id, description, longdescription, qty, base_qty,
+ sellprice, discount, unit, reqdate, project_id, serialnumber, ship,
+ pricegroup_id, ordnumber, transdate, cusordnumber, subtotal,
+ marge_percent, marge_total, lastcost, price_factor_id, price_factor, marge_price_factor)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
+ (SELECT factor FROM price_factors WHERE id = ?), ?)|;
push(@values,
- conv_i($form->{id}), conv_i($form->{"id_$i"}),
+ conv_i($orderitems_id), conv_i($form->{id}), conv_i($form->{"id_$i"}),
$form->{"description_$i"}, $form->{"longdescription_$i"},
$form->{"qty_$i"}, $baseqty,
$fxsellprice, $form->{"discount_$i"},
$form->{"serialnumber_$i"}, $form->{"ship_$i"}, conv_i($pricegroup_id),
$form->{"ordnumber_$i"}, conv_date($form->{"transdate_$i"}),
$form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f',
- $form->{"marge_percent_$i"}, $form->{"marge_total_$i"},
+ $form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"},
$form->{"lastcost_$i"},
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
conv_i($form->{"marge_price_factor_$i"}));
$form->{"sellprice_$i"} = $fxsellprice;
$form->{"discount_$i"} *= 100;
+
+ CVar->save_custom_variables(module => 'IC',
+ sub_module => 'orderitems',
+ trans_id => $orderitems_id,
+ configs => $ic_cvar_configs,
+ variables => $form,
+ name_prefix => 'ic_',
+ name_postfix => "_$i",
+ dbh => $dbh);
}
}
globalproject_id = ?, employee_id = ?, salesman_id = ?, cp_id = ?, transaction_description = ?, marge_total = ?, marge_percent = ?
WHERE id = ?|;
- @values = ($form->{ordnumber}, $form->{quonumber},
+ @values = ($form->{ordnumber} || '', $form->{quonumber},
$form->{cusordnumber}, conv_date($form->{transdate}),
conv_i($form->{vendor_id}), conv_i($form->{customer_id}),
$amount, $netamount, conv_date($reqdate),
$form->save_status($dbh);
# Link this record to the records it was created from.
- RecordLinks->create_links('dbh' => $dbh,
- 'mode' => 'ids',
- 'from_table' => 'oe',
- 'from_ids' => $form->{convert_from_oe_ids},
- 'to_table' => 'oe',
- 'to_id' => $form->{id},
- );
+ $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};
+ if (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 (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
if ($form->{vc} eq 'customer') {
$form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $form->{exchangerate}, 0);
$form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
"quonumber" : "ordnumber"};
- Common::webdav_folder($form) if ($main::webdav);
+ Common::webdav_folder($form);
my $rc = $dbh->commit;
- $dbh->disconnect;
+
+ $self->save_periodic_invoices_config(dbh => $dbh,
+ oe_id => $form->{id},
+ config_yaml => $form->{periodic_invoices_config})
+ if ($form->{type} eq 'sales_order');
$main::lxdebug->leave_sub();
return $rc;
}
-# this function closes multiple orders given in $form->{ordnumber_#}.
-# use this for multiple orders that don't have to be saved back
-# single orders should use OE::save instead.
-sub close_orders {
- $main::lxdebug->enter_sub();
+sub save_periodic_invoices_config {
+ my ($self, %params) = @_;
- my ($self, $myconfig, $form) = @_;
+ return if !$params{oe_id};
- # get ids from $form
- map { push @ids, $form->{"ordnumber_$_"} if $form->{"ordnumber_$_"} }
- (1 .. $form->{rowcount});
+ my $config = $params{config_yaml} ? YAML::Load($params{config_yaml}) : undef;
+ return if 'HASH' ne ref $config;
- my $dbh = $form->dbconnect($myconfig);
- $query = qq|UPDATE oe SET | .
- qq|closed = TRUE | .
- qq|WHERE ordnumber IN (|
- . join(', ', map { $dbh->quote($_) } @ids) . qq|)|;
- $dbh->do($query) || $form->dberror($query);
- $dbh->disconnect;
+ my $obj = SL::DB::Manager::PeriodicInvoicesConfig->find_by(oe_id => $params{oe_id})
+ || SL::DB::PeriodicInvoicesConfig->new(oe_id => $params{oe_id});
+ $obj->update_attributes(%{ $config });
+}
- $main::lxdebug->leave_sub();
+sub load_periodic_invoice_config {
+ my $self = shift;
+ my $form = shift;
+
+ delete $form->{periodic_invoices_config};
+
+ if ($form->{id}) {
+ my $config_obj = SL::DB::Manager::PeriodicInvoicesConfig->find_by(oe_id => $form->{id});
+
+ if ($config_obj) {
+ my $config = { map { $_ => $config_obj->$_ } qw(active terminated periodicity start_date_as_date end_date_as_date extend_automatically_by ar_chart_id
+ print printer_id copies) };
+ $form->{periodic_invoices_config} = YAML::Dump($config);
+ }
+ }
}
-sub close_order {
+sub _close_quotations_rfqs {
$main::lxdebug->enter_sub();
- my ($self, $myconfig, $form) = @_;
+ my $self = shift;
+ my %params = @_;
- return $main::lxdebug->leave_sub() unless ($form->{"id"});
+ Common::check_params(\%params, qw(from_id to_id));
- my $dbh = $form->dbconnect($myconfig);
- do_query($form, $dbh, qq|UPDATE oe SET closed = TRUE where id = ?|,
- $form->{"id"});
- $dbh->disconnect;
+ my $myconfig = \%main::myconfig;
+ my $form = $main::form;
+
+ my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+ my $query = qq|SELECT quotation FROM oe WHERE id = ?|;
+ my $sth = prepare_query($form, $dbh, $query);
+
+ do_statement($form, $sth, $query, conv_i($params{to_id}));
+
+ my ($quotation) = $sth->fetchrow_array();
+
+ if ($quotation) {
+ $main::lxdebug->leave_sub();
+ return;
+ }
+
+ my @close_ids;
+
+ 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);
+ }
+
+ $sth->finish();
+
+ 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);
+
+ $dbh->commit() unless ($params{dbh});
+ }
$main::lxdebug->leave_sub();
}
sub delete {
$main::lxdebug->enter_sub();
- my ($self, $myconfig, $form, $spool) = @_;
+ my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->dbconnect_noauto($myconfig);
+ my $dbh = $form->get_standard_dbh;
+ $dbh->begin_work;
# delete spool files
my $query = qq|SELECT s.spoolfile FROM status s | .
qq|WHERE s.trans_id = ?|;
my @values = (conv_i($form->{id}));
- $sth = $dbh->prepare($query);
+ my $sth = $dbh->prepare($query);
$sth->execute(@values) || $self->dberror($query);
my $spoolfile;
# delete-values
@values = (conv_i($form->{id}));
+ # periodic invoices and their configuration
+ do_query($form, $dbh, qq|DELETE FROM periodic_invoices WHERE config_id IN (SELECT id FROM periodic_invoices_configs WHERE oe_id = ?)|, @values);
+ do_query($form, $dbh, qq|DELETE FROM periodic_invoices_configs WHERE oe_id = ?|, @values);
+
# delete status entries
$query = qq|DELETE FROM status | .
qq|WHERE trans_id = ?|;
do_query($form, $dbh, $query, @values);
my $rc = $dbh->commit;
- $dbh->disconnect;
if ($rc) {
+ my $spool = $::lx_office_conf{paths}->{spool};
foreach $spoolfile (@spoolfiles) {
unlink "$spool/$spoolfile" if $spoolfile;
}
my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->dbconnect_noauto($myconfig);
+ my $dbh = $form->get_standard_dbh;
my ($query, $query_add, @values, @ids, $sth);
+ my $ic_cvar_configs = CVar->get_configs(module => 'IC',
+ dbh => $dbh);
+
# translate the ids (given by id_# and trans_id_#) into one array of ids, so we can join them later
map {
push @ids, $form->{"trans_id_$_"}
undef @ids;
}
- my $query_add = '';
+ # and remember for the rest of the function
+ my $is_collective_order = scalar @ids;
+
if (!$form->{id}) {
my $wday = (localtime(time))[6];
my $next_workday = $wday == 5 ? 3 : $wday == 6 ? 2 : 1;
JOIN ${vc} cv ON (o.${vc}_id = cv.id)
LEFT JOIN employee e ON (o.employee_id = e.id)
LEFT JOIN department d ON (o.department_id = d.id) | .
- ($form->{id}
- ? "WHERE o.id = ?"
+ ($form->{id}
+ ? "WHERE o.id = ?"
: "WHERE o.id IN (" . join(', ', map("? ", @ids)) . ")"
);
@values = $form->{id} ? ($form->{id}) : @ids;
$sth = prepare_execute_query($form, $dbh, $query, @values);
- $ref = $sth->fetchrow_hashref(NAME_lc);
- map { $form->{$_} = $ref->{$_} } keys %$ref;
+ $ref = $sth->fetchrow_hashref("NAME_lc");
+
+ if ($ref) {
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+ # remove any trailing whitespace
+ $form->{currency} =~ s/\s*$//;
- $form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
- "quonumber" : "ordnumber"};
+ $form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ? "quonumber" : "ordnumber"};
- # set all entries for multiple ids blank that yield different information
- while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
- map { $form->{$_} = '' if ($ref->{$_} ne $form->{$_}) } keys %$ref;
+ # set all entries for multiple ids blank that yield different information
+ while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
+ map { $form->{$_} = '' if ($ref->{$_} ne $form->{$_}) } keys %$ref;
+ }
}
# if not given, fill transdate with current_date
$query = qq|SELECT s.* FROM shipto s WHERE s.trans_id = ? AND s.module = 'OE'|;
$sth = prepare_execute_query($form, $dbh, $query, $form->{id});
- $ref = $sth->fetchrow_hashref(NAME_lc);
+ $ref = $sth->fetchrow_hashref("NAME_lc");
delete($ref->{id});
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
$query = qq|SELECT s.printed, s.emailed, s.spoolfile, s.formname FROM status s WHERE s.trans_id = ?|;
$sth = prepare_execute_query($form, $dbh, $query, $form->{id});
- while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
$form->{printed} .= "$ref->{formname} " if $ref->{printed};
$form->{emailed} .= "$ref->{formname} " if $ref->{emailed};
$form->{queued} .= "$ref->{formname} $ref->{spoolfile} " if $ref->{spoolfile};
# stuff different from the whole will not be overwritten, but saved with a suffix.
$query =
qq|SELECT o.id AS orderitems_id,
- c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid,
+ c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid,
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, o.description, o.qty,
+ p.partnumber, p.assembly, p.listprice, o.description, o.qty,
o.sellprice, o.parts_id AS id, o.unit, o.discount, p.bin, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id,
o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost,
o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription,
@ids = $form->{id} ? ($form->{id}) : @ids;
$sth = prepare_execute_query($form, $dbh, $query, @values);
- while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
+ # Retrieve custom variables.
+ my $cvars = CVar->get_custom_variables(dbh => $dbh,
+ module => 'IC',
+ sub_module => 'orderitems',
+ trans_id => $ref->{orderitems_id},
+ );
+ map { $ref->{"ic_cvar_$_->{name}"} = $_->{value} } @{ $cvars };
+
+ # Handle accounts.
if (!$ref->{"part_inventory_accno_id"}) {
map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid));
}
delete $ref->{orderitems_id} if (@ids);
# get tax rates and description
- $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno};
+ my $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno};
$query =
qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber | .
qq|FROM tax t LEFT JOIN chart c on (c.id = t.chart_id) | .
qq| WHERE tk.chart_id = (SELECT id FROM chart WHERE accno = ?) | .
qq| AND startdate <= $transdate ORDER BY startdate DESC LIMIT 1) | .
qq|ORDER BY c.accno|;
- $stw = prepare_execute_query($form, $dbh, $query, $accno_id);
+ my $stw = prepare_execute_query($form, $dbh, $query, $accno_id);
$ref->{taxaccounts} = "";
my $i = 0;
- while ($ptr = $stw->fetchrow_hashref(NAME_lc)) {
+ while (my $ptr = $stw->fetchrow_hashref("NAME_lc")) {
if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) {
$i++;
$ptr->{accno} = $i;
}
chop $ref->{taxaccounts};
+
push @{ $form->{form_details} }, $ref;
$stw->finish;
}
$form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? "buy" : "sell");
- Common::webdav_folder($form) if ($main::webdav);
+ Common::webdav_folder($form);
+
+ $self->load_periodic_invoice_config($form);
my $rc = $dbh->commit;
- $dbh->disconnect;
$main::lxdebug->leave_sub();
return $rc;
}
+sub retrieve_simple {
+ $main::lxdebug->enter_sub();
+
+ my $self = shift;
+ my %params = @_;
+
+ Common::check_params(\%params, qw(id));
+
+ my $myconfig = \%main::myconfig;
+ my $form = $main::form;
+
+ my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+ my $oe_query = qq|SELECT * FROM oe WHERE id = ?|;
+ my $oi_query = qq|SELECT * FROM orderitems WHERE trans_id = ?|;
+
+ my $order = selectfirst_hashref_query($form, $dbh, $oe_query, conv_i($params{id}));
+ $order->{orderitems} = selectall_hashref_query( $form, $dbh, $oi_query, conv_i($params{id}));
+
+ $main::lxdebug->leave_sub();
+
+ return $order;
+}
+
sub order_details {
$main::lxdebug->enter_sub();
my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->dbconnect($myconfig);
+ my $dbh = $form->get_standard_dbh;
my $query;
my @values = ();
my $sth;
my $position = 0;
my $subtotal_header = 0;
my $subposition = 0;
+ my %taxaccounts;
+ my %taxbase;
+ my $tax_rate;
+ my $taxamount;
+
my %oid = ('Pg' => 'oid',
'Oracle' => 'rowid');
- my (@project_ids, %projectnumbers);
+ my (@project_ids, %projectnumbers, %projectdescriptions);
push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"});
- $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS');
+ $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
+ 'departments' => 'ALL_DEPARTMENTS');
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 = "";
}
if (@project_ids) {
- $query = "SELECT id, projectnumber FROM project WHERE id IN (" .
+ $query = "SELECT id, projectnumber, description FROM project WHERE id IN (" .
join(", ", map("?", @project_ids)) . ")";
$sth = prepare_execute_query($form, $dbh, $query, @project_ids);
while (my $ref = $sth->fetchrow_hashref()) {
$projectnumbers{$ref->{id}} = $ref->{projectnumber};
+ $projectdescriptions{$ref->{id}} = $ref->{description};
}
$sth->finish();
}
$form->{"globalprojectnumber"} = $projectnumbers{$form->{"globalproject_id"}};
+ $form->{"globalprojectdescription"} = $projectdescriptions{$form->{"globalproject_id"}};
+
+ $form->{discount} = [];
+
+ $form->{TEMPLATE_ARRAYS} = { };
+ IC->prepare_parts_for_printing();
+
+ my $ic_cvar_configs = CVar->get_configs(module => 'IC');
my @arrays =
qw(runningnumber number description longdescription qty ship unit bin
partnotes serialnumber reqdate sellprice listprice netprice
discount p_discount discount_sub nodiscount_sub
- linetotal nodiscount_linetotal tax_rate projectnumber
- price_factor price_factor_name);
+ linetotal nodiscount_linetotal tax_rate projectnumber projectdescription
+ price_factor price_factor_name partsgroup);
+
+ push @arrays, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
+
+ my @tax_arrays = qw(taxbase tax taxdescription taxrate taxnumber);
+
+ map { $form->{TEMPLATE_ARRAYS}->{$_} = [] } (@arrays, @tax_arrays);
my $sameitem = "";
foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
$i = $item->[0];
if ($item->[1] ne $sameitem) {
- push(@{ $form->{description} }, qq|$item->[1]|);
+ push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, qq|$item->[1]|);
$sameitem = $item->[1];
- map({ push(@{ $form->{$_} }, "") } grep({ $_ ne "description" } @arrays));
+ map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
}
$form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
my $price_factor = $price_factors{$form->{"price_factor_id_$i"}} || { 'factor' => 1 };
- push @{ $form->{runningnumber} }, $position;
- push @{ $form->{number} }, $form->{"partnumber_$i"};
- push @{ $form->{description} }, $form->{"description_$i"};
- push @{ $form->{longdescription} }, $form->{"longdescription_$i"};
- push @{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"});
- push @{ $form->{ship} }, $form->format_amount($myconfig, $form->{"ship_$i"});
- push @{ $form->{unit} }, $form->{"unit_$i"};
- push @{ $form->{bin} }, $form->{"bin_$i"};
- push @{ $form->{partnotes} }, $form->{"partnotes_$i"};
- push @{ $form->{serialnumber} }, $form->{"serialnumber_$i"};
- push @{ $form->{reqdate} }, $form->{"reqdate_$i"};
- push @{ $form->{sellprice} }, $form->{"sellprice_$i"};
- push @{ $form->{listprice} }, $form->{"listprice_$i"};
- push @{ $form->{price_factor} }, $price_factor->{formatted_factor};
- push @{ $form->{price_factor_name} }, $price_factor->{description};
+ push @{ $form->{TEMPLATE_ARRAYS}->{runningnumber} }, $position;
+ push @{ $form->{TEMPLATE_ARRAYS}->{number} }, $form->{"partnumber_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{description} }, $form->{"description_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{longdescription} }, $form->{"longdescription_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"});
+ push @{ $form->{TEMPLATE_ARRAYS}->{qty_nofmt} }, $form->{"qty_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{ship} }, $form->format_amount($myconfig, $form->{"ship_$i"});
+ push @{ $form->{TEMPLATE_ARRAYS}->{ship_nofmt} }, $form->{"ship_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{unit} }, $form->{"unit_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{bin} }, $form->{"bin_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{partnotes} }, $form->{"partnotes_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{serialnumber} }, $form->{"serialnumber_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{reqdate} }, $form->{"reqdate_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{sellprice} }, $form->{"sellprice_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{sellprice_nofmt} }, $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+ push @{ $form->{TEMPLATE_ARRAYS}->{listprice} }, $form->{"listprice_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{price_factor} }, $price_factor->{formatted_factor};
+ push @{ $form->{TEMPLATE_ARRAYS}->{price_factor_name} }, $price_factor->{description};
+ push @{ $form->{TEMPLATE_ARRAYS}->{partsgroup} }, $form->{"partsgroup_$i"};
my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
my ($dec) = ($sellprice =~ /\.(\d+)/);
my $decimalplaces = max 2, length($dec);
- my $discount = $form->round_amount($form->{"qty_$i"} * $sellprice * $form->{"discount_$i"} / 100 / $price_factor->{factor}, $decimalplaces);
- my $linetotal = $form->round_amount($form->{"qty_$i"} * $sellprice * (100 - $form->{"discount_$i"}) / 100 / $price_factor->{factor}, 2);
+ my $parsed_discount = $form->parse_amount($myconfig, $form->{"discount_$i"});
+ my $linetotal_exact = $form->{"qty_$i"} * $sellprice * (100 - $parsed_discount) / 100 / $price_factor->{factor};
+ my $linetotal = $form->round_amount($linetotal_exact, 2);
+ my $discount = $form->round_amount($form->{"qty_$i"} * $sellprice * $parsed_discount / 100 / $price_factor->{factor} - ($linetotal - $linetotal_exact),
+ $decimalplaces);
my $nodiscount_linetotal = $form->round_amount($form->{"qty_$i"} * $sellprice / $price_factor->{factor}, 2);
$form->{"netprice_$i"} = $form->round_amount($form->{"qty_$i"} ? ($linetotal / $form->{"qty_$i"}) : 0, 2);
- push @{ $form->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : '';
+ push @{ $form->{TEMPLATE_ARRAYS}->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : '';
+ push @{ $form->{TEMPLATE_ARRAYS}->{netprice_nofmt} }, ($form->{"netprice_$i"} != 0) ? $form->{"netprice_$i"} : '';
$linetotal = ($linetotal != 0) ? $linetotal : '';
- push @{ $form->{discount} }, ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, $decimalplaces) : '';
- push @{ $form->{p_discount} }, $form->{"discount_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{discount} }, ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, 2) : '';
+ push @{ $form->{TEMPLATE_ARRAYS}->{discount_nofmt} }, ($discount != 0) ? $discount * -1 : '';
+ push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} }, $form->{"discount_$i"};
$form->{ordtotal} += $linetotal;
$form->{nodiscount_total} += $nodiscount_linetotal;
}
if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) {
- push @{ $form->{discount_sub} }, $form->format_amount($myconfig, $discount_subtotal, 2);
- push @{ $form->{nodiscount_sub} }, $form->format_amount($myconfig, $nodiscount_subtotal, 2);
+ push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, $form->format_amount($myconfig, $discount_subtotal, 2);
+ push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub_nofmt} }, $discount_subtotal;
+ push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, $form->format_amount($myconfig, $nodiscount_subtotal, 2);
+ push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub_nofmt} }, $nodiscount_subtotal;
$discount_subtotal = 0;
$nodiscount_subtotal = 0;
$subtotal_header = 0;
} else {
- push @{ $form->{discount_sub} }, "";
- push @{ $form->{nodiscount_sub} }, "";
+ push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, "";
+ push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, "";
}
if (!$form->{"discount_$i"}) {
$nodiscount += $linetotal;
}
- push @{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2);
- push @{ $form->{nodiscount_linetotal} }, $form->format_amount($myconfig, $nodiscount_linetotal, 2);
-
- push(@{ $form->{projectnumber} }, $projectnumbers{$form->{"project_id_$i"}});
+ push @{ $form->{TEMPLATE_ARRAYS}->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2);
+ push @{ $form->{TEMPLATE_ARRAYS}->{linetotal_nofmt} }, $linetotal_exact;
+ push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_linetotal} }, $form->format_amount($myconfig, $nodiscount_linetotal, 2);
+ push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_linetotal_nofmt} }, $nodiscount_linetotal;
+ push(@{ $form->{TEMPLATE_ARRAYS}->{projectnumber} }, $projectnumbers{$form->{"project_id_$i"}});
+ push(@{ $form->{TEMPLATE_ARRAYS}->{projectdescription} }, $projectdescriptions{$form->{"project_id_$i"}});
my ($taxamount, $taxbase);
my $taxrate = 0;
}
if ($taxamount != 0) {
- foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
- $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
- $taxbase{$item} += $taxbase;
+ foreach my $accno (split / /, $form->{"taxaccounts_$i"}) {
+ $taxaccounts{$accno} += $taxamount * $form->{"${accno}_rate"} / $taxrate;
+ $taxbase{$accno} += $taxbase;
}
}
$tax_rate = $taxrate * 100;
- push(@{ $form->{tax_rate} }, qq|$tax_rate|);
+ push(@{ $form->{TEMPLATE_ARRAYS}->{tax_rate} }, qq|$tax_rate|);
if ($form->{"assembly_$i"}) {
$sameitem = "";
}
$query = qq|SELECT p.partnumber, p.description, p.unit, a.qty, | .
- qq|pg.partsgroup | .
- qq|FROM assembly a | .
- qq| JOIN parts p ON (a.parts_id = p.id) | .
- qq| LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | .
- qq| WHERE a.bom = '1' | .
- qq| AND a.id = ? | . $sortorder;
- @values = ($form->{"id_$i"});
+ qq|pg.partsgroup | .
+ qq|FROM assembly a | .
+ qq| JOIN parts p ON (a.parts_id = p.id) | .
+ qq| LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | .
+ qq| WHERE a.bom = '1' | .
+ qq| AND a.id = ? | . $sortorder;
+ @values = ($form->{"id_$i"});
$sth = $dbh->prepare($query);
$sth->execute(@values) || $form->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
- map({ push(@{ $form->{$_} }, "") } grep({ $_ ne "description" } @arrays));
+ map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
$sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
- push(@{ $form->{description} }, $sameitem);
+ push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $sameitem);
}
- push(@{ $form->{description} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq|, $ref->{partnumber}, $ref->{description}|);
- map({ push(@{ $form->{$_} }, "") } grep({ $_ ne "description" } @arrays));
+ push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq|, $ref->{partnumber}, $ref->{description}|);
+ map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
}
$sth->finish;
}
+ push @{ $form->{TEMPLATE_ARRAYS}->{"ic_cvar_$_->{name}"} },
+ CVar->format_to_template(CVar->parse($form->{"ic_cvar_$_->{name}_$i"}, $_), $_)
+ for @{ $ic_cvar_configs };
}
}
my $tax = 0;
foreach $item (sort keys %taxaccounts) {
- push(@{ $form->{taxbase} },
- $form->format_amount($myconfig, $taxbase{$item}, 2));
-
$tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
- push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
- push(@{ $form->{taxdescription} }, $form->{"${item}_description"} . q{ } . 100 * $form->{"${item}_rate"} . q{%});
- push(@{ $form->{taxrate} },
- $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
- push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"});
+ push(@{ $form->{TEMPLATE_ARRAYS}->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
+ push(@{ $form->{TEMPLATE_ARRAYS}->{taxbase_nofmt} }, $taxbase{$item});
+ push(@{ $form->{TEMPLATE_ARRAYS}->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
+ push(@{ $form->{TEMPLATE_ARRAYS}->{tax_nofmt} }, $taxamount);
+ push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
+ push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate_nofmt} }, $form->{"${item}_rate"} * 100);
+ push(@{ $form->{TEMPLATE_ARRAYS}->{taxdescription} }, $form->{"${item}_description"} . q{ } . 100 * $form->{"${item}_rate"} . q{%});
+ push(@{ $form->{TEMPLATE_ARRAYS}->{taxnumber} }, $form->{"${item}_taxnumber"});
}
$form->{nodiscount_subtotal} = $form->format_amount($myconfig, $form->{nodiscount_total}, 2);
$form->{yesdiscount} = $form->format_amount($myconfig, $form->{nodiscount_total} - $nodiscount, 2);
if($form->{taxincluded}) {
- $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal} - $tax, 2);
+ $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal} - $tax, 2);
+ $form->{subtotal_nofmt} = $form->{ordtotal} - $tax;
} else {
- $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
+ $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
+ $form->{subtotal_nofmt} = $form->{ordtotal};
}
$form->{ordtotal} = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
my ($self, $dbh, $id) = @_;
my $query = qq|SELECT description FROM project WHERE id = ?|;
- my ($value) = selectrow_query($form, $dbh, $query, $id);
+ my ($value) = selectrow_query($main::form, $dbh, $query, $id);
$main::lxdebug->leave_sub();
}
1;
+
+__END__
+
+=head1 NAME
+
+OE.pm - Order entry module
+
+=head1 DESCRIPTION
+
+OE.pm is part of the OE module. OE is responsible for sales and purchase orders, as well as sales quotations and purchase requests. This file abstracts the database tables C<oe> and C<orderitems>.
+
+=head1 FUNCTIONS
+
+=over 4
+
+=item retrieve_simple PARAMS
+
+simple OE retrieval by id. does not look up customer, vendor, units or any other stuff. only oe and orderitems.
+
+ my $order = retrieve_simple(id => 2);
+
+ $order => {
+ %_OE_CONTENT,
+ orderitems => [
+ %_ORDERITEM_ROW_1,
+ %_ORDERITEM_ROW_2,
+ ...
+ ]
+ }
+
+=back
+
+=cut