-
- if ($form->{eur} && ($form->{item} ne 'service')) {
- $form->{IC} = $form->{IC_expense};
- }
-
- ($form->{inventory_accno}) = split(/--/, $form->{IC});
- ($form->{expense_accno}) = split(/--/, $form->{IC_expense});
- ($form->{income_accno}) = split(/--/, $form->{IC_income});
-
- # connect to database, turn off AutoCommit
- my $dbh = $form->dbconnect_noauto($myconfig);
-
- # save the part
- # make up a unique handle and store in partnumber field
- # then retrieve the record based on the unique handle to get the id
- # replace the partnumber field with the actual variable
- # add records for makemodel
-
- # if there is a $form->{id} then replace the old entry
- # delete all makemodel entries and add the new ones
-
- # escape '
- map { $form->{$_} =~ s/\'/\'\'/g } qw(partnumber description notes unit);
-
- # undo amount formatting
- map { $form->{$_} = $form->parse_amount($myconfig, $form->{$_}) }
- qw(rop weight listprice sellprice gv lastcost stock);
-
- # set date to NULL if nothing entered
- $form->{priceupdate} =
- ($form->{priceupdate}) ? qq|'$form->{priceupdate}'| : "NULL";
-
- $form->{makemodel} = (($form->{make_1}) || ($form->{model_1})) ? 1 : 0;
-
- $form->{alternate} = 0;
- $form->{assembly} = ($form->{item} eq 'assembly') ? 1 : 0;
- $form->{obsolete} *= 1;
- $form->{shop} *= 1;
- $form->{onhand} *= 1;
- $form->{ve} *= 1;
- $form->{ge} *= 1;
-
- my ($query, $sth);
-
- if ($form->{id}) {
-
- # get old price
- $query = qq|SELECT p.sellprice, p.weight
- FROM parts p
- WHERE p.id = $form->{id}|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- my ($sellprice, $weight) = $sth->fetchrow_array;
- $sth->finish;
-
- # if item is part of an assembly adjust all assemblies
- $query = qq|SELECT a.id, a.qty
- FROM assembly a
- WHERE a.parts_id = $form->{id}|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- while (my ($id, $qty) = $sth->fetchrow_array) {
- &update_assembly($dbh, $form, $id, $qty, $sellprice * 1, $weight * 1);
+ my $dbh = $form->get_standard_dbh($myconfig);
+
+ # sanity backend check
+ croak "Cannot combine soldtotal with default bin or default warehouse" if ($form->{l_soldtotal} && ($form->{l_bin} || $form->{l_warehouse}));
+
+ $form->{parts} = +{ };
+ $form->{soldtotal} = undef if $form->{l_soldtotal}; # security fix. top100 insists on putting strings in there...
+
+ my @simple_filters = qw(partnumber ean description partsgroup microfiche drawing onhand);
+ my @project_filters = qw(projectnumber projectdescription);
+ my @makemodel_filters = qw(make model);
+ my @invoice_oi_filters = qw(serialnumber soldtotal);
+ my @apoe_filters = qw(transdate);
+ my @like_filters = (@simple_filters, @invoice_oi_filters);
+ my @all_columns = (@simple_filters, @makemodel_filters, @apoe_filters, @project_filters, qw(serialnumber));
+ my @simple_l_switches = (@all_columns, qw(notes listprice sellprice lastcost priceupdate weight unit rop image shop insertdate));
+ my %no_simple_l_switches = (warehouse => 'wh.description as warehouse', bin => 'bin.description as bin');
+ my @oe_flags = qw(bought sold onorder ordered rfq quoted);
+ my @qsooqr_flags = qw(invnumber ordnumber quonumber trans_id name module qty);
+ my @deliverydate_flags = qw(deliverydate);
+# my @other_flags = qw(onhand); # ToDO: implement these
+# my @inactive_flags = qw(l_subtotal short l_linetotal);
+
+ my @select_tokens = qw(id factor part_type classification_id);
+ my @where_tokens = qw(1=1);
+ my @group_tokens = ();
+ my @bind_vars = ();
+ my %joins_needed = ();
+
+ my %joins = (
+ partsgroup => 'LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)',
+ makemodel => 'LEFT JOIN makemodel mm ON (mm.parts_id = p.id)',
+ pfac => 'LEFT JOIN price_factors pfac ON (pfac.id = p.price_factor_id)',
+ invoice_oi =>
+ q|LEFT JOIN (
+ SELECT parts_id, description, serialnumber, trans_id, unit, sellprice, qty, assemblyitem, deliverydate, 'invoice' AS ioi, project_id, id FROM invoice UNION
+ SELECT parts_id, description, serialnumber, trans_id, unit, sellprice, qty, FALSE AS assemblyitem, NULL AS deliverydate, 'orderitems' AS ioi, project_id, id FROM orderitems
+ ) AS ioi ON ioi.parts_id = p.id|,
+ apoe =>
+ q|LEFT JOIN (
+ SELECT id, transdate, 'ir' AS module, ordnumber, quonumber, invnumber, FALSE AS quotation, NULL AS customer_id, vendor_id, NULL AS deliverydate, globalproject_id, 'invoice' AS ioi FROM ap UNION
+ SELECT id, transdate, 'is' AS module, ordnumber, quonumber, invnumber, FALSE AS quotation, customer_id, NULL AS vendor_id, deliverydate, globalproject_id, 'invoice' AS ioi FROM ar UNION
+ SELECT id, transdate, 'oe' AS module, ordnumber, quonumber, NULL AS invnumber, quotation, customer_id, vendor_id, reqdate AS deliverydate, globalproject_id, 'orderitems' AS ioi FROM oe
+ ) AS apoe ON ((ioi.trans_id = apoe.id) AND (ioi.ioi = apoe.ioi))|,
+ cv =>
+ q|LEFT JOIN (
+ SELECT id, name, 'customer' AS cv FROM customer UNION
+ SELECT id, name, 'vendor' AS cv FROM vendor
+ ) AS cv ON cv.id = apoe.customer_id OR cv.id = apoe.vendor_id|,
+ mv => 'LEFT JOIN vendor AS mv ON mv.id = mm.make',
+ project => 'LEFT JOIN project AS pj ON pj.id = COALESCE(ioi.project_id, apoe.globalproject_id)',
+ warehouse => 'LEFT JOIN warehouse AS wh ON wh.id = p.warehouse_id',
+ bin => 'LEFT JOIN bin ON bin.id = p.bin_id',
+ );
+ my @join_order = qw(partsgroup makemodel mv invoice_oi apoe cv pfac project warehouse bin);
+
+ my %table_prefix = (
+ deliverydate => 'apoe.', serialnumber => 'ioi.',
+ transdate => 'apoe.', trans_id => 'ioi.',
+ module => 'apoe.', name => 'cv.',
+ ordnumber => 'apoe.', make => 'mm.',
+ quonumber => 'apoe.', model => 'mm.',
+ invnumber => 'apoe.', partsgroup => 'pg.',
+ lastcost => 'p.', , soldtotal => ' ',
+ factor => 'pfac.', projectnumber => 'pj.',
+ 'SUM(ioi.qty)' => ' ', projectdescription => 'pj.',
+ description => 'p.',
+ qty => 'ioi.',
+ serialnumber => 'ioi.',
+ quotation => 'apoe.',
+ cv => 'cv.',
+ "ioi.id" => ' ',
+ "ioi.ioi" => ' ',
+ );
+
+ # if the join condition in these blocks are met, the column
+ # of the specified table will gently override (coalesce actually) the original value
+ # use it to conditionally coalesce values from subtables
+ my @column_override = (
+ # column name, prefix, joins_needed, nick name (in case column is named like another)
+ [ 'description', 'ioi.', 'invoice_oi' ],
+ [ 'deliverydate', 'ioi.', 'invoice_oi' ],
+ [ 'transdate', 'apoe.', 'apoe' ],
+ [ 'unit', 'ioi.', 'invoice_oi' ],
+ [ 'sellprice', 'ioi.', 'invoice_oi' ],
+ );
+
+ # careful with renames. these are HARD, and any filters done on the original column will break
+ my %renamed_columns = (
+ 'factor' => 'price_factor',
+ 'SUM(ioi.qty)' => 'soldtotal',
+ 'ioi.id' => 'ioi_id',
+ 'ioi.ioi' => 'ioi',
+ 'projectdescription' => 'projectdescription',
+ 'insertdate' => 'insertdate',
+ );
+
+ my %real_column = (
+ projectdescription => 'description',
+ insertdate => 'itime::DATE',
+ );
+
+ my $make_token_builder = sub {
+ my $joins_needed = shift;
+ sub {
+ my ($nick, $alias) = @_;
+ my ($col) = $real_column{$nick} || $nick;
+ my @coalesce_tokens =
+ map { ($_->[1] || 'p.') . $_->[0] }
+ grep { !$_->[2] || $joins_needed->{$_->[2]} }
+ grep { ($_->[3] || $_->[0]) eq $nick }
+ @column_override, [ $col, $table_prefix{$nick}, undef , $nick ];
+
+ my $coalesce = scalar @coalesce_tokens > 1;
+ return ($coalesce
+ ? sprintf 'COALESCE(%s)', join ', ', @coalesce_tokens
+ : shift @coalesce_tokens)
+ . ($alias && ($coalesce || $renamed_columns{$nick})
+ ? " AS " . ($renamed_columns{$nick} || $nick)
+ : '');