package OE;
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 @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| ex.$rate AS exchangerate, | .
qq| pr.projectnumber AS globalprojectnumber, | .
qq| e.name AS employee, s.name AS salesman, | .
- qq| ct.country, ct.ustid | .
+ 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);
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});
push(@values, '%' . $form->{transaction_description} . '%');
}
+ if ($form->{periodic_invoices_active} ne $form->{periodic_invoices_inactive}) {
+ my $not = 'NOT' if ($form->{periodic_invoices_inactive});
+ $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 = (
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};
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 $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;
}
$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->{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;
}
+sub save_periodic_invoices_config {
+ my ($self, %params) = @_;
+
+ return if !$params{oe_id};
+
+ my $config = $params{config_yaml} ? YAML::Load($params{config_yaml}) : undef;
+ return if 'HASH' ne ref $config;
+
+ 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 });
+}
+
+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_quotations_rfqs {
$main::lxdebug->enter_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 $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 = ?|;
$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);
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;
@values = $form->{id} ? ($form->{id}) : @ids;
$sth = prepare_execute_query($form, $dbh, $query, @values);
- $ref = $sth->fetchrow_hashref(NAME_lc);
+ $ref = $sth->fetchrow_hashref("NAME_lc");
map { $form->{$_} = $ref->{$_} } keys %$ref;
$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)) {
+ while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
map { $form->{$_} = '' if ($ref->{$_} ne $form->{$_}) } keys %$ref;
}
$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};
@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',
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;
$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 $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"});
}
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} = [];
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
+ linetotal nodiscount_linetotal tax_rate projectnumber projectdescription
price_factor price_factor_name partsgroup);
push @arrays, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_linetotal} }, $form->format_amount($myconfig, $nodiscount_linetotal, 2);
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;
}
$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->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
$sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
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