diff options
author | christopherm <christopherm@4979c152-3d1c-0410-bac9-87ea11338e46> | 2006-09-01 01:16:38 +0000 |
---|---|---|
committer | christopherm <christopherm@4979c152-3d1c-0410-bac9-87ea11338e46> | 2006-09-01 01:16:38 +0000 |
commit | ac5b087ea2d9ba7428d367aaeb288534158fee9a (patch) | |
tree | 2dbe0bdea0b653a215ba9ddfdf627cb57855050d /bin/lynx |
Initial Import
git-svn-id: https://ledger-smb.svn.sourceforge.net/svnroot/ledger-smb/ledger-smb@1 4979c152-3d1c-0410-bac9-87ea11338e46
Diffstat (limited to 'bin/lynx')
-rwxr-xr-x | bin/lynx/aa.pl | 1693 | ||||
-rwxr-xr-x | bin/lynx/admin.pl | 1612 | ||||
-rwxr-xr-x | bin/lynx/am.pl | 3271 | ||||
-rwxr-xr-x | bin/lynx/ap.pl | 40 | ||||
-rwxr-xr-x | bin/lynx/ar.pl | 40 | ||||
-rwxr-xr-x | bin/lynx/arap.pl | 918 | ||||
-rwxr-xr-x | bin/lynx/arapprn.pl | 591 | ||||
-rwxr-xr-x | bin/lynx/bp.pl | 531 | ||||
-rwxr-xr-x | bin/lynx/ca.pl | 514 | ||||
-rwxr-xr-x | bin/lynx/cp.pl | 1392 | ||||
-rwxr-xr-x | bin/lynx/ct.pl | 2478 | ||||
-rwxr-xr-x | bin/lynx/gl.pl | 1128 | ||||
-rwxr-xr-x | bin/lynx/hr.pl | 1246 | ||||
-rwxr-xr-x | bin/lynx/ic.pl | 3238 | ||||
-rwxr-xr-x | bin/lynx/io.pl | 1683 | ||||
-rwxr-xr-x | bin/lynx/ir.pl | 845 | ||||
-rwxr-xr-x | bin/lynx/is.pl | 952 | ||||
-rwxr-xr-x | bin/lynx/jc.pl | 1912 | ||||
-rwxr-xr-x | bin/lynx/login.pl | 350 | ||||
-rwxr-xr-x | bin/lynx/menu.pl | 153 | ||||
-rwxr-xr-x | bin/lynx/oe.pl | 3023 | ||||
-rwxr-xr-x | bin/lynx/pe.pl | 2578 | ||||
-rwxr-xr-x | bin/lynx/pos.pl | 938 | ||||
-rwxr-xr-x | bin/lynx/ps.pl | 45 | ||||
-rwxr-xr-x | bin/lynx/pw.pl | 73 | ||||
-rwxr-xr-x | bin/lynx/rc.pl | 502 | ||||
-rwxr-xr-x | bin/lynx/rp.pl | 2351 |
27 files changed, 34097 insertions, 0 deletions
diff --git a/bin/lynx/aa.pl b/bin/lynx/aa.pl new file mode 100755 index 00000000..5fbb9c93 --- /dev/null +++ b/bin/lynx/aa.pl @@ -0,0 +1,1693 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2005 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# AR / AP +# +#====================================================================== + +# any custom scripts for this one +if (-f "$form->{path}/custom_aa.pl") { + eval { require "$form->{path}/custom_aa.pl"; }; +} +if (-f "$form->{path}/$form->{login}_aa.pl") { + eval { require "$form->{path}/$form->{login}_aa.pl"; }; +} + + +1; +# end of main + + +# this is for our long dates +# $locale->text('January') +# $locale->text('February') +# $locale->text('March') +# $locale->text('April') +# $locale->text('May ') +# $locale->text('June') +# $locale->text('July') +# $locale->text('August') +# $locale->text('September') +# $locale->text('October') +# $locale->text('November') +# $locale->text('December') + +# this is for our short month +# $locale->text('Jan') +# $locale->text('Feb') +# $locale->text('Mar') +# $locale->text('Apr') +# $locale->text('May') +# $locale->text('Jun') +# $locale->text('Jul') +# $locale->text('Aug') +# $locale->text('Sep') +# $locale->text('Oct') +# $locale->text('Nov') +# $locale->text('Dec') + + +sub add { + + $form->{title} = "Add"; + $form->{callback} = "$form->{script}?action=add&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &create_links; + + $form->{focus} = "amount_1"; + &display_form; + +} + + +sub edit { + + $form->{title} = "Edit"; + + &create_links; + &display_form; + +} + + +sub display_form { + + &form_header; + &form_footer; + +} + + +sub create_links { + + $form->create_links($form->{ARAP}, \%myconfig, $form->{vc}); + + $duedate = $form->{duedate}; + $taxincluded = $form->{taxincluded}; + + $form->{formname} = "transaction"; + $form->{format} = "postscript" if $myconfig{printer}; + $form->{media} = $myconfig{printer}; + + $form->{selectformname} = qq|<option value="transaction">|.$locale->text('Transaction'); + + if ($latex) { + if ($form->{ARAP} eq 'AR') { + $form->{selectformname} .= qq| + <option value="receipt">|.$locale->text('Receipt'); + } else { + $form->{selectformname} .= qq| + <option value="check">|.$locale->text('Check'); + } + } + + # currencies + @curr = split /:/, $form->{currencies}; + $form->{defaultcurrency} = $curr[0]; + chomp $form->{defaultcurrency}; + + for (@curr) { $form->{selectcurrency} .= "<option>$_\n" } + + AA->get_name(\%myconfig, \%$form); + + $form->{currency} =~ s/ //g; + $form->{duedate} = $duedate if $duedate; + $form->{taxincluded} = $taxincluded if $form->{id}; + + $form->{notes} = $form->{intnotes} if !$form->{id}; + + $form->{"old$form->{vc}"} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|; + $form->{oldtransdate} = $form->{transdate}; + + # customers/vendors + $form->{"select$form->{vc}"} = ""; + if (@{ $form->{"all_$form->{vc}"} }) { + $form->{$form->{vc}} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|; + for (@{ $form->{"all_$form->{vc}"} }) { $form->{"select$form->{vc}"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + $form->{department} = "$form->{department}--$form->{department_id}" if $form->{department_id}; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + $form->{employee} = "$form->{employee}--$form->{employee_id}"; + # sales staff + if (@{ $form->{all_employee} }) { + $form->{selectemployee} = ""; + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + # projects + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + } + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + # forex + $form->{forex} = $form->{exchangerate}; + $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1; + + $netamount = 0; + $tax = 0; + $taxrate = 0; + $ml = ($form->{ARAP} eq 'AR') ? 1 : -1; + + foreach $key (keys %{ $form->{"$form->{ARAP}_links"} }) { + + $form->{"select$key"} = ""; + foreach $ref (@{ $form->{"$form->{ARAP}_links"}{$key} }) { + if ($key eq "$form->{ARAP}_tax") { + $form->{"select$form->{ARAP}_tax_$ref->{accno}"} = "<option>$ref->{accno}--$ref->{description}\n"; + next; + } + $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n"; + } + + # if there is a value we have an old entry + for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) { + if ($key eq "$form->{ARAP}_paid") { + $form->{"$form->{ARAP}_paid_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; + $form->{"paid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount} * -1 * $ml; + $form->{"datepaid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{transdate}; + $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i-1]->{source}; + $form->{"memo_$i"} = $form->{acc_trans}{$key}->[$i-1]->{memo}; + + $form->{"forex_$i"} = $form->{"exchangerate_$i"} = $form->{acc_trans}{$key}->[$i-1]->{exchangerate}; + + $form->{paidaccounts}++; + } else { + + $akey = $key; + $akey =~ s/$form->{ARAP}_//; + + if ($key eq "$form->{ARAP}_tax") { + $form->{"${key}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; + $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = $form->{acc_trans}{$key}->[$i-1]->{amount} * $ml; + + $tax += $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"}; + $taxrate += $form->{"$form->{acc_trans}{$key}->[$i-1]->{accno}_rate"}; + + } else { + $form->{"${akey}_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount} * $ml; + + if ($akey eq 'amount') { + $form->{"description_$i"} = $form->{acc_trans}{$key}->[$i-1]->{memo}; + $form->{rowcount}++; + $netamount += $form->{"${akey}_$i"}; + + $form->{"projectnumber_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{projectnumber}--$form->{acc_trans}{$key}->[$i-1]->{project_id}" if $form->{acc_trans}{$key}->[$i-1]->{project_id}; + } else { + $form->{invtotal} = $form->{acc_trans}{$key}->[$i-1]->{amount} * -1 * $ml; + } + $form->{"${key}_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; + } + } + } + } + + $form->{paidaccounts} = 1 if not defined $form->{paidaccounts}; + + if ($form->{taxincluded}) { + $diff = 0; + # add tax to individual amounts + for $i (1 .. $form->{rowcount}) { + if ($netamount) { + $amount = $form->{"amount_$i"} * (1 + $tax / $netamount); + $form->{"amount_$i"} = $form->round_amount($amount, 2); + } + } + } + + $form->{invtotal} = $netamount + $tax; + + # check if calculated is equal to stored + # taxincluded is terrible to calculate + # this works only if all taxes are checked + + @taxaccounts = split / /, $form->{taxaccounts}; + + if ($form->{id}) { + if ($form->{taxincluded}) { + + $ml = 1; + + for (0 .. 1) { + $taxrate = 0; + $diff = 0; + + for (@taxaccounts) { $taxrate += $form->{"${_}_rate"} if ($form->{"${_}_rate"} * $ml) > 0 } + $taxrate *= $ml; + + foreach $item (@taxaccounts) { + + if (($form->{"${item}_rate"} * $ml) > 0) { + if ($taxrate) { + $amount = $form->{invtotal} * $form->{"${item}_rate"} / (1 + $taxrate); + $tax = $form->round_amount($amount, 2); + $tax{$item} = $form->round_amount($amount - $diff, 2); + $diff = $tax{$item} - ($amount - $diff); + + if ($tax) { + if ($form->{"tax_$item"} == $tax{$item}) { + $form->{"calctax_$item"} = 1; + } + } + } + } + } + $ml *= -1; + } + + } else { + for (@taxaccounts) { + $tax = $form->round_amount($netamount * $form->{"${_}_rate"}, 2); + if ($tax) { + if ($form->{"tax_$_"} == $tax) { + $form->{"calctax_$_"} = 1; + } + } + } + } + + } else { + for (@taxaccounts) { $form->{"calctax_$_"} = 1 } + } + + + $form->{rowcount}++ if ($form->{id} || !$form->{rowcount}); + + $form->{$form->{ARAP}} = $form->{"$form->{ARAP}_1"}; + $form->{rowcount} = 1 unless $form->{"$form->{ARAP}_amount_1"}; + + $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto})); + + # readonly + if (! $form->{readonly}) { + $form->{readonly} = 1 if $myconfig{acs} =~ /$form->{ARAP}--Add Transaction/; + } + +} + + +sub form_header { + + $title = $form->{title}; + $form->{title} = $locale->text("$title $form->{ARAP} Transaction"); + + $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : ""; + +# $locale->text('Add AR Transaction') +# $locale->text('Edit AR Transaction') +# $locale->text('Add AP Transaction') +# $locale->text('Edit AP Transaction') + + # set option selected + for ("$form->{ARAP}", "currency") { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/<option>\Q$form->{$_}\E/<option selected>$form->{$_}/; + } + + for ("$form->{vc}", "department", "employee", "formname") { + $form->{"select$_"} = $form->unescape($form->{"select$_"}); + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + $form->{selectprojectnumber} = $form->unescape($form->{selectprojectnumber}); + + # format amounts + $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate}); + + $exchangerate = qq|<tr>|; + $exchangerate .= qq| + <th align=right nowrap>|.$locale->text('Currency').qq|</th> + <td><select name=currency>$form->{selectcurrency}</select></td> | if $form->{defaultcurrency}; + $exchangerate .= qq| + <input type=hidden name=selectcurrency value="$form->{selectcurrency}"> + <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}> +|; + + if ($form->{defaultcurrency} && $form->{currency} ne $form->{defaultcurrency}) { + if ($form->{forex}) { + $exchangerate .= qq| + <th align=right>|.$locale->text('Exchange Rate').qq|</th> + <td><input type=hidden name=exchangerate value=$form->{exchangerate}>$form->{exchangerate}</td> +|; + } else { + $exchangerate .= qq| + <th align=right>|.$locale->text('Exchange Rate').qq|</th> + <td><input name=exchangerate size=10 value=$form->{exchangerate}></td> +|; + } + } + $exchangerate .= qq| +<input type=hidden name=forex value=$form->{forex}> +</tr> +|; + + $taxincluded = ""; + if ($form->{taxaccounts}) { + $taxincluded = qq| + <tr> + <td align=right><input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td> + <th align=left nowrap>|.$locale->text('Tax Included').qq|</th> + </tr> +|; + } + + + if (($rows = $form->numtextrows($form->{notes}, 50) - 1) < 2) { + $rows = 2; + } + $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|; + + $department = qq| + <tr> + <th align="right" nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select> + <input type=hidden name=selectdepartment value="|.$form->escape($form->{selectdepartment},1).qq|"> + </td> + </tr> +| if $form->{selectdepartment}; + + + $n = ($form->{creditremaining} < 0) ? "0" : "1"; + + $name = ($form->{"select$form->{vc}"}) ? qq|<select name="$form->{vc}">$form->{"select$form->{vc}"}</select>| : qq|<input name="$form->{vc}" value="$form->{$form->{vc}}" size=35>|; + + $employee = qq| + <input type=hidden name=employee value="$form->{employee}"> +|; + + if ($form->{selectemployee}) { + $label = ($form->{ARAP} eq 'AR') ? $locale->text('Salesperson') : $locale->text('Employee'); + + $employee = qq| + <tr> + <th align=right nowrap>$label</th> + <td><select name=employee>$form->{selectemployee}</select></td> + <input type=hidden name=selectemployee value="|.$form->escape($form->{selectemployee},1).qq|"> + </tr> +|; + } + + $focus = ($form->{focus}) ? $form->{focus} : "amount_$form->{rowcount}"; + + $form->header; + + print qq| +<body onload="document.forms[0].${focus}.focus()" /> + +<form method=post action=$form->{script}> + +<input type=hidden name=type value="$form->{formname}"> +<input type=hidden name=title value="$title"> + +|; + + $form->hide_form(qw(id printed emailed sort closedto locked oldtransdate audittrail recurring checktax)); + + if ($form->{vc} eq 'customer') { + $label = $locale->text('Customer'); + } else { + $label = $locale->text('Vendor'); + } + + $form->hide_form("old$form->{vc}", "$form->{vc}_id", "terms", "creditlimit", "creditremaining", "selectcurrency", "defaultcurrency", "select$form->{ARAP}_amount", "rowcount"); + + print qq| + +<table width=100%> + <tr class=listtop> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> + <th align="right" nowrap>$label</th> + <td colspan=3>$name</td> + <input type=hidden name="select$form->{vc}" value="|.$form->escape($form->{"select$form->{vc}"},1).qq|"> + </tr> + <tr> + <td></td> + <td colspan=3> + <table width=100%> + <tr> + <th align=left nowrap>|.$locale->text('Credit Limit').qq|</th> + <td>$form->{creditlimit}</td> + <th align=left nowrap>|.$locale->text('Remaining').qq|</th> + <td class="plus$n">|.$form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0").qq|</td> + </tr> + </table> + </td> + </tr> + $exchangerate + $department + $taxincluded + </table> + </td> + <td align=right> + <table> + $employee + <tr> + <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th> + <td><input name=invnumber size=20 value="$form->{invnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Order Number').qq|</th> + <td><input name=ordnumber size=20 value="$form->{ordnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Invoice Date').qq|</th> + <td><input name=transdate size=11 title="($myconfig{'dateformat'})" value=$form->{transdate}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Due Date').qq|</th> + <td><input name=duedate size=11 title="$myconfig{'dateformat'}" value=$form->{duedate}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('PO Number').qq|</th> + <td><input name=ponumber size=20 value="$form->{ponumber}"></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <input type=hidden name=selectprojectnumber value="|.$form->escape($form->{selectprojectnumber},1).qq|"> + <tr> + <td> + <table> +|; + + $project = qq| + <th>|.$locale->text('Project').qq|</th> +| if $form->{selectprojectnumber}; + + print qq| + <tr> + <th>|.$locale->text('Amount').qq|</th> + <th></th> + <th>|.$locale->text('Account').qq|</th> + <th>|.$locale->text('Description').qq|</th> + $project + </tr> +|; + + for $i (1 .. $form->{rowcount}) { + + $selectamount = $form->{"select$form->{ARAP}_amount"}; + $selectamount =~ s/option>\Q$form->{"$form->{ARAP}_amount_$i"}\E/option selected>$form->{"$form->{ARAP}_amount_$i"}/; + + $selectprojectnumber = $form->{selectprojectnumber}; + $selectprojectnumber =~ s/(<option value="\Q$form->{"projectnumber_$i"}\E")/$1 selected/; + + # format amounts + $form->{"amount_$i"} = $form->format_amount(\%myconfig, $form->{"amount_$i"}, 2); + + $project = qq| + <td align=right><select name="projectnumber_$i">$selectprojectnumber</select></td> +| if $form->{selectprojectnumber}; + + if (($rows = $form->numtextrows($form->{"description_$i"}, 40)) > 1) { + $description = qq|<td><textarea name="description_$i" rows=$rows cols=40>$form->{"description_$i"}</textarea></td>|; + } else { + $description = qq|<td><input name="description_$i" size=40 value="$form->{"description_$i"}"></td>|; + } + + print qq| + <tr valign=top> + <td><input name="amount_$i" size=10 value="$form->{"amount_$i"}" accesskey="$i"></td> + <td></td> + <td><select name="$form->{ARAP}_amount_$i">$selectamount</select></td> + $description + $project + </tr> +|; + } + + foreach $item (split / /, $form->{taxaccounts}) { + + $form->{"calctax_$item"} = ($form->{"calctax_$item"}) ? "checked" : ""; + + $form->{"tax_$item"} = $form->format_amount(\%myconfig, $form->{"tax_$item"}, 2); + + print qq| + <tr> + <td><input name="tax_$item" size=10 value=$form->{"tax_$item"}></td> + <td align=right><input name="calctax_$item" class=checkbox type=checkbox value=1 $form->{"calctax_$item"}></td> + <td><select name="$form->{ARAP}_tax_$item">$form->{"select$form->{ARAP}_tax_$item"}</select></td> + </tr> +|; + + $form->hide_form("${item}_rate", "${item}_description", "${item}_taxnumber", "select$form->{ARAP}_tax_$item"); + } + + $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2); + + $form->hide_form("oldinvtotal", "oldtotalpaid", "taxaccounts", "select$form->{ARAP}"); + + print qq| + <tr> + <th align=left>$form->{invtotal}</th> + <td></td> + <td><select name=$form->{ARAP}>$form->{"select$form->{ARAP}"}</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('Notes').qq|</th> + <td></td> + <td colspan=3>$notes</td> + </tr> + </table> + </td> + </tr> + + <tr class=listheading> + <th class=listheading>|.$locale->text('Payments').qq|</th> + </tr> + + <tr> + <td> + <table width=100%> +|; + + if ($form->{currency} eq $form->{defaultcurrency}) { + @column_index = qw(datepaid source memo paid ARAP_paid); + } else { + @column_index = qw(datepaid source memo paid exchangerate ARAP_paid); + } + + $column_data{datepaid} = "<th>".$locale->text('Date')."</th>"; + $column_data{paid} = "<th>".$locale->text('Amount')."</th>"; + $column_data{exchangerate} = "<th>".$locale->text('Exch')."</th>"; + $column_data{ARAP_paid} = "<th>".$locale->text('Account')."</th>"; + $column_data{source} = "<th>".$locale->text('Source')."</th>"; + $column_data{memo} = "<th>".$locale->text('Memo')."</th>"; + + print " + <tr> +"; + + for (@column_index) { print "$column_data{$_}\n" } + + print " + </tr> +"; + + + $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"}); + for $i (1 .. $form->{paidaccounts}) { + + $form->hide_form("cleared_$i"); + + print " + <tr> +"; + + $form->{"select$form->{ARAP}_paid_$i"} = $form->{"select$form->{ARAP}_paid"}; + $form->{"select$form->{ARAP}_paid_$i"} =~ s/option>\Q$form->{"$form->{ARAP}_paid_$i"}\E/option selected>$form->{"$form->{ARAP}_paid_$i"}/; + + # format amounts + $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2); + $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"}); + + $exchangerate = qq| |; + if ($form->{currency} ne $form->{defaultcurrency}) { + if ($form->{"forex_$i"}) { + $form->hide_form("exchangerate_$i"); + $exchangerate = qq|$form->{"exchangerate_$i"}|; + } else { + $exchangerate = qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|; + } + } + + $form->hide_form("forex_$i"); + + $column_data{paid} = qq|<td align=center><input name="paid_$i" size=11 value=$form->{"paid_$i"}></td>|; + $column_data{ARAP_paid} = qq|<td align=center><select name="$form->{ARAP}_paid_$i">$form->{"select$form->{ARAP}_paid_$i"}</select></td>|; + $column_data{exchangerate} = qq|<td align=center>$exchangerate</td>|; + $column_data{datepaid} = qq|<td align=center><input name="datepaid_$i" size=11 value=$form->{"datepaid_$i"}></td>|; + $column_data{source} = qq|<td align=center><input name="source_$i" size=11 value="$form->{"source_$i"}"></td>|; + $column_data{memo} = qq|<td align=center><input name="memo_$i" size=11 value="$form->{"memo_$i"}"></td>|; + + for (@column_index) { print qq|$column_data{$_}\n| } + + print " + </tr> +"; + } + + $form->hide_form("paidaccounts", "select$form->{ARAP}_paid"); + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub form_footer { + + $form->hide_form(qw(callback path login sessionid)); + + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + +# type=submit $locale->text('Update') +# type=submit $locale->text('Print') +# type=submit $locale->text('Post') +# type=submit $locale->text('Print and Post') +# type=submit $locale->text('Schedule') +# type=submit $locale->text('Ship to') +# type=submit $locale->text('Post as new') +# type=submit $locale->text('Print and Post as new') +# type=submit $locale->text('Delete') + + if (! $form->{readonly}) { + + &print_options; + + print "<br>"; + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') }, + 'Post' => { ndx => 3, key => 'O', value => $locale->text('Post') }, + 'Print and Post' => { ndx => 4, key => 'R', value => $locale->text('Print and Post') }, + 'Post as new' => { ndx => 5, key => 'N', value => $locale->text('Post as new') }, + 'Print and Post as new' => { ndx => 6, key => 'W', value => $locale->text('Print and Post as new') }, + 'Schedule' => { ndx => 7, key => 'H', value => $locale->text('Schedule') }, + 'Delete' => { ndx => 8, key => 'D', value => $locale->text('Delete') }, + ); + + if ($form->{id}) { + + if ($form->{locked} || $transdate <= $closedto) { + for ("Post", "Print and Post", "Delete") { delete $button{$_} } + } + + if (!$latex) { + for ("Print and Post", "Print and Post as new") { delete $button{$_} } + } + + } else { + + for ("Post as new", "Print and Post as new", "Delete") { delete $button{$_} } + delete $button{"Print and Post"} if ! $latex; + + if ($transdate <= $closedto) { + for ("Post", "Print and Post") { delete $button{$_} } + } + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub update { + my $display = shift; + + if (!$display) { + + $form->{invtotal} = 0; + + $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate}); + + @flds = ("amount", "$form->{ARAP}_amount", "projectnumber", "description"); + $count = 0; + @a = (); + for $i (1 .. $form->{rowcount}) { + $form->{"amount_$i"} = $form->parse_amount(\%myconfig, $form->{"amount_$i"}); + if ($form->{"amount_$i"}) { + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + + $form->redo_rows(\@flds, \@a, $count, $form->{rowcount}); + $form->{rowcount} = $count + 1; + + for (1 .. $form->{rowcount}) { $form->{invtotal} += $form->{"amount_$_"} } + + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, ($form->{ARAP} eq 'AR') ? 'buy' : 'sell'))); + + if ($newname = &check_name($form->{vc})) { + $form->{notes} = $form->{intnotes} unless $form->{id}; + &rebuild_vc($form->{vc}, $form->{ARAP}, $form->{transdate}); + } + if ($form->{transdate} ne $form->{oldtransdate}) { + $form->{duedate} = $form->current_date(\%myconfig, $form->{transdate}, $form->{terms} * 1); + $form->{oldtransdate} = $form->{transdate}; + $newproj = &rebuild_vc($form->{vc}, $form->{ARAP}, $form->{transdate}) if ! $newname; + $form->all_projects(\%myconfig, undef, $form->{transdate}) if ! $newproj; + + $form->{selectemployee} = ""; + if (@{ $form->{all_employee} }) { + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + } + } + + # recalculate taxes + @taxaccounts = split / /, $form->{taxaccounts}; + + for (@taxaccounts) { $form->{"tax_$_"} = $form->parse_amount(\%myconfig, $form->{"tax_$_"}) } + + if ($form->{taxincluded}) { + + $ml = 1; + + for (0 .. 1) { + $taxrate = 0; + $diff = 0; + + for (@taxaccounts) { + if (($form->{"${_}_rate"} * $ml) > 0) { + if ($form->{"calctax_$_"}) { + $taxrate += $form->{"${_}_rate"}; + } else { + if ($form->{checktax}) { + if ($form->{"tax_$_"}) { + $taxrate += $form->{"${_}_rate"}; + } + } + } + } + } + + $taxrate *= $ml; + + foreach $item (@taxaccounts) { + if (($form->{"${item}_rate"} * $ml) > 0) { + + if ($taxrate) { + $a = $form->{invtotal} * $form->{"${item}_rate"} / (1 + $taxrate); + $b = $form->round_amount($a, 2); + $tax = $form->round_amount($a - $diff, 2); + $diff = $b - ($a - $diff); + } + $form->{"tax_$item"} = $tax if $form->{"calctax_$item"}; + + $form->{"select$form->{ARAP}_tax_$item"} = qq|<option>$item--$form->{"${item}_description"}|; + $totaltax += $form->{"tax_$item"}; + } + } + $ml *= -1; + } + $totaltax += $form->round_amount($diff, 2); + + $form->{checktax} = 1; + + } else { + foreach $item (@taxaccounts) { + $form->{"calctax_$item"} = 1 if $form->{calctax}; + + if ($form->{"calctax_$item"}) { + $form->{"tax_$item"} = $form->round_amount($form->{invtotal} * $form->{"${item}_rate"}, 2); + } + $form->{"select$form->{ARAP}_tax_$item"} = qq|<option>$item--$form->{"${item}_description"}|; + $totaltax += $form->{"tax_$item"}; + } + } + + $form->{invtotal} = ($form->{taxincluded}) ? $form->{invtotal} : $form->{invtotal} + $totaltax; + + $j = 1; + for $i (1 .. $form->{paidaccounts}) { + if ($form->{"paid_$i"}) { + for (qw(datepaid source memo cleared)) { $form->{"${_}_$j"} = $form->{"${_}_$i"} } + for (qw(paid exchangerate)) { $form->{"${_}_$j"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + $totalpaid += $form->{"paid_$j"}; + + $form->{"exchangerate_$j"} = $exchangerate if ($form->{"forex_$j"} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$j"}, ($form->{ARAP} eq 'AR') ? 'buy' : 'sell'))); + + if ($j++ != $i) { + for (qw(datepaid source memo paid exchangerate forex cleared)) { delete $form->{"${_}_$i"} } + } + } else { + for (qw(datepaid source memo paid exchangerate forex cleared)) { delete $form->{"${_}_$i"} } + } + } + $form->{paidaccounts} = $j; + + $form->{creditremaining} -= ($form->{invtotal} - $totalpaid + $form->{oldtotalpaid} - $form->{oldinvtotal}); + $form->{oldinvtotal} = $form->{invtotal}; + $form->{oldtotalpaid} = $totalpaid; + + &display_form; + +} + + +sub post { + + $label = ($form->{vc} eq 'customer') ? $locale->text('Customer missing!') : $locale->text('Vendor missing!'); + + # check if there is an invoice number, invoice and due date + $form->isblank("transdate", $locale->text('Invoice Date missing!')); + $form->isblank("duedate", $locale->text('Due Date missing!')); + $form->isblank($form->{vc}, $label); + + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + + $form->error($locale->text('Cannot post transaction for a closed period!')) if ($transdate <= $closedto); + + $form->isblank("exchangerate", $locale->text('Exchange rate missing!')) if ($form->{currency} ne $form->{defaultcurrency}); + + for $i (1 .. $form->{paidaccounts}) { + if ($form->{"paid_$i"}) { + $datepaid = $form->datetonum(\%myconfig, $form->{"datepaid_$i"}); + + $form->isblank("datepaid_$i", $locale->text('Payment date missing!')); + + $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto); + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->{"exchangerate_$i"} = $form->{exchangerate} if ($transdate == $datepaid); + $form->isblank("exchangerate_$i", $locale->text('Exchange rate for payment missing!')); + } + } + } + + # if oldname ne name redo form + ($name) = split /--/, $form->{$form->{vc}}; + if ($form->{"old$form->{vc}"} ne qq|$name--$form->{"$form->{vc}_id"}|) { + &update; + exit; + } + + if (! $form->{repost}) { + if ($form->{id}) { + &repost; + exit; + } + } + + if (AA->post_transaction(\%myconfig, \%$form)) { + $form->redirect($locale->text('Transaction posted!')); + } else { + $form->error($locale->text('Cannot post transaction!')); + } + +} + + +sub delete { + + $form->{title} = $locale->text('Confirm!'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->{action} = "yes"; + $form->hide_form; + + print qq| +<h2 class=confirm>$form->{title}</h2> + +<h4>|.$locale->text('Are you sure you want to delete Transaction').qq| $form->{invnumber}</h4> + +<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|"> +</form> + +</body> +</html> +|; + +} + + + +sub yes { + + if (AA->delete_transaction(\%myconfig, \%$form, $spool)) { + $form->redirect($locale->text('Transaction deleted!')); + } else { + $form->error($locale->text('Cannot delete transaction!')); + } + +} + + +sub search { + + $form->create_links($form->{ARAP}, \%myconfig, $form->{vc}); + + $form->{"select$form->{ARAP}"} = "<option>\n"; + for (@{ $form->{"$form->{ARAP}_links"}{$form->{ARAP}} }) { $form->{"select$form->{ARAP}"} .= "<option>$_->{accno}--$_->{description}\n" } + + if (@{ $form->{"all_$form->{vc}"} }) { + $selectname = ""; + for (@{ $form->{"all_$form->{vc}"} }) { $selectname .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + $selectname = qq|<select name="$form->{vc}"><option>\n$selectname</select>|; + } else { + $selectname = qq|<input name=$form->{vc} size=35>|; + } + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + + $l_department = qq|<input name="l_department" class=checkbox type=checkbox value=Y> |.$locale->text('Department'); + + $department = qq| + <tr> + <th align=right nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select></td> + </tr> +|; + } + + if (@{ $form->{all_employee} }) { + $form->{selectemployee} = "<option>\n"; + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + + $employeelabel = ($form->{ARAP} eq 'AR') ? $locale->text('Salesperson') : $locale->text('Employee'); + + $employee = qq| + <tr> + <th align=right nowrap>$employeelabel</th> + <td colspan=3><select name=employee>$form->{selectemployee}</select></td> + </tr> +|; + + $l_employee = qq|<input name="l_employee" class=checkbox type=checkbox value=Y> $employeelabel|; + + $l_manager = qq|<input name="l_manager" class=checkbox type=checkbox value=Y> |.$locale->text('Manager'); + } + + + $form->{title} = ($form->{ARAP} eq 'AR') ? $locale->text('AR Transactions') : $locale->text('AP Transactions'); + + $invnumber = qq| + <tr> + <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th> + <td colspan=3><input name=invnumber size=20></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Order Number').qq|</th> + <td colspan=3><input name=ordnumber size=20></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('PO Number').qq|</th> + <td colspan=3><input name=ponumber size=20></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Source').qq|</th> + <td colspan=3><input name=source size=40></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Description').qq|</th> + <td colspan=3><input name=description size=40></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Notes').qq|</th> + <td colspan=3><input name=notes size=40></td> + </tr> +|; + + $openclosed = qq| + <tr> + <td nowrap><input name=open class=checkbox type=checkbox value=Y checked> |.$locale->text('Open').qq|</td> + <td nowrap><input name=closed class=checkbox type=checkbox value=Y> |.$locale->text('Closed').qq|</td> + </tr> +|; + + $summary = qq| + <tr> + <td><input name=summary type=radio class=radio value=1 checked> |.$locale->text('Summary').qq|</td> + <td><input name=summary type=radio class=radio value=0> |.$locale->text('Detail').qq| + </td> + </tr> +|; + + + if ($form->{outstanding}) { + $form->{title} = ($form->{ARAP} eq 'AR') ? $locale->text('AR Outstanding') : $locale->text('AP Outstanding'); + $invnumber = ""; + $openclosed = ""; + $summary = ""; + } + + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + + $name = $locale->text('Customer'); + $l_name = qq|<input name="l_name" class=checkbox type=checkbox value=Y checked> $name|; + $l_till = qq|<input name="l_till" class=checkbox type=checkbox value=Y> |.$locale->text('Till'); + + if ($form->{vc} eq 'vendor') { + $name = $locale->text('Vendor'); + $l_till = ""; + $l_name = qq|<input name="l_name" class=checkbox type=checkbox value=Y checked> $name|; + } + + @a = (); + push @a, qq|<input name="l_runningnumber" class=checkbox type=checkbox value=Y> |.$locale->text('No.'); + push @a, qq|<input name="l_id" class=checkbox type=checkbox value=Y> |.$locale->text('ID'); + push @a, qq|<input name="l_invnumber" class=checkbox type=checkbox value=Y checked> |.$locale->text('Invoice Number'); + push @a, qq|<input name="l_ordnumber" class=checkbox type=checkbox value=Y> |.$locale->text('Order Number'); + push @a, qq|<input name="l_ponumber" class=checkbox type=checkbox value=Y> |.$locale->text('PO Number'); + push @a, qq|<input name="l_transdate" class=checkbox type=checkbox value=Y checked> |.$locale->text('Invoice Date'); + push @a, $l_name; + push @a, $l_employee if $l_employee; + push @a, $l_manager if $l_employee; + push @a, $l_department if $l_department; + push @a, qq|<input name="l_netamount" class=checkbox type=checkbox value=Y> |.$locale->text('Amount'); + push @a, qq|<input name="l_tax" class=checkbox type=checkbox value=Y> |.$locale->text('Tax'); + push @a, qq|<input name="l_amount" class=checkbox type=checkbox value=Y checked> |.$locale->text('Total'); + push @a, qq|<input name="l_curr" class=checkbox type=checkbox value=Y> |.$locale->text('Currency'); + push @a, qq|<input name="l_datepaid" class=checkbox type=checkbox value=Y> |.$locale->text('Date Paid'); + push @a, qq|<input name="l_paid" class=checkbox type=checkbox value=Y checked> |.$locale->text('Paid'); + push @a, qq|<input name="l_duedate" class=checkbox type=checkbox value=Y> |.$locale->text('Due Date'); + push @a, qq|<input name="l_due" class=checkbox type=checkbox value=Y> |.$locale->text('Amount Due'); + push @a, qq|<input name="l_notes" class=checkbox type=checkbox value=Y> |.$locale->text('Notes'); + push @a, $l_till if $l_till; + push @a, qq|<input name="l_shippingpoint" class=checkbox type=checkbox value=Y> |.$locale->text('Shipping Point'); + push @a, qq|<input name="l_shipvia" class=checkbox type=checkbox value=Y> |.$locale->text('Ship via'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Account').qq|</th> + <td colspan=3><select name=$form->{ARAP}>$form->{"select$form->{ARAP}"}</select></td> + </tr> + <tr> + <th align=right>$name</th> + <td colspan=3>$selectname</td> + </tr> + $employee + $department + $invnumber + <tr> + <th align=right>|.$locale->text('Ship via').qq|</th> + <td colspan=3><input name=shipvia size=40></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('From').qq|</th> + <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + </table> + </td> + </tr> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td> + <table width=100%> + $openclosed + $summary +|; + + $form->{sort} = "transdate"; + $form->hide_form(qw(title outstanding sort)); + + + while (@a) { + for (1 .. 5) { + print qq|<td nowrap>|. shift @a; + print qq|</td>\n|; + } + print qq|</tr>\n|; + } + + print qq| + <tr> + <td nowrap><input name="l_subtotal" class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq|</td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<input type=hidden name=action value=continue> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">|; + + $form->hide_form(qw(nextsub path login sessionid)); + + print qq| +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub transactions { + + if ($form->{$form->{vc}}) { + $form->{$form->{vc}} = $form->unescape($form->{$form->{vc}}); + ($form->{$form->{vc}}, $form->{"$form->{vc}_id"}) = split(/--/, $form->{$form->{vc}}); + } + + AA->transactions(\%myconfig, \%$form); + + $href = "$form->{script}?action=transactions"; + for (qw(direction oldsort till outstanding path login sessionid summary)) { $href .= qq|&$_=$form->{$_}| } + $href .= "&title=".$form->escape($form->{title}); + + $form->sort_order(); + + $callback = "$form->{script}?action=transactions"; + for (qw(direction oldsort till outstanding path login sessionid summary)) { $callback .= qq|&$_=$form->{$_}| } + $callback .= "&title=".$form->escape($form->{title},1); + + if ($form->{$form->{ARAP}}) { + $callback .= "&$form->{ARAP}=".$form->escape($form->{$form->{ARAP}},1); + $href .= "&$form->{ARAP}=".$form->escape($form->{$form->{ARAP}}); + $form->{$form->{ARAP}} =~ s/--/ /; + $option = $locale->text('Account')." : $form->{$form->{ARAP}}"; + } + + if ($form->{$form->{vc}}) { + $callback .= "&$form->{vc}=".$form->escape($form->{$form->{vc}},1).qq|--$form->{"$form->{vc}_id"}|; + $href .= "&$form->{vc}=".$form->escape($form->{$form->{vc}}).qq|--$form->{"$form->{vc}_id"}|; + $option .= "\n<br>" if ($option); + $name = ($form->{vc} eq 'customer') ? $locale->text('Customer') : $locale->text('Vendor'); + $option .= "$name : $form->{$form->{vc}}"; + } + if ($form->{department}) { + $callback .= "&department=".$form->escape($form->{department},1); + $href .= "&department=".$form->escape($form->{department}); + ($department) = split /--/, $form->{department}; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Department')." : $department"; + } + if ($form->{employee}) { + $callback .= "&employee=".$form->escape($form->{employee},1); + $href .= "&employee=".$form->escape($form->{employee}); + ($employee) = split /--/, $form->{employee}; + $option .= "\n<br>" if ($option); + if ($form->{ARAP} eq 'AR') { + $option .= $locale->text('Salesperson'); + } else { + $option .= $locale->text('Employee'); + } + $option .= " : $employee"; + } + + if ($form->{invnumber}) { + $callback .= "&invnumber=".$form->escape($form->{invnumber},1); + $href .= "&invnumber=".$form->escape($form->{invnumber}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Invoice Number')." : $form->{invnumber}"; + } + if ($form->{ordnumber}) { + $callback .= "&ordnumber=".$form->escape($form->{ordnumber},1); + $href .= "&ordnumber=".$form->escape($form->{ordnumber}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Order Number')." : $form->{ordnumber}"; + } + if ($form->{ponumber}) { + $callback .= "&ponumber=".$form->escape($form->{ponumber},1); + $href .= "&ponumber=".$form->escape($form->{ponumber}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('PO Number')." : $form->{ponumber}"; + } + if ($form->{source}) { + $callback .= "&source=".$form->escape($form->{source},1); + $href .= "&source=".$form->escape($form->{source}); + $option .= "\n<br>" if $option; + $option .= $locale->text('Source')." : $form->{source}"; + } + if ($form->{description}) { + $callback .= "&description=".$form->escape($form->{description},1); + $href .= "&description=".$form->escape($form->{description}); + $option .= "\n<br>" if $option; + $option .= $locale->text('Description')." : $form->{description}"; + } + if ($form->{notes}) { + $callback .= "¬es=".$form->escape($form->{notes},1); + $href .= "¬es=".$form->escape($form->{notes}); + $option .= "\n<br>" if $option; + $option .= $locale->text('Notes')." : $form->{notes}"; + } + if ($form->{shipvia}) { + $callback .= "&shipvia=".$form->escape($form->{shipvia},1); + $href .= "&shipvia=".$form->escape($form->{shipvia}); + $option .= "\n<br>" if $option; + $option .= $locale->text('Ship via')." : $form->{shipvia}"; + } + if ($form->{transdatefrom}) { + $callback .= "&transdatefrom=$form->{transdatefrom}"; + $href .= "&transdatefrom=$form->{transdatefrom}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1); + } + if ($form->{transdateto}) { + $callback .= "&transdateto=$form->{transdateto}"; + $href .= "&transdateto=$form->{transdateto}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{transdateto}, 1); + } + if ($form->{open}) { + $callback .= "&open=$form->{open}"; + $href .= "&open=$form->{open}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Open'); + } + if ($form->{closed}) { + $callback .= "&closed=$form->{closed}"; + $href .= "&closed=$form->{closed}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Closed'); + } + + @columns = $form->sort_columns(qw(transdate id invnumber ordnumber ponumber name netamount tax amount paid due curr datepaid duedate notes till employee manager shippingpoint shipvia department)); + pop @columns if $form->{department}; + unshift @columns, "runningnumber"; + + foreach $item (@columns) { + if ($form->{"l_$item"} eq "Y") { + push @column_index, $item; + + if ($form->{l_curr} && $item =~ /(amount|tax|paid|due)/) { + push @column_index, "fx_$item"; + } + + # add column to href and callback + $callback .= "&l_$item=Y"; + $href .= "&l_$item=Y"; + } + } + + if (!$form->{summary}) { + foreach $item (qw(source debit credit accno description projectnumber)) { + push @column_index, $item; + } + } + + if ($form->{l_subtotal} eq 'Y') { + $callback .= "&l_subtotal=Y"; + $href .= "&l_subtotal=Y"; + } + + $employee = ($form->{ARAP} eq 'AR') ? $locale->text('Salesperson') : $locale->text('Employee'); + $name = ($form->{vc} eq 'customer') ? $locale->text('Customer') : $locale->text('Vendor'); + + $column_header{runningnumber} = qq|<th class=listheading> </th>|; + $column_header{id} = "<th><a class=listheading href=$href&sort=id>".$locale->text('ID')."</a></th>"; + $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>"; + $column_header{duedate} = "<th><a class=listheading href=$href&sort=duedate>".$locale->text('Due Date')."</a></th>"; + $column_header{invnumber} = "<th><a class=listheading href=$href&sort=invnumber>".$locale->text('Invoice')."</a></th>"; + $column_header{ordnumber} = "<th><a class=listheading href=$href&sort=ordnumber>".$locale->text('Order')."</a></th>"; + $column_header{ponumber} = "<th><a class=listheading href=$href&sort=ponumber>".$locale->text('PO Number')."</a></th>"; + $column_header{name} = "<th><a class=listheading href=$href&sort=name>$name</a></th>"; + $column_header{netamount} = "<th class=listheading>" . $locale->text('Amount') . "</th>"; + $column_header{tax} = "<th class=listheading>" . $locale->text('Tax') . "</th>"; + $column_header{amount} = "<th class=listheading>" . $locale->text('Total') . "</th>"; + $column_header{paid} = "<th class=listheading>" . $locale->text('Paid') . "</th>"; + $column_header{datepaid} = "<th><a class=listheading href=$href&sort=datepaid>" . $locale->text('Date Paid') . "</a></th>"; + $column_header{due} = "<th class=listheading>" . $locale->text('Amount Due') . "</th>"; + $column_header{notes} = "<th class=listheading>".$locale->text('Notes')."</th>"; + $column_header{employee} = "<th><a class=listheading href=$href&sort=employee>$employee</th>"; + $column_header{manager} = "<th><a class=listheading href=$href&sort=manager>".$locale->text('Manager')."</th>"; + $column_header{till} = "<th class=listheading><a class=listheading href=$href&sort=till>".$locale->text('Till')."</th>"; + + $column_header{shippingpoint} = "<th><a class=listheading href=$href&sort=shippingpoint>" . $locale->text('Shipping Point') . "</a></th>"; + $column_header{shipvia} = "<th><a class=listheading href=$href&sort=shipvia>" . $locale->text('Ship via') . "</a></th>"; + + $column_header{curr} = "<th><a class=listheading href=$href&sort=curr>" . $locale->text('Curr') . "</a></th>"; + for (qw(amount tax netamount paid due)) { $column_header{"fx_$_"} = "<th> </th>" } + + $column_header{department} = "<th><a class=listheading href=$href&sort=department>" . $locale->text('Department') . "</a></th>"; + + $column_header{accno} = "<th><a class=listheading href=$href&sort=accno>" . $locale->text('Account') . "</a></th>"; + $column_header{source} = "<th><a class=listheading href=$href&sort=source>" . $locale->text('Source') . "</a></th>"; + $column_header{debit} = "<th class=listheading>" . $locale->text('Debit') . "</th>"; + $column_header{credit} = "<th class=listheading>" . $locale->text('Credit') . "</th>"; + $column_header{projectnumber} = "<th><a class=listheading href=$href&sort=projectnumber>" . $locale->text('Project') . "</a></th>"; + $column_header{description} = "<th><a class=listheading href=$href&sort=linedescription>" . $locale->text('Description') . "</a></th>"; + + $form->{title} = ($form->{title}) ? $form->{title} : $locale->text('AR Transactions'); + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + + # add sort and escape callback, this one we use for the add sub + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + # flip direction + $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC"; + $href =~ s/&direction=(\w+)&/&direction=$direction&/; + + if (@{ $form->{transactions} }) { + $sameitem = $form->{transactions}->[0]->{$form->{sort}}; + } + + # sums and tax on reports by Antonio Gallardo + # + $i = 0; + foreach $ref (@{ $form->{transactions} }) { + + $i++; + + if ($form->{l_subtotal} eq 'Y') { + if ($sameitem ne $ref->{$form->{sort}}) { + &subtotal; + $sameitem = $ref->{$form->{sort}}; + } + } + + if ($form->{l_curr}) { + for (qw(netamount amount paid)) { $ref->{"fx_$_"} = $ref->{$_}/$ref->{exchangerate} } + + for (qw(netamount amount paid)) { $column_data{"fx_$_"} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{"fx_$_"}, 2, " ")."</td>" } + + $column_data{fx_tax} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{fx_amount} - $ref->{fx_netamount}, 2, " ")."</td>"; + $column_data{fx_due} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{fx_amount} - $ref->{fx_paid}, 2, " ")."</td>"; + + $subtotalfxnetamount += $ref->{fx_netamount}; + $subtotalfxamount += $ref->{fx_amount}; + $subtotalfxpaid += $ref->{fx_paid}; + + $totalfxnetamount += $ref->{fx_netamount}; + $totalfxamount += $ref->{fx_amount}; + $totalfxpaid += $ref->{fx_paid}; + + } + + $column_data{runningnumber} = "<td align=right>$i</td>"; + + for (qw(netamount amount paid debit credit)) { $column_data{$_} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{$_}, 2, " ")."</td>" } + + $column_data{tax} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount} - $ref->{netamount}, 2, " ")."</td>"; + $column_data{due} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount} - $ref->{paid}, 2, " ")."</td>"; + + + $subtotalnetamount += $ref->{netamount}; + $subtotalamount += $ref->{amount}; + $subtotalpaid += $ref->{paid}; + $subtotaldebit += $ref->{debit}; + $subtotalcredit += $ref->{credit}; + + $totalnetamount += $ref->{netamount}; + $totalamount += $ref->{amount}; + $totalpaid += $ref->{paid}; + $totaldebit += $ref->{debit}; + $totalcredit += $ref->{credit}; + + $module = ($ref->{invoice}) ? ($form->{ARAP} eq 'AR') ? "is.pl" : "ir.pl" : $form->{script}; + $module = ($ref->{till}) ? "ps.pl" : $module; + + $column_data{invnumber} = "<td><a href=$module?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{invnumber} </a></td>"; + + for (qw(notes description)) { $ref->{$_} =~ s/\r?\n/<br>/g } + for (qw(transdate datepaid duedate department ordnumber ponumber notes shippingpoint shipvia employee manager till source description projectnumber)) { $column_data{$_} = "<td>$ref->{$_} </td>" } + for (qw(id curr)) { $column_data{$_} = "<td>$ref->{$_}</td>" } + + $column_data{accno} = qq|<td><a href=ca.pl?path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&action=list_transactions&accounttype=standard&accno=$ref->{accno}&fromdate=$form->{transdatefrom}&todate=$form->{transdateto}&sort=transdate&l_subtotal=$form->{l_subtotal}&prevreport=$callback>$ref->{accno}</a></td>|; + + $column_data{name} = qq|<td><a href=ct.pl?path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&action=edit&id=$ref->{"$form->{vc}_id"}&db=$form->{vc}&callback=$callback>$ref->{name}</a></td>|; + + if ($ref->{id} != $sameid) { + $j++; $j %= 2; + } + + print " + <tr class=listrow$j> +"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + $sameid = $ref->{id}; + + + } + + if ($form->{l_subtotal} eq 'Y') { + &subtotal; + $sameitem = $ref->{$form->{sort}}; + } + + # print totals + print qq| + <tr class=listtotal> +|; + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{netamount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalnetamount, 2, " ")."</th>"; + $column_data{tax} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount - $totalnetamount, 2, " ")."</th>"; + $column_data{amount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount, 2, " ")."</th>"; + $column_data{paid} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalpaid, 2, " ")."</th>"; + $column_data{due} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount - $totalpaid, 2, " ")."</th>"; + $column_data{debit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totaldebit, 2, " ")."</th>"; + $column_data{credit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalcredit, 2, " ")."</th>"; + + if ($form->{l_curr} && $form->{sort} eq 'curr' && $form->{l_subtotal}) { + $column_data{fx_netamount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalfxnetamount, 2, " ")."</th>"; + $column_data{fx_tax} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalfxamount - $totalfxnetamount, 2, " ")."</th>"; + $column_data{fx_amount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalfxamount, 2, " ")."</th>"; + $column_data{fx_paid} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalfxpaid, 2, " ")."</th>"; + $column_data{fx_due} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalfxamount - $totalfxpaid, 2, " ")."</th>"; + } + + for (@column_index) { print "\n$column_data{$_}" } + + if ($myconfig{acs} !~ /$form->{ARAP}--$form->{ARAP}/) { + $i = 1; + if ($form->{ARAP} eq 'AR') { + $button{'AR--Add Transaction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('AR Transaction').qq|"> |; + $button{'AR--Add Transaction'}{order} = $i++; + $button{'AR--Sales Invoice'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Sales Invoice.').qq|"> |; + $button{'AR--Sales Invoice'}{order} = $i++; + } else { + $button{'AP--Add Transaction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('AP Transaction').qq|"> |; + $button{'AP--Add Transaction'}{order} = $i++; + $button{'AP--Vendor Invoice'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Vendor Invoice.').qq|"> |; + $button{'AP--Vendor Invoice'}{order} = $i++; + } + + foreach $item (split /;/, $myconfig{acs}) { + delete $button{$item}; + } + } + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->hide_form("callback", "path", "login", "sessionid", "$form->{vc}", "$form->{vc}_id"); + + if (! $form->{till}) { + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub subtotal { + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{tax} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount - $subtotalnetamount, 2, " ")."</th>"; + $column_data{amount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount, 2, " ")."</th>"; + $column_data{paid} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalpaid, 2, " ")."</th>"; + $column_data{due} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount - $subtotalpaid, 2, " ")."</th>"; + $column_data{debit} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotaldebit, 2, " ")."</th>"; + $column_data{credit} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalcredit, 2, " ")."</th>"; + + if ($form->{l_curr} && $form->{sort} eq 'curr' && $form->{l_subtotal}) { + $column_data{fx_tax} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalfxamount - $subtotalfxnetamount, 2, " ")."</th>"; + $column_data{fx_amount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalfxamount, 2, " ")."</th>"; + $column_data{fx_paid} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalfxpaid, 2, " ")."</th>"; + $column_data{fx_due} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalfxmount - $subtotalfxpaid, 2, " ")."</th>"; + } + + $subtotalnetamount = 0; + $subtotalamount = 0; + $subtotalpaid = 0; + $subtotaldebit = 0; + $subtotalcredit = 0; + + $subtotalfxnetamount = 0; + $subtotalfxamount = 0; + $subtotalfxpaid = 0; + + print "<tr class=listsubtotal>"; + + for (@column_index) { print "\n$column_data{$_}" } + +print " +</tr> +"; + +} + + + diff --git a/bin/lynx/admin.pl b/bin/lynx/admin.pl new file mode 100755 index 00000000..ac422b8f --- /dev/null +++ b/bin/lynx/admin.pl @@ -0,0 +1,1612 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2002 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# setup module +# add/edit/delete users +# +#====================================================================== + +$menufile = "menu.ini"; + +use SL::Form; +use SL::User; + + +$form = new Form; + +$locale = new Locale $language, "admin"; +$form->{charset} = $locale->{charset}; + +eval { require DBI; }; +$form->error($locale->text('DBI not installed!')) if ($@); + +$form->{stylesheet} = "sql-ledger.css"; +$form->{favicon} = "favicon.ico"; +$form->{timeout} = 600; + +require "$form->{path}/pw.pl"; + +# customization +if (-f "$form->{path}/custom_$form->{script}") { + eval { require "$form->{path}/custom_$form->{script}"; }; + $form->error($@) if ($@); +} + + +if ($form->{action}) { + + &check_password unless $form->{action} eq 'logout'; + + &{ $locale->findsub($form->{action}) }; + +} else { + + # if there are no drivers bail out + $form->error($locale->text('No Database Drivers available!')) unless (User->dbdrivers); + + # create memberfile + if (! -f $memberfile) { + open(FH, ">$memberfile") or $form->error("$memberfile : $!"); + print FH qq|# LedgerSMB Small Medium Business Accounting members + +[root login] +password= + +|; + close FH; + } + + &adminlogin; + +} + +1; +# end + + +sub adminlogin { + + $form->{title} = qq|LedgerSMB $form->{version} |.$locale->text('Administration'); + + $form->header; + + print qq| +<script language="JavaScript" type="text/javascript"> +<!-- +function sf(){ + document.admin.password.focus(); +} +// End --> +</script> + +<body class=admin onload="sf()"> + +<div align=center> + +<a href="http://sourceforge.net/projects/ledger-smb/"><img src=ledger-smb.png border=0></a> +<h1 class=login>|.$locale->text('Version').qq| $form->{version}<p>|.$locale->text('Administration').qq|</h1> + +<form method=post action="$form->{script}" name=admin> + +<table> + <tr> + <th>|.$locale->text('Password').qq|</th> + <td><input type=password name=password></td> + <td><input type=submit class=submit name=action value="|.$locale->text('Login').qq|"></td> + </tr> +<input type=hidden name=action value=login> +<input type=hidden name=path value=$form->{path}> +</table> + +</form> + +<a href=http://sourceforge.net/projects/ledger-smb/>LedgerSMB |.$locale->text('website').qq|</a> + +</div> + +</body> +</html> +|; + +} + + +sub login { + + &list_users; + +} + + +sub logout { + + $form->{callback} = "$form->{script}?path=$form->{path}&endsession=1"; + $form->redirect($locale->text('You are logged out')); + +} + + +sub add_user { + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." ".$locale->text('Administration')." / ".$locale->text('Add User'); + + $form->{Oracle_sid} = $sid; + $form->{Oracle_dbport} = '1521'; + $form->{Oracle_dbhost} = `hostname`; + + if (-f "css/sql-ledger.css") { + $myconfig->{stylesheet} = "sql-ledger.css"; + } + $myconfig->{vclimit} = 1000; + $myconfig->{menuwidth} = 155; + $myconfig->{timeout} = 3600; + + &form_header; + &form_footer; + +} + + + +sub edit { + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." ".$locale->text('Administration')." / ".$locale->text('Edit User'); + $form->{edit} = 1; + + &form_header; + &form_footer; + +} + + +sub form_footer { + + if ($form->{edit}) { + $delete = qq|<input type=submit class=submit name=action value="|.$locale->text('Delete').qq|"> +<input type=hidden name=edit value=1>|; + } + + print qq| + +<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&sessionid=$form->{sessionid}"> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=submit class=submit name=action value="|.$locale->text('Save').qq|"> +$delete + +</form> + +</body> +</html> +|; + +} + + +sub list_users { + + open(FH, "$memberfile") or $form->error("$memberfile : $!"); + + $nologin = qq| +<input type=submit class=submit name=action value="|.$locale->text('Lock System').qq|">|; + + if (-e "$userspath/nologin") { + $nologin = qq| +<input type=submit class=submit name=action value="|.$locale->text('Unlock System').qq|">|; + } + + + while (<FH>) { + chop; + + if (/^\[.*\]/) { + $login = $_; + $login =~ s/(\[|\])//g; + } + + if (/^(name=|company=|templates=|dbuser=|dbdriver=|dbname=|dbhost=)/) { + chop ($var = $&); + ($null, $member{$login}{$var}) = split /=/, $_, 2; + } + } + + close(FH); + +# type=submit $locale->text('Pg Database Administration') +# type=submit $locale->text('PgPP Database Administration') +# type=submit $locale->text('Oracle Database Administration') + + foreach $item (User->dbdrivers) { + $dbdrivers .= qq|<input name=action type=submit class=submit value="|.$locale->text("$item Database Administration").qq|">|; + } + + + $column_header{login} = qq|<th>|.$locale->text('Login').qq|</th>|; + $column_header{name} = qq|<th>|.$locale->text('Name').qq|</th>|; + $column_header{company} = qq|<th>|.$locale->text('Company').qq|</th>|; + $column_header{dbdriver} = qq|<th>|.$locale->text('Driver').qq|</th>|; + $column_header{dbhost} = qq|<th>|.$locale->text('Host').qq|</th>|; + $column_header{dataset} = qq|<th>|.$locale->text('Dataset').qq|</th>|; + $column_header{templates} = qq|<th>|.$locale->text('Templates').qq|</th>|; + + @column_index = qw(login name company dbdriver dbhost dataset templates); + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." ".$locale->text('Administration'); + + $form->{login} = "root login"; + $form->header; + + print qq| +<body class=admin> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <tr class=listheading> + <th>$form->{title}</th> + </tr> + <tr size=5></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + +foreach $key (sort keys %member) { + $href = "$script?action=edit&login=$key&path=$form->{path}&sessionid=$form->{sessionid}"; + $href =~ s/ /%20/g; + + $member{$key}{templates} =~ s/^$templates\///; + $member{$key}{dbhost} = $locale->text('localhost') unless $member{$key}{dbhost}; + $member{$key}{dbname} = $member{$key}{dbuser} if ($member{$key}{dbdriver} eq 'Oracle'); + + $column_data{login} = qq|<td><a href=$href>$key</a></td>|; + $column_data{name} = qq|<td>$member{$key}{name}</td>|; + $column_data{company} = qq|<td>$member{$key}{company}</td>|; + $column_data{dbdriver} = qq|<td>$member{$key}{dbdriver}</td>|; + $column_data{dbhost} = qq|<td>$member{$key}{dbhost}</td>|; + $column_data{dataset} = qq|<td>$member{$key}{dbname}</td>|; + $column_data{templates} = qq|<td>$member{$key}{templates}</td>|; + + $i++; $i %= 2; + print qq| + <tr class=listrow$i>|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr>|; +} + + +print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<br><input type=submit class=submit name=action value="|.$locale->text('Add User').qq|"> +<input type=submit class=submit name=action value="|.$locale->text('Change Admin Password').qq|"> + +$dbdrivers +$nologin + +<input type=submit class=submit name=action value="|.$locale->text('Logout').qq|"> + +</form> + +|.$locale->text('Click on login name to edit!').qq| +<br> +|.$locale->text('To add a user to a group edit a name, change the login name and save. A new user with the same variables will then be saved under the new login name.').qq| + +</body> +</html> +|; + +} + + + +sub form_header { + + # if there is a login, get user + if ($form->{login}) { + # get user + $myconfig = new User "$memberfile", "$form->{login}"; + + for (qw(company address signature)) { $myconfig->{$_} = $form->quote($myconfig->{$_}) } + for (qw(address signature)) { $myconfig->{$_} =~ s/\\n/\n/g } + + # strip basedir from templates directory + $myconfig->{templates} =~ s/^$templates\///; + + $myconfig->{dbpasswd} = unpack 'u', $myconfig->{dbpasswd}; + } + + foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd)) { + $dateformat .= ($item eq $myconfig->{dateformat}) ? "<option selected>$item\n" : "<option>$item\n"; + } + + foreach $item (qw(1,000.00 1000.00 1.000,00 1000,00 1'000.00)) { + $numberformat .= ($item eq $myconfig->{numberformat}) ? "<option selected>$item\n" : "<option>$item\n"; + } + + + %countrycodes = User->country_codes; + $countrycodes = ""; + + foreach $key (sort { $countrycodes{$a} cmp $countrycodes{$b} } keys %countrycodes) { + $countrycodes .= ($myconfig->{countrycode} eq $key) ? "<option selected value=$key>$countrycodes{$key}" : "<option value=$key>$countrycodes{$key}"; + } + $countrycodes = qq|<option value="">English\n$countrycodes|; + + # is there a templates basedir + if (! -d "$templates") { + $form->error($locale->text('Directory').": $templates ".$locale->text('does not exist')); + } + + opendir TEMPLATEDIR, "$templates/." or $form->error("$templates : $!"); + @all = grep !/^\.\.?$/, readdir TEMPLATEDIR; + closedir TEMPLATEDIR; + + @allhtml = sort grep /\.html/, @all; + + @alldir = (); + for (@all) { + if (-d "$templates/$_") { + push @alldir, $_; + } + } + + @allhtml = reverse grep !/Default/, @allhtml; + push @allhtml, 'Default'; + @allhtml = reverse @allhtml; + + foreach $item (sort @alldir) { + if ($item eq $myconfig->{templates}) { + $usetemplates .= qq|<option selected>$item\n|; + } else { + $usetemplates .= qq|<option>$item\n|; + } + } + + $lastitem = $allhtml[0]; + $lastitem =~ s/-.*//g; + $mastertemplates = qq|<option>$lastitem\n|; + foreach $item (@allhtml) { + $item =~ s/-.*//g; + + if ($item ne $lastitem) { + $mastertemplates .= qq|<option>$item\n|; + $lastitem = $item; + } + } + + opendir CSS, "css/."; + @all = grep /.*\.css$/, readdir CSS; + closedir CSS; + + foreach $item (@all) { + if ($item eq $myconfig->{stylesheet}) { + $selectstylesheet .= qq|<option selected>$item\n|; + } else { + $selectstylesheet .= qq|<option>$item\n|; + } + } + $selectstylesheet .= "<option>\n"; + + if (%printer && $latex) { + $selectprinter = "<option>\n"; + foreach $item (sort keys %printer) { + if ($myconfig->{printer} eq $item) { + $selectprinter .= qq|<option value="$item" selected>$item\n|; + } else { + $selectprinter .= qq|<option value="$item">$item\n|; + } + } + + $printer = qq| + <tr> + <th align=right>|.$locale->text('Printer').qq|</th> + <td><select name=printer>$selectprinter</select></td> + </tr> +|; + + } + + $user = $form->{login}; + $form->{login} = "root login"; + $form->header; + $form->{login} = $user; + + print qq| +<body class=admin> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr class=listheading><th colspan=2>$form->{title}</th></tr> + <tr size=5></tr> + <tr valign=top> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Login').qq|</th> + <td><input name=login value="$myconfig->{login}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input type=password name=new_password size=8 value=$myconfig->{password}></td> + <input type=hidden name=old_password value=$myconfig->{password}> + </tr> + <tr> + <th align=right>|.$locale->text('Name').qq|</th> + <td><input name=name size=15 value="$myconfig->{name}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('E-mail').qq|</th> + <td><input name=email size=30 value="$myconfig->{email}"></td> + </tr> + <tr valign=top> + <th align=right>|.$locale->text('Signature').qq|</th> + <td><textarea name=signature rows=3 cols=35>$myconfig->{signature}</textarea></td> + </tr> + <tr> + <th align=right>|.$locale->text('Phone').qq|</th> + <td><input name=tel size=14 value="$myconfig->{tel}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Fax').qq|</th> + <td><input name=fax size=14 value="$myconfig->{fax}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Company').qq|</th> + <td><input name=company size=35 value="$myconfig->{company}"></td> + </tr> + <tr valign=top> + <th align=right>|.$locale->text('Address').qq|</th> + <td><textarea name=address rows=4 cols=35>$myconfig->{address}</textarea></td> + </tr> + </table> + </td> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Date Format').qq|</th> + <td><select name=dateformat>$dateformat</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('Number Format').qq|</th> + <td><select name=numberformat>$numberformat</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('Dropdown Limit').qq|</th> + <td><input name=vclimit value="$myconfig->{vclimit}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Menu Width').qq|</th> + <td><input name=menuwidth value="$myconfig->{menuwidth}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Language').qq|</th> + <td><select name=countrycode>$countrycodes</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('Session Timeout').qq|</th> + <td><input name=newtimeout value="$myconfig->{timeout}"></td> + </tr> + + <tr> + <th align=right>|.$locale->text('Stylesheet').qq|</th> + <td><select name=userstylesheet>$selectstylesheet</select></td> + </tr> + $printer + <tr> + <th align=right>|.$locale->text('Use Templates').qq|</th> + <td><select name=usetemplates>$usetemplates</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('New Templates').qq|</th> + <td><input name=newtemplates></td> + </tr> + <tr> + <th align=right>|.$locale->text('Setup Templates').qq|</th> + <td><select name=mastertemplates>$mastertemplates</select></td> + </tr> + <input type=hidden name=templates value=$myconfig->{templates}> + </table> + </td> + </tr> + <tr class=listheading> + <th colspan=2>|.$locale->text('Database').qq|</th> + </tr>|; + + # list section for database drivers + foreach $item (User->dbdrivers) { + + print qq| + <tr> + <td colspan=2> + <table> + <tr>|; + + $checked = ""; + if ($myconfig->{dbdriver} eq $item) { + for (qw(dbhost dbport dbuser dbpasswd dbname sid)) { $form->{"${item}_$_"} = $myconfig->{$_} } + $checked = "checked"; + } + + print qq| + <th align=right>|.$locale->text('Driver').qq|</th> + <td><input name=dbdriver type=radio class=radio value=$item $checked> $item</td> + <th align=right>|.$locale->text('Host').qq|</th> + <td><input name="${item}_dbhost" size=30 value=$form->{"${item}_dbhost"}></td> + </tr> + <tr>|; + + if ($item =~ /Pg/) { + print qq| + <th align=right>|.$locale->text('Dataset').qq|</th> + <td><input name="${item}_dbname" size=15 value=$form->{"${item}_dbname"}></td> + <th align=right>|.$locale->text('Port').qq|</th> + <td><input name="${item}_dbport" size=4 value=$form->{"${item}_dbport"}></td> + </tr> + <tr> + <th align=right>|.$locale->text('User').qq|</th> + <td><input name="${item}_dbuser" size=15 value=$form->{"${item}_dbuser"}></td> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input name="${item}_dbpasswd" type=password size=10 value=$form->{"${item}_dbpasswd"}></td> + </tr>|; + + } + + if ($item eq 'Oracle') { + print qq| + <th align=right>SID</th> + <td><input name=Oracle_sid value=$form->{Oracle_sid}></td> + <th align=right>|.$locale->text('Port').qq|</th> + <td><input name="${item}_dbport size=4 value=$form->{"${item}_dbport"}></td> + </tr> + <tr> + <th align=right>|.$locale->text('Dataset').qq|</th> + <td><input name="${item}_dbuser" size=15 value=$form->{"${item}_dbuser"}></td> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input name="${item}_dbpasswd" type=password size=10 value=$form->{"${item}_dbpasswd"}></td> + + </tr>|; + } + + + print qq| + <input type=hidden name=old_dbpasswd value=$myconfig->{dbpasswd}> + </table> + </td> + </tr> + <tr> + <td colspan=2><hr size=2 noshade></td> + </tr> +|; + + } + + + # access control + open(FH, $menufile) or $form->error("$menufile : $!"); + # scan for first menu level + @a = <FH>; + close(FH); + + if (open(FH, "custom_$menufile")) { + push @a, <FH>; + } + close(FH); + + foreach $item (@a) { + next unless $item =~ /\[\w+/; + next if $item =~ /\#/; + + $item =~ s/(\[|\])//g; + chop $item; + + if ($item =~ /--/) { + ($level, $menuitem) = split /--/, $item, 2; + } else { + $level = $item; + $menuitem = $item; + push @acsorder, $item; + } + + push @{ $acs{$level} }, $menuitem; + + } + + %role = ( 'admin' => $locale->text('Administrator'), + 'user' => $locale->text('User'), + 'supervisor' => $locale->text('Supervisor'), + 'manager' => $locale->text('Manager') + + ); + + $selectrole = ""; + foreach $item (qw(user admin supervisor manager)) { + $selectrole .= ($myconfig->{role} eq $item) ? "<option selected value=$item>$role{$item}\n" : "<option value=$item>$role{$item}\n"; + } + + print qq| + <tr class=listheading> + <th colspan=2>|.$locale->text('Access Control').qq|</th> + </tr> + <tr> + <td><select name=role>$selectrole</select></td> + </tr> +|; + + foreach $item (split /;/, $myconfig->{acs}) { + ($key, $value) = split /--/, $item, 2; + $excl{$key}{$value} = 1; + } + + foreach $key (@acsorder) { + + $checked = "checked"; + if ($form->{login}) { + $checked = ($excl{$key}{$key}) ? "" : "checked"; + } + + # can't have variable names with & and spaces + $item = $form->escape("${key}--$key",1); + + $acsheading = $key; + $acsheading =~ s/ / /g; + + $acsheading = qq| + <th align=left nowrap><input name="$item" class=checkbox type=checkbox value=1 $checked> $acsheading</th>\n|; + $menuitems .= "$item;"; + $acsdata = " + <td>"; + + foreach $item (@{ $acs{$key} }) { + + next if ($key eq $item); + + $checked = "checked"; + if ($form->{login}) { + $checked = ($excl{$key}{$item}) ? "" : "checked"; + } + + $acsitem = $form->escape("${key}--$item",1); + + $acsdata .= qq| + <br><input name="$acsitem" class=checkbox type=checkbox value=1 $checked> $item|; + $menuitems .= "$acsitem;"; + } + + $acsdata .= " + </td>"; + + print qq| + <tr valign=top>$acsheading $acsdata + </tr> +|; + } + + print qq|<input type=hidden name=acs value="$menuitems"> + + <tr> + <td colspan=2><hr size=3 noshade></td> + </tr> +</table> +</div> +|; + +} + + +sub save { + + # no driver checked + $form->error($locale->text('Database Driver not checked!')) unless $form->{dbdriver}; + + # no spaces allowed in login name + $form->{login} =~ s/ //g; + + $form->isblank("login", $locale->text('Login name missing!')); + + # check for duplicates + if (!$form->{edit}) { + $temp = new User "$memberfile", "$form->{login}"; + + if ($temp->{login}) { + $form->error("$form->{login} ".$locale->text('is already a member!')); + } + } + + # no spaces allowed in directories + $form->{newtemplates} =~ s/( |\.\.|\*)//g; + + if ($form->{newtemplates} ne "") { + $form->{templates} = $form->{newtemplates}; + } else { + $form->{templates} = ($form->{usetemplates}) ? $form->{usetemplates} : $form->{login}; + } + + # is there a basedir + if (! -d "$templates") { + $form->error($locale->text('Directory').": $templates ".$locale->text('does not exist')); + } + + # add base directory to $form->{templates} + $form->{templates} = "$templates/$form->{templates}"; + + + $myconfig = new User "$memberfile", "$form->{login}"; + + # redo acs variable and delete all the acs codes + @acs = split /;/, $form->{acs}; + + $form->{acs} = ""; + foreach $item (@acs) { + $item = $form->escape($item,1); + if (!$form->{$item}) { + $form->{acs} .= $form->unescape($form->unescape("$item")).";"; + } + delete $form->{$item}; + } + + # check which database was filled in + + $form->{dbhost} = $form->{"$form->{dbdriver}_dbhost"}; + $form->{dbport} = $form->{"$form->{dbdriver}_dbport"}; + $form->{dbpasswd} = $form->{"$form->{dbdriver}_dbpasswd"}; + $form->{dbuser} = $form->{"$form->{dbdriver}_dbuser"}; + $form->{dbname} = $form->{"$form->{dbdriver}_dbname"}; + + if ($form->{dbdriver} eq 'Oracle') { + $form->{sid} = $form->{Oracle_sid}, ; + + $form->isblank("dbhost", $locale->text('Hostname missing!')); + $form->isblank("dbport", $locale->text('Port missing!')); + $form->isblank("dbuser", $locale->text('Dataset missing!')); + } + if ($form->{dbdriver} =~ /Pg/) { + $form->isblank("dbname", $locale->text('Dataset missing!')); + $form->isblank("dbuser", $locale->text('Database User missing!')); + } + + foreach $item (keys %{$form}) { + $myconfig->{$item} = $form->{$item}; + } + + $myconfig->{password} = $form->{old_password}; + $myconfig->{password} = $form->{new_password} if $form->{new_password} ne $form->{old_password}; + $myconfig->{timeout} = $form->{newtimeout}; + + delete $myconfig->{stylesheet}; + if ($form->{userstylesheet}) { + $myconfig->{stylesheet} = $form->{userstylesheet}; + } + + $myconfig->{packpw} = 1; + + $myconfig->save_member($memberfile, $userspath); + + # create user template directory and copy master files + if (! -d "$form->{templates}") { + + umask(002); + + if (mkdir "$form->{templates}", oct("771")) { + + umask(007); + + # copy templates to the directory + opendir TEMPLATEDIR, "$templates/." or $form->error("$templates : $!"); + @templates = grep /$form->{mastertemplates}-/, readdir TEMPLATEDIR; + closedir TEMPLATEDIR; + + foreach $file (@templates) { + open(TEMP, "$templates/$file") or $form->error("$templates/$file : $!"); + + $file =~ s/$form->{mastertemplates}-//; + open(NEW, ">$form->{templates}/$file") or $form->error("$form->{templates}/$file : $!"); + + while ($line = <TEMP>) { + print NEW $line; + } + close(TEMP); + close(NEW); + } + } else { + $form->error("$form->{templates} : $!"); + } + } + + $form->redirect($locale->text('User saved!')); + +} + + +sub delete { + + $form->{templates} = ($form->{templates}) ? "$templates/$form->{templates}" : "$templates/$form->{login}"; + + $form->error("$memberfile ".$locale->text('locked!')) if (-f ${memberfile}.LCK); + + open(FH, ">${memberfile}.LCK") or $form->error("${memberfile}.LCK : $!"); + close(FH); + + if (! open(CONF, "+<$memberfile")) { + unlink "${memberfile}.LCK"; + $form->error("$memberfile : $!"); + } + + @config = <CONF>; + + seek(CONF, 0, 0); + truncate(CONF, 0); + + while ($line = shift @config) { + + chop $line; + + if ($line =~ /^\[/) { + last if ($line eq "[$form->{login}]"); + $login = &login_name($line); + } + + if ($line =~ /^templates=/) { + ($null, $user{$login}) = split /=/, $line, 2; + } + + print CONF "$line\n"; + } + + # remove everything up to next login or EOF + # and save template variable + while ($line = shift @config) { + + chop $line; + + ($key, $value) = split /=/, $line, 2; + $myconfig{$key} = $value; + + last if ($line =~ /^\[/); + } + + # this one is either the next login or EOF + print CONF "$line\n"; + + $login = &login_name($line); + + + while ($line = shift @config) { + + chop $line; + + if ($line =~ /^\[/) { + $login = &login_name($line); + } + + if ($line =~ /^templates=/) { + ($null, $user{$login}) = split /=/, $line, 2; + } + + print CONF "$line\n"; + } + + close(CONF); + unlink "${memberfile}.LCK"; + + # scan %user for $templatedir + foreach $login (keys %user) { + last if ($found = ($form->{templates} eq $user{$login})); + } + + # if found keep directory otherwise delete + if (!$found) { + # delete it if there is a template directory + $dir = "$form->{templates}"; + if (-d "$dir") { + unlink <$dir/*>; + rmdir "$dir"; + } + } + + if ($myconfig{dbconnect}) { + $myconfig{dbpasswd} = unpack 'u', $myconfig{dbpasswd}; + for (keys %myconfig) { $form->{$_} = $myconfig{$_} } + + User->delete_login(\%$form); + + # delete config file for user + unlink "$userspath/$form->{login}.conf"; + } + + $form->redirect($locale->text('User deleted!')); + +} + + +sub login_name { + my $login = shift; + + $login =~ s/\[\]//g; + return ($login) ? $login : undef; + +} + + +sub change_admin_password { + + $form->{title} = qq|LedgerSMB |.$locale->text('Accounting')." ".$locale->text('Administration')." / ".$locale->text('Change Admin Password'); + + $form->{login} = "root login"; + $form->header; + + print qq| +<body class=admin> + +<form method=post action=$form->{script}> + +<table> + <tr> + <tr class=listheading> + <th>|.$locale->text('Change Password').qq|</th> + </tr> + <tr size=5></tr> + <tr> + <td> + <table width=100%> + <tr> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input type=password name=new_password></td> + </tr> + <tr> + <th align=right>|.$locale->text('Confirm').qq|</th> + <td><input type=password name=confirm_password></td> + </tr> + </table> + </td> + </tr> + +</table> + +<br> +<hr size=3 noshade> +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<p> +<input type=submit class=submit name=action value="|.$locale->text('Change Password').qq|"> + +</form> + +</body> +</html> +|; + +} + + +sub change_password { + + $form->error($locale->text('Passwords do not match!')) if $form->{new_password} ne $form->{confirm_password}; + + $root->{password} = $form->{new_password}; + + $root->{'root login'} = 1; + $root->save_member($memberfile); + + $form->{callback} = "$form->{script}?action=list_users&path=$form->{path}&sessionid=$form->{sessionid}"; + + $form->redirect($locale->text('Password changed!')); + +} + + +sub check_password { + + $root = new User "$memberfile", "root login"; + + if ($root->{password}) { + + if ($form->{password}) { + $form->{callback} .= "&password=$form->{password}" if $form->{callback}; + $form->{sessionid} = time; + if ($root->{password} ne crypt $form->{password}, 'ro') { + &getpassword; + exit; + } + } else { + if ($ENV{HTTP_USER_AGENT}) { + $ENV{HTTP_COOKIE} =~ s/;\s*/;/g; + %cookie = split /[=;]/, $ENV{HTTP_COOKIE}; + $cookie = ($form->{path} eq 'bin/lynx') ? $cookie{login} : $cookie{"SQL-Ledger-root login"}; + if (! $cookie || $cookie ne $form->{sessionid}) { + &getpassword; + exit; + } + } + } + } + +} + + +sub pg_database_administration { + + $form->{dbdriver} = 'Pg'; + &dbselect_source; + +} + + +sub pgpp_database_administration { + + $form->{dbdriver} = 'PgPP'; + &dbselect_source; + +} + + +sub oracle_database_administration { + + $form->{dbdriver} = 'Oracle'; + &dbselect_source; + +} + + +sub dbdriver_defaults { + + # load some defaults for the selected driver + %driverdefaults = ( 'Pg' => { dbport => '', + dbuser => 'sql-ledger', + dbdefault => 'template1', + dbhost => '', + connectstring => $locale->text('Connect to') + }, + 'Oracle' => { dbport => '1521', + dbuser => 'oralin', + dbdefault => $sid, + dbhost => `hostname`, + connectstring => 'SID' + } + ); + + $driverdefaults{PgPP} = $driverdefaults{Pg}; + + for (keys %{ $driverdefaults{Pg} }) { $form->{$_} = $driverdefaults{$form->{dbdriver}}{$_} } + +} + + +sub dbselect_source { + + &dbdriver_defaults; + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." / ".$locale->text('Database Administration'); + + $form->{login} = "root login"; + $form->header; + + print qq| +<body class=admin> + +<center> +<h2>$form->{title}</h2> + +<form method=post action=$form->{script}> + +<table> + <tr> + <td> + <table> + <tr class=listheading> + <th colspan=4>|.$locale->text('Database').qq|</th> + </tr> + <input type=hidden name=dbdriver value=$form->{dbdriver}> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Host').qq|</th> + <td><input name=dbhost size=25 value=$form->{dbhost}></td> + <th align=right>|.$locale->text('Port').qq|</th> + <td><input name=dbport size=5 value=$form->{dbport}></td> + </tr> + <tr> + <th align=right>|.$locale->text('User').qq|</th> + <td><input name=dbuser size=10 value=$form->{dbuser}></td> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input type=password name=dbpasswd size=10></td> + </tr> + <tr> + + <th align=right>$form->{connectstring}</th> + <td colspan=3><input name=dbdefault size=10 value=$form->{dbdefault}></td> + + </tr> + </table> + </td> + </tr> + </table> + +<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&sessionid=$form->{sessionid}"> +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<br> + +<input type=submit class=submit name=action value="|.$locale->text('Create Dataset').qq|"> +<input type=submit class=submit name=action value="|.$locale->text('Update Dataset').qq|"> +<input type=submit class=submit name=action value="|.$locale->text('Delete Dataset').qq|"> + +</form> + + </td> + </tr> +</table> + +<p>|.$locale->text('This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!') + +.qq| +</body> +</html> +|; + +} + + +sub continue { + + &{ $form->{nextsub} }; + +} + + +sub update_dataset { + + %needsupdate = User->dbneedsupdate(\%$form); + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Update Dataset'); + + $form->{login} = "root login"; + $form->header; + + print qq| +<body class=admin> + + +<center> +<h2>$form->{title}</h2> +|; + + + foreach $key (sort keys %needsupdate) { + if ($needsupdate{$key} ne $form->{dbversion}) { + $upd .= qq|<input name="db$key" class=checkbox type=checkbox value=1 checked> $key\n|; + $form->{dbupdate} .= "db$key "; + } + } + + chop $form->{dbupdate}; + + + if ($form->{dbupdate}) { + + print qq| +<table width=100%> +<form method=post action=$form->{script}> + +<input type=hidden name=dbdriver value=$form->{dbdriver}> +<input type=hidden name=dbhost value=$form->{dbhost}> +<input type=hidden name=dbport value=$form->{dbport}> +<input type=hidden name=dbuser value=$form->{dbuser}> +<input type=hidden name=dbpasswd value=$form->{dbpasswd}> +<input type=hidden name=dbdefault value=$form->{dbdefault}> + +<tr class=listheading> + <th>|.$locale->text('The following Datasets need to be updated').qq|</th> +</tr> +<tr> +<td> + +$upd + +</td> +</tr> +<tr> +<td> + +<input name=dbupdate type=hidden value="$form->{dbupdate}"> + +<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&sessionid=$form->{sessionid}"> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=hidden name=nextsub value=dbupdate> + +<hr size=3 noshade> + +<br> +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> + +</td></tr> +</table> +</form> +|; + + } else { + + print $locale->text('DBA')." : $form->{dbuser} : " .$locale->text('All Datasets up to date!'); + + } + + print qq| + +</body> +</html> +|; + +} + + +sub dbupdate { + + User->dbupdate(\%$form); + + $form->redirect($locale->text('Dataset updated!')); + +} + + +sub create_dataset { + + @dbsources = sort User->dbsources(\%$form); + + opendir SQLDIR, "sql/." or $form->error($!); + foreach $item (sort grep /-chart\.sql/, readdir SQLDIR) { + next if ($item eq 'Default-chart.sql'); + $item =~ s/-chart\.sql//; + push @charts, qq|<input name=chart class=radio type=radio value="$item">$item|; + } + closedir SQLDIR; + + # add Default at beginning + unshift @charts, qq|<input name=chart class=radio type=radio value="Default" checked>Default|; + + $selectencoding = qq|<option> + <option value=SQL_ASCII>ASCII + <option value=EUC_JP>Japanese EUC + <option value=EUC_CN>Chinese EUC + <option value=EUC_KR>Korean EUC + <option value=JOHAB>Korean EUC (Hangle base) + <option value=EUC_TW>Taiwan EUC + <option value=UNICODE>Unicode (UTF-8) + <option value=MULE_INTERNAL>Mule internal type + <option value=LATIN1>ISO 8859-1/ECMA 94 (Latin alphabet no. 1) + <option value=LATIN2>ISO 8859-2/ECMA 94 (Latin alphabet no. 2) + <option value=LATIN3>ISO 8859-3/ECMA 94 (Latin alphabet no. 3) + <option value=LATIN4>ISO 8859-4/ECMA 94 (Latin alphabet no. 4) + <option value=LATIN5>ISO 8859-9/ECMA 128 (Latin alphabet no. 5) + <option value=LATIN6>ISO 8859-10/ECMA 144 (Latin alphabet no. 6) + <option value=LATIN7>ISO 8859-13 (Latin alphabet no. 7) + <option value=LATIN8>ISO 8859-14 (Latin alphabet no. 8) + <option value=LATIN9>ISO 8859-15 (Latin alphabet no. 9) + <option value=LATIN10>ISO 8859-16/ASRO SR 14111 (Latin alphabet no. 10) + <option value=ISO_8859_5>ISO 8859-5/ECMA 113 (Latin/Cyrillic) + <option value=ISO_8859_6>ISO 8859-6/ECMA 114 (Latin/Arabic) + <option value=ISO_8859_7>ISO 8859-7/ECMA 118 (Latin/Greek) + <option value=ISO_8859_8>ISO 8859-8/ECMA 121 (Latin/Hebrew) + <option value=KOI8>KOI8-R(U) + <option value=WIN>Windows CP1251 + <option value=ALT>Windows CP866 + <option value=WIN1256>Windows CP1256 (Arabic) + <option value=TCVN>Windows CP1258 (Vietnamese) + <option value=WIN874>Windows CP874 (Thai) + |; + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Create Dataset'); + + $form->{login} = "root login"; + $form->header; + + print qq| +<body class=admin> + + +<center> +<h2>$form->{title}</h2> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr class=listheading> + <th colspan=2> </th> + </tr> + + <tr> + + <th align=right nowrap>|.$locale->text('Existing Datasets').qq|</th> + <td> +|; + + for (@dbsources) { print "[ $_ ] " } + + print qq| + </td> + </tr> + + <tr> + + <th align=right nowrap>|.$locale->text('Create Dataset').qq|</th> + <td><input name=db></td> + + </tr> + + <tr> + + <th align=right nowrap>|.$locale->text('Multibyte Encoding').qq|</th> + <td><select name=encoding>$selectencoding</select></td> + + </tr> + + <tr> + + <th align=right nowrap>|.$locale->text('Create Chart of Accounts').qq|</th> + <td> + <table> +|; + + while (@charts) { + print qq| + <tr> +|; + + for (0 .. 2) { print "<td>$charts[$_]</td>\n" } + + print qq| + </tr> +|; + + splice @charts, 0, 3; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td colspan=2> + <hr size=3 noshade> + </td> + </tr> +</table> +|; + + $form->hide_form(qw(dbdriver dbuser dbhost dbport dbpasswd dbdefault path sessionid)); + + print qq| + +<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&sessionid=$form->{sessionid}"> +<input type=hidden name=nextsub value=dbcreate> + +<br> +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> + + +</form> + +</body> +</html> +|; + +} + + +sub dbcreate { + + $form->isblank("db", $locale->text('Dataset missing!')); + + User->dbcreate(\%$form); + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Create Dataset'); + + $form->{login} = "root login"; + $form->header; + + print qq| +<body class=admin> + + +<center> +<h2>$form->{title}</h2> + +<form method=post action=$form->{script}>| + +.$locale->text('Dataset')." $form->{db} ".$locale->text('successfully created!') + +.qq| + +<input type=hidden name=path value="$form->{path}"> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=hidden name=nextsub value=list_users> + +<p><input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + + +</body> +</html> +|; + +} + + +sub delete_dataset { + + if (@dbsources = User->dbsources_unused(\%$form, $memberfile)) { + foreach $item (sort @dbsources) { + $dbsources .= qq|<input name=db class=radio type=radio value=$item> $item |; + } + } else { + $form->error($locale->text('Nothing to delete!')); + } + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Delete Dataset'); + + $form->{login} = "root login"; + $form->header; + + print qq| +<body class=admin> + +<h2>$form->{title}</h2> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr class=listheading> + <th>|.$locale->text('The following Datasets are not in use and can be deleted').qq|</th> + </tr> + + <tr> + <td> + $dbsources + </td> + </tr> + + <tr><td> +<p> +<input type=hidden name=dbdriver value=$form->{dbdriver}> +<input type=hidden name=dbuser value=$form->{dbuser}> +<input type=hidden name=dbhost value=$form->{dbhost}> +<input type=hidden name=dbport value=$form->{dbport}> +<input type=hidden name=dbpasswd value=$form->{dbpasswd}> +<input type=hidden name=dbdefault value=$form->{dbdefault}> + +<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&sessionid=$form->{sessionid}"> + +<input type=hidden name=path value="$form->{path}"> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=hidden name=nextsub value=dbdelete> + +<hr size=3 noshade> + +<br> +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> + + </td></tr> +</table> + +</form> + +</body> +</html> +|; + +} + + +sub dbdelete { + + if (!$form->{db}) { + $form->error($locale->text('No Dataset selected!')); + } + + User->dbdelete(\%$form); + + $form->{title} = "LedgerSMB ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Delete Dataset'); + + $form->{login} = "root login"; + $form->header; + + print qq| +<body class=admin> + + +<center> +<h2>$form->{title}</h2> + +<form method=post action=$form->{script}> + +$form->{db} |.$locale->text('successfully deleted!') + +.qq| + +<input type=hidden name=path value="$form->{path}"> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=hidden name=nextsub value=list_users> + +<p><input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + + +</body> +</html> +|; + +} + + +sub unlock_system { + + unlink "$userspath/nologin"; + + $form->{callback} = "$form->{script}?action=list_users&path=$form->{path}&sessionid=$form->{sessionid}"; + + $form->redirect($locale->text('Lockfile removed!')); + +} + + +sub lock_system { + + open(FH, ">$userspath/nologin") or $form->error($locale->text('Cannot create Lock!')); + close(FH); + + $form->{callback} = "$form->{script}?action=list_users&path=$form->{path}&sessionid=$form->{sessionid}"; + + $form->redirect($locale->text('Lockfile created!')); + +} + + diff --git a/bin/lynx/am.pl b/bin/lynx/am.pl new file mode 100755 index 00000000..ad2e91b2 --- /dev/null +++ b/bin/lynx/am.pl @@ -0,0 +1,3271 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# administration +# +#====================================================================== + + +use SL::AM; +use SL::CA; +use SL::Form; +use SL::User; +use SL::RP; +use SL::GL; + + +1; +# end of main + + + +sub add { &{ "add_$form->{type}" } }; +sub edit { &{ "edit_$form->{type}" } }; +sub save { &{ "save_$form->{type}" } }; +sub delete { &{ "delete_$form->{type}" } }; + + +sub save_as_new { + + delete $form->{id}; + + &save; + +} + + +sub add_account { + + $form->{title} = "Add"; + $form->{charttype} = "A"; + + $form->{callback} = "$form->{script}?action=list_account&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &account_header; + &form_footer; + +} + + +sub edit_account { + + $form->{title} = "Edit"; + + $form->{accno} =~ s/\\'/'/g; + $form->{accno} =~ s/\\\\/\\/g; + + AM->get_account(\%myconfig, \%$form); + + foreach my $item (split(/:/, $form->{link})) { + $form->{$item} = "checked"; + } + + &account_header; + &form_footer; + +} + + +sub account_header { + + $form->{title} = $locale->text("$form->{title} Account"); + + $checked{$form->{charttype}} = "checked"; + $checked{contra} = "checked" if $form->{contra}; + $checked{"$form->{category}_"} = "checked"; + + for (qw(accno description)) { $form->{$_} = $form->quote($form->{$_}) } + +# this is for our parser only! +# type=submit $locale->text('Add Account') +# type=submit $locale->text('Edit Account') + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=id value=$form->{id}> +<input type=hidden name=type value=account> + +<input type=hidden name=inventory_accno_id value=$form->{inventory_accno_id}> +<input type=hidden name=income_accno_id value=$form->{income_accno_id}> +<input type=hidden name=expense_accno_id value=$form->{expense_accno_id}> +<input type=hidden name=fxgain_accno_id values=$form->{fxgain_accno_id}> +<input type=hidden name=fxloss_accno_id values=$form->{fxloss_accno_id}> + +<table border=0 width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Account Number').qq|</th> + <td><input name=accno size=20 value="$form->{accno}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td><input name=description size=40 value="$form->{description}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Account Type').qq|</th> + <td> + <table> + <tr valign=top> + <td><input name=category type=radio class=radio value=A $checked{A_}> |.$locale->text('Asset').qq|\n<br> + <input name=category type=radio class=radio value=L $checked{L_}> |.$locale->text('Liability').qq|\n<br> + <input name=category type=radio class=radio value=Q $checked{Q_}> |.$locale->text('Equity').qq|\n<br> + <input name=category type=radio class=radio value=I $checked{I_}> |.$locale->text('Income').qq|\n<br> + <input name=category type=radio class=radio value=E $checked{E_}> |.$locale->text('Expense') + .qq|</td> + <td> + <input name=contra class=checkbox type=checkbox value=1 $checked{contra}> |.$locale->text('Contra').qq| + </td> + <td> + <input name=charttype type=radio class=radio value="H" $checked{H}> |.$locale->text('Heading').qq|<br> + <input name=charttype type=radio class=radio value="A" $checked{A}> |.$locale->text('Account') + .qq|</td> + </tr> + </table> + </td> + </tr> +|; + + +if ($form->{charttype} eq "A") { + print qq| + <tr> + <td colspan=2> + <table> + <tr> + <th align=left>|.$locale->text('Is this a summary account to record').qq|</th> + <td> + <input name=AR class=checkbox type=checkbox value=AR $form->{AR}> |.$locale->text('AR') + .qq| <input name=AP class=checkbox type=checkbox value=AP $form->{AP}> |.$locale->text('AP') + .qq| <input name=IC class=checkbox type=checkbox value=IC $form->{IC}> |.$locale->text('Inventory') + .qq|</td> + </tr> + </table> + </td> + </tr> + <tr> + <th colspan=2>|.$locale->text('Include in drop-down menus').qq|</th> + </tr> + <tr valign=top> + <td colspan=2> + <table width=100%> + <tr> + <th align=left>|.$locale->text('Receivables').qq|</th> + <th align=left>|.$locale->text('Payables').qq|</th> + <th align=left>|.$locale->text('Tracking Items').qq|</th> + <th align=left>|.$locale->text('Non-tracking Items').qq|</th> + </tr> + <tr> + <td> + <input name=AR_amount class=checkbox type=checkbox value=AR_amount $form->{AR_amount}> |.$locale->text('Income').qq|\n<br> + <input name=AR_paid class=checkbox type=checkbox value=AR_paid $form->{AR_paid}> |.$locale->text('Payment').qq|\n<br> + <input name=AR_tax class=checkbox type=checkbox value=AR_tax $form->{AR_tax}> |.$locale->text('Tax') .qq| + </td> + <td> + <input name=AP_amount class=checkbox type=checkbox value=AP_amount $form->{AP_amount}> |.$locale->text('Expense/Asset').qq|\n<br> + <input name=AP_paid class=checkbox type=checkbox value=AP_paid $form->{AP_paid}> |.$locale->text('Payment').qq|\n<br> + <input name=AP_tax class=checkbox type=checkbox value=AP_tax $form->{AP_tax}> |.$locale->text('Tax') .qq| + </td> + <td> + <input name=IC_sale class=checkbox type=checkbox value=IC_sale $form->{IC_sale}> |.$locale->text('Income').qq|\n<br> + <input name=IC_cogs class=checkbox type=checkbox value=IC_cogs $form->{IC_cogs}> |.$locale->text('COGS').qq|\n<br> + <input name=IC_taxpart class=checkbox type=checkbox value=IC_taxpart $form->{IC_taxpart}> |.$locale->text('Tax') .qq| + </td> + <td> + <input name=IC_income class=checkbox type=checkbox value=IC_income $form->{IC_income}> |.$locale->text('Income').qq|\n<br> + <input name=IC_expense class=checkbox type=checkbox value=IC_expense $form->{IC_expense}> |.$locale->text('Expense').qq|\n<br> + <input name=IC_taxservice class=checkbox type=checkbox value=IC_taxservice $form->{IC_taxservice}> |.$locale->text('Tax') .qq| + </td> + </tr> + </table> + </td> + </tr> + <tr> + </tr> +|; +} + +print qq| + <tr> + <th align=right>|.$locale->text('GIFI').qq|</th> + <td><input name=gifi_accno size=9 value=$form->{gifi_accno}></td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub form_footer { + + $form->hide_form(qw(callback path login sessionid)); + +# type=submit $locale->text('Save') +# type=submit $locale->text('Save as new') +# type=submit $locale->text('Delete') + + %button = (); + + if ($form->{id}) { + $button{'Save'} = { ndx => 3, key => 'S', value => $locale->text('Save') }; + $button{'Save as new'} = { ndx => 7, key => 'N', value => $locale->text('Save as new') }; + + if ($form->{orphaned}) { + $button{'Delete'} = { ndx => 16, key => 'D', value => $locale->text('Delete') }; + } + } else { + $button{'Save'} = { ndx => 3, key => 'S', value => $locale->text('Save') }; + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub save_account { + + $form->isblank("accno", $locale->text('Account Number missing!')); + $form->isblank("category", $locale->text('Account Type missing!')); + + # check for conflicting accounts + if ($form->{AR} || $form->{AP} || $form->{IC}) { + $a = ""; + for (qw(AR AP IC)) { $a .= $form->{$_} } + $form->error($locale->text('Cannot set account for more than one of AR, AP or IC')) if length $a > 2; + + for (qw(AR_amount AR_tax AR_paid AP_amount AP_tax AP_paid IC_taxpart IC_taxservice IC_sale IC_cogs IC_income IC_expense)) { $form->error("$form->{AR}$form->{AP}$form->{IC} ". $locale->text('account cannot be set to any other type of account')) if $form->{$_} } + } + + foreach $item ("AR", "AP") { + $i = 0; + for ("${item}_amount", "${item}_paid", "${item}_tax") { $i++ if $form->{$_} } + $form->error($locale->text('Cannot set multiple options for')." $item") if $i > 1; + } + + if (AM->save_account(\%myconfig, \%$form)) { + $form->redirect($locale->text('Account saved!')); + } else { + $form->error($locale->text('Cannot save account!')); + } + +} + + +sub list_account { + + CA->all_accounts(\%myconfig, \%$form); + + $form->{title} = $locale->text('Chart of Accounts'); + + # construct callback + $callback = "$form->{script}?action=list_account&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + @column_index = qw(accno gifi_accno description debit credit link); + + $column_header{accno} = qq|<th class=listtop>|.$locale->text('Account').qq|</a></th>|; + $column_header{gifi_accno} = qq|<th class=listtop>|.$locale->text('GIFI').qq|</a></th>|; + $column_header{description} = qq|<th class=listtop>|.$locale->text('Description').qq|</a></th>|; + $column_header{debit} = qq|<th class=listtop>|.$locale->text('Debit').qq|</a></th>|; + $column_header{credit} = qq|<th class=listtop>|.$locale->text('Credit').qq|</a></th>|; + $column_header{link} = qq|<th class=listtop>|.$locale->text('Link').qq|</a></th>|; + + + $form->header; + $colspan = $#column_index + 1; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop colspan=$colspan>$form->{title}</th> + </tr> + <tr height=5></tr> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| +</tr> +|; + + # escape callback + $callback = $form->escape($callback); + + foreach $ca (@{ $form->{CA} }) { + + $ca->{debit} = " "; + $ca->{credit} = " "; + + if ($ca->{amount} > 0) { + $ca->{credit} = $form->format_amount(\%myconfig, $ca->{amount}, 2, " "); + } + if ($ca->{amount} < 0) { + $ca->{debit} = $form->format_amount(\%myconfig, -$ca->{amount}, 2, " "); + } + + $ca->{link} =~ s/:/<br>/og; + + $gifi_accno = $form->escape($ca->{gifi_accno}); + + if ($ca->{charttype} eq "H") { + print qq|<tr class=listheading>|; + + $column_data{accno} = qq|<th><a class=listheading href=$form->{script}?action=edit_account&id=$ca->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ca->{accno}</a></th>|; + $column_data{gifi_accno} = qq|<th class=listheading><a href=$form->{script}?action=edit_gifi&accno=$gifi_accno&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ca->{gifi_accno}</a> </th>|; + $column_data{description} = qq|<th class=listheading>$ca->{description} </th>|; + $column_data{debit} = qq|<th> </th>|; + $column_data{credit} = qq| <th> </th>|; + $column_data{link} = qq|<th> </th>|; + + } else { + $i++; $i %= 2; + print qq| +<tr valign=top class=listrow$i>|; + $column_data{accno} = qq|<td><a href=$form->{script}?action=edit_account&id=$ca->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ca->{accno}</a></td>|; + $column_data{gifi_accno} = qq|<td><a href=$form->{script}?action=edit_gifi&accno=$gifi_accno&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ca->{gifi_accno}</a> </td>|; + $column_data{description} = qq|<td>$ca->{description} </td>|; + $column_data{debit} = qq|<td align=right>$ca->{debit}</td>|; + $column_data{credit} = qq|<td align=right>$ca->{credit}</td>|; + $column_data{link} = qq|<td>$ca->{link} </td>|; + + } + + for (@column_index) { print "$column_data{$_}\n" } + + print "</tr>\n"; + } + + print qq| + <tr><td colspan=$colspan><hr size=3 noshade></td></tr> +</table> + +</body> +</html> +|; + +} + + +sub delete_account { + + $form->{title} = $locale->text('Delete Account'); + + foreach $id (qw(inventory_accno_id income_accno_id expense_accno_id fxgain_accno_id fxloss_accno_id)) { + if ($form->{id} == $form->{$id}) { + $form->error($locale->text('Cannot delete default account!')); + } + } + + if (AM->delete_account(\%myconfig, \%$form)) { + $form->redirect($locale->text('Account deleted!')); + } else { + $form->error($locale->text('Cannot delete account!')); + } + +} + + +sub list_gifi { + + @{ $form->{fields} } = qw(accno description); + $form->{table} = "gifi"; + + AM->gifi_accounts(\%myconfig, \%$form); + + $form->{title} = $locale->text('GIFI'); + + # construct callback + $callback = "$form->{script}?action=list_gifi&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + @column_index = qw(accno description); + + $column_header{accno} = qq|<th class=listheading>|.$locale->text('GIFI').qq|</a></th>|; + $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</a></th>|; + + + $form->header; + $colspan = $#column_index + 1; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop colspan=$colspan>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| +</tr> +|; + + # escape callback + $callback = $form->escape($callback); + + foreach $ca (@{ $form->{ALL} }) { + + $i++; $i %= 2; + + print qq| +<tr valign=top class=listrow$i>|; + + $accno = $form->escape($ca->{accno}); + $column_data{accno} = qq|<td><a href=$form->{script}?action=edit_gifi&coa=1&accno=$accno&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ca->{accno}</td>|; + $column_data{description} = qq|<td>$ca->{description} </td>|; + + for (@column_index) { print "$column_data{$_}\n" } + + print "</tr>\n"; + } + + print qq| + <tr> + <td colspan=$colspan><hr size=3 noshade></td> + </tr> +</table> + +</body> +</html> +|; + +} + + +sub add_gifi { + $form->{title} = "Add"; + + # construct callback + $form->{callback} = "$form->{script}?action=list_gifi&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->{coa} = 1; + + &gifi_header; + &gifi_footer; + +} + + +sub edit_gifi { + + $form->{title} = "Edit"; + + AM->get_gifi(\%myconfig, \%$form); + + $form->error($locale->text('Account does not exist!')) unless $form->{accno}; + + &gifi_header; + &gifi_footer; + +} + + +sub gifi_header { + + $form->{title} = $locale->text("$form->{title} GIFI"); + +# $locale->text('Add GIFI') +# $locale->text('Edit GIFI') + + for (qw(accno description)) { $form->{$_} = $form->quote($form->{$_}) } + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=id value="$form->{accno}"> +<input type=hidden name=type value=gifi> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('GIFI').qq|</th> + <td><input name=accno size=20 value="$form->{accno}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td><input name=description size=60 value="$form->{description}"></td> + </tr> + </table> + </td> + </tr> + <tr> + <td colspan=2><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub gifi_footer { + + $form->hide_form(qw(callback path login sessionid)); + +# type=submit $locale->text('Save') +# type=submit $locale->text('Copy to COA') +# type=submit $locale->text('Delete') + + %button = (); + + $button{'Save'} = { ndx => 3, key => 'S', value => $locale->text('Save') }; + + if ($form->{accno}) { + if ($form->{orphaned}) { + $button{'Delete'} = { ndx => 16, key => 'D', value => $locale->text('Delete') }; + } + } + + if ($form->{coa}) { + $button{'Copy to COA'} = { ndx => 7, key => 'C', value => $locale->text('Copy to COA') }; + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub save_gifi { + + $form->isblank("accno", $locale->text('GIFI missing!')); + AM->save_gifi(\%myconfig, \%$form); + $form->redirect($locale->text('GIFI saved!')); + +} + + +sub copy_to_coa { + + $form->isblank("accno", $locale->text('GIFI missing!')); + + AM->save_gifi(\%myconfig, \%$form); + + delete $form->{id}; + $form->{gifi_accno} = $form->{accno}; + + $form->{title} = "Add"; + $form->{charttype} = "A"; + + &account_header; + &form_footer; + +} + + +sub delete_gifi { + + AM->delete_gifi(\%myconfig, \%$form); + $form->redirect($locale->text('GIFI deleted!')); + +} + + +sub add_department { + + $form->{title} = "Add"; + $form->{role} = "P"; + + $form->{callback} = "$form->{script}?action=add_department&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &department_header; + &form_footer; + +} + + +sub edit_department { + + $form->{title} = "Edit"; + + AM->get_department(\%myconfig, \%$form); + + &department_header; + &form_footer; + +} + + +sub list_department { + + AM->departments(\%myconfig, \%$form); + + $href = "$form->{script}?action=list_department&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->sort_order(); + + $form->{callback} = "$form->{script}?action=list_department&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $callback = $form->escape($form->{callback}); + + $form->{title} = $locale->text('Departments'); + + @column_index = qw(description cost profit); + + $column_header{description} = qq|<th width=90%><a class=listheading href=$href>|.$locale->text('Description').qq|</a></th>|; + $column_header{cost} = qq|<th class=listheading nowrap>|.$locale->text('Cost Center').qq|</th>|; + $column_header{profit} = qq|<th class=listheading nowrap>|.$locale->text('Profit Center').qq|</th>|; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + foreach $ref (@{ $form->{ALL} }) { + + $i++; $i %= 2; + + print qq| + <tr valign=top class=listrow$i> +|; + + $costcenter = ($ref->{role} eq "C") ? "*" : " "; + $profitcenter = ($ref->{role} eq "P") ? "*" : " "; + + $column_data{description} = qq|<td><a href=$form->{script}?action=edit_department&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{description}</td>|; + $column_data{cost} = qq|<td align=center>$costcenter</td>|; + $column_data{profit} = qq|<td align=center>$profitcenter</td>|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->{type} = "department"; + + $form->hide_form(qw(type callback path login sessionid)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Add Department').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + + </body> + </html> +|; + +} + + +sub department_header { + + $form->{title} = $locale->text("$form->{title} Department"); + +# $locale->text('Add Department') +# $locale->text('Edit Department') + + $form->{description} = $form->quote($form->{description}); + + if (($rows = $form->numtextrows($form->{description}, 60)) > 1) { + $description = qq|<textarea name="description" rows=$rows cols=60 wrap=soft>$form->{description}</textarea>|; + } else { + $description = qq|<input name=description size=60 value="$form->{description}">|; + } + + $costcenter = "checked" if $form->{role} eq "C"; + $profitcenter = "checked" if $form->{role} eq "P"; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=id value=$form->{id}> +<input type=hidden name=type value=department> + +<table width=100%> + <tr> + <th class=listtop colspan=2>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td>$description</td> + </tr> + <tr> + <td></td> + <td><input type=radio style=radio name=role value="C" $costcenter> |.$locale->text('Cost Center').qq| + <input type=radio style=radio name=role value="P" $profitcenter> |.$locale->text('Profit Center').qq| + </td> + <tr> + <td colspan=2><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub save_department { + + $form->isblank("description", $locale->text('Description missing!')); + AM->save_department(\%myconfig, \%$form); + $form->redirect($locale->text('Department saved!')); + +} + + +sub delete_department { + + AM->delete_department(\%myconfig, \%$form); + $form->redirect($locale->text('Department deleted!')); + +} + + +sub add_business { + + $form->{title} = "Add"; + + $form->{callback} = "$form->{script}?action=add_business&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &business_header; + &form_footer; + +} + + +sub edit_business { + + $form->{title} = "Edit"; + + AM->get_business(\%myconfig, \%$form); + + &business_header; + + $form->{orphaned} = 1; + &form_footer; + +} + + +sub list_business { + + AM->business(\%myconfig, \%$form); + + $href = "$form->{script}?action=list_business&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->sort_order(); + + $form->{callback} = "$form->{script}?action=list_business&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $callback = $form->escape($form->{callback}); + + $form->{title} = $locale->text('Type of Business'); + + @column_index = qw(description discount); + + $column_header{description} = qq|<th width=90%><a class=listheading href=$href>|.$locale->text('Description').qq|</a></th>|; + $column_header{discount} = qq|<th class=listheading>|.$locale->text('Discount').qq| %</th>|; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + foreach $ref (@{ $form->{ALL} }) { + + $i++; $i %= 2; + + print qq| + <tr valign=top class=listrow$i> +|; + + $discount = $form->format_amount(\%myconfig, $ref->{discount} * 100, 2, " "); + + $column_data{description} = qq|<td><a href=$form->{script}?action=edit_business&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{description}</td>|; + $column_data{discount} = qq|<td align=right>$discount</td>|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->{type} = "business"; + + $form->hide_form(qw(type callback path login sessionid)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Add Business').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + + </form> + + </body> + </html> +|; + +} + + +sub business_header { + + $form->{title} = $locale->text("$form->{title} Business"); + +# $locale->text('Add Business') +# $locale->text('Edit Business') + + $form->{description} = $form->quote($form->{description}); + $form->{discount} = $form->format_amount(\%myconfig, $form->{discount} * 100); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=id value=$form->{id}> +<input type=hidden name=type value=business> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Type of Business').qq|</th> + <td><input name=description size=30 value="$form->{description}"></td> + <tr> + <tr> + <th align=right>|.$locale->text('Discount').qq| %</th> + <td><input name=discount size=5 value=$form->{discount}></td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub save_business { + + $form->isblank("description", $locale->text('Description missing!')); + AM->save_business(\%myconfig, \%$form); + $form->redirect($locale->text('Business saved!')); + +} + + +sub delete_business { + + AM->delete_business(\%myconfig, \%$form); + $form->redirect($locale->text('Business deleted!')); + +} + + + +sub add_sic { + + $form->{title} = "Add"; + + $form->{callback} = "$form->{script}?action=add_sic&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &sic_header; + &form_footer; + +} + + +sub edit_sic { + + $form->{title} = "Edit"; + + $form->{code} =~ s/\\'/'/g; + $form->{code} =~ s/\\\\/\\/g; + + AM->get_sic(\%myconfig, \%$form); + $form->{id} = $form->{code}; + + &sic_header; + + $form->{orphaned} = 1; + &form_footer; + +} + + +sub list_sic { + + AM->sic(\%myconfig, \%$form); + + $href = "$form->{script}?action=list_sic&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->sort_order(); + + $form->{callback} = "$form->{script}?action=list_sic&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $callback = $form->escape($form->{callback}); + + $form->{title} = $locale->text('Standard Industrial Codes'); + + @column_index = $form->sort_columns(qw(code description)); + + $column_header{code} = qq|<th><a class=listheading href=$href&sort=code>|.$locale->text('Code').qq|</a></th>|; + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + foreach $ref (@{ $form->{ALL} }) { + + $i++; $i %= 2; + + if ($ref->{sictype} eq 'H') { + print qq| + <tr valign=top class=listheading> +|; + $column_data{code} = qq|<th><a href=$form->{script}?action=edit_sic&code=$ref->{code}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{code}</th>|; + $column_data{description} = qq|<th>$ref->{description}</th>|; + + } else { + print qq| + <tr valign=top class=listrow$i> +|; + + $column_data{code} = qq|<td><a href=$form->{script}?action=edit_sic&code=$ref->{code}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{code}</td>|; + $column_data{description} = qq|<td>$ref->{description}</td>|; + + } + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->{type} = "sic"; + + $form->hide_form(qw(type callback path login sessionid)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Add SIC').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + + </body> + </html> +|; + +} + + +sub sic_header { + + $form->{title} = $locale->text("$form->{title} SIC"); + +# $locale->text('Add SIC') +# $locale->text('Edit SIC') + + for (qw(code description)) { $form->{$_} = $form->quote($form->{$_}) } + + $checked = ($form->{sictype} eq 'H') ? "checked" : ""; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=type value=sic> +<input type=hidden name=id value="$form->{code}"> + +<table width=100%> + <tr> + <th class=listtop colspan=2>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <th align=right>|.$locale->text('Code').qq|</th> + <td><input name=code size=10 value="$form->{code}"></td> + <tr> + <tr> + <td></td> + <th align=left><input name=sictype class=checkbox type=checkbox value="H" $checked> |.$locale->text('Heading').qq|</th> + <tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td><input name=description size=60 value="$form->{description}"></td> + </tr> + <td colspan=2><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub save_sic { + + $form->isblank("code", $locale->text('Code missing!')); + $form->isblank("description", $locale->text('Description missing!')); + AM->save_sic(\%myconfig, \%$form); + $form->redirect($locale->text('SIC saved!')); + +} + + +sub delete_sic { + + AM->delete_sic(\%myconfig, \%$form); + $form->redirect($locale->text('SIC deleted!')); + +} + + +sub add_language { + + $form->{title} = "Add"; + + $form->{callback} = "$form->{script}?action=add_language&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &language_header; + &form_footer; + +} + + +sub edit_language { + + $form->{title} = "Edit"; + + $form->{code} =~ s/\\'/'/g; + $form->{code} =~ s/\\\\/\\/g; + + AM->get_language(\%myconfig, \%$form); + $form->{id} = $form->{code}; + + &language_header; + + $form->{orphaned} = 1; + &form_footer; + +} + + +sub list_language { + + AM->language(\%myconfig, \%$form); + + $href = "$form->{script}?action=list_language&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->sort_order(); + + $form->{callback} = "$form->{script}?action=list_language&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $callback = $form->escape($form->{callback}); + + $form->{title} = $locale->text('Languages'); + + @column_index = $form->sort_columns(qw(code description)); + + $column_header{code} = qq|<th><a class=listheading href=$href&sort=code>|.$locale->text('Code').qq|</a></th>|; + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + foreach $ref (@{ $form->{ALL} }) { + + $i++; $i %= 2; + + print qq| + <tr valign=top class=listrow$i> +|; + + $column_data{code} = qq|<td><a href=$form->{script}?action=edit_language&code=$ref->{code}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{code}</td>|; + $column_data{description} = qq|<td>$ref->{description}</td>|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->{type} = "language"; + + $form->hide_form(qw(type callback path login sessionid)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Add Language').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + + </body> + </html> +|; + +} + + +sub language_header { + + $form->{title} = $locale->text("$form->{title} Language"); + +# $locale->text('Add Language') +# $locale->text('Edit Language') + + for (qw(code description)) { $form->{$_} = $form->quote($form->{$_}) } + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=type value=language> +<input type=hidden name=id value="$form->{code}"> + +<table width=100%> + <tr> + <th class=listtop colspan=2>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <th align=right>|.$locale->text('Code').qq|</th> + <td><input name=code size=10 value="$form->{code}"></td> + <tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td><input name=description size=60 value="$form->{description}"></td> + </tr> + <td colspan=2><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub save_language { + + $form->isblank("code", $locale->text('Code missing!')); + $form->isblank("description", $locale->text('Description missing!')); + + $form->{code} =~ s/(\.\.|\*)//g; + + AM->save_language(\%myconfig, \%$form); + + if (! -d "$myconfig{templates}/$form->{code}") { + + umask(002); + + if (mkdir "$myconfig{templates}/$form->{code}", oct("771")) { + + umask(007); + + opendir TEMPLATEDIR, "$myconfig{templates}" or $form->error("$myconfig{templates} : $!"); + @templates = grep !/^(\.|\.\.)/, readdir TEMPLATEDIR; + closedir TEMPLATEDIR; + + foreach $file (@templates) { + if (-f "$myconfig{templates}/$file") { + open(TEMP, "$myconfig{templates}/$file") or $form->error("$myconfig{templates}/$file : $!"); + + open(NEW, ">$myconfig{templates}/$form->{code}/$file") or $form->error("$myconfig{templates}/$form->{code}/$file : $!"); + + while ($line = <TEMP>) { + print NEW $line; + } + close(TEMP); + close(NEW); + } + } + } else { + $form->error("${templates}/$form->{code} : $!"); + } + } + + $form->redirect($locale->text('Language saved!')); + +} + + +sub delete_language { + + $form->{title} = $locale->text('Confirm!'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + for (qw(action nextsub)) { delete $form->{$_} } + + $form->hide_form; + + print qq| +<h2 class=confirm>$form->{title}</h2> + +<h4>|.$locale->text('Deleting a language will also delete the templates for the language').qq| $form->{invnumber}</h4> + +<input type=hidden name=action value=continue> +<input type=hidden name=nextsub value=yes_delete_language> +<input name=action class=submit type=submit value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub yes_delete_language { + + AM->delete_language(\%myconfig, \%$form); + + # delete templates + $dir = "$myconfig{templates}/$form->{code}"; + if (-d $dir) { + unlink <$dir/*>; + rmdir "$myconfig{templates}/$form->{code}"; + } + $form->redirect($locale->text('Language deleted!')); + +} + + +sub display_stylesheet { + + $form->{file} = "css/$myconfig{stylesheet}"; + &display_form; + +} + + +sub list_templates { + + AM->language(\%myconfig, \%$form); + + if (! @{ $form->{ALL} }) { + &display_form; + exit; + } + + unshift @{ $form->{ALL} }, { code => '.', description => $locale->text('Default Template') }; + + $href = "$form->{script}?action=list_templates&direction=$form->{direction}&oldsort=$form->{oldsort}&file=$form->{file}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->sort_order(); + + $form->{callback} = "$form->{script}?action=list_templates&direction=$form->{direction}&oldsort=$form->{oldsort}&file=$form->{file}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $callback = $form->escape($form->{callback}); + + chomp $myconfig{templates}; + $form->{file} =~ s/$myconfig{templates}//; + $form->{file} =~ s/\///; + $form->{title} = $form->{file}; + + @column_index = $form->sort_columns(qw(code description)); + + $column_header{code} = qq|<th><a class=listheading href=$href&sort=code>|.$locale->text('Code').qq|</a></th>|; + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + foreach $ref (@{ $form->{ALL} }) { + + $i++; $i %= 2; + + print qq| + <tr valign=top class=listrow$i> +|; + + $column_data{code} = qq|<td><a href=$form->{script}?action=display_form&file=$myconfig{templates}/$ref->{code}/$form->{file}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&code=$ref->{code}&callback=$callback>$ref->{code}</td>|; + $column_data{description} = qq|<td>$ref->{description}</td>|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> + +<input name=callback type=hidden value="$form->{callback}"> + +<input type=hidden name=type value=language> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + + </body> + </html> +|; + +} + + +sub display_form { + + $form->{file} =~ s/^(.:)*?\/|\.\.\///g; + $form->{file} =~ s/^\/*//g; + $form->{file} =~ s/$userspath//; + $form->{file} =~ s/$memberfile//; + + $form->error("$!: $form->{file}") unless -f $form->{file}; + + AM->load_template(\%$form); + + $form->{title} = $form->{file}; + + $form->{body} =~ s/<%include (.*?)%>/<a href=$form->{script}\?action=display_form&file=$myconfig{templates}\/$form->{code}\/$1&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}>$1<\/a>/g; + + # if it is anything but html + if ($form->{file} !~ /\.html$/) { + $form->{body} = "<pre>\n$form->{body}\n</pre>"; + } + + $form->header; + + print qq| +<body> + +$form->{body} + +<form method=post action=$form->{script}> +|; + + $form->{type} = "template"; + + $form->hide_form(qw(file type path login sessionid)); + + print qq| +<input name=action type=submit class=submit value="|.$locale->text('Edit').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub edit_template { + + AM->load_template(\%$form); + + $form->{title} = $locale->text('Edit Template'); + # convert   to &nbsp; + $form->{body} =~ s/ /&nbsp;/gi; + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input name=file type=hidden value=$form->{file}> +<input name=type type=hidden value=template> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input name=callback type=hidden value="$form->{script}?action=display_form&file=$form->{file}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"> + +<textarea name=body rows=25 cols=70> +$form->{body} +</textarea> + +<br> +<input type=submit class=submit name=action value="|.$locale->text('Save').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print q| + </form> + + +</body> +</html> +|; + +} + + +sub save_template { + + AM->save_template(\%$form); + $form->redirect($locale->text('Template saved!')); + +} + + +sub defaults { + + # get defaults for account numbers and last numbers + AM->defaultaccounts(\%myconfig, \%$form); + + foreach $key (keys %{ $form->{accno} }) { + foreach $accno (sort keys %{ $form->{accno}{$key} }) { + $form->{account}{$key} .= "<option>$accno--$form->{accno}{$key}{$accno}{description}\n"; + $form->{accno}{$form->{accno}{$key}{$accno}{id}} = $accno; + } + } + + for (qw(IC IC_inventory IC_income IC_expense FX_gain FX_loss)) { $form->{account}{$_} =~ s/>$form->{accno}{$form->{defaults}{$_}}/ selected>$form->{accno}{$form->{defaults}{$_}}/ } + + for (qw(accno defaults)) { delete $form->{$_} } + + $form->{title} = $locale->text('System Defaults'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=type value=defaults> + +<table width=100%> + <tr><th class=listtop>$form->{title}</th></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Business Number').qq|</th> + <td><input name=businessnumber size=25 value="$form->{businessnumber}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Weight Unit').qq|</th> + <td><input name=weightunit size=5 value="$form->{weightunit}"></td> + </tr> + </table> + </td> + </tr> + <tr> + <th class=listheading>|.$locale->text('Last Numbers & Default Accounts').qq|</th> + </tr> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Inventory').qq|</th> + <td><select name=IC>$form->{account}{IC}</select></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Income').qq|</th> + <td><select name=IC_income>$form->{account}{IC_income}</select></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Expense').qq|</th> + <td><select name=IC_expense>$form->{account}{IC_expense}</select></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Foreign Exchange Gain').qq|</th> + <td><select name=FX_gain>$form->{account}{FX_gain}</select></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Foreign Exchange Loss').qq|</th> + <td><select name=FX_loss>$form->{account}{FX_loss}</select></td> + </tr> + </table> + </td> + </tr> + <tr> + <th align=left>|.$locale->text('Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies').qq|</th> + </tr> + <tr> + <td> + <input name=curr size=40 value="$form->{curr}"> + </td> + </tr> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('GL Reference Number').qq|</th> + <td><input name=glnumber size=40 value="$form->{glnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Sales Invoice/AR Transaction Number').qq|</th> + <td><input name=sinumber size=40 value="$form->{sinumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Sales Order Number').qq|</th> + <td><input name=sonumber size=40 value="$form->{sonumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Vendor Invoice/AP Transaction Number').qq|</th> + <td><input name=vinumber size=40 value="$form->{vinumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Purchase Order Number').qq|</th> + <td><input name=ponumber size=40 value="$form->{ponumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Sales Quotation Number').qq|</th> + <td><input name=sqnumber size=40 value="$form->{sqnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('RFQ Number').qq|</th> + <td><input name=rfqnumber size=40 value="$form->{rfqnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Part Number').qq|</th> + <td><input name=partnumber size=40 value="$form->{partnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Job/Project Number').qq|</th> + <td><input name=projectnumber size=40 value="$form->{projectnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Employee Number').qq|</th> + <td><input name=employeenumber size=40 value="$form->{employeenumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Customer Number').qq|</th> + <td><input name=customernumber size=40 value="$form->{customernumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Vendor Number').qq|</th> + <td><input name=vendornumber size=40 value="$form->{vendornumber}"></td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Save').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub taxes { + + # get tax account numbers + AM->taxes(\%myconfig, \%$form); + + $i = 0; + foreach $ref (@{ $form->{taxrates} }) { + $i++; + $form->{"taxrate_$i"} = $form->format_amount(\%myconfig, $ref->{rate}); + $form->{"taxdescription_$i"} = $ref->{description}; + + for (qw(taxnumber validto)) { $form->{"${_}_$i"} = $ref->{$_} } + $form->{taxaccounts} .= "$ref->{id}_$i "; + } + chop $form->{taxaccounts}; + + &display_taxes; + +} + + +sub display_taxes { + + $form->{title} = $locale->text('Taxes'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=type value=taxes> + +<table width=100%> + <tr><th class=listtop>$form->{title}</th></tr> + <tr> + <td> + <table> + <tr> + <th></th> + <th>|.$locale->text('Rate').qq| (%)</th> + <th>|.$locale->text('Number').qq|</th> + <th>|.$locale->text('Valid To').qq|</th> + </tr> +|; + + for (split(/ /, $form->{taxaccounts})) { + + ($null, $i) = split /_/, $_; + + $form->{"taxrate_$i"} = $form->format_amount(\%myconfig, $form->{"taxrate_$i"}); + + $form->hide_form("taxdescription_$i"); + + print qq| + <tr> + <th align=right>|; + + if ($form->{"taxdescription_$i"} eq $sametax) { + print ""; + } else { + print qq|$form->{"taxdescription_$i"}|; + } + + print qq|</th> + <td><input name="taxrate_$i" size=6 value=$form->{"taxrate_$i"}></td> + <td><input name="taxnumber_$i" value="$form->{"taxnumber_$i"}"></td> + <td><input name="validto_$i" size=11 value="$form->{"validto_$i"}" title="$myconfig{dateformat}"></td> + </tr> +|; + $sametax = $form->{"taxdescription_$i"}; + + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + $form->hide_form(qw(taxaccounts path login sessionid)); + + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Update').qq|"> +<input type=submit class=submit name=action value="|.$locale->text('Save').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub update { + + @a = split / /, $form->{taxaccounts}; + $ndx = $#a + 1; + + foreach $item (@a) { + ($accno, $i) = split /_/, $item; + push @t, $accno; + + if ($form->{"validto_$i"}) { + $j = $i + 1; + if ($form->{"taxdescription_$i"} ne $form->{"taxdescription_$j"}) { + #insert line + for ($j = $ndx + 1; $j > $i; $j--) { + $k = $j - 1; + for (qw(taxrate taxdescription taxnumber validto)) { $form->{"${_}_$j"} = $form->{"${_}_$k"} } + } + $ndx++; + $k = $i + 1; + for (qw(taxdescription taxnumber)) { $form->{"${_}_$k"} = $form->{"${_}_$i"} } + for (qw(taxrate validto)) { $form->{"${_}_$k"} = "" } + push @t, $accno; + } + } else { + # remove line + $j = $i + 1; + if ($form->{"taxdescription_$i"} eq $form->{"taxdescription_$j"}) { + for ($j = $i + 1; $j <= $ndx; $j++) { + $k = $j + 1; + for (qw(taxrate taxdescription taxnumber validto)) { $form->{"${_}_$j"} = $form->{"${_}_$k"} } + } + $ndx--; + splice @t, $i-1, 1; + } + } + + } + + $i = 1; + $form->{taxaccounts} = ""; + for (@t) { + $form->{taxaccounts} .= "${_}_$i "; + $i++; + } + chop $form->{taxaccounts}; + + &display_taxes; + +} + + + +sub config { + + foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd)) { + $dateformat .= ($item eq $myconfig{dateformat}) ? "<option selected>$item\n" : "<option>$item\n"; + } + + foreach $item (qw(1,000.00 1000.00 1.000,00 1000,00 1'000.00)) { + $numberformat .= ($item eq $myconfig{numberformat}) ? "<option selected>$item\n" : "<option>$item\n"; + } + + for (qw(name company address signature)) { $myconfig{$_} = $form->quote($myconfig{$_}) } + for (qw(address signature)) { $myconfig{$_} =~ s/\\n/\n/g } + + %countrycodes = User->country_codes; + $countrycodes = ''; + + foreach $key (sort { $countrycodes{$a} cmp $countrycodes{$b} } keys %countrycodes) { + $countrycodes .= ($myconfig{countrycode} eq $key) ? "<option selected value=$key>$countrycodes{$key}\n" : "<option value=$key>$countrycodes{$key}\n"; + } + $countrycodes = qq|<option value="">English\n$countrycodes|; + + opendir CSS, "css/."; + @all = grep /.*\.css$/, readdir CSS; + closedir CSS; + + foreach $item (@all) { + if ($item eq $myconfig{stylesheet}) { + $selectstylesheet .= qq|<option selected>$item\n|; + } else { + $selectstylesheet .= qq|<option>$item\n|; + } + } + $selectstylesheet .= "<option>\n"; + + if (%printer && $latex) { + $selectprinter = "<option>\n"; + foreach $item (sort keys %printer) { + if ($myconfig{printer} eq $item) { + $selectprinter .= qq|<option value="$item" selected>$item\n|; + } else { + $selectprinter .= qq|<option value="$item">$item\n|; + } + } + + $printer = qq| + <tr> + <th align=right>|.$locale->text('Printer').qq|</th> + <td><select name=printer>$selectprinter</select></td> + </tr> +|; + } + + $form->{title} = $locale->text('Edit Preferences for').qq| $form->{login}|; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=old_password value=$myconfig{password}> +<input type=hidden name=type value=preferences> +<input type=hidden name=role value=$myconfig{role}> + +<table width=100%> + <tr><th class=listtop>$form->{title}</th></tr> + <tr> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Name').qq|</th> + <td><input name=name size=20 value="$myconfig{name}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('E-mail').qq|</th> + <td><input name=email size=35 value="$myconfig{email}"></td> + </tr> + <tr valign=top> + <th align=right>|.$locale->text('Signature').qq|</th> + <td><textarea name=signature rows=3 cols=35>$myconfig{signature}</textarea></td> + </tr> + <tr> + <th align=right>|.$locale->text('Phone').qq|</th> + <td><input name=tel size=14 value="$myconfig{tel}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Fax').qq|</th> + <td><input name=fax size=14 value="$myconfig{fax}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Company').qq|</th> + <td><input name=company size=35 value="$myconfig{company}"></td> + </tr> + <tr valign=top> + <th align=right>|.$locale->text('Address').qq|</th> + <td><textarea name=address rows=4 cols=35>$myconfig{address}</textarea></td> + </tr> + </table> + </td> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input type=password name=new_password size=10 value=$myconfig{password}></td> + </tr> + <tr> + <th align=right>|.$locale->text('Confirm').qq|</th> + <td><input type=password name=confirm_password size=10></td> + </tr> + <tr> + <th align=right>|.$locale->text('Date Format').qq|</th> + <td><select name=dateformat>$dateformat</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('Number Format').qq|</th> + <td><select name=numberformat>$numberformat</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('Dropdown Limit').qq|</th> + <td><input name=vclimit size=10 value="$myconfig{vclimit}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Menu Width').qq|</th> + <td><input name=menuwidth size=10 value="$myconfig{menuwidth}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Language').qq|</th> + <td><select name=countrycode>$countrycodes</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('Session Timeout').qq|</th> + <td><input name=timeout size=10 value="$myconfig{timeout}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Stylesheet').qq|</th> + <td><select name=usestylesheet>$selectstylesheet</select></td> + </tr> + $printer + </table> + </td> + </tr> + </table> + </td> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Save').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub save_defaults { + + if (AM->save_defaults(\%myconfig, \%$form)) { + $form->redirect($locale->text('Defaults saved!')); + } else { + $form->error($locale->text('Cannot save defaults!')); + } + +} + + +sub save_taxes { + + if (AM->save_taxes(\%myconfig, \%$form)) { + $form->redirect($locale->text('Taxes saved!')); + } else { + $form->error($locale->text('Cannot save taxes!')); + } + +} + + +sub save_preferences { + + $form->{stylesheet} = $form->{usestylesheet}; + + if ($form->{new_password} ne $form->{old_password}) { + $form->error($locale->text('Password does not match!')) if $form->{new_password} ne $form->{confirm_password}; + } + + if (AM->save_preferences(\%myconfig, \%$form, $memberfile, $userspath)) { + $form->redirect($locale->text('Preferences saved!')); + } else { + $form->error($locale->text('Cannot save preferences!')); + } + +} + + +sub backup { + + if ($form->{media} eq 'email') { + $form->error($locale->text('No email address for')." $myconfig{name}") unless ($myconfig{email}); + + $form->{OUT} = "$sendmail"; + + } + + $SIG{INT} = 'IGNORE'; + AM->backup(\%myconfig, \%$form, $userspath, $gzip); + + if ($form->{media} eq 'email') { + $form->redirect($locale->text('Backup sent to').qq| $myconfig{email}|); + } + +} + + + +sub audit_control { + + $form->{title} = $locale->text('Audit Control'); + + AM->closedto(\%myconfig, \%$form); + + if ($form->{revtrans}) { + $checked{revtransY} = "checked"; + } else { + $checked{revtransN} = "checked"; + } + + if ($form->{audittrail}) { + $checked{audittrailY} = "checked"; + } else { + $checked{audittrailN} = "checked"; + } + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<table width=100%> + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Enforce transaction reversal for all dates').qq|</th> + <td><input name=revtrans class=radio type=radio value="1" $checked{revtransY}> |.$locale->text('Yes').qq| <input name=revtrans class=radio type=radio value="0" $checked{revtransN}> |.$locale->text('No').qq|</td> + </tr> + <tr> + <th align=right>|.$locale->text('Close Books up to').qq|</th> + <td><input name=closedto size=11 title="$myconfig{dateformat}" value=$form->{closedto}></td> + </tr> + <tr> + <th align=right>|.$locale->text('Activate Audit trail').qq|</th> + <td><input name=audittrail class=radio type=radio value="1" $checked{audittrailY}> |.$locale->text('Yes').qq| <input name=audittrail class=radio type=radio value="0" $checked{audittrailN}> |.$locale->text('No').qq|</td> + </tr> + <tr> + <th align=right>|.$locale->text('Remove Audit trail up to').qq|</th> + <td><input name=removeaudittrail size=11 title="$myconfig{dateformat}"></td> + </tr> + </table> + </td> + </tr> +</table> + +<hr size=3 noshade> + +<br> +<input type=hidden name=nextsub value=doclose> +<input type=hidden name=action value=continue> +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> + +</form> + +</body> +</html> +|; + +} + + +sub doclose { + + AM->closebooks(\%myconfig, \%$form); + + if ($form->{revtrans}) { + $msg = $locale->text('Transaction reversal enforced for all dates'); + } else { + + if ($form->{closedto}) { + $msg = $locale->text('Transaction reversal enforced up to') + ." ".$locale->date(\%myconfig, $form->{closedto}, 1); + } else { + $msg = $locale->text('Books are open'); + } + } + + $msg .= "<p>"; + if ($form->{audittrail}) { + $msg .= $locale->text('Audit trail enabled'); + } else { + $msg .= $locale->text('Audit trail disabled'); + } + + $msg .= "<p>"; + if ($form->{removeaudittrail}) { + $msg .= $locale->text('Audit trail removed up to') + ." ".$locale->date(\%myconfig, $form->{removeaudittrail}, 1); + } + + $form->redirect($msg); + +} + + +sub add_warehouse { + + $form->{title} = "Add"; + + $form->{callback} = "$form->{script}?action=add_warehouse&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &warehouse_header; + &form_footer; + +} + + +sub edit_warehouse { + + $form->{title} = "Edit"; + + AM->get_warehouse(\%myconfig, \%$form); + + &warehouse_header; + &form_footer; + +} + + +sub list_warehouse { + + AM->warehouses(\%myconfig, \%$form); + + $href = "$form->{script}?action=list_warehouse&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->sort_order(); + + $form->{callback} = "$form->{script}?action=list_warehouse&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $callback = $form->escape($form->{callback}); + + $form->{title} = $locale->text('Warehouses'); + + @column_index = qw(description); + + $column_header{description} = qq|<th width=100%><a class=listheading href=$href>|.$locale->text('Description').qq|</a></th>|; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + foreach $ref (@{ $form->{ALL} }) { + + $i++; $i %= 2; + + print qq| + <tr valign=top class=listrow$i> +|; + + $column_data{description} = qq|<td><a href=$form->{script}?action=edit_warehouse&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{description}</td>|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->{type} = "warehouse"; + + $form->hide_form(qw(type callback path login sessionid)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Add Warehouse').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + + </body> + </html> +|; + +} + + + +sub warehouse_header { + + $form->{title} = $locale->text("$form->{title} Warehouse"); + +# $locale->text('Add Warehouse') +# $locale->text('Edit Warehouse') + + $form->{description} = $form->quote($form->{description}); + + if (($rows = $form->numtextrows($form->{description}, 60)) > 1) { + $description = qq|<textarea name="description" rows=$rows cols=60 wrap=soft>$form->{description}</textarea>|; + } else { + $description = qq|<input name=description size=60 value="$form->{description}">|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=id value=$form->{id}> +<input type=hidden name=type value=warehouse> + +<table width=100%> + <tr> + <th class=listtop colspan=2>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td>$description</td> + </tr> + <tr> + <td colspan=2><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub save_warehouse { + + $form->isblank("description", $locale->text('Description missing!')); + AM->save_warehouse(\%myconfig, \%$form); + $form->redirect($locale->text('Warehouse saved!')); + +} + + +sub delete_warehouse { + + AM->delete_warehouse(\%myconfig, \%$form); + $form->redirect($locale->text('Warehouse deleted!')); + +} + + +sub yearend { + + AM->earningsaccounts(\%myconfig, \%$form); + $chart = ""; + for (@{ $form->{chart} }) { $chart .= "<option>$_->{accno}--$_->{description}" } + + $form->{title} = $locale->text('Yearend'); + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=decimalplaces value=2> +<input type=hidden name=l_accno value=Y> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Yearend').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}" value=$todate></td> + </tr> + <tr> + <th align=right>|.$locale->text('Reference').qq|</th> + <td><input name=reference size=20 value="|.$locale->text('Yearend').qq|"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td><textarea name=description rows=3 cols=50 wrap=soft></textarea></td> + </tr> + <tr> + <th align=right>|.$locale->text('Retained Earnings').qq|</th> + <td><select name=accno>$chart</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('Method').qq|</th> + <td><input name=method class=radio type=radio value=accrual checked> |.$locale->text('Accrual').qq| <input name=method class=radio type=radio value=cash> |.$locale->text('Cash').qq|</td> + </tr> + </table> + </td> + </tr> +</table> + +<hr size=3 noshade> + +<input type=hidden name=nextsub value=generate_yearend> +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">|; + +} + + +sub generate_yearend { + + $form->isblank("todate", $locale->text('Yearend date missing!')); + + RP->yearend_statement(\%myconfig, \%$form); + + $form->{transdate} = $form->{todate}; + + $earnings = 0; + + $form->{rowcount} = 1; + foreach $key (keys %{ $form->{I} }) { + if ($form->{I}{$key}{charttype} eq "A") { + $form->{"debit_$form->{rowcount}"} = $form->{I}{$key}{this}; + $earnings += $form->{I}{$key}{this}; + $form->{"accno_$form->{rowcount}"} = $key; + $form->{rowcount}++; + $ok = 1; + } + } + + foreach $key (keys %{ $form->{E} }) { + if ($form->{E}{$key}{charttype} eq "A") { + $form->{"credit_$form->{rowcount}"} = $form->{E}{$key}{this} * -1; + $earnings += $form->{E}{$key}{this}; + $form->{"accno_$form->{rowcount}"} = $key; + $form->{rowcount}++; + $ok = 1; + } + } + if ($earnings > 0) { + $form->{"credit_$form->{rowcount}"} = $earnings; + $form->{"accno_$form->{rowcount}"} = $form->{accno} + } else { + $form->{"debit_$form->{rowcount}"} = $earnings * -1; + $form->{"accno_$form->{rowcount}"} = $form->{accno} + } + + if ($ok) { + if (AM->post_yearend(\%myconfig, \%$form)) { + $form->redirect($locale->text('Yearend posted!')); + } else { + $form->error($locale->text('Yearend posting failed!')); + } + } else { + $form->error('Nothing to do!'); + } + +} + + + +sub company_logo { + + $myconfig{address} =~ s/\\n/<br>/g; + $myconfig{dbhost} = $locale->text('localhost') unless $myconfig{dbhost}; + + $form->{stylesheet} = $myconfig{stylesheet}; + + $form->{title} = $locale->text('About'); + + # create the logo screen + $form->header; + + print qq| +<body> + +<pre> + +</pre> +<center> +<a href="http://sourceforge.net/projects/ledger-smb/" target=_blank><img src=ledger-smb.png border=0></a> +<h1 class=login>|.$locale->text('Version').qq| $form->{version}</h1> + +<p> +|.$locale->text('Licensed to').qq| +<p> +<b> +$myconfig{company} +<br>$myconfig{address} +</b> + +<p> +<table border=0> + <tr> + <th align=right>|.$locale->text('User').qq|</th> + <td>$myconfig{name}</td> + </tr> + <tr> + <th align=right>|.$locale->text('Dataset').qq|</th> + <td>$myconfig{dbname}</td> + </tr> + <tr> + <th align=right>|.$locale->text('Database Host').qq|</th> + <td>$myconfig{dbhost}</td> + </tr> +</table> + +</center> + +</body> +</html> +|; + +} + + +sub recurring_transactions { + +# $locale->text('Day') +# $locale->text('Days') +# $locale->text('Month') +# $locale->text('Months') +# $locale->text('Week') +# $locale->text('Weeks') +# $locale->text('Year') +# $locale->text('Years') + + $form->{stylesheet} = $myconfig{stylesheet}; + + $form->{title} = $locale->text('Recurring Transactions'); + + $column_header{id} = ""; + + AM->recurring_transactions(\%myconfig, \%$form); + + $href = "$form->{script}?action=recurring_transactions"; + for (qw(direction oldsort path login sessionid)) { $href .= qq|&$_=$form->{$_}| } + + $form->sort_order(); + + # create the logo screen + $form->header; + + @column_index = qw(ndx reference description); + + push @column_index, qw(nextdate enddate id amount curr repeat howmany recurringemail recurringprint); + + $column_header{reference} = "<th><a class=listheading href=$href&sort=reference>".$locale->text('Reference').qq"</a></th>"; + $column_header{ndx} = "<th class=listheading> </th>"; + $column_header{id} = "<th class=listheading>".$locale->text('ID')."</th>"; + $column_header{description} = "<th class=listheading>".$locale->text('Description')."</th>"; + $column_header{nextdate} = "<th><a class=listheading href=$href&sort=nextdate>".$locale->text('Next')."</a></th>"; + $column_header{enddate} = "<th><a class=listheading href=$href&sort=enddate>".$locale->text('Ends')."</a></th>"; + $column_header{amount} = "<th class=listheading>".$locale->text('Amount')."</th>"; + $column_header{curr} = "<th class=listheading> </th>"; + $column_header{repeat} = "<th class=listheading>".$locale->text('Every')."</th>"; + $column_header{howmany} = "<th class=listheading>".$locale->text('Times')."</th>"; + $column_header{recurringemail} = "<th class=listheading>".$locale->text('E-mail')."</th>"; + $column_header{recurringprint} = "<th class=listheading>".$locale->text('Print')."</th>"; + +print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + $i = 1; + $colspan = $#column_index + 1; + + %tr = ( ar => $locale->text('AR'), + ap => $locale->text('AP'), + gl => $locale->text('GL'), + so => $locale->text('Sales Orders'), + po => $locale->text('Purchase Orders'), + ); + + %f = &formnames; + + foreach $transaction (sort keys %{ $form->{transactions} }) { + print qq| + <tr> + <th class=listheading colspan=$colspan>$tr{$transaction}</th> + </tr> +|; + + foreach $ref (@{ $form->{transactions}{$transaction} }) { + + for (@column_index) { $column_data{$_} = "<td nowrap>$ref->{$_}</td>" } + + if ($ref->{repeat} > 1) { + $unit = $locale->text(ucfirst $ref->{unit}); + $repeat = "$ref->{repeat} $unit"; + } else { + chop $ref->{unit}; + $unit = $locale->text(ucfirst $ref->{unit}); + $repeat = $unit; + } + + $column_data{ndx} = qq|<td></td>|; + + if (!$ref->{expired}) { + if ($ref->{overdue} <= 0) { + $k++; + $column_data{ndx} = qq|<td nowrap><input name="ndx_$k" class=checkbox type=checkbox value=$ref->{id} checked></td>|; + } + } + + $reference = ($ref->{reference}) ? $ref->{reference} : $locale->text('Next Number'); + $column_data{reference} = qq|<td nowrap><a href=$form->{script}?action=edit_recurring&id=$ref->{id}&vc=$ref->{vc}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&module=$ref->{module}&invoice=$ref->{invoice}&transaction=$ref->{transaction}&recurringnextdate=$ref->{nextdate}>$reference</a></td>|; + + $module = "$ref->{module}.pl"; + $type = ""; + if ($ref->{module} eq 'ar') { + $module = "is.pl" if $ref->{invoice}; + $ref->{amount} /= $ref->{exchangerate}; + } + if ($ref->{module} eq 'ap') { + $module = "ir.pl" if $ref->{invoice}; + $ref->{amount} /= $ref->{exchangerate}; + } + if ($ref->{module} eq 'oe') { + $type = ($ref->{vc} eq 'customer') ? "sales_order" : "purchase_order"; + } + + $column_data{id} = qq|<td><a href=$module?action=edit&id=$ref->{id}&vc=$ref->{vc}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$type&readonly=1>$ref->{id}</a></td>|; + + $column_data{repeat} = "<td align=right nowrap>$repeat</td>"; + $column_data{howmany} = "<td align=right nowrap>".$form->format_amount(\%myconfig, $ref->{howmany})."</td>"; + $column_data{amount} = "<td align=right nowrap>".$form->format_amount(\%myconfig, $ref->{amount}, 2)."</td>"; + + $column_data{recurringemail} = "<td nowrap>"; + @f = split /:/, $ref->{recurringemail}; + for (0 .. $#f) { $column_data{recurringemail} .= "$f{$f[$_]}<br>" } + $column_data{recurringemail} .= "</td>"; + + $column_data{recurringprint} = "<td nowrap>"; + @f = split /:/, $ref->{recurringprint}; + for (0 .. $#f) { $column_data{recurringprint} .= "$f{$f[$_]}<br>" } + $column_data{recurringprint} .= "</td>"; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + } + } + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input name=lastndx type=hidden value=$k> +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Process Transactions').qq|">| if $k; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub edit_recurring { + + %links = ( ar => 'create_links', + ap => 'create_links', + gl => 'create_links', + is => 'invoice_links', + ir => 'invoice_links', + oe => 'order_links', + ); + %prepare = ( is => 'prepare_invoice', + ir => 'prepare_invoice', + oe => 'prepare_order', + ); + + $form->{callback} = "$form->{script}?action=recurring_transactions&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->{type} = "transaction"; + + if ($form->{module} eq 'ar') { + if ($form->{invoice}) { + $form->{type} = "invoice"; + $form->{module} = "is"; + } + } + if ($form->{module} eq 'ap') { + if ($form->{invoice}) { + $form->{type} = "invoice"; + $form->{module} = "ir"; + } + } + + if ($form->{module} eq 'oe') { + %tr = ( so => sales_order, + po => purchase_order, + ); + + $form->{type} = $tr{$form->{transaction}}; + } + + $form->{script} = "$form->{module}.pl"; + do "$form->{path}/$form->{script}"; + + &{ $links{$form->{module}} }; + + # return if transaction doesn't exist + $form->redirect unless $form->{recurring}; + + if ($prepare{$form->{module}}) { + &{ $prepare{$form->{module}} }; + } + + $form->{selectformat} = qq|<option value="html">html\n|; + if ($latex) { + $form->{selectformat} .= qq| + <option value="postscript">|.$locale->text('Postscript').qq| + <option value="pdf">|.$locale->text('PDF'); + } + + &schedule; + +} + + +sub process_transactions { + + # save variables + my $pt = new Form; + for (keys %$form) { $pt->{$_} = $form->{$_} } + + my $defaultprinter; + while (my ($key, $value) = each %printer) { + if ($value =~ /lpr/) { + $defaultprinter = $key; + last; + } + } + + $myconfig{vclimit} = 0; + %f = &formnames; + + for (my $i = 1; $i <= $pt->{lastndx}; $i++) { + if ($pt->{"ndx_$i"}) { + $id = $pt->{"ndx_$i"}; + + # process transaction + AM->recurring_details(\%myconfig, \%$pt, $id); + + $header = $form->{header}; + # reset $form + for (keys %$form) { delete $form->{$_}; } + for (qw(login path sessionid stylesheet timeout)) { $form->{$_} = $pt->{$_}; } + $form->{id} = $id; + $form->{header} = $header; + + # post, print, email + if ($pt->{arid} || $pt->{apid} || $pt->{oeid}) { + if ($pt->{arid} || $pt->{apid}) { + if ($pt->{arid}) { + $form->{script} = ($pt->{invoice}) ? "is.pl" : "ar.pl"; + $form->{ARAP} = "AR"; + $form->{module} = "ar"; + $invfld = "sinumber"; + } else { + $form->{script} = ($pt->{invoice}) ? "ir.pl" : "ap.pl"; + $form->{ARAP} = "AP"; + $form->{module} = "ap"; + $invfld = "vinumber"; + } + do "$form->{path}/$form->{script}"; + + if ($pt->{invoice}) { + &invoice_links; + &prepare_invoice; + + for (keys %$form) { $form->{$_} = $form->unquote($form->{$_}) } + + } else { + &create_links; + + $form->{type} = "transaction"; + for (1 .. $form->{rowcount} - 1) { $form->{"amount_$_"} = $form->format_amount(\%myconfig, $form->{"amount_$_"}, 2) } + for (1 .. $form->{paidaccounts}) { $form->{"paid_$_"} = $form->format_amount(\%myconfig, $form->{"paid_$_"}, 2) } + + } + + delete $form->{"$form->{ARAP}_links"}; + for (qw(acc_trans invoice_details)) { delete $form->{$_} } + for (qw(department employee language month partsgroup project years)) { delete $form->{"all_$_"} } + + $form->{invnumber} = $pt->{reference}; + $form->{transdate} = $pt->{nextdate}; + + # tax accounts + $form->all_taxaccounts(\%myconfig, undef, $form->{transdate}); + + # calculate duedate + $form->{duedate} = $form->add_date(\%myconfig, $form->{transdate}, $pt->{overdue}, "days"); + + if ($pt->{payment}) { + # calculate date paid + for ($j = 1; $j <= $form->{paidaccounts}; $j++) { + $form->{"datepaid_$j"} = $form->add_date(\%myconfig, $form->{transdate}, $pt->{paid}, "days"); + + ($form->{"$form->{ARAP}_paid_$j"}) = split /--/, $form->{"$form->{ARAP}_paid_$j"}; + delete $form->{"cleared_$j"}; + } + + $form->{paidaccounts}++; + } else { + $form->{paidaccounts} = -1; + } + + for (qw(id recurring intnotes printed emailed queued)) { delete $form->{$_} } + + ($form->{$form->{ARAP}}) = split /--/, $form->{$form->{ARAP}}; + + $form->{invnumber} = $form->update_defaults(\%myconfig, "$invfld") unless $form->{invnumber}; + $form->{reference} = $form->{invnumber}; + for (qw(invnumber reference)) { $form->{$_} = $form->unquote($form->{$_}) } + + if ($pt->{invoice}) { + if ($pt->{arid}) { + $form->info("\n".$locale->text('Posting')." ".$locale->text('Sales Invoice')." $form->{invnumber}"); + $ok = IS->post_invoice(\%myconfig, \%$form); + } else { + $form->info("\n".$locale->text('Posting')." ".$locale->text('Vendor Invoice')." $form->{invnumber}"); + $ok = IR->post_invoice(\%myconfig, \%$form); + } + } else { + if ($pt->{arid}) { + $form->info("\n".$locale->text('Posting')." ".$locale->text('Transaction')." $form->{invnumber}"); + } else { + $form->info("\n".$locale->text('Posting')." ".$locale->text('Transaction')." $form->{invnumber}"); + } + + $ok = AA->post_transaction(\%myconfig, \%$form); + + } + $form->info(" ..... ".$locale->text('done')); + + # print form + if ($latex && $ok) { + $ok = &print_recurring(\%$pt, $defaultprinter); + } + + &email_recurring(\%$pt) if $ok; + + } else { + + # order + $form->{script} = "oe.pl"; + $form->{module} = "oe"; + + $ordnumber = "ordnumber"; + if ($pt->{customer_id}) { + $form->{vc} = "customer"; + $form->{type} = "sales_order"; + $ordfld = "sonumber"; + $flabel = $locale->text('Sales Order'); + } else { + $form->{vc} = "vendor"; + $form->{type} = "purchase_order"; + $ordfld = "ponumber"; + $flabel = $locale->text('Purchase Order'); + } + require "$form->{path}/$form->{script}"; + + &order_links; + &prepare_order; + + for (keys %$form) { $form->{$_} = $form->unquote($form->{$_}) } + + $form->{$ordnumber} = $pt->{reference}; + $form->{transdate} = $pt->{nextdate}; + + # calculate reqdate + $form->{reqdate} = $form->add_date(\%myconfig, $form->{transdate}, $pt->{req}, "days") if $form->{reqdate}; + + for (qw(id recurring intnotes printed emailed queued)) { delete $form->{$_} } + for (1 .. $form->{rowcount}) { delete $form->{"orderitems_id_$_"} } + + $form->{$ordnumber} = $form->update_defaults(\%myconfig, "$ordfld") unless $form->{$ordnumber}; + $form->{reference} = $form->{$ordnumber}; + for ("$ordnumber", "reference") { $form->{$_} = $form->unquote($form->{$_}) } + $form->{closed} = 0; + + $form->info("\n".$locale->text('Saving')." ".$flabel." $form->{$ordnumber}"); + if ($ok = OE->save(\%myconfig, \%$form)) { + $form->info(" ..... ".$locale->text('done')); + } else { + $form->info(" ..... ".$locale->text('failed')); + } + + # print form + if ($latex && $ok) { + &print_recurring(\%$pt, $defaultprinter); + } + + &email_recurring(\%$pt); + + } + + } else { + # GL transaction + GL->transaction(\%myconfig, \%$form); + + $form->{reference} = $pt->{reference}; + $form->{transdate} = $pt->{nextdate}; + + $j = 1; + foreach $ref (@{ $form->{GL} }) { + $form->{"accno_$j"} = "$ref->{accno}--$ref->{description}"; + + $form->{"projectnumber_$j"} = "$ref->{projectnumber}--$ref->{project_id}" if $ref->{project_id}; + $form->{"fx_transaction_$j"} = $ref->{fx_transaction}; + + if ($ref->{amount} < 0) { + $form->{"debit_$j"} = $ref->{amount} * -1; + } else { + $form->{"credit_$j"} = $ref->{amount}; + } + + $j++; + } + + $form->{rowcount} = $j; + + for (qw(id recurring)) { delete $form->{$_} } + $form->info("\n".$locale->text('Posting')." ".$locale->text('GL Transaction')." $form->{reference}"); + $ok = GL->post_transaction(\%myconfig, \%$form); + $form->info(" ..... ".$locale->text('done')); + + } + + AM->update_recurring(\%myconfig, \%$pt, $id) if $ok; + + } + } + + $form->{callback} = "am.pl?action=recurring_transactions&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&header=$form->{header}"; + $form->redirect; + +} + + +sub print_recurring { + my ($pt, $defaultprinter) = @_; + + my %f = &formnames; + my $ok = 1; + + if ($pt->{recurringprint}) { + @f = split /:/, $pt->{recurringprint}; + for ($j = 0; $j <= $#f; $j += 3) { + $media = $f[$j+2]; + $media ||= $myconfig->{printer} if $printer{$myconfig->{printer}}; + $media ||= $defaultprinter; + + $form->info("\n".$locale->text('Printing')." ".$locale->text($f{$f[$j]})." $form->{reference}"); + + @a = ("perl", "$form->{script}", "action=reprint&module=$form->{module}&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}&id=$form->{id}&formname=$f[$j]&format=$f[$j+1]&media=$media&vc=$form->{vc}&ARAP=$form->{ARAP}"); + + $ok = !(system(@a)); + + if ($ok) { + $form->info(" ..... ".$locale->text('done')); + } else { + $form->info(" ..... ".$locale->text('failed')); + last; + } + } + } + + $ok; + +} + + +sub email_recurring { + my ($pt) = @_; + + my %f = &formnames; + my $ok = 1; + + if ($pt->{recurringemail}) { + + @f = split /:/, $pt->{recurringemail}; + for ($j = 0; $j <= $#f; $j += 2) { + + $form->info("\n".$locale->text('Sending')." ".$locale->text($f{$f[$j]})." $form->{reference}"); + + # no email, bail out + if (!$form->{email}) { + $form->info(" ..... ".$locale->text('E-mail address missing!')); + last; + } + + $message = $form->escape($pt->{message},1); + + @a = ("perl", "$form->{script}", "action=reprint&module=$form->{module}&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}&id=$form->{id}&formname=$f[$j]&format=$f[$j+1]&media=email&vc=$form->{vc}&ARAP=$form->{ARAP}&message=$message"); + + $ok = !(system(@a)); + + if ($ok) { + $form->info(" ..... ".$locale->text('done')); + } else { + $form->info(" ..... ".$locale->text('failed')); + last; + } + } + } + + $ok; + +} + + + +sub formnames { + +# $locale->text('Transaction') +# $locale->text('Invoice') +# $locale->text('Credit Invoice') +# $locale->text('Debit Invoice') +# $locale->text('Packing List') +# $locale->text('Pick List') +# $locale->text('Sales Order') +# $locale->text('Work Order') +# $locale->text('Purchase Order') +# $locale->text('Bin List') + + my %f = ( transaction => 'Transaction', + invoice => 'Invoice', + credit_invoice => 'Credit Invoice', + debit_invoice => 'Debit Invoice', + packing_list => 'Packing List', + pick_list => 'Pick List', + sales_order => 'Sales Order', + work_order => 'Work Order', + purchase_order => 'Purchase Order', + bin_list => 'Bin List', + ); + + %f; + +} + + +sub continue { &{ $form->{nextsub} } }; + diff --git a/bin/lynx/ap.pl b/bin/lynx/ap.pl new file mode 100755 index 00000000..8eb246e0 --- /dev/null +++ b/bin/lynx/ap.pl @@ -0,0 +1,40 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (C) 2000 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Accounts Payable +# +#====================================================================== + +use SL::PE; +use SL::IR; + +require "$form->{path}/arap.pl"; +require "$form->{path}/arapprn.pl"; +require "$form->{path}/aa.pl"; + +$form->{vc} = 'vendor'; +$form->{ARAP} = 'AP'; + +1; +# end of main + diff --git a/bin/lynx/ar.pl b/bin/lynx/ar.pl new file mode 100755 index 00000000..4a475578 --- /dev/null +++ b/bin/lynx/ar.pl @@ -0,0 +1,40 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2000 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Accounts Receivable +# +#====================================================================== + +use SL::PE; +use SL::IS; + +require "$form->{path}/arap.pl"; +require "$form->{path}/arapprn.pl"; +require "$form->{path}/aa.pl"; + +$form->{vc} = 'customer'; +$form->{ARAP} = 'AR'; + +1; +# end of main + diff --git a/bin/lynx/arap.pl b/bin/lynx/arap.pl new file mode 100755 index 00000000..6fc44370 --- /dev/null +++ b/bin/lynx/arap.pl @@ -0,0 +1,918 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2003 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# common routines for gl, ar, ap, is, ir, oe +# + +use SL::AA; + +# any custom scripts for this one +if (-f "$form->{path}/custom_arap.pl") { + eval { require "$form->{path}/custom_arap.pl"; }; +} +if (-f "$form->{path}/$form->{login}_arap.pl") { + eval { require "$form->{path}/$form->{login}_arap.pl"; }; +} + + +1; +# end of main + + +sub check_name { + my ($name) = @_; + + my ($new_name, $new_id) = split /--/, $form->{$name}; + my $rv = 0; + + # if we use a selection + if ($form->{"select$name"}) { + if ($form->{"old$name"} ne $form->{$name}) { + # this is needed for is, ir and oe + for (split / /, $form->{taxaccounts}) { delete $form->{"${_}_rate"} } + + # for credit calculations + $form->{oldinvtotal} = 0; + $form->{oldtotalpaid} = 0; + $form->{calctax} = 1; + + $form->{"${name}_id"} = $new_id; + AA->get_name(\%myconfig, \%$form); + + $form->{$name} = $form->{"old$name"} = "$new_name--$new_id"; + $form->{currency} =~ s/ //g; + + # put employee together if there is a new employee_id + $form->{employee} = "$form->{employee}--$form->{employee_id}" if $form->{employee_id}; + + $rv = 1; + } + } else { + + # check name, combine name and id + if ($form->{"old$name"} ne qq|$form->{$name}--$form->{"${name}_id"}|) { + # this is needed for is, ir and oe + for (split / /, $form->{taxaccounts}) { delete $form->{"${_}_rate"} } + + # for credit calculations + $form->{oldinvtotal} = 0; + $form->{oldtotalpaid} = 0; + $form->{calctax} = 1; + + # return one name or a list of names in $form->{name_list} + if (($rv = $form->get_name(\%myconfig, $name, $form->{transdate})) > 1) { + &select_name($name); + exit; + } + + if ($rv == 1) { + # we got one name + $form->{"${name}_id"} = $form->{name_list}[0]->{id}; + $form->{$name} = $form->{name_list}[0]->{name}; + $form->{"old$name"} = qq|$form->{$name}--$form->{"${name}_id"}|; + + AA->get_name(\%myconfig, \%$form); + + $form->{currency} =~ s/ //g; + # put employee together if there is a new employee_id + $form->{employee} = "$form->{employee}--$form->{employee_id}" if $form->{employee_id}; + + } else { + # name is not on file + $msg = ucfirst $name . " not on file!"; + $form->error($locale->text($msg)); + } + } + } + + $rv; + +} + +# $locale->text('Customer not on file!') +# $locale->text('Vendor not on file!') + + +sub select_name { + my ($table) = @_; + + @column_index = qw(ndx name address); + + $label = ucfirst $table; + $column_data{ndx} = qq|<th> </th>|; + $column_data{name} = qq|<th class=listheading>|.$locale->text($label).qq|</th>|; + $column_data{address} = qq|<th class=listheading colspan=5>|.$locale->text('Address').qq|</th>|; + + # list items with radio button on a form + $form->header; + + $title = $locale->text('Select from one of the names below'); + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$title</th> + </tr> + <tr space=5></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + @column_index = qw(ndx name address city state zipcode country); + + my $i = 0; + foreach $ref (@{ $form->{name_list} }) { + $checked = ($i++) ? "" : "checked"; + + $ref->{name} = $form->quote($ref->{name}); + + $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|; + $column_data{name} = qq|<td><input name="new_name_$i" type=hidden value="$ref->{name}">$ref->{name}</td>|; + $column_data{address} = qq|<td>$ref->{address1} $ref->{address2}</td>|; + for (qw(city state zipcode country)) { $column_data{$_} = qq|<td>$ref->{$_} </td>| } + + $j++; $j %= 2; + print qq| + <tr class=listrow$j>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> + +<input name="new_id_$i" type=hidden value=$ref->{id}> + +|; + + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input name=lastndx type=hidden value=$i> + +|; + + # delete variables + for (qw(nextsub name_list)) { delete $form->{$_} } + + $form->{action} = "name_selected"; + + $form->hide_form; + + print qq| +<input type=hidden name=nextsub value=name_selected> +<input type=hidden name=vc value=$table> +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + + +sub name_selected { + + # replace the variable with the one checked + + # index for new item + $i = $form->{ndx}; + + $form->{$form->{vc}} = $form->{"new_name_$i"}; + $form->{"$form->{vc}_id"} = $form->{"new_id_$i"}; + $form->{"old$form->{vc}"} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|; + + # delete all the new_ variables + for $i (1 .. $form->{lastndx}) { + for (qw(id, name)) { delete $form->{"new_${_}_$i"} } + } + + for (qw(ndx lastndx nextsub)) { delete $form->{$_} } + + AA->get_name(\%myconfig, \%$form); + + # put employee together if there is a new employee_id + $form->{employee} = "$form->{employee}--$form->{employee_id}" if $form->{employee_id}; + + &update(1); + +} + + +sub rebuild_vc { + my ($vc, $ARAP, $transdate, $job) = @_; + + ($null, $form->{employee_id}) = split /--/, $form->{employee}; + $form->all_vc(\%myconfig, $vc, $ARAP, undef, $transdate, $job); + $form->{"select$vc"} = ""; + for (@{ $form->{"all_$vc"} }) { $form->{"select$vc"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + + $form->{selectprojectnumber} = ""; + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + } + + 1; +} + + + +sub add_transaction { + my ($module) = @_; + + delete $form->{script}; + $form->{action} = "add"; + $form->{type} = "invoice" if $module =~ /(is|ir)/; + + $form->{callback} = $form->escape($form->{callback},1); + $argv = ""; + for (keys %$form) { $argv .= "$_=$form->{$_}&" } + + $form->{callback} = "$module.pl?$argv"; + + $form->redirect; + +} + + + +sub check_project { + + for $i (1 .. $form->{rowcount}) { + $form->{"project_id_$i"} = "" unless $form->{"projectnumber_$i"}; + if ($form->{"projectnumber_$i"} ne $form->{"oldprojectnumber_$i"}) { + if ($form->{"projectnumber_$i"}) { + # get new project + $form->{projectnumber} = $form->{"projectnumber_$i"}; + if (($rows = PE->projects(\%myconfig, $form)) > 1) { + # check form->{project_list} how many there are + $form->{rownumber} = $i; + &select_project; + exit; + } + + if ($rows == 1) { + $form->{"project_id_$i"} = $form->{project_list}->[0]->{id}; + $form->{"projectnumber_$i"} = $form->{project_list}->[0]->{projectnumber}; + $form->{"oldprojectnumber_$i"} = $form->{project_list}->[0]->{projectnumber}; + } else { + # not on file + $form->error($locale->text('Project not on file!')); + } + } else { + $form->{"oldprojectnumber_$i"} = ""; + } + } + } + +} + + +sub select_project { + + @column_index = qw(ndx projectnumber description); + + $column_data{ndx} = qq|<th> </th>|; + $column_data{projectnumber} = qq|<th>|.$locale->text('Number').qq|</th>|; + $column_data{description} = qq|<th>|.$locale->text('Description').qq|</th>|; + + # list items with radio button on a form + $form->header; + + $title = $locale->text('Select from one of the projects below'); + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=rownumber value=$form->{rownumber}> + +<table width=100%> + <tr> + <th class=listtop>$title</th> + </tr> + <tr space=5></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + my $i = 0; + foreach $ref (@{ $form->{project_list} }) { + $checked = ($i++) ? "" : "checked"; + + $ref->{name} = $form->quote($ref->{name}); + + $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|; + $column_data{projectnumber} = qq|<td><input name="new_projectnumber_$i" type=hidden value="$ref->{projectnumber}">$ref->{projectnumber}</td>|; + $column_data{description} = qq|<td>$ref->{description}</td>|; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> + +<input name="new_id_$i" type=hidden value=$ref->{id}> + +|; + + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input name=lastndx type=hidden value=$i> + +|; + + # delete list variable + for (qw(nextsub project_list)) { delete $form->{$_} } + + $form->{action} = "project_selected"; + + $form->hide_form; + + print qq| +<input type=hidden name=nextsub value=project_selected> +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub project_selected { + + # replace the variable with the one checked + + # index for new item + $i = $form->{ndx}; + + $form->{"projectnumber_$form->{rownumber}"} = $form->{"new_projectnumber_$i"}; + $form->{"oldprojectnumber_$form->{rownumber}"} = $form->{"new_projectnumber_$i"}; + $form->{"project_id_$form->{rownumber}"} = $form->{"new_id_$i"}; + + # delete all the new_ variables + for $i (1 .. $form->{lastndx}) { + for (qw(id projectnumber description)) { delete $form->{"new_${_}_$i"} } + } + + for (qw(ndx lastndx nextsub)) { delete $form->{$_} } + + if ($form->{update}) { + &{ $form->{update} }; + } else { + &update; + } + +} + + +sub post_as_new { + + for (qw(id printed emailed queued)) { delete $form->{$_} } + &post; + +} + + +sub print_and_post_as_new { + + for (qw(id printed emailed queued)) { delete $form->{$_} } + &print_and_post; + +} + + +sub repost { + + if ($form->{type} =~ /_order/) { + if ($form->{print_and_save}) { + $form->{nextsub} = "print_and_save"; + $msg = $locale->text('You are printing and saving an existing order'); + } else { + $form->{nextsub} = "save"; + $msg = $locale->text('You are saving an existing order'); + } + } elsif ($form->{type} =~ /_quotation/) { + if ($form->{print_and_save}) { + $form->{nextsub} = "print_and_save"; + $msg = $locale->text('You are printing and saving an existing quotation'); + } else { + $form->{nextsub} = "save"; + $msg = $locale->text('You are saving an existing quotation'); + } + } else { + if ($form->{print_and_post}) { + $form->{nextsub} = "print_and_post"; + $msg = $locale->text('You are printing and posting an existing transaction!'); + } else { + $form->{nextsub} = "post"; + $msg = $locale->text('You are posting an existing transaction!'); + } + } + + delete $form->{action}; + $form->{repost} = 1; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->hide_form; + + print qq| +<h2 class=confirm>|.$locale->text('Warning!').qq|</h2> + +<h4>$msg</h4> + +<input name=action class=submit type=submit value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub schedule { + + ($form->{recurringreference}, $form->{recurringstartdate}, $form->{recurringrepeat}, $form->{recurringunit}, $form->{recurringhowmany}, $form->{recurringpayment}, $form->{recurringprint}, $form->{recurringemail}, $form->{recurringmessage}) = split /,/, $form->{recurring}; + + $form->{recurringreference} = $form->quote($form->unescape($form->{recurringreference})); + $form->{recurringmessage} = $form->quote($form->unescape($form->{recurringmessage})); + + $form->{recurringstartdate} ||= $form->{transdate}; + $recurringpayment = "checked" if $form->{recurringpayment}; + + if ($form->{paidaccounts}) { + $postpayment = qq| + <tr> + <th align=right nowrap>|.$locale->text('Include Payment').qq|</th> + <td><input name=recurringpayment type=checkbox class=checkbox value=1 $recurringpayment></td> + </tr> +|; + } + + if ($form->{recurringnextdate}) { + $nextdate = qq| + <tr> + <th align=right nowrap>|.$locale->text('Next Date').qq|</th> + <td><input name=recurringnextdate size=11 title="($myconfig{'dateformat'})" value=$form->{recurringnextdate}></td> + </tr> +|; + } + + @a = split /<option/, $form->unescape($form->{selectformname}); + %formname = (); + + for ($i = 1; $i <= $#a; $i++) { + $a[$i] =~ /"(.*)"/; + $v = $1; + $a[$i] =~ />(.*)/; + $formname{$v} = $1; + } + for (qw(check receipt)) { delete $formname{$_} } + + $selectformat = $form->unescape($form->{selectformat}); + + if ($form->{type} !~ /transaction/ && %formname) { + $email = qq| + <table> + <tr> + <th colspan=2 class=listheading>|.$locale->text('E-mail').qq|</th> + </tr> + + <tr> + <td> + <table> +|; + + # formname:format + @p = split /:/, $form->{recurringemail}; + %p = (); + for ($i = 0; $i <= $#p; $i += 2) { + $p{$p[$i]}{format} = $p[$i+1]; + } + + foreach $item (keys %formname) { + + $checked = ($p{$item}{format}) ? "checked" : ""; + $selectformat =~ s/ selected//; + $p{$item}{format} ||= "pdf"; + $selectformat =~ s/(<option value="\Q$p{$item}{format}\E")/$1 selected/; + + $email .= qq| + <tr> + <td><input name="email$item" type=checkbox class=checkbox value=1 $checked></td> + <th align=left>$formname{$item}</th> + <td><select name="emailformat$item">$selectformat</select></td> + </tr> +|; + } + + $email .= qq| + </table> + </td> + </tr> + </table> +|; + + $message = qq| + <table> + <tr> + <th class=listheading>|.$locale->text('E-mail message').qq|</th> + </tr> + + <tr> + <td><textarea name="recurringmessage" rows=10 cols=60 wrap=soft>$form->{recurringmessage}</textarea></td> + </tr> + </table> +|; + + } + + + if (%printer && $latex && %formname) { + $selectprinter = qq|<option>\n|; + for (sort keys %printer) { $selectprinter .= qq|<option value="$_">$_\n| } + + # formname:format:printer + @p = split /:/, $form->{recurringprint}; + + %p = (); + for ($i = 0; $i <= $#p; $i += 3) { + $p{$p[$i]}{formname} = $p[$i]; + $p{$p[$i]}{format} = $p[$i+1]; + $p{$p[$i]}{printer} = $p[$i+2]; + } + + $print = qq| + <table> + <tr> + <th colspan=2 class=listheading>|.$locale->text('Print').qq|</th> + </tr> + + <tr> + <td> + <table> +|; + + $selectformat =~ s/<option.*html//; + foreach $item (keys %formname) { + + $selectprinter =~ s/ selected//; + $selectprinter =~ s/(<option value="\Q$p{$item}{printer}\E")/$1 selected/; + + $checked = ($p{$item}{formname}) ? "checked" : ""; + + $selectformat =~ s/ selected//; + $p{$item}{format} ||= "postscript"; + $selectformat =~ s/(<option value="\Q$p{$item}{format}\E")/$1 selected/; + + $print .= qq| + <tr> + <td><input name="print$item" type=checkbox class=checkbox value=1 $checked></td> + <th align=left>$formname{$item}</th> + <td><select name="printprinter$item">$selectprinter</select></td> + <td><select name="printformat$item">$selectformat</select></td> + </tr> +|; + } + + $print .= qq| + </table> + </td> + </tr> + </table> +|; + + + } + + $selectrepeat = ""; + for (1 .. 31) { $selectrepeat .= qq|<option value="$_">$_\n| } + $selectrepeat =~ s/(<option value="$form->{recurringrepeat}")/$1 selected/; + + $selectunit = qq|<option value="days">|.$locale->text('Day(s)').qq| + <option value="weeks">|.$locale->text('Week(s)').qq| + <option value="months">|.$locale->text('Month(s)').qq| + <option value="years">|.$locale->text('Year(s)'); + + if ($form->{recurringunit}) { + $selectunit =~ s/(<option value="$form->{recurringunit}")/$1 selected/; + } + + if ($form->{$form->{vc}}) { + $description = $form->{$form->{vc}}; + } else { + $description = $form->{description}; + } + + $repeat = qq| + <table> + <tr> + <th colspan=3 class=listheading>|.$locale->text('Repeat').qq|</th> + </tr> + + <tr> + <th align=right nowrap>|.$locale->text('Every').qq|</th> + <td><select name=recurringrepeat>$selectrepeat</td> + <td><select name=recurringunit>$selectunit</td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('For').qq|</th> + <td><input name=recurringhowmany size=3 value=$form->{recurringhowmany}></td> + <th align=left nowrap>|.$locale->text('time(s)').qq|</th> + </tr> + </table> +|; + + + $title = $locale->text('Recurring Transaction') ." ". $locale->text('for') ." $description"; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr class=listtop> + <th class=listtop>$title</th> + </tr> + <tr space=5></tr> + <tr> + <td> + <table> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Reference').qq|</th> + <td><input name=recurringreference size=20 value="$form->{recurringreference}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Startdate').qq|</th> + <td><input name=recurringstartdate size=11 title="($myconfig{'dateformat'})" value=$form->{recurringstartdate}></td> + </tr> + $nextdate + </table> + </td> + </tr> + </table> + </td> + </tr> + + <tr> + <td> + <table> + $postpayment + </table> + </td> + </tr> + + <tr> + <td> + <table> + <tr valign=top> + <td>$repeat</td> + <td>$print</td> + </tr> + <tr valign=top> + <td>$email</td> + <td>$message</td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +|; + +# type=submit $locale->text('Save Schedule') +# type=submit $locale->text('Delete Schedule') + + %button = ('Save Schedule' => { ndx => 1, key => 'S', value => $locale->text('Save Schedule') }, + 'Delete Schedule' => { ndx => 16, key => 'D', value => $locale->text('Delete Schedule') }, + ); + + $form->print_button(\%button, 'Save Schedule'); + + if ($form->{recurring}) { + $form->print_button(\%button, 'Delete Schedule'); + } + + # delete variables + for (qw(action recurring)) { delete $form->{$_} } + for (qw(reference startdate nextdate enddate repeat unit howmany payment print email message)) { delete $form->{"recurring$_"} } + + $form->hide_form; + + print qq| + +</form> + +</body> +</html> +|; + +} + + +sub save_schedule { + + $form->{recurring} = ""; + + $form->{recurringreference} = $form->escape($form->{recurringreference},1); + $form->{recurringmessage} = $form->escape($form->{recurringmessage},1); + if ($form->{recurringstartdate}) { + for (qw(reference startdate repeat unit howmany payment)) { $form->{recurring} .= qq|$form->{"recurring$_"},| } + } + + @a = split /<option/, $form->unescape($form->{selectformname}); + @p = (); + + for ($i = 1; $i <= $#a; $i++) { + $a[$i] =~ /"(.*)"/; + push @p, $1; + } + + $recurringemail = ""; + for (@p) { $recurringemail .= qq|$_:$form->{"emailformat$_"}:| if $form->{"email$_"} } + chop $recurringemail; + + $recurringprint = ""; + for (@p) { $recurringprint .= qq|$_:$form->{"printformat$_"}:$form->{"printprinter$_"}:| if $form->{"print$_"} } + chop $recurringprint; + + $form->{recurring} .= qq|$recurringprint,$recurringemail,$form->{recurringmessage}| if $recurringemail || $recurringprint; + + $form->save_recurring(undef, \%myconfig) if $form->{id}; + + if ($form->{recurringid}) { + $form->redirect; + } else { + &update; + } + +} + + +sub delete_schedule { + + $form->{recurring} = ""; + + $form->save_recurring(undef, \%myconfig) if $form->{id}; + + if ($form->{recurringid}) { + $form->redirect; + } else { + &update; + } + +} + + +sub reprint { + + $myconfig{vclimit} = 0; + $pf = "print_form"; + + for (qw(format formname media message)) { $temp{$_} = $form->{$_} } + + if ($form->{module} eq 'oe') { + &order_links; + &prepare_order; + delete $form->{order_details}; + for (keys %$form) { $form->{$_} = $form->unquote($form->{$_}) } + } else { + if ($form->{type} eq 'invoice') { + &invoice_links; + &prepare_invoice; + for (keys %$form) { $form->{$_} = $form->unquote($form->{$_}) } + } else { + &create_links; + $form->{rowcount}--; + for (1 .. $form->{rowcount}) { $form->{"amount_$_"} = $form->format_amount(\%myconfig, $form->{"amount_$_"}, 2) } + for (split / /, $form->{taxaccounts}) { $form->{"tax_$_"} = $form->format_amount(\%myconfig, $form->{"tax_$_"}, 2) } + $pf = "print_transaction"; + } + for (qw(acc_trans invoice_details)) { delete $form->{$_} } + } + + for (qw(department employee language month partsgroup project years)) { delete $form->{"all_$_"} } + + for (keys %temp) { $form->{$_} = $temp{$_} } + + $form->{rowcount}++; + $form->{paidaccounts}++; + + delete $form->{paid}; + + for (1 .. $form->{paidaccounts}) { $form->{"paid_$_"} = $form->format_amount(\%myconfig, $form->{"paid_$_"}, 2) } + + $form->{copies} = 1; + + &$pf; + + if ($form->{media} eq 'email') { + # add email message + $now = scalar localtime; + $cc = $locale->text('Cc').qq|: $form->{cc}\n| if $form->{cc}; + $bcc = $locale->text('Bcc').qq|: $form->{bcc}\n| if $form->{bcc}; + + $form->{intnotes} .= qq|\n\n| if $form->{intnotes}; + $form->{intnotes} .= qq|[email]\n| + .$locale->text('Date').qq|: $now\n| + .$locale->text('To').qq|: $form->{email}\n${cc}${bcc}| + .$locale->text('Subject').qq|: $form->{subject}\n\n| + .$locale->text('Message').qq|: |; + + $form->{intnotes} .= ($form->{message}) ? $form->{message} : $locale->text('sent'); + + $form->save_intnotes(\%myconfig, $form->{module}); + } + +} + + +sub continue { &{ $form->{nextsub} } }; +sub gl_transaction { &add }; +sub ar_transaction { &add_transaction(ar) }; +sub ap_transaction { &add_transaction(ap) }; +sub sales_invoice_ { &add_transaction(is) }; +sub vendor_invoice_ { &add_transaction(ir) }; + diff --git a/bin/lynx/arapprn.pl b/bin/lynx/arapprn.pl new file mode 100755 index 00000000..8519df47 --- /dev/null +++ b/bin/lynx/arapprn.pl @@ -0,0 +1,591 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2003 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# +# printing routines for ar, ap +# + +# any custom scripts for this one +if (-f "$form->{path}/custom_arapprn.pl") { + eval { require "$form->{path}/custom_arapprn.pl"; }; +} +if (-f "$form->{path}/$form->{login}_arapprn.pl") { + eval { require "$form->{path}/$form->{login}_arapprn.pl"; }; +} + + +1; +# end of main + + +sub print { + + if ($form->{media} !~ /screen/) { + $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/; + $old_form = new Form; + for (keys %$form) { $old_form->{$_} = $form->{$_} } + } + + if ($form->{formname} =~ /(check|receipt)/) { + if ($form->{media} eq 'screen') { + $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/; + } + } + + if (! $form->{invnumber}) { + $invfld = 'sinumber'; + $invfld = 'vinumber' if $form->{ARAP} eq 'AP'; + $form->{invnumber} = $form->update_defaults(\%myconfig, $invfld); + if ($form->{media} eq 'screen') { + if ($form->{media} eq 'screen') { + &update; + exit; + } + } + } + + if ($form->{formname} =~ /(check|receipt)/) { + if ($form->{media} ne 'screen') { + for (qw(action header)) { delete $form->{$_} } + $form->{invtotal} = $form->{oldinvtotal}; + + foreach $key (keys %$form) { + $form->{$key} =~ s/&/%26/g; + $form->{previousform} .= qq|$key=$form->{$key}&|; + } + chop $form->{previousform}; + $form->{previousform} = $form->escape($form->{previousform}, 1); + } + + if ($form->{paidaccounts} > 1) { + if ($form->{"paid_$form->{paidaccounts}"}) { + &update; + exit; + } elsif ($form->{paidaccounts} > 2) { + # select payment + &select_payment; + exit; + } + } else { + $form->error($locale->text('Nothing to print!')); + } + + } + + &{ "print_$form->{formname}" }($old_form, 1); + +} + + +sub print_check { + my ($old_form, $i) = @_; + + $display_form = ($form->{display_form}) ? $form->{display_form} : "display_form"; + + if ($form->{"paid_$i"}) { + @a = (); + + if (exists $form->{longformat}) { + $form->{"datepaid_$i"} = $locale->date(\%myconfig, $form->{"datepaid_$i"}, $form->{longformat}); + } + + push @a, "source_$i", "memo_$i"; + $form->format_string(@a); + } + + $form->{amount} = $form->{"paid_$i"}; + + if (($form->{formname} eq 'check' && $form->{vc} eq 'customer') || + ($form->{formname} eq 'receipt' && $form->{vc} eq 'vendor')) { + $form->{amount} =~ s/-//g; + } + + for (qw(datepaid source memo)) { $form->{$_} = $form->{"${_}_$i"} } + + &{ "$form->{vc}_details" }; + @a = qw(name address1 address2 city state zipcode country); + + foreach $item (qw(invnumber ordnumber)) { + $temp{$item} = $form->{$item}; + delete $form->{$item}; + push(@{ $form->{$item} }, $temp{$item}); + } + push(@{ $form->{invdate} }, $form->{transdate}); + push(@{ $form->{due} }, $form->format_amount(\%myconfig, $form->{oldinvtotal}, 2)); + push(@{ $form->{paid} }, $form->{"paid_$i"}); + + use SL::CP; + $c = CP->new(($form->{language_code}) ? $form->{language_code} : $myconfig{countrycode}); + $c->init; + ($whole, $form->{decimal}) = split /\./, $form->parse_amount(\%myconfig, $form->{amount}); + + $form->{decimal} .= "00"; + $form->{decimal} = substr($form->{decimal}, 0, 2); + $form->{text_decimal} = $c->num2text($form->{decimal} * 1); + $form->{text_amount} = $c->num2text($whole); + $form->{integer_amount} = $form->format_amount($myconfig, $whole); + + ($form->{employee}) = split /--/, $form->{employee}; + + $form->{notes} =~ s/^\s+//g; + push @a, "notes"; + + for (qw(company address tel fax businessnumber)) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/\n/g; + + push @a, qw(company address tel fax businessnumber text_amount text_decimal); + + $form->format_string(@a); + + $form->{templates} = "$myconfig{templates}"; + $form->{IN} = ($form->{formname} eq 'transaction') ? lc $form->{ARAP} . "_$form->{formname}.html" : "$form->{formname}.html"; + + if ($form->{format} =~ /(postscript|pdf)/) { + $form->{IN} =~ s/html$/tex/; + } + + if ($form->{media} !~ /(screen)/) { + $form->{OUT} = "| $printer{$form->{media}}"; + + if ($form->{printed} !~ /$form->{formname}/) { + + $form->{printed} .= " $form->{formname}"; + $form->{printed} =~ s/^ //; + + $form->update_status(\%myconfig); + } + + %audittrail = ( tablename => lc $form->{ARAP}, + reference => $form->{invnumber}, + formname => $form->{formname}, + action => 'printed', + id => $form->{id} ); + + %status = (); + for (qw(printed audittrail)) { $status{$_} = $form->{$_} } + + $status{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail); + + } + + $form->{fileid} = $invnumber; + $form->{fileid} =~ s/(\s|\W)+//g; + + $form->parse_template(\%myconfig, $userspath); + + if ($form->{previousform}) { + + $previousform = $form->unescape($form->{previousform}); + + for (keys %$form) { delete $form->{$_} } + + foreach $item (split /&/, $previousform) { + ($key, $value) = split /=/, $item, 2; + $value =~ s/%26/&/g; + $form->{$key} = $value; + } + + for (qw(exchangerate creditlimit creditremaining)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + for (1 .. $form->{rowcount}) { $form->{"amount_$_"} = $form->parse_amount(\%myconfig, $form->{"amount_$_"}) } + for (split / /, $form->{taxaccounts}) { $form->{"tax_$_"} = $form->parse_amount(\%myconfig, $form->{"tax_$_"}) } + + for $i (1 .. $form->{paidaccounts}) { + for (qw(paid exchangerate)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + } + + for (qw(printed audittrail)) { $form->{$_} = $status{$_} } + + &{ "$display_form" }; + + } + +} + + +sub print_receipt { + my ($old_form, $i) = @_; + + &print_check($old_form, $i); + +} + + +sub print_transaction { + my ($old_form) = @_; + + $display_form = ($form->{display_form}) ? $form->{display_form} : "display_form"; + + + &{ "$form->{vc}_details" }; + @a = qw(name address1 address2 city state zipcode country); + + + $form->{invtotal} = 0; + foreach $i (1 .. $form->{rowcount} - 1) { + ($form->{tempaccno}, $form->{tempaccount}) = split /--/, $form->{"$form->{ARAP}_amount_$i"}; + ($form->{tempprojectnumber}) = split /--/, $form->{"projectnumber_$i"}; + $form->{tempdescription} = $form->{"description_$i"}; + + $form->format_string(qw(tempaccno tempaccount tempprojectnumber tempdescription)); + + push(@{ $form->{accno} }, $form->{tempaccno}); + push(@{ $form->{account} }, $form->{tempaccount}); + push(@{ $form->{description} }, $form->{tempdescription}); + push(@{ $form->{projectnumber} }, $form->{tempprojectnumber}); + + push(@{ $form->{amount} }, $form->{"amount_$i"}); + + $form->{subtotal} += $form->parse_amount(\%myconfig, $form->{"amount_$i"}); + + } + + foreach $accno (split / /, $form->{taxaccounts}) { + if ($form->{"tax_$accno"}) { + $form->format_string("${accno}_description"); + + $tax += $form->parse_amount(\%myconfig, $form->{"tax_$accno"}); + + $form->{"${accno}_tax"} = $form->{"tax_$accno"}; + push(@{ $form->{tax} }, $form->{"tax_$accno"}); + + push(@{ $form->{taxdescription} }, $form->{"${accno}_description"}); + + $form->{"${accno}_taxrate"} = $form->format_amount($myconfig, $form->{"${accno}_rate"} * 100); + push(@{ $form->{taxrate} }, $form->{"${accno}_taxrate"}); + + push(@{ $form->{taxnumber} }, $form->{"${accno}_taxnumber"}); + } + } + + $tax = 0 if $form->{taxincluded}; + + push @a, $form->{ARAP}; + $form->format_string(@a); + + $form->{paid} = 0; + for $i (1 .. $form->{paidaccounts} - 1) { + + if ($form->{"paid_$i"}) { + @a = (); + $form->{paid} += $form->parse_amount(\%myconfig, $form->{"paid_$i"}); + + if (exists $form->{longformat}) { + $form->{"datepaid_$i"} = $locale->date(\%myconfig, $form->{"datepaid_$i"}, $form->{longformat}); + } + + push @a, "$form->{ARAP}_paid_$i", "source_$i", "memo_$i"; + $form->format_string(@a); + + ($accno, $account) = split /--/, $form->{"$form->{ARAP}_paid_$i"}; + + push(@{ $form->{payment} }, $form->{"paid_$i"}); + push(@{ $form->{paymentdate} }, $form->{"datepaid_$i"}); + push(@{ $form->{paymentaccount} }, $account); + push(@{ $form->{paymentsource} }, $form->{"source_$i"}); + push(@{ $form->{paymentmemo} }, $form->{"memo_$i"}); + } + + } + + $form->{invtotal} = $form->{subtotal} + $tax; + $form->{total} = $form->{invtotal} - $form->{paid}; + + use SL::CP; + $c = CP->new(($form->{language_code}) ? $form->{language_code} : $myconfig{countrycode}); + $c->init; + ($whole, $form->{decimal}) = split /\./, $form->{invtotal}; + + $form->{decimal} .= "00"; + $form->{decimal} = substr($form->{decimal}, 0, 2); + $form->{text_decimal} = $c->num2text($form->{decimal} * 1); + $form->{text_amount} = $c->num2text($whole); + $form->{integer_amount} = $form->format_amount($myconfig, $whole); + + for (qw(invtotal subtotal paid total)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) } + + ($form->{employee}) = split /--/, $form->{employee}; + + if (exists $form->{longformat}) { + for (qw(duedate transdate)) { $form->{$_} = $locale->date(\%myconfig, $form->{$_}, $form->{longformat}) } + } + + $form->{notes} =~ s/^\s+//g; + + @a = ("invnumber", "transdate", "duedate", "notes"); + + for (qw(company address tel fax businessnumber)) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/\n/g; + + push @a, qw(company address tel fax businessnumber text_amount text_decimal); + + $form->format_string(@a); + + $form->{invdate} = $form->{transdate}; + + $form->{templates} = "$myconfig{templates}"; + $form->{IN} = ($form->{formname} eq 'transaction') ? lc $form->{ARAP} . "_$form->{formname}.html" : "$form->{formname}.html"; + + if ($form->{format} =~ /(postscript|pdf)/) { + $form->{IN} =~ s/html$/tex/; + } + + if ($form->{media} !~ /(screen)/) { + $form->{OUT} = "| $printer{$form->{media}}"; + + if ($form->{printed} !~ /$form->{formname}/) { + + $form->{printed} .= " $form->{formname}"; + $form->{printed} =~ s/^ //; + + $form->update_status(\%myconfig); + } + + $old_form->{printed} = $form->{printed} if %$old_form; + + %audittrail = ( tablename => lc $form->{ARAP}, + reference => $form->{"invnumber"}, + formname => $form->{formname}, + action => 'printed', + id => $form->{id} ); + + $old_form->{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail) if %$old_form; + + } + + $form->{fileid} = $form->{invnumber}; + $form->{fileid} =~ s/(\s|\W)+//g; + + $form->parse_template(\%myconfig, $userspath); + + if (%$old_form) { + $old_form->{invnumber} = $form->{invnumber}; + $old_form->{invtotal} = $form->{invtotal}; + + for (keys %$form) { delete $form->{$_} } + for (keys %$old_form) { $form->{$_} = $old_form->{$_} } + + if (! $form->{printandpost}) { + for (qw(exchangerate creditlimit creditremaining)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + for (1 .. $form->{rowcount}) { $form->{"amount_$_"} = $form->parse_amount(\%myconfig, $form->{"amount_$_"}) } + for (split / /, $form->{taxaccounts}) { $form->{"tax_$_"} = $form->parse_amount(\%myconfig, $form->{"tax_$_"}) } + + for $i (1 .. $form->{paidaccounts}) { + for (qw(paid exchangerate)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + } + } + + &{ "$display_form" }; + + } + +} + + +sub vendor_details { IR->vendor_details(\%myconfig, \%$form) }; +sub customer_details { IS->customer_details(\%myconfig, \%$form) }; + + +sub select_payment { + + @column_index = ("ndx", "datepaid", "source", "memo", "paid", "$form->{ARAP}_paid"); + + # list payments with radio button on a form + $form->header; + + $title = $locale->text('Select payment'); + + $column_data{ndx} = qq|<th width=1%> </th>|; + $column_data{datepaid} = qq|<th>|.$locale->text('Date').qq|</th>|; + $column_data{source} = qq|<th>|.$locale->text('Source').qq|</th>|; + $column_data{memo} = qq|<th>|.$locale->text('Memo').qq|</th>|; + $column_data{paid} = qq|<th>|.$locale->text('Amount').qq|</th>|; + $column_data{"$form->{ARAP}_paid"} = qq|<th>|.$locale->text('Account').qq|</th>|; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$title</th> + </tr> + <tr space=5></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + $checked = "checked"; + foreach $i (1 .. $form->{paidaccounts} - 1) { + + for (@column_index) { $column_data{$_} = qq|<td>$form->{"${_}_$i"}</td>| } + + $paid = $form->{"paid_$i"}; + $ok = 1; + + $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|; + $column_data{paid} = qq|<td align=right>$paid</td>|; + + $checked = ""; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + for (qw(action nextsub)) { delete $form->{$_} } + + $form->hide_form; + + print qq| + +<br> +<input type=hidden name=nextsub value=payment_selected> +|; + + if ($ok) { + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">|; + } + + print qq| +</form> + +</body> +</html> +|; + +} + +sub payment_selected { + + &{ "print_$form->{formname}" }($form->{oldform}, $form->{ndx}); + +} + + +sub print_options { + + if ($form->{selectlanguage}) { + $form->{"selectlanguage"} = $form->unescape($form->{"selectlanguage"}); + $form->{"selectlanguage"} =~ s/ selected//; + $form->{"selectlanguage"} =~ s/(<option value="\Q$form->{language_code}\E")/$1 selected/; + $lang = qq|<select name=language_code>$form->{selectlanguage}</select> + <input type=hidden name=selectlanguage value="|. + $form->escape($form->{selectlanguage},1).qq|">|; + } + + $form->{selectformname} = $form->unescape($form->{selectformname}); + $form->{selectformname} =~ s/ selected//; + $form->{selectformname} =~ s/(<option value="\Q$form->{formname}\E")/$1 selected/; + + $type = qq|<select name=formname>$form->{selectformname}</select> + <input type=hidden name=selectformname value="|.$form->escape($form->{selectformname},1).qq|">|; + + $media = qq|<select name=media> + <option value="screen">|.$locale->text('Screen'); + + $form->{selectformat} = qq|<option value="html">html\n|; + + if (%printer && $latex) { + for (sort keys %printer) { $media .= qq| + <option value="$_">$_| } + } + + if ($latex) { + $form->{selectformat} .= qq| + <option value="postscript">|.$locale->text('Postscript').qq| + <option value="pdf">|.$locale->text('PDF'); + } + + $format = qq|<select name=format>$form->{selectformat}</select>|; + $format =~ s/(<option value="\Q$form->{format}\E")/$1 selected/; + $format .= qq| + <input type=hidden name=selectformat value="|.$form->escape($form->{selectformat},1).qq|">|; + $media .= qq|</select>|; + $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/; + + print qq| + <table width=100%> + <tr> + <td>$type</td> + <td>$lang</td> + <td>$format</td> + <td>$media</td> + <td align=right width=90%> + |; + + if ($form->{printed} =~ /$form->{formname}/) { + print $locale->text('Printed').qq|<br>|; + } + + if ($form->{recurring}) { + print $locale->text('Scheduled'); + } + + print qq| + </td> + </tr> + </table> +|; + +} + + +sub print_and_post { + + $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/; + $form->error($locale->text('Select a Printer!')) if $form->{media} eq 'screen'; + + $form->{printandpost} = 1; + $form->{display_form} = "post"; + &print; + +} + + diff --git a/bin/lynx/bp.pl b/bin/lynx/bp.pl new file mode 100755 index 00000000..ce724baa --- /dev/null +++ b/bin/lynx/bp.pl @@ -0,0 +1,531 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2003 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Batch printing +# +#====================================================================== + + +use SL::BP; + +1; +# end of main + + +sub search { + +# $locale->text('Sales Invoices') +# $locale->text('Packing Lists') +# $locale->text('Pick Lists') +# $locale->text('Sales Orders') +# $locale->text('Work Orders') +# $locale->text('Purchase Orders') +# $locale->text('Bin Lists') +# $locale->text('Quotations') +# $locale->text('RFQs') +# $locale->text('Time Cards') + + # setup customer/vendor selection + BP->get_vc(\%myconfig, \%$form); + + if (@{ $form->{"all_$form->{vc}"} }) { + $name = "<option>\n"; + for (@{ $form->{"all_$form->{vc}"} }) { $name .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + $name = qq|<select name=$form->{vc}>$name</select>|; + } else { + $name = qq|<input name=$form->{vc} size=35>|; + } + +# $locale->text('Customer') +# $locale->text('Vendor') +# $locale->text('Employee') + + %label = ( invoice => { title => 'Sales Invoices', name => 'Customer' }, + packing_list => { title => 'Packing Lists', name => 'Customer' }, + pick_list => { title => 'Pick Lists', name => 'Customer' }, + sales_order => { title => 'Sales Orders', name => 'Customer' }, + work_order => { title => 'Work Orders', name => 'Customer' }, + purchase_order => { title => 'Purchase Orders', name => 'Vendor' }, + bin_list => { title => 'Bin Lists', name => 'Vendor' }, + sales_quotation => { title => 'Quotations', name => 'Customer' }, + request_quotation => { title => 'RFQs', name => 'Vendor' }, + timecard => { title => 'Time Cards', name => 'Employee' }, + ); + + $label{invoice}{invnumber} = qq| + <tr> + <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th> + <td colspan=3><input name=invnumber size=20></td> + </tr> +|; + $label{invoice}{ordnumber} = qq| + <tr> + <th align=right nowrap>|.$locale->text('Order Number').qq|</th> + <td colspan=3><input name=ordnumber size=20></td> + </tr> +|; + $label{sales_quotation}{quonumber} = qq| + <tr> + <th align=right nowrap>|.$locale->text('Quotation Number').qq|</th> + <td colspan=3><input name=quonumber size=20></td> + </tr> +|; + + $label{packing_list}{invnumber} = $label{invoice}{invnumber}; + $label{packing_list}{ordnumber} = $label{invoice}{ordnumber}; + $label{pick_list}{invnumber} = $label{invoice}{invnumber}; + $label{pick_list}{ordnumber} = $label{invoice}{ordnumber}; + $label{sales_order}{ordnumber} = $label{invoice}{ordnumber}; + $label{work_order}{ordnumber} = $label{invoice}{ordnumber}; + $label{purchase_order}{ordnumber} = $label{invoice}{ordnumber}; + $label{bin_list}{ordnumber} = $label{invoice}{ordnumber}; + $label{request_quotation}{quonumber} = $label{sales_quotation}{quonumber}; + + # do one call to text + $form->{title} = $locale->text('Print')." ".$locale->text($label{$form->{type}}{title}); + + # accounting years + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(vc type title)); + + print qq| +<table width=100%> + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text($label{$form->{type}}{name}).qq|</th> + <td colspan=3>$name</td> + </tr> + $account + $label{$form->{type}}{invnumber} + $label{$form->{type}}{ordnumber} + $label{$form->{type}}{quonumber} + <tr> + <th align=right nowrap>|.$locale->text('From').qq|</th> + <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=sort value=transdate> +<input type=hidden name=nextsub value=list_spool> + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| + +</form> + +</body> +</html> +|; + +} + + + +sub remove { + + $selected = 0; + + for $i (1 .. $form->{rowcount}) { + if ($form->{"checked_$i"}) { + $selected = 1; + last; + } + } + + $form->error('Nothing selected!') unless $selected; + + $form->{title} = $locale->text('Confirm!'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + for (qw(action header)) { delete $form->{$_} } + + foreach $key (keys %$form) { + print qq|<input type=hidden name=$key value="$form->{$key}">\n|; + } + + print qq| +<h2 class=confirm>$form->{title}</h2> + +<h4>|.$locale->text('Are you sure you want to remove the marked entries from the queue?').qq|</h4> + +<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|"> +</form> + +</body> +</html> +|; + +} + + + +sub yes { + + $form->info($locale->text('Removing marked entries from queue ...')); + $form->{callback} .= "&header=1" if $form->{callback}; + + if (BP->delete_spool(\%myconfig, \%$form, $spool)) { + $form->redirect($locale->text('Removed spoolfiles!')); + } else { + $form->error($locale->text('Cannot remove files!')); + } + +} + + +sub print { + + if ($form->{callback}) { + for (1 .. $form->{rowcount}) { $form->{callback} .= "&checked_$_=1" if $form->{"checked_$_"} } + $form->{callback} .= "&header=1"; + } + + for $i (1 .. $form->{rowcount}) { + if ($form->{"checked_$i"}) { + $form->{OUT} = "| $printer{$form->{media}}"; + $form->info($locale->text('Printing')." ..."); + + if (BP->print_spool(\%myconfig, \%$form, $spool)) { + print $locale->text('done'); + $form->redirect($locale->text('Marked entries printed!')); + } + exit; + } + } + + $form->error('Nothing selected!'); + +} + + +sub list_spool { + + $form->{$form->{vc}} = $form->unescape($form->{$form->{vc}}); + ($form->{$form->{vc}}, $form->{"$form->{vc}_id"}) = split(/--/, $form->{$form->{vc}}); + + BP->get_spoolfiles(\%myconfig, \%$form); + + $title = $form->escape($form->{title}); + $href = "$form->{script}?action=list_spool&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&vc=$form->{vc}&type=$form->{type}&title=$title"; + + $form->sort_order(); + + $title = $form->escape($form->{title},1); + $callback = "$form->{script}?action=list_spool&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&vc=$form->{vc}&type=$form->{type}&title=$title"; + + if ($form->{$form->{vc}}) { + $callback .= "&$form->{vc}=".$form->escape($form->{$form->{vc}},1); + $href .= "&$form->{vc}=".$form->escape($form->{$form->{vc}}); + $option = ($form->{vc} eq 'customer') ? $locale->text('Customer') : $locale->text('Vendor'); + $option .= " : $form->{$form->{vc}}"; + } + if ($form->{account}) { + $callback .= "&account=".$form->escape($form->{account},1); + $href .= "&account=".$form->escape($form->{account}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Account')." : $form->{account}"; + } + if ($form->{invnumber}) { + $callback .= "&invnumber=".$form->escape($form->{invnumber},1); + $href .= "&invnumber=".$form->escape($form->{invnumber}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Invoice Number')." : $form->{invnumber}"; + } + if ($form->{ordnumber}) { + $callback .= "&ordnumber=".$form->escape($form->{ordnumber},1); + $href .= "&ordnumber=".$form->escape($form->{ordnumber}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Order Number')." : $form->{ordnumber}"; + } + if ($form->{quonumber}) { + $callback .= "&quonumber=".$form->escape($form->{quonumber},1); + $href .= "&quonumber=".$form->escape($form->{quonumber}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Quotation Number')." : $form->{quonumber}"; + } + + if ($form->{transdatefrom}) { + $callback .= "&transdatefrom=$form->{transdatefrom}"; + $href .= "&transdatefrom=$form->{transdatefrom}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1); + } + if ($form->{transdateto}) { + $callback .= "&transdateto=$form->{transdateto}"; + $href .= "&transdateto=$form->{transdateto}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{transdateto}, 1); + } + + $name = ucfirst $form->{vc}; + + @columns = qw(transdate); + if ($form->{type} =~ /(invoice)/) { + push @columns, "invnumber"; + } + if ($form->{type} =~ /(packing|pick)_list/) { + push @columns, "invnumber"; + } + if ($form->{type} =~ /_(order|list)$/) { + push @columns, "ordnumber"; + } + if ($form->{type} =~ /_quotation$/) { + push @columns, "quonumber"; + } + if ($form->{type} eq 'timecard') { + push @columns, "id"; + } + + + push @columns, (name, spoolfile); + @column_index = $form->sort_columns(@columns); + unshift @column_index, "checked"; + + $column_header{checked} = "<th class=listheading> </th>"; + $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>"; + $column_header{invnumber} = "<th><a class=listheading href=$href&sort=invnumber>".$locale->text('Invoice')."</a></th>"; + $column_header{ordnumber} = "<th><a class=listheading href=$href&sort=ordnumber>".$locale->text('Order')."</a></th>"; + $column_header{quonumber} = "<th><a class=listheading href=$href&sort=quonumber>".$locale->text('Quotation')."</a></th>"; + $column_header{name} = "<th><a class=listheading href=$href&sort=name>".$locale->text($name)."</a></th>"; + $column_header{id} = "<th><a class=listheading href=$href&sort=id>".$locale->text('ID')."</a></th>"; + $column_header{spoolfile} = "<th class=listheading>".$locale->text('Spoolfile')."</th>"; + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + + # add sort and escape callback, this one we use for the add sub + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + $i = 0; + + foreach $ref (@{ $form->{SPOOL} }) { + + $i++; + + $form->{"checked_$i"} = "checked" if $form->{"checked_$i"}; + + # this is for audittrail + $form->{module} = $ref->{module}; + + if ($ref->{invoice}) { + $ref->{module} = ($ref->{module} eq 'ar') ? "is" : "ir"; + } + $module = "$ref->{module}.pl"; + + $column_data{transdate} = "<td>$ref->{transdate} </td>"; + + if ($spoolfile eq $ref->{spoolfile}) { + $column_data{checked} = qq|<td></td>|; + } else { + $column_data{checked} = qq|<td><input name=checked_$i type=checkbox class=checkbox $form->{"checked_$i"} $form->{"checked_$i"}></td>|; + } + + for (qw(id invnumber ordnumber quonumber)) { $column_data{$_} = qq|<td>$ref->{$_}</td>| } + + if ($ref->{module} eq 'oe') { + $column_data{invnumber} = qq|<td> </td>|; + $column_data{ordnumber} = qq|<td><a href=$module?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$form->{type}&callback=$callback>$ref->{ordnumber}</a></td> + <input type=hidden name="reference_$i" value="$ref->{ordnumber}">|; + + $column_data{quonumber} = qq|<td><a href=$module?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$form->{type}&callback=$callback>$ref->{quonumber}</a></td> + <input type=hidden name="reference_$i" value="$ref->{quonumber}">|; + + } elsif ($ref->{module} eq 'jc') { + $column_data{id} = qq|<td><a href=$module?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$form->{type}&callback=$callback>$ref->{id}</a></td> + <input type=hidden name="reference_$i" value="$ref->{id}">|; + } else { + $column_data{invnumber} = qq|<td><a href=$module?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$form->{type}&callback=$callback>$ref->{invnumber}</a></td> + <input type=hidden name="reference_$i" value="$ref->{invnumber}">|; + } + + + $column_data{name} = "<td>$ref->{name}</td>"; + $column_data{spoolfile} = qq|<td><a href=$spool/$ref->{spoolfile}>$ref->{spoolfile}</a></td> + +|; + + $spoolfile = $ref->{spoolfile}; + + $j++; $j %= 2; + print " + <tr class=listrow$j> +"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| +<input type=hidden name="id_$i" value=$ref->{id}> +<input type=hidden name="spoolfile_$i" value=$ref->{spoolfile}> + + </tr> +|; + + } + + print qq| +<input type=hidden name=rowcount value=$i> + + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +|; + + $form->hide_form(qw(callback title vc type sort module account path login sessionid)); + + if (%printer && $latex) { + foreach $key (sort keys %printer) { + print qq| +<input name=media type=radio class=radio value="$key" |; + print qq|checked| if $key eq $myconfig{printer}; + print qq|>$key|; + } + + print qq|<p>\n|; + +# type=submit $locale->text('Select all') +# type=submit $locale->text('Print') +# type=submit $locale->text('Remove') + + %button = ('Select all' => { ndx => 2, key => 'A', value => $locale->text('Select all') }, + 'Print' => { ndx => 3, key => 'P', value => $locale->text('Print') }, + 'Remove' => { ndx => 4, key => 'R', value => $locale->text('Remove') }, + ); + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub select_all { + + for (1 .. $form->{rowcount}) { $form->{"checked_$_"} = 1 } + &list_spool; + +} + + +sub continue { &{ $form->{nextsub} } }; + diff --git a/bin/lynx/ca.pl b/bin/lynx/ca.pl new file mode 100755 index 00000000..8ea9980d --- /dev/null +++ b/bin/lynx/ca.pl @@ -0,0 +1,514 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (C) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# module for Chart of Accounts, Income Statement and Balance Sheet +# search and edit transactions posted by the GL, AR and AP +# +#====================================================================== + +use SL::CA; + +1; +# end of main + +# this is for our long dates +# $locale->text('January') +# $locale->text('February') +# $locale->text('March') +# $locale->text('April') +# $locale->text('May ') +# $locale->text('June') +# $locale->text('July') +# $locale->text('August') +# $locale->text('September') +# $locale->text('October') +# $locale->text('November') +# $locale->text('December') + +# this is for our short month +# $locale->text('Jan') +# $locale->text('Feb') +# $locale->text('Mar') +# $locale->text('Apr') +# $locale->text('May') +# $locale->text('Jun') +# $locale->text('Jul') +# $locale->text('Aug') +# $locale->text('Sep') +# $locale->text('Oct') +# $locale->text('Nov') +# $locale->text('Dec') + + +sub chart_of_accounts { + + CA->all_accounts(\%myconfig, \%$form); + + @column_index = qw(accno gifi_accno description debit credit); + + $column_header{accno} = qq|<th class=listtop>|.$locale->text('Account').qq|</th>\n|; + $column_header{gifi_accno} = qq|<th class=listtop>|.$locale->text('GIFI').qq|</th>\n|; + $column_header{description} = qq|<th class=listtop>|.$locale->text('Description').qq|</th>\n|; + $column_header{debit} = qq|<th class=listtop>|.$locale->text('Debit').qq|</th>\n|; + $column_header{credit} = qq|<th class=listtop>|.$locale->text('Credit').qq|</th>\n|; + + + $form->{title} = $locale->text('Chart of Accounts'); + + $colspan = $#column_index + 1; + + $form->header; + + print qq| +<body> + +<table border=0 width=100%> + <tr><th class=listtop colspan=$colspan>$form->{title}</th></tr> + <tr height="5"></tr> + <tr class=listheading>|; + + for (@column_index) { print $column_header{$_} } + + print qq| + </tr> +|; + + + foreach $ca (@{ $form->{CA} }) { + + $description = $form->escape($ca->{description}); + $gifi_description = $form->escape($ca->{gifi_description}); + + $href = qq|$form->{script}?path=$form->{path}&action=list&accno=$ca->{accno}&login=$form->{login}&sessionid=$form->{sessionid}&description=$description&gifi_accno=$ca->{gifi_accno}&gifi_description=$gifi_description|; + + if ($ca->{charttype} eq "H") { + print qq|<tr class=listheading>|; + for (qw(accno description)) { $column_data{$_} = "<th class=listheading>$ca->{$_}</th>" } + $column_data{gifi_accno} = "<th class=listheading>$ca->{gifi_accno} </th>"; + } else { + $i++; $i %= 2; + print qq|<tr class=listrow$i>|; + $column_data{accno} = "<td><a href=$href>$ca->{accno}</a></td>"; + $column_data{gifi_accno} = "<td><a href=$href&accounttype=gifi>$ca->{gifi_accno}</a> </td>"; + $column_data{description} = "<td>$ca->{description}</td>"; + } + + $column_data{debit} = "<td align=right>".$form->format_amount(\%myconfig, $ca->{debit}, 2, " ")."</td>\n"; + $column_data{credit} = "<td align=right>".$form->format_amount(\%myconfig, $ca->{credit}, 2, " ")."</td>\n"; + + $totaldebit += $ca->{debit}; + $totalcredit += $ca->{credit}; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| +</tr> +|; + } + + for (qw(accno gifi_accno description)) { $column_data{$_} = "<td> </td>" } + + $column_data{debit} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $totaldebit, 2, 0)."</th>"; + $column_data{credit} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $totalcredit, 2, 0)."</th>"; + + print "<tr class=listtotal>"; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| +</tr> +<tr> + <td colspan=$colspan><hr size=3 noshade></td> +</tr> +</table> + +</body> +</html> +|; + +} + + +sub list { + + $form->{title} = $locale->text('List Transactions'); + if ($form->{accounttype} eq 'gifi') { + $form->{title} .= " - ".$locale->text('GIFI')." $form->{gifi_accno} - $form->{gifi_description}"; + } else { + $form->{title} .= " - ".$locale->text('Account')." $form->{accno} - $form->{description}"; + } + + # get departments + $form->all_departments(\%myconfig); + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + $department = qq| + <tr> + <th align=right nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select></td> + </tr> +| if $form->{selectdepartment}; + + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=accno value=$form->{accno}> +<input type=hidden name=description value="$form->{description}"> + +<input type=hidden name=sort value=transdate> +<input type=hidden name=oldsort value=transdate> + +<input type=hidden name=accounttype value=$form->{accounttype}> +<input type=hidden name=gifi_accno value=$form->{gifi_accno}> +<input type=hidden name=gifi_description value="$form->{gifi_description}"> + +<table border=0 width=100%> + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr + <tr valign=top> + <td> + <table> + $department + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=fromdate size=11 title="$myconfig{dateformat}"></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + <tr> + <th align=right>|.$locale->text('Include in Report').qq|</th> + <td colspan=3> + <input name=l_accno class=checkbox type=checkbox value=Y> |.$locale->text('AR/AP').qq| + <input name=l_subtotal class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq| + </td> + </tr> + </table> + </td> + </tr> + <tr><td><hr size=3 noshade></td></tr> +</table> + +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<br><input class=submit type=submit name=action value="|.$locale->text('List Transactions').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub list_transactions { + + CA->all_transactions(\%myconfig, \%$form); + + $department = $form->escape($form->{department}); + $projectnumber = $form->escape($form->{projectnumber}); + $title = $form->escape($form->{title}); + + # construct href + $href = "$form->{script}?action=list_transactions&department=$department&projectnumber=$projectnumber&title=$title"; + for (qw(path oldsort accno login sessionid fromdate todate accounttype gifi_accno l_heading l_subtotal l_accno)) { $href .= "&$_=$form->{$_}" } + + $drilldown = $href; + $drilldown .= "&sort=$form->{sort}"; + + $href .= "&direction=$form->{direction}"; + + $form->sort_order(); + + $drilldown .= "&direction=$form->{direction}"; + + $form->{prevreport} = $href unless $form->{prevreport}; + $href .= "&prevreport=".$form->escape($form->{prevreport}); + $drilldown .= "&prevreport=".$form->escape($form->{prevreport}); + + # figure out which column comes first + $column_header{transdate} = qq|<th><a class=listheading href=$href&sort=transdate>|.$locale->text('Date').qq|</a></th>|; + $column_header{reference} = qq|<th><a class=listheading href=$href&sort=reference>|.$locale->text('Reference').qq|</a></th>|; + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + $column_header{cleared} = qq|<th class=listheading>|.$locale->text('R').qq|</th>|; + $column_header{source} = qq|<th class=listheading>|.$locale->text('Source').qq|</th>|; + $column_header{debit} = qq|<th class=listheading>|.$locale->text('Debit').qq|</th>|; + $column_header{credit} = qq|<th class=listheading>|.$locale->text('Credit').qq|</th>|; + $column_header{balance} = qq|<th class=listheading>|.$locale->text('Balance').qq|</th>|; + $column_header{accno} = qq|<th class=listheading>|.$locale->text('AR/AP').qq|</th>|; + + @columns = qw(transdate reference description debit credit); + if ($form->{link} =~ /_paid/) { + @columns = qw(transdate reference description source cleared debit credit); + } + push @columns, "accno" if $form->{l_accno}; + @column_index = $form->sort_columns(@columns); + + + if ($form->{accounttype} eq 'gifi') { + for (qw(accno description)) { $form->{$_} = $form->{"gifi_$_"} } + } + if ($form->{accno}) { + push @column_index, "balance"; + } + + $form->{title} = ($form->{accounttype} eq 'gifi') ? $locale->text('GIFI') : $locale->text('Account'); + + $form->{title} .= " $form->{accno} - $form->{description}"; + + if ($form->{department}) { + ($department) = split /--/, $form->{department}; + $options = $locale->text('Department')." : $department<br>"; + } + if ($form->{projectnumber}) { + ($projectnumber) = split /--/, $form->{projectnumber}; + $options .= $locale->text('Project Number')." : $projectnumber<br>"; + } + + + if ($form->{fromdate} || $form->{todate}) { + + if ($form->{fromdate}) { + $fromdate = $locale->date(\%myconfig, $form->{fromdate}, 1); + } + if ($form->{todate}) { + $todate = $locale->date(\%myconfig, $form->{todate}, 1); + } + + $form->{period} = "$fromdate - $todate"; + } else { + $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1); + } + + $form->{period} = "<a href=$form->{prevreport}>$form->{period}</a>" if $form->{prevreport}; + + $options .= $form->{period}; + + + # construct callback + $department = $form->escape($form->{department},1); + $projectnumber = $form->escape($form->{projectnumber},1); + $title = $form->escape($form->{title},1); + $form->{prevreport} = $form->escape($form->{prevreport},1); + + $form->{callback} = "$form->{script}?action=list_transactions&department=$department&projectnumber=$projectnumber&title=$title"; + for (qw(path direction oldsort accno login sessionid fromdate todate accounttype gifi_accno l_heading l_subtotal l_accno prevreport)) { $form->{callback} .= "&$_=$form->{$_}" } + + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$options</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + # add sort to callback + $form->{callback} = $form->escape($form->{callback} . "&sort=$form->{sort}"); + + if (@{ $form->{CA} }) { + $sameitem = $form->{CA}->[0]->{$form->{sort}}; + } + + $ml = ($form->{category} =~ /(A|E)/) ? -1 : 1; + $ml *= -1 if $form->{contra}; + + if ($form->{accno} && $form->{balance}) { + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</td>"; + + $i++; $i %= 2; + + print qq| + <tr class=listrow$i> +|; + for (@column_index) { print "$column_data{$_}\n" } + print qq| + </tr> +|; + + } + + foreach $ca (@{ $form->{CA} }) { + + if ($form->{l_subtotal} eq 'Y') { + if ($sameitem ne $ca->{$form->{sort}}) { + &ca_subtotal; + } + } + + # construct link to source + $href = "<a href=$ca->{module}.pl?path=$form->{path}&action=edit&id=$ca->{id}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$form->{callback}>$ca->{reference}</a>"; + + + $column_data{debit} = "<td align=right>".$form->format_amount(\%myconfig, $ca->{debit}, 2, " ")."</td>"; + $column_data{credit} = "<td align=right>".$form->format_amount(\%myconfig, $ca->{credit}, 2, " ")."</td>"; + + $form->{balance} += $ca->{amount}; + $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</td>"; + + $subtotaldebit += $ca->{debit}; + $subtotalcredit += $ca->{credit}; + + $totaldebit += $ca->{debit}; + $totalcredit += $ca->{credit}; + + $column_data{transdate} = qq|<td>$ca->{transdate}</td>|; + $column_data{reference} = qq|<td>$href</td>|; + $column_data{description} = qq|<td>$ca->{description} </td>|; + + $column_data{cleared} = ($ca->{cleared}) ? qq|<td>*</td>| : qq|<td> </td>|; + $column_data{source} = qq|<td>$ca->{source} </td>|; + + $column_data{accno} = qq|<td>|; + for (@{ $ca->{accno} }) { $column_data{accno} .= "<a href=$drilldown&accno=$_>$_</a> " } + $column_data{accno} .= qq| </td>|; + + if ($ca->{id} != $sameid) { + $i++; $i %= 2; + } + $sameid = $ca->{id}; + + print qq| + <tr class=listrow$i> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + } + + + if ($form->{l_subtotal} eq 'Y') { + &ca_subtotal; + } + + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{debit} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $totaldebit, 2, " ")."</th>"; + $column_data{credit} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $totalcredit, 2, " ")."</th>"; + $column_data{balance} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</th>"; + + print qq| + <tr class=listtotal> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +</body> +</html> +|; + +} + + +sub ca_subtotal { + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{debit} = "<th align=right class=listsubtotal>".$form->format_amount(\%myconfig, $subtotaldebit, 2, " ") . "</th>"; + $column_data{credit} = "<th align=right class=listsubtotal>".$form->format_amount(\%myconfig, $subtotalcredit, 2, " ") . "</th>"; + + $subtotaldebit = 0; + $subtotalcredit = 0; + + $sameitem = $ca->{$form->{sort}}; + + print qq| + <tr class=listsubtotal> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + +} + diff --git a/bin/lynx/cp.pl b/bin/lynx/cp.pl new file mode 100755 index 00000000..e7303904 --- /dev/null +++ b/bin/lynx/cp.pl @@ -0,0 +1,1392 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2002 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Payment module +# +#====================================================================== + + +use SL::CP; +use SL::OP; +use SL::IS; +use SL::IR; + +require "$form->{path}/arap.pl"; + +1; +# end of main + + +sub payment { + + if ($form->{type} eq 'receipt') { + $form->{ARAP} = "AR"; + $form->{arap} = "ar"; + $form->{vc} = "customer"; + $form->{formname} = "receipt"; + } + if ($form->{type} eq 'check') { + $form->{ARAP} = "AP"; + $form->{arap} = "ap"; + $form->{vc} = "vendor"; + $form->{formname} = "check"; + } + + $form->{payment} = "payment"; + + $form->{callback} = "$form->{script}?action=payment&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&all_vc=$form->{all_vc}&type=$form->{type}"; + + # setup customer/vendor selection for open invoices + if ($form->{all_vc}) { + $form->all_vc(\%myconfig, $form->{vc}, $form->{ARAP}, undef, $form->{datepaid}); + } else { + CP->get_openvc(\%myconfig, \%$form); + if ($myconfig{vclimit} > 0) { + $form->{"all_$form->{vc}"} = $form->{name_list}; + } + } + + $form->{"select$form->{vc}"} = ""; + if (@{ $form->{"all_$form->{vc}"} }) { + $form->{"$form->{vc}_id"} = $form->{"all_$form->{vc}"}->[0]->{id}; + for (@{ $form->{"all_$form->{vc}"} }) { $form->{"select$form->{vc}"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + $form->{department} = "$form->{department}--$form->{department_id}" if $form->{department}; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + CP->paymentaccounts(\%myconfig, \%$form); + + $form->{selectaccount} = ""; + $form->{"select$form->{ARAP}"} = ""; + + for (@{ $form->{PR}{"$form->{ARAP}_paid"} }) { $form->{selectaccount} .= "<option>$_->{accno}--$_->{description}\n" } + for (@{ $form->{PR}{$form->{ARAP}} }) { $form->{"select$form->{ARAP}"} .= "<option>$_->{accno}--$_->{description}\n" } + + # currencies + @curr = split /:/, $form->{currencies}; + $form->{defaultcurrency} = $curr[0]; + chomp $form->{defaultcurrency}; + + $form->{selectcurrency} = ""; + for (@curr) { $form->{selectcurrency} .= "<option>$_\n" } + + $form->{currency} = $form->{defaultcurrency}; + $form->{oldcurrency} = $form->{currency}; + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->{forex} = $form->{exchangerate} = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{datepaid}, ($form->{vc} eq 'customer') ? "buy" : "sell"); + } + + $form->{olddatepaid} = $form->{datepaid}; + + $form->{media} = $myconfig{printer}; + $form->{format} = "pdf" unless $myconfig{printer}; + + &payment_header; + &payment_footer; + +} + + +sub payments { + + if ($form->{type} eq 'receipt') { + $form->{ARAP} = "AR"; + $form->{arap} = "ar"; + $form->{vc} = "customer"; + $form->{formname} = "receipt"; + } + if ($form->{type} eq 'check') { + $form->{ARAP} = "AP"; + $form->{arap} = "ap"; + $form->{vc} = "vendor"; + $form->{formname} = "check"; + } + + $form->{payment} = "payments"; + + $form->{callback} = "$form->{script}?action=$form->{action}"; + for (qw(path login sessionid type)) { $form->{callback} .= "&$_=$form->{$_}" } + + CP->paymentaccounts(\%myconfig, \%$form); + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + $form->{department} = "$form->{department}--$form->{department_id}" if $form->{department}; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + $form->{selectaccount} = ""; + $form->{"select$form->{ARAP}"} = ""; + + for (@{ $form->{PR}{"$form->{ARAP}_paid"} }) { $form->{selectaccount} .= "<option>$_->{accno}--$_->{description}\n" } + for (@{ $form->{PR}{$form->{ARAP}} }) { $form->{"select$form->{ARAP}"} .= "<option>$_->{accno}--$_->{description}\n" } + + # currencies + @curr = split /:/, $form->{currencies}; + $form->{defaultcurrency} = $curr[0]; + chomp $form->{defaultcurrency}; + + $form->{selectcurrency} = ""; + for (@curr) { $form->{selectcurrency} .= "<option>$_\n" } + + $form->{oldcurrency} = $form->{currency} = $form->{defaultcurrency}; + $form->{oldduedateto} = $form->{datepaid}; + + $form->{media} = $myconfig{printer}; + $form->{format} = "pdf" unless $myconfig{printer}; + + &payments_header; + &invoices_due; + &payments_footer; + +} + + +sub payments_header { + + if ($form->{type} eq 'receipt') { + $form->{title} = $locale->text('Receipts'); + } + if ($form->{type} eq 'check') { + $form->{title} = $locale->text('Payments'); + } + + + for ("department") { + $form->{"select$_"} = $form->unescape($form->{"select$_"}); + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + for ("account", "currency", "$form->{ARAP}") { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/option>\Q$form->{$_}\E/option selected>$form->{$_}/; + } + + if ($form->{defaultcurrency}) { + $exchangerate = qq| + <tr> + <th align=right nowrap>|.$locale->text('Currency').qq|</th> + <td><select name=currency>$form->{selectcurrency}</select></td> + <input type=hidden name=selectcurrency value="$form->{selectcurrency}"> + <input type=hidden name=oldcurrency value=$form->{oldcurrency}> + </tr> +|; + } + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate}); + + if ($form->{forex}) { + $exchangerate .= qq| + <tr> + <th align=right nowrap>|.$locale->text('Exchange Rate').qq|</th> + <td colspan=3><input type=hidden name=exchangerate size=10 value=$form->{exchangerate}>$form->{exchangerate}</td> + </tr> +|; + } else { + $exchangerate .= qq| + <tr> + <th align=right nowrap>|.$locale->text('Exchange Rate').qq|</th> + <td colspan=3><input name=exchangerate size=10 value=$form->{exchangerate}></td> + </tr> +|; + } + } + + $department = qq| + <tr> + <th align="right" nowrap>|.$locale->text('Department').qq|</th> + <td><select name=department>$form->{selectdepartment}</select> + <input type=hidden name=selectdepartment value="|.$form->escape($form->{selectdepartment},1).qq|"> + </td> + </tr> +| if $form->{selectdepartment}; + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(defaultcurrency closedto vc type formname arap ARAP title oldduedatefrom oldduedateto payment olddepartment)); + + print qq| +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Due Date').qq| |.$locale->text('From').qq|</th> + <td><input name=duedatefrom value="$form->{duedatefrom}" title="$myconfig{dateformat}" size=11></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=duedateto value="$form->{duedateto}" title="$myconfig{dateformat}" size=11></td> + </tr> + </table> + </td> + </td> + <td align=right> + <table> + $department + <tr> + <th align=right nowrap>|.$locale->text($form->{ARAP}).qq|</th> + <td colspan=3><select name=$form->{ARAP}>$form->{"select$form->{ARAP}"}</select> + </td> + <input type=hidden name="select$form->{ARAP}" value="$form->{"select$form->{ARAP}"}"> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Account').qq|</th> + <td colspan=3><select name=account>$form->{selectaccount}</select> + <input type=hidden name=selectaccount value="$form->{selectaccount}"> + </td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Date').qq|</th> + <td><input name=datepaid value="$form->{datepaid}" title="$myconfig{dateformat}" size=11></td> + </tr> + $exchangerate + </table> + </td> + </tr> + </table> + </td> + </tr> +|; + +} + + +sub invoices_due { + + @column_index = qw(name invnumber transdate amount due checked paid memo source); + push @column_index, "language" if $form->{selectlanguage}; + + $colspan = $#column_index + 1; + + $invoice = $locale->text('Invoices'); + $vclabel = ucfirst $form->{vc}; + $vclabel = $locale->text($vclabel); + + print qq| + <input type=hidden name=column_index value="id @column_index"> + <tr> + <td> + <table width=100%> + <tr> + <th class=listheading colspan=$colspan>$invoice</th> + </tr> +|; + + $column_data{name} = qq|<th nowrap>$vclabel</th>|; + $column_data{invnumber} = qq|<th nowrap>|.$locale->text('Invoice')."</th>"; + $column_data{transdate} = qq|<th nowrap>|.$locale->text('Date')."</th>"; + $column_data{amount} = qq|<th nowrap>|.$locale->text('Amount')."</th>"; + $column_data{due} = qq|<th nowrap>|.$locale->text('Amount Due')."</th>"; + $column_data{paid} = qq|<th nowrap>|.$locale->text('Amount')."</th>"; + $column_data{checked} = qq|<th nowrap>|.$locale->text('Select')."</th>"; + $column_data{memo} = qq|<th nowrap>|.$locale->text('Memo')."</th>"; + $column_data{source} = qq|<th nowrap>|.$locale->text('Source')."</th>"; + $column_data{language} = qq|<th nowrap>|.$locale->text('Language')."</th>"; + + print qq| + <tr> +|; + for (@column_index) { print "$column_data{$_}\n" } + print qq| + </tr> +|; + + $form->{selectlanguage} = $form->unescape($form->{selectlanguage}); + + for $i (1 .. $form->{rowcount}) { + + for (qw(amount due paid)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + $totalamount += $form->{"amount_$i"}; + $totaldue += $form->{"due_$i"}; + $totalpaid += $form->{"paid_$i"}; + + for (qw(amount due paid)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } + + $column_data{invnumber} = qq|<td>$form->{"invnumber_$i"}</td> + <input type=hidden name="invnumber_$i" value="$form->{"invnumber_$i"}"> + <input type=hidden name="id_$i" value=$form->{"id_$i"}>|; + $column_data{transdate} = qq|<td>$form->{"transdate_$i"}</td> + <input type=hidden name="transdate_$i" value=$form->{"transdate_$i"}>|; + $column_data{amount} = qq|<td align=right>$form->{"amount_$i"}</td> + <input type=hidden name="amount_$i" value=$form->{"amount_$i"}>|; + $column_data{due} = qq|<td align=right>$form->{"due_$i"}</td> + <input type=hidden name="due_$i" value=$form->{"due_$i"}>|; + + $column_data{paid} = qq|<td align=right><input name="paid_$i" size=10 value=$form->{"paid_$i"}></td>|; + + if ($same_id eq $form->{"$form->{vc}_id_$i"}) { + for (qw(name memo source language)) { $column_data{$_} = qq|<td> </td>| } + } else { + $column_data{name} = qq|<td>$form->{"name_$i"}</td>|; + $column_data{memo} = qq|<td align=right><input name="memo_$i" size=10 value="$form->{"memo_$i"}"></td>|; + $column_data{source} = qq|<td align=right><input name="source_$i" size=10 value="$form->{"source_$i"}"></td>|; + + if ($form->{selectlanguage}) { + $selectlanguage = $form->{selectlanguage}; + $selectlanguage =~ s/(<option value="\Q$form->{"language_code_$i"}\E")/$1 selected/; + $column_data{language} = qq|<td><select name="language_code_$i">$selectlanguage</select></td>|; + } + + } + + $column_data{name} .= qq| + <input type=hidden name="name_$i" value="$form->{"name_$i"}"> + <input type=hidden name="$form->{vc}_id_$i" value="$form->{"$form->{vc}_id_$i"}">|; + + $form->{"checked_$i"} = ($form->{"checked_$i"}) ? "checked" : ""; + $column_data{checked} = qq|<td align=center><input name="checked_$i" type=checkbox class=checkbox $form->{"checked_$i"}></td>|; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j> +|; + for (@column_index) { print "$column_data{$_}\n" } + print qq| + </tr> +|; + + $same_id = $form->{"$form->{vc}_id_$i"}; + + } + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{amount} = qq|<th class=listtotal align=right>|.$form->format_amount(\%myconfig, $totalamount, 2, " ").qq|</th>|; + $column_data{due} = qq|<th class=listtotal align=right>|.$form->format_amount(\%myconfig, $totaldue, 2, " ").qq|</th>|; + $column_data{paid} = qq|<th class=listtotal align=right>|.$form->format_amount(\%myconfig, $totalpaid, 2, " ").qq|</th>|; + + print qq| + <tr class=listtotal> +|; + for (@column_index) { print "$column_data{$_}\n" } + print qq| + </tr> + </table> + </td> + </tr> +<input type=hidden name=selectlanguage value="|.$form->escape($form->{selectlanguage},1).qq|"> +|; + +} + + +sub payments_footer { + + $form->{DF}{$form->{format}} = "selected"; + + $transdate = $form->datetonum(\%myconfig, $form->{datepaid}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + + if ($latex) { + + $media = qq|<select name=media> + <option value=screen>|.$locale->text('Screen'); + + if (%printer) { + for (sort keys %printer) { $media .= qq| + <option value="$_">$_| } + } + + $media .= qq|</select>|; + $format = qq|<select name=format> + <option value=postscript $form->{DF}{postscript}>|.$locale->text('Postscript').qq| + <option value=pdf $form->{DF}{pdf}>|.$locale->text('PDF').qq|</select>|; + } + + print qq| + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +# type=submit $locale->text('Update') +# type=submit $locale->text('Post') +# type=submit $locale->text('Print') +# type=submit $locale->text('Select all') + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Select all' => { ndx => 2, key => 'A', value => $locale->text('Select all') }, + 'Print' => { ndx => 3, key => 'P', value => $locale->text('Print') }, + 'Post' => { ndx => 4, key => 'O', value => $locale->text('Post') }, + ); + + if (! $latex) { + delete $button{'Print'}; + } + + if ($transdate <= $closedto) { + for ('Post', 'Print') { delete $button{$_} } + $media = $format = ""; + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/; + + print qq| + $format + $media +|; + + $form->hide_form(qw(callback rowcount path login sessionid)); + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub select_all { + + for (1 .. $form->{rowcount}) { $form->{"checked_$_"} = 1 } + &{"update_$form->{payment}"} + +} + + +sub update { + my ($new_name_selected) = @_; + + &{"update_$form->{payment}"}; + +} + + +sub update_payments { + + if ($form->{ARAP} eq 'AR') { + $buysell = "buy"; + } else { + $buysell = "sell"; + } + + if (($form->{oldduedatefrom} ne $form->{duedatefrom}) || ($form->{oldduedateto} ne $form->{duedateto}) || ($form->{department} ne $form->{olddepartment})) { + CP->get_openinvoices(\%myconfig, \%$form); + $form->{redo} = 1; + } + + if ($form->{currency} ne $form->{oldcurrency}) { + $form->{oldcurrency} = $form->{currency}; + if (!$form->{redo}) { + CP->get_openinvoices(\%myconfig, \%$form); + $form->{redo} = 1; + } + } + + for (qw(duedatefrom duedateto department)) { $form->{"old$_"} = $form->{$_} } + + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{datepaid}, $buysell))); + + if ($form->{redo}) { + $form->{rowcount} = 0; + + $i = 0; + foreach $ref (@{ $form->{PR} }) { + $i++; + for (qw(id name invnumber transdate)) { $form->{"${_}_$i"} = $ref->{$_} } + $form->{"$form->{vc}_id_$i"} = $ref->{"$form->{vc}_id"}; + $ref->{exchangerate} = 1 unless $ref->{exchangerate}; + $form->{"amount_$i"} = $ref->{amount} / $ref->{exchangerate}; + $form->{"due_$i"} = ($ref->{amount} - $ref->{paid}) / $ref->{exchangerate}; + $form->{"checked_$i"} = ""; + $form->{"paid_$i"} = ""; + + # need to format + for (qw(amount due)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } + } + + $form->{rowcount} = $i; + } + + $form->{amount} = $form->parse_amount(\%myconfig, $form->{amount}); + + # recalculate + $amount = 0; + for $i (1 .. $form->{rowcount}) { + + for (qw(amount due paid)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + if ($form->{"checked_$i"}) { + # calculate paid_$i + if (!$form->{"paid_$i"}) { + $form->{"paid_$i"} = $form->{"due_$i"}; + } + + $amount += $form->{"paid_$i"}; + $form->{redo} = 1; + } else { + $form->{"paid_$i"} = ""; + } + + for (qw(amount due paid)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } + } + + $form->{amount} += ($amount - $form->{oldamount}) if $form->{redo}; + + &payments_header; + &invoices_due; + &payments_footer; + +} + + +sub update_payment { + + if ($form->{vc} eq 'customer') { + $buysell = "buy"; + } else { + $buysell = "sell"; + } + + $department = $form->{department}; + + # get customer/vendor + &check_openvc; + $form->{department} = $department; + + if ($form->{datepaid} ne $form->{olddatepaid}) { + $form->{olddatepaid} = $form->{datepaid}; + $form->{oldall_vc} = !$form->{oldall_vc} if $form->{all_vc}; + } + + if ($form->{department} ne $form->{olddepartment}) { + $form->{olddepartment} = $form->{department}; + $form->{redo} = 1; + } + + # if we switched to all_vc + if ($form->{all_vc} ne $form->{oldall_vc}) { + + if ($form->{"select$form->{vc}"}) { + $form->{redo} = ($form->{"old$name"} ne $form->{$name}); + } else { + $form->{redo} = ($form->{"old$name"} ne qq|$form->{$name}--$form->{"${name}_id"}|); + } + + $form->{"select$form->{vc}"} = ""; + + if ($form->{all_vc}) { + $form->all_vc(\%myconfig, $form->{vc}, $form->{ARAP}, undef, $form->{datepaid}); + + if (@{ $form->{"all_$form->{vc}"} }) { + for (@{ $form->{"all_$form->{vc}"} }) { $form->{"select$form->{vc}"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + } else { + if (($myconfig{vclimit} * 1) > 0) { + $form->{$form->{vc}} = ""; + } + + CP->get_openvc(\%myconfig, \%$form); + + if (($myconfig{vclimit} * 1) > 0) { + $form->{"all_$form->{vc}"} = $form->{name_list}; + } + + if (@{ $form->{"all_$form->{vc}"} }) { + $newvc = qq|$form->{"all_$form->{vc}"}[0]->{name}--$form->{"all_$form->{vc}"}[0]->{id}|; + for (@{ $form->{"all_$form->{vc}"} }) { $form->{"select$form->{vc}"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + + + # if the name is not the same + if ($form->{"select$form->{vc}"} !~ /$form->{$form->{vc}}/) { + $form->{$form->{vc}} = $newvc; + &check_openvc; + } + } + } + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + } + + if ($new_name_selected || $form->{redo}) { + CP->get_openinvoices(\%myconfig, \%$form); + ($newvc) = split /--/, $form->{$form->{vc}}; + $form->{"old$form->{vc}"} = qq|$newvc--$form->{"$form->{vc}_id"}|;; + $form->{redo} = 1; + } + + if ($form->{currency} ne $form->{oldcurrency}) { + $form->{oldcurrency} = $form->{currency}; + if (!$form->{redo}) { + CP->get_openinvoices(\%myconfig, \%$form); + $form->{redo} = 1; + } + } + + + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{datepaid}, $buysell))); + + if ($form->{redo}) { + $form->{rowcount} = 0; + + $i = 0; + foreach $ref (@{ $form->{PR} }) { + $i++; + $form->{"id_$i"} = $ref->{id}; + $form->{"invnumber_$i"} = $ref->{invnumber}; + $form->{"transdate_$i"} = $ref->{transdate}; + $ref->{exchangerate} = 1 unless $ref->{exchangerate}; + $form->{"amount_$i"} = $ref->{amount} / $ref->{exchangerate}; + $form->{"due_$i"} = ($ref->{amount} - $ref->{paid}) / $ref->{exchangerate}; + $form->{"checked_$i"} = ""; + $form->{"paid_$i"} = ""; + + # need to format + for (qw(amount due)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } + } + $form->{rowcount} = $i; + } + + $form->{amount} = $form->parse_amount(\%myconfig, $form->{amount}); + + # recalculate + $amount = 0; + for $i (1 .. $form->{rowcount}) { + + for (qw(amount due paid)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + if ($form->{"checked_$i"}) { + # calculate paid_$i + if (!$form->{"paid_$i"}) { + $form->{"paid_$i"} = $form->{"due_$i"}; + } + + $amount += $form->{"paid_$i"}; + $form->{redo} = 1; + } else { + $form->{"paid_$i"} = ""; + } + + for (qw(amount due paid)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } + } + + $form->{amount} += ($amount - $form->{oldamount}) if $form->{redo}; + + &payment_header; + &list_invoices; + &payment_footer; + +} + + + + +sub payment_header { + + $vclabel = ucfirst $form->{vc}; + $vclabel = $locale->text($vclabel); + + if ($form->{type} eq 'receipt') { + $form->{title} = $locale->text('Receipt'); + } + if ($form->{type} eq 'check') { + $form->{title} = $locale->text('Payment'); + } + + +# $locale->text('Customer') +# $locale->text('Vendor') + + if ($form->{$form->{vc}} eq "") { + for (qw(address1 address2 city zipcode state country)) { $form->{$_} = "" } + } + + for ("$form->{vc}", "department") { + $form->{"select$_"} = $form->unescape($form->{"select$_"}); + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + for ("account", "currency", "$form->{ARAP}") { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/option>\Q$form->{$_}\E/option selected>$form->{$_}/; + } + + if ($form->{defaultcurrency}) { + $exchangerate = qq| + <tr> + <th align=right nowrap>|.$locale->text('Currency').qq|</th> + <td><select name=currency>$form->{selectcurrency}</select></td> + <input type=hidden name=selectcurrency value="$form->{selectcurrency}"> + <input type=hidden name=oldcurrency value=$form->{oldcurrency}> + </tr> +|; + } + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate}); + + if ($form->{forex}) { + $exchangerate .= qq| + <tr> + <th align=right nowrap>|.$locale->text('Exchange Rate').qq|</th> + <td colspan=3><input type=hidden name=exchangerate size=10 value=$form->{exchangerate}>$form->{exchangerate}</td> + </tr> +|; + } else { + $exchangerate .= qq| + <tr> + <th align=right nowrap>|.$locale->text('Exchange Rate').qq|</th> + <td colspan=3><input name=exchangerate size=10 value=$form->{exchangerate}></td> + </tr> +|; + } + } + + $vc = ($form->{"select$form->{vc}"}) ? qq|<select name=$form->{vc}>$form->{"select$form->{vc}"}\n</select>| : qq|<input name=$form->{vc} size=35 value="$form->{$form->{vc}}">|; + + if ($form->{all_vc}) { + $allvc = "checked"; + } else { + $allvc = ""; + } + +# $locale->text('AR') +# $locale->text('AP') + + $department = qq| + <tr> + <th align="right" nowrap>|.$locale->text('Department').qq|</th> + <td><select name=department>$form->{selectdepartment}</select> + <input type=hidden name=selectdepartment value="|.$form->escape($form->{selectdepartment},1).qq|"> + </td> + </tr> +| if $form->{selectdepartment}; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(defaultcurrency closedto vc type ARAP arap title formname payment olddepartment)); + + print qq| + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> + <td align=right> + <input name=all_vc type=checkbox class=checkbox value=Y $allvc> + <input type=hidden name="oldall_vc" value="$form->{all_vc}"></td> + <th align=left>|.$locale->text('All').qq|</th> + </tr> + <tr> + <th align=right>$vclabel</th> + <td>$vc</td> + <input type=hidden name="select$form->{vc}" value="|.$form->escape($form->{"select$form->{vc}"},1).qq|"> + <input type=hidden name="$form->{vc}_id" value=$form->{"$form->{vc}_id"}> + <input type=hidden name="old$form->{vc}" value="$form->{"old$form->{vc}"}"> + </tr> + <tr valign=top> + <th align=right nowrap>|.$locale->text('Address').qq|</th> + <td colspan=2> + <table> + <tr> + <td>$form->{address1}</td> + </tr> + <tr> + <td>$form->{address2}</td> + </tr> + <td>$form->{city}</td> + </tr> + </tr> + <td>$form->{state}</td> + </tr> + </tr> + <td>$form->{zipcode}</td> + </tr> + <tr> + <td>$form->{country}</td> + </tr> + </table> + </td> + <input type=hidden name=address1 value="$form->{address1}"> + <input type=hidden name=address2 value="$form->{address2}"> + <input type=hidden name=city value="$form->{city}"> + <input type=hidden name=state value="$form->{state}"> + <input type=hidden name=zipcode value="$form->{zipcode}"> + <input type=hidden name=country value="$form->{country}"> + </tr> + <tr> + <th align=right>|.$locale->text('Memo').qq|</th> + <td colspan=2><input name="memo" size=30 value="$form->{memo}"></td> + </tr> + </table> + </td> + <td align=right> + <table> + $department + <tr> + <th align=right nowrap>|.$locale->text($form->{ARAP}).qq|</th> + <td colspan=3><select name=$form->{ARAP}>$form->{"select$form->{ARAP}"}</select> + </td> + <input type=hidden name="select$form->{ARAP}" value="$form->{"select$form->{ARAP}"}"> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Account').qq|</th> + <td colspan=3><select name=account>$form->{selectaccount}</select> + <input type=hidden name=selectaccount value="$form->{selectaccount}"> + </td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Date').qq|</th> + <td><input name=datepaid value="$form->{datepaid}" title="$myconfig{dateformat}" size=11></td> + <input type=hidden name=olddatepaid value=$form->{olddatepaid}> + </tr> + $exchangerate + <tr> + <th align=right nowrap>|.$locale->text('Source').qq|</th> + <td colspan=3><input name=source value="$form->{source}" size=10></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Amount').qq|</th> + <td colspan=3><input name=amount size=10 value=|.$form->format_amount(\%myconfig, $form->{amount}, 2).qq|></td> + <input type=hidden name=oldamount value=$form->{amount}> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> +|; + +} + + +sub list_invoices { + + @column_index = qw(invnumber transdate amount due checked paid); + + $colspan = $#column_index + 1; + + $invoice = $locale->text('Invoices'); + + print qq| + <input type=hidden name=column_index value="id @column_index"> + <tr> + <td> + <table width=100%> + <tr> + <th class=listheading colspan=$colspan>$invoice</th> + </tr> +|; + + $column_data{invnumber} = qq|<th nowrap>|.$locale->text('Invoice')."</th>"; + $column_data{transdate} = qq|<th nowrap>|.$locale->text('Date')."</th>"; + $column_data{amount} = qq|<th nowrap>|.$locale->text('Amount')."</th>"; + $column_data{due} = qq|<th nowrap>|.$locale->text('Amount Due')."</th>"; + $column_data{paid} = qq|<th nowrap>|.$locale->text('Amount')."</th>"; + $column_data{checked} = qq|<th nowrap>|.$locale->text('Select')."</th>"; + + print qq| + <tr> +|; + for (@column_index) { print "$column_data{$_}\n" } + print qq| + </tr> +|; + + for $i (1 .. $form->{rowcount}) { + + for (qw(amount due paid)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + $totalamount += $form->{"amount_$i"}; + $totaldue += $form->{"due_$i"}; + $totalpaid += $form->{"paid_$i"}; + + for (qw(amount due paid)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } + + $column_data{invnumber} = qq|<td>$form->{"invnumber_$i"}</td> + <input type=hidden name="invnumber_$i" value="$form->{"invnumber_$i"}"> + <input type=hidden name="id_$i" value=$form->{"id_$i"}>|; + $column_data{transdate} = qq|<td width=15%>$form->{"transdate_$i"}</td> + <input type=hidden name="transdate_$i" value=$form->{"transdate_$i"}>|; + $column_data{amount} = qq|<td align=right width=15%>$form->{"amount_$i"}</td> + <input type=hidden name="amount_$i" value=$form->{"amount_$i"}>|; + $column_data{due} = qq|<td align=right width=15%>$form->{"due_$i"}</td> + <input type=hidden name="due_$i" value=$form->{"due_$i"}>|; + + $column_data{paid} = qq|<td align=right width=15%><input name="paid_$i" size=10 value=$form->{"paid_$i"}></td>|; + + $form->{"checked_$i"} = ($form->{"checked_$i"}) ? "checked" : ""; + $column_data{checked} = qq|<td align=center width=10%><input name="checked_$i" type=checkbox class=checkbox $form->{"checked_$i"}></td>|; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j> +|; + for (@column_index) { print "$column_data{$_}\n" } + print qq| + </tr> +|; + } + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{amount} = qq|<th class=listtotal align=right>|.$form->format_amount(\%myconfig, $totalamount, 2, " ").qq|</th>|; + $column_data{due} = qq|<th class=listtotal align=right>|.$form->format_amount(\%myconfig, $totaldue, 2, " ").qq|</th>|; + $column_data{paid} = qq|<th class=listtotal align=right>|.$form->format_amount(\%myconfig, $totalpaid, 2, " ").qq|</th>|; + + print qq| + <tr class=listtotal> +|; + for (@column_index) { print "$column_data{$_}\n" } + print qq| + </tr> + </table> + </td> + </tr> +|; + +} + + +sub payment_footer { + + $form->{DF}{$form->{format}} = "selected"; + + $transdate = $form->datetonum(\%myconfig, $form->{datepaid}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + + if ($latex) { + if ($form->{selectlanguage}) { + $form->{"selectlanguage"} = $form->unescape($form->{"selectlanguage"}); + $form->{"selectlanguage"} =~ s/ selected//; + $form->{"selectlanguage"} =~ s/(<option value="\Q$form->{language_code}\E")/$1 selected/; + $lang = qq|<select name=language_code>$form->{selectlanguage}</select> + <input type=hidden name=selectlanguage value="|. + $form->escape($form->{selectlanguage},1).qq|">|; + } + + $media = qq|<select name=media> + <option value=screen>|.$locale->text('Screen'); + + if (%printer) { + for (sort keys %printer) { $media .= qq| + <option value="$_">$_| } + } + + $media .= qq|</select>|; + $format = qq|<select name=format> + <option value=postscript $form->{DF}{postscript}>|.$locale->text('Postscript').qq| + <option value=pdf $form->{DF}{pdf}>|.$locale->text('PDF').qq|</select>|; + } + + print qq| + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Select all' => { ndx => 2, key => 'A', value => $locale->text('Select all') }, + 'Print' => { ndx => 3, key => 'P', value => $locale->text('Print') }, + 'Post' => { ndx => 4, key => 'O', value => $locale->text('Post') }, + ); + + if (! $latex) { + delete $button{'Print'}; + } + + if ($transdate <= $closedto) { + for ('Post', 'Print') { delete $button{$_} } + $media = $format = ""; + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/; + + print qq| + $lang + $format + $media +|; + + $form->hide_form(qw(callback rowcount path login sessionid)); + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub post { &{"post_$form->{payment}"} } + + +sub post_payments { + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->error($locale->text('Exchange rate missing!')) unless $form->{exchangerate}; + } + + if (CP->post_payments(\%myconfig, \%$form)) { + $form->redirect($locale->text('Payments posted!')); + } else { + $form->error($locale->text('Posting failed!')); + } + +} + + +sub post_payment { + + &check_form; + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->error($locale->text('Exchange rate missing!')) unless $form->{exchangerate}; + } + + $msg1 = "$form->{title} posted!"; + $msg2 = "Cannot post $form->{title}!"; + +# $locale->text('Payment posted!') +# $locale->text('Receipt posted!') +# $locale->text('Cannot post Payment!') +# $locale->text('Cannot post Receipt!') + + + $form->{amount} = $form->format_amount(\%myconfig, $form->{amount}, 2); + + $source = $form->{source}; + $source =~ s/(\d+)/$1 + 1/e; + + if ($form->{callback}) { + $form->{callback} .= "&source=$source"; + } + + if (CP->post_payment(\%myconfig, \%$form)) { + $form->redirect($locale->text($msg1)); + } else { + $form->error($locale->text($msg2)); + } + +} + + +sub print { + + &{ "print_$form->{payment}" }; + &update if $form->{media} ne 'screen'; + +} + + +sub print_payments { + + $form->error($locale->text('Select postscript or PDF!')) if ($form->{format} !~ /(postscript|pdf)/); + + $SIG{INT} = 'IGNORE'; + + for (qw(company address)) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/\n/g; + + %oldform = (); + for (keys %$form) { $oldform{$_} = $form->{$_} }; + + @a = qw(name company address text_amount text_decimal address1 address2 city state zipcode country memo); + for (@a) { $temp{$_} = $form->{$_} } + + $form->format_string(@a); + + $ok = 0; + $j = 0; + $temp{rowcount} = $form->{rowcount}; + + for $i (1 .. $temp{rowcount}) { + + if ($form->{"$form->{vc}_id_$i"} ne $form->{"$form->{vc}_id"}) { + + $form->{rowcount} = $j; + for (1 .. $j) { $form->{"id_$_"} = $temp{"id_$_"} } + &print_form if $ok; + + $ok = 0; + $j = 0; + $form->{amount} = 0; + for (qw(invnumber invdate due paid)) { @{ $form->{$_} } = () } + for (qw(language_code source memo)) { $form->{$_} = $form->{"${_}_$i"} } + + } + + if ($form->{"checked_$i"}) { + $j++; + $ok = 1; + $temp{"id_$j"} = $form->{"id_$i"}; + $form->{"invdate_$i"} = $form->{"transdate_$i"}; + for (qw(invnumber invdate due paid)) { push @{ $form->{$_} }, $form->{"${_}_$i"} } + $form->{amount} += $form->parse_amount(\%myconfig, $form->{"paid_$i"}); + $form->{"$form->{vc}_id"} = $form->{"$form->{vc}_id_$i"}; + } + + } + + $form->{rowcount} = $j; + for (1 .. $j) { $form->{"id_$_"} = $temp{"id_$_"} } + + &print_form if $ok; + + for (keys %oldform) { $form->{$_} = $oldform{$_} } + +} + + +sub print_form { + + $c = CP->new(($form->{language_code}) ? $form->{language_code} : $myconfig{countrycode}); + $c->init; + + ($whole, $form->{decimal}) = split /\./, $form->{amount}; + $form->{amount} = $form->format_amount(\%myconfig, $form->{amount}, 2); + $form->{decimal} .= "00"; + $form->{decimal} = substr($form->{decimal}, 0, 2); + $form->{text_decimal} = $c->num2text($form->{decimal} * 1); + $form->{text_amount} = $c->num2text($whole); + $form->{integer_amount} = $form->format_amount($myconfig, $whole); + + $datepaid = $form->datetonum(\%myconfig, $form->{datepaid}); + ($form->{yyyy}, $form->{mm}, $form->{dd}) = $datepaid =~ /(....)(..)(..)/; + + &{ "$form->{vc}_details" }; + + $form->{templates} = "$myconfig{templates}"; + $form->{IN} = "$form->{formname}.tex"; + + if ($form->{media} ne 'screen') { + $form->{OUT} = "| $printer{$form->{media}}"; + } + + $form->parse_template(\%myconfig, $userspath); + +} + + +sub print_payment { + + &check_form; + + for (qw(company address)) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/\n/g; + + @a = qw(name company address text_amount text_decimal address1 address2 city state zipcode country memo); + + %temp = (); + for (@a) { $temp{$_} = $form->{$_} } + + $form->format_string(@a); + + &print_form; + + for (keys %temp) { $form->{$_} = $temp{$_} } + +} + + +sub customer_details { IS->customer_details(\%myconfig, \%$form) }; +sub vendor_details { IR->vendor_details(\%myconfig, \%$form) }; + + +sub check_form { + + &check_openvc; + + if ($form->{currency} ne $form->{oldcurrency}) { + &update; + exit; + } + + $form->error($locale->text('Date missing!')) unless $form->{datepaid}; + + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + $datepaid = $form->datetonum(\%myconfig, $form->{datepaid}); + + $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto); + + # this is just to format the year + $form->{datepaid} = $locale->date(\%myconfig, $form->{datepaid}); + + $amount = $form->parse_amount(\%myconfig, $form->{amount}); + $form->{amount} = $amount; + + for $i (1 .. $form->{rowcount}) { + if ($form->{"paid_$i"}) { + $amount -= $form->parse_amount(\%myconfig, $form->{"paid_$i"}); + + push(@{ $form->{paid} }, $form->{"paid_$i"}); + push(@{ $form->{due} }, $form->{"due_$i"}); + push(@{ $form->{invnumber} }, $form->{"invnumber_$i"}); + push(@{ $form->{invdate} }, $form->{"transdate_$i"}); + } + } + + if ($form->round_amount($amount, 2) != 0) { + push(@{ $form->{paid} }, $form->format_amount(\%myconfig, $amount, 2)); + push(@{ $form->{due} }, $form->format_amount(\%myconfig, 0, "0")); + push(@{ $form->{invnumber} }, ($form->{ARAP} eq 'AR') ? $locale->text('Deposit') : $locale->text('Prepayment')); + push(@{ $form->{invdate} }, $form->{datepaid}); + } + +} + + +sub check_openvc { + + $name = $form->{vc}; + ($new_name, $new_id) = split /--/, $form->{$name}; + + if ($form->{all_vc}) { + if ($form->{"select$name"}) { + $ok = ($form->{"old$name"} ne $form->{$name}); + } else { + $ok = ($form->{"old$name"} ne qq|$form->{$name}--$form->{"${name}_id"}|); + } + + if ($ok) { + $form->{redo} = 1; + if ($form->{"select$name"}) { + $form->{"${name}_id"} = $new_id; + AA->get_name(\%myconfig, \%$form); + $form->{$name} = $form->{"old$name"} = "$new_name--$new_id"; + } else { + &check_name($form->{vc}); + } + } + + } else { + + # if we use a selection + if ($form->{"select$name"}) { + if ($form->{"old$name"} ne $form->{$name}) { + + $form->{"${name}_id"} = $new_id; + AA->get_name(\%myconfig, \%$form); + + $form->{$name} = $form->{"old$name"} = "$new_name--$new_id"; + $form->{redo} = 1; + } + } else { + + # check name, combine name and id + if ($form->{"old$name"} ne qq|$form->{$name}--$form->{"${name}_id"}|) { + + # return one name or a list of names in $form->{name_list} + if (($rv = CP->get_openvc(\%myconfig, \%$form)) > 1) { + $form->{redo} = 1; + &select_name($name); + exit; + } + + if ($rv == 1) { + # we got one name + $form->{"${name}_id"} = $form->{name_list}[0]->{id}; + $form->{$name} = $form->{name_list}[0]->{name}; + $form->{"old$name"} = qq|$form->{$name}--$form->{"${name}_id"}|; + + AA->get_name(\%myconfig, \%$form); + + } else { + # nothing open + $form->error($locale->text('Nothing open!')); + } + + $form->{redo} = 1; + } + } + } + +} + + diff --git a/bin/lynx/ct.pl b/bin/lynx/ct.pl new file mode 100755 index 00000000..300fda0a --- /dev/null +++ b/bin/lynx/ct.pl @@ -0,0 +1,2478 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: Reed White <alta@alta-research.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# customer/vendor module +# +#====================================================================== + +use SL::CT; + +1; +# end of main + + + +sub add { + + $form->{title} = "Add"; +# $locale->text('Add Customer') +# $locale->text('Add Vendor') + + $form->{callback} = "$form->{script}?action=add&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + CT->create_links(\%myconfig, \%$form); + + &form_header; + &form_footer; + +} + + +sub history { + +# $locale->text('Customer History') +# $locale->text('Vendor History') + + $history = 1; + $label = ucfirst $form->{db}; + $label .= " History"; + + if ($form->{db} eq 'customer') { + $invlabel = $locale->text('Sales Invoices'); + $ordlabel = $locale->text('Sales Orders'); + $quolabel = $locale->text('Quotations'); + } else { + $invlabel = $locale->text('Vendor Invoices'); + $ordlabel = $locale->text('Purchase Orders'); + $quolabel = $locale->text('Request for Quotations'); + } + + $form->{title} = $locale->text($label); + + $form->{nextsub} = "list_history"; + + $transactions = qq| + <tr> + <td></td> + <td> + <table> + <tr> + <td> + <table> + <tr> + <td><input name=type type=radio class=radio value=invoice checked> $invlabel</td> + </tr> + <tr> + <td><input name=type type=radio class=radio value=order> $ordlabel</td> + </tr> + <tr> + <td><input name="type" type=radio class=radio value=quotation> $quolabel</td> + </tr> + </table> + </td> + <td> + <table> + <tr> + <th>|.$locale->text('From').qq|</th> + <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td> + <th>|.$locale->text('To').qq|</th> + <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + <tr> + <td></td> + <td colspan=3> + <input name="open" type=checkbox class=checkbox value=Y checked> |.$locale->text('Open').qq| + <input name="closed" type=checkbox class=checkbox value=Y checked> |.$locale->text('Closed').qq| + </td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> +|; + + $include = qq| + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td> + <table> + <tr> + <td><input name=history type=radio class=radio value=summary checked> |.$locale->text('Summary').qq|</td> + <td><input name=history type=radio class=radio value=detail> |.$locale->text('Detail').qq| + </td> + </tr> + <tr> + <td> + <input name="l_partnumber" type=checkbox class=checkbox value=Y checked> |.$locale->text('Part Number').qq| + </td> + <td> + <input name="l_description" type=checkbox class=checkbox value=Y checked> |.$locale->text('Description').qq| + </td> + <td> + <input name="l_sellprice" type=checkbox class=checkbox value=Y checked> |.$locale->text('Sell Price').qq| + </td> + <td> + <input name="l_curr" type=checkbox class=checkbox value=Y> |.$locale->text('Currency').qq| + </td> + </tr> + <tr> + <td> + <input name="l_qty" type=checkbox class=checkbox value=Y> |.$locale->text('Qty').qq| + </td> + <td> + <input name="l_unit" type=checkbox class=checkbox value=Y> |.$locale->text('Unit').qq| + </td> + <td> + <input name="l_discount" type=checkbox class=checkbox value=Y> |.$locale->text('Discount').qq| + </td> + <tr> + </tr> + <td> + <input name="l_deliverydate" type=checkbox class=checkbox value=Y> |.$locale->text('Delivery Date').qq| + </td> + <td> + <input name="l_projectnumber" type=checkbox class=checkbox value=Y> |.$locale->text('Project Number').qq| + </td> + <td> + <input name="l_serialnumber" type=checkbox class=checkbox value=Y> |.$locale->text('Serial Number').qq| + </td> + </tr> + </table> + </td> + </tr> +|; + + &search_name; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</body> +</html> +|; + +} + + +sub transactions { + + if ($form->{db} eq 'customer') { + $translabel = $locale->text('AR Transactions'); + $invlabel = $locale->text('Sales Invoices'); + $ordlabel = $locale->text('Sales Orders'); + $quolabel = $locale->text('Quotations'); + } else { + $translabel = $locale->text('AP Transactions'); + $invlabel = $locale->text('Vendor Invoices'); + $ordlabel = $locale->text('Purchase Orders'); + $quolabel = $locale->text('Request for Quotations'); + } + + + $transactions = qq| + <tr> + <td></td> + <td> + <table> + <tr> + <td> + <table> + <tr> + <td><input name="l_transnumber" type=checkbox class=checkbox value=Y> $translabel</td> + </tr> + <tr> + <td><input name="l_invnumber" type=checkbox class=checkbox value=Y> $invlabel</td> + </tr> + <tr> + <td><input name="l_ordnumber" type=checkbox class=checkbox value=Y> $ordlabel</td> + </tr> + <tr> + <td><input name="l_quonumber" type=checkbox class=checkbox value=Y> $quolabel</td> + </tr> + </table> + </td> + <td> + <table> + <tr> + <th>|.$locale->text('From').qq|</th> + <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td> + <th>|.$locale->text('To').qq|</th> + <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + <tr> + <td></td> + <td colspan=3> + <input name="open" type=checkbox class=checkbox value=Y checked> |.$locale->text('Open').qq| + <input name="closed" type=checkbox class=checkbox value=Y checked> |.$locale->text('Closed').qq| + </td> + </tr> + <tr> + <td></td> + <td colspan=3> + <input name="l_amount" type=checkbox class=checkbox value=Y checked> |.$locale->text('Amount').qq| + <input name="l_tax" type=checkbox class=checkbox value=Y checked> |.$locale->text('Tax').qq| + <input name="l_total" type=checkbox class=checkbox value=Y checked> |.$locale->text('Total').qq| + <input name="l_subtotal" type=checkbox class=checkbox value=Y> |.$locale->text('Subtotal').qq| + </td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> +|; + +} + + +sub include_in_report { + + $label = ucfirst $form->{db}; + + @a = (); + + push @a, qq|<input name="l_ndx" type=checkbox class=checkbox value=Y> |.$locale->text('No.'); + push @a, qq|<input name="l_id" type=checkbox class=checkbox value=Y> |.$locale->text('ID'); + push @a, qq|<input name="l_$form->{db}number" type=checkbox class=checkbox value=Y> |.$locale->text($label . ' Number'); + push @a, qq|<input name="l_name" type=checkbox class=checkbox value=Y $form->{l_name}> |.$locale->text('Company Name'); + push @a, qq|<input name="l_contact" type=checkbox class=checkbox value=Y $form->{l_contact}> |.$locale->text('Contact'); + push @a, qq|<input name="l_email" type=checkbox class=checkbox value=Y $form->{l_email}> |.$locale->text('E-mail'); + push @a, qq|<input name="l_address" type=checkbox class=checkbox value=Y> |.$locale->text('Address'); + push @a, qq|<input name="l_city" type=checkbox class=checkbox value=Y> |.$locale->text('City'); + push @a, qq|<input name="l_state" type=checkbox class=checkbox value=Y> |.$locale->text('State/Province'); + push @a, qq|<input name="l_zipcode" type=checkbox class=checkbox value=Y> |.$locale->text('Zip/Postal Code'); + push @a, qq|<input name="l_country" type=checkbox class=checkbox value=Y> |.$locale->text('Country'); + push @a, qq|<input name="l_phone" type=checkbox class=checkbox value=Y $form->{l_phone}> |.$locale->text('Phone'); + push @a, qq|<input name="l_fax" type=checkbox class=checkbox value=Y> |.$locale->text('Fax'); + push @a, qq|<input name="l_cc" type=checkbox class=checkbox value=Y> |.$locale->text('Cc'); + + if ($myconfig{role} =~ /(admin|manager)/) { + push @a, qq|<input name="l_bcc" type=checkbox class=checkbox value=Y> |.$locale->text('Bcc'); + } + + push @a, qq|<input name="l_notes" type=checkbox class=checkbox value=Y> |.$locale->text('Notes'); + push @a, qq|<input name="l_discount" type=checkbox class=checkbox value=Y> |.$locale->text('Discount'); + push @a, qq|<input name="l_taxaccount" type=checkbox class=checkbox value=Y> |.$locale->text('Tax Account'); + push @a, qq|<input name="l_taxnumber" type=checkbox class=checkbox value=Y> |.$locale->text('Tax Number'); + + if ($form->{db} eq 'customer') { + push @a, qq|<input name="l_employee" type=checkbox class=checkbox value=Y> |.$locale->text('Salesperson'); + push @a, qq|<input name="l_manager" type=checkbox class=checkbox value=Y> |.$locale->text('Manager'); + push @a, qq|<input name="l_pricegroup" type=checkbox class=checkbox value=Y> |.$locale->text('Pricegroup'); + + } else { + push @a, qq|<input name="l_employee" type=checkbox class=checkbox value=Y> |.$locale->text('Employee'); + push @a, qq|<input name="l_manager" type=checkbox class=checkbox value=Y> |.$locale->text('Manager'); + push @a, qq|<input name="l_gifi_accno" type=checkbox class=checkbox value=Y> |.$locale->text('GIFI'); + + } + + push @a, qq|<input name="l_sic_code" type=checkbox class=checkbox value=Y> |.$locale->text('SIC'); + push @a, qq|<input name="l_iban" type=checkbox class=checkbox value=Y> |.$locale->text('IBAN'); + push @a, qq|<input name="l_bic" type=checkbox class=checkbox value=Y> |.$locale->text('BIC'); + push @a, qq|<input name="l_business" type=checkbox class=checkbox value=Y> |.$locale->text('Type of Business'); + push @a, qq|<input name="l_terms" type=checkbox class=checkbox value=Y> |.$locale->text('Terms'); + push @a, qq|<input name="l_language" type=checkbox class=checkbox value=Y> |.$locale->text('Language'); + push @a, qq|<input name="l_startdate" type=checkbox class=checkbox value=Y> |.$locale->text('Startdate'); + push @a, qq|<input name="l_enddate" type=checkbox class=checkbox value=Y> |.$locale->text('Enddate'); + + + $include = qq| + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td> + <table> +|; + + while (@a) { + $include .= qq|<tr>\n|; + for (1 .. 5) { + $include .= qq|<td nowrap>|. shift @a; + $include .= qq|</td>\n|; + } + $include .= qq|</tr>\n|; + } + + $include .= qq| + </table> + </td> + </tr> +|; + +} + + +sub search { + +# $locale->text('Customers') +# $locale->text('Vendors') + + $form->{title} = $locale->text('Search') unless $form->{title}; + + for (qw(name contact phone email)) { $form->{"l_$_"} = 'checked' } + + $form->{nextsub} = "list_names"; + + $orphan = qq| + <tr> + <td></td> + <td><input name=status class=radio type=radio value=all checked> |.$locale->text('All').qq| + <input name=status class=radio type=radio value=active> |.$locale->text('Active').qq| + <input name=status class=radio type=radio value=inactive> |.$locale->text('Inactive').qq| + <input name=status class=radio type=radio value=orphaned> |.$locale->text('Orphaned').qq|</td> + </tr> +|; + + + &transactions; + &include_in_report; + &search_name; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub search_name { + + $label = ucfirst $form->{db}; + + if ($form->{db} eq 'customer') { + $employee = qq| + <th align=right nowrap>|.$locale->text('Salesperson').qq|</th> + <td><input name=employee size=32></td> +|; + } + if ($form->{db} eq 'vendor') { + $employee = qq| + <th align=right nowrap>|.$locale->text('Employee').qq|</th> + <td><input name=employee size=32></td> +|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=db value=$form->{db}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + <tr valign=top> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Company Name').qq|</th> + <td><input name=name size=32></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Contact').qq|</th> + <td><input name=contact size=32></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('E-mail').qq|</th> + <td><input name=email size=32></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Phone').qq|</th> + <td><input name=phone size=20></td> + </tr> + <tr> + $employee + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Notes').qq|</th> + <td colspan=3><textarea name=notes rows=3 cols=32></textarea></td> + </tr> + </table> + </td> + + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text($label . ' Number').qq|</th> + <td><input name=$form->{db}number size=32></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Address').qq|</th> + <td><input name=address size=32></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('City').qq|</th> + <td><input name=city size=32></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('State/Province').qq|</th> + <td><input name=state size=32></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Zip/Postal Code').qq|</th> + <td><input name=zipcode size=10></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Country').qq|</th> + <td><input name=country size=32></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Startdate').qq|</th> + <td>|.$locale->text('From').qq| <input name=startdatefrom size=11 title="$myconfig{dateformat}"> |.$locale->text('To').qq| <input name=startdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + + <tr> + <td> + <table> + + $orphan + $transactions + $include + + </table> + </td> + </tr> + + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=nextsub value=$form->{nextsub}> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<br> +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> +</form> +|; + +} + + +sub list_names { + + CT->search(\%myconfig, \%$form); + + $href = "$form->{script}?action=list_names&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}&l_subtotal=$form->{l_subtotal}"; + + $form->sort_order(); + + $callback = "$form->{script}?action=list_names&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}&l_subtotal=$form->{l_subtotal}"; + + @columns = $form->sort_columns(id, name, "$form->{db}number", address, + city, state, zipcode, country, contact, + phone, fax, email, cc, bcc, employee, + manager, notes, discount, terms, + taxaccount, taxnumber, gifi_accno, sic_code, business, + pricegroup, language, iban, bic, + startdate, enddate, + invnumber, invamount, invtax, invtotal, + ordnumber, ordamount, ordtax, ordtotal, + quonumber, quoamount, quotax, quototal); + unshift @columns, "ndx"; + + $form->{l_invnumber} = "Y" if $form->{l_transnumber}; + foreach $item (qw(inv ord quo)) { + if ($form->{"l_${item}number"}) { + for (qw(amount tax total)) { $form->{"l_$item$_"} = $form->{"l_$_"} } + $removeemployee = 1; + $openclosed = 1; + } + } + $form->{open} = $form->{closed} = "" if !$openclosed; + + + foreach $item (@columns) { + if ($form->{"l_$item"} eq "Y") { + push @column_index, $item; + + # add column to href and callback + $callback .= "&l_$item=Y"; + $href .= "&l_$item=Y"; + } + } + + foreach $item (qw(amount tax total transnumber)) { + if ($form->{"l_$item"} eq "Y") { + $callback .= "&l_$item=Y"; + $href .= "&l_$item=Y"; + } + } + + + if ($form->{status} eq 'all') { + $option = $locale->text('All'); + } + if ($form->{status} eq 'orphaned') { + $option = $locale->text('Orphaned'); + } + if ($form->{status} eq 'active') { + $option = $locale->text('Active'); + } + if ($form->{status} eq 'inactive') { + $option = $locale->text('Inactive'); + } + + if ($form->{name}) { + $callback .= "&name=".$form->escape($form->{name},1); + $href .= "&name=".$form->escape($form->{name}); + $option .= "\n<br>".$locale->text('Name')." : $form->{name}"; + } + if ($form->{address}) { + $callback .= "&address=".$form->escape($form->{address},1); + $href .= "&address=".$form->escape($form->{address}); + $option .= "\n<br>".$locale->text('Address')." : $form->{address}"; + } + if ($form->{city}) { + $callback .= "&city=".$form->escape($form->{city},1); + $href .= "&city=".$form->escape($form->{city}); + $option .= "\n<br>".$locale->text('City')." : $form->{city}"; + } + if ($form->{state}) { + $callback .= "&state=".$form->escape($form->{state},1); + $href .= "&state=".$form->escape($form->{state}); + $option .= "\n<br>".$locale->text('State')." : $form->{state}"; + } + if ($form->{zipcode}) { + $callback .= "&zipcode=".$form->escape($form->{zipcode},1); + $href .= "&zipcode=".$form->escape($form->{zipcode}); + $option .= "\n<br>".$locale->text('Zip/Postal Code')." : $form->{zipcode}"; + } + if ($form->{country}) { + $callback .= "&country=".$form->escape($form->{country},1); + $href .= "&country=".$form->escape($form->{country}); + $option .= "\n<br>".$locale->text('Country')." : $form->{country}"; + } + if ($form->{contact}) { + $callback .= "&contact=".$form->escape($form->{contact},1); + $href .= "&contact=".$form->escape($form->{contact}); + $option .= "\n<br>".$locale->text('Contact')." : $form->{contact}"; + } + if ($form->{employee}) { + $callback .= "&employee=".$form->escape($form->{employee},1); + $href .= "&employee=".$form->escape($form->{employee}); + $option .= "\n<br>"; + if ($form->{db} eq 'customer') { + $option .= $locale->text('Salesperson'); + } + if ($form->{db} eq 'vendor') { + $option .= $locale->text('Employee'); + } + $option .= " : $form->{employee}"; + } + + $fromdate = ""; + $todate = ""; + if ($form->{startdatefrom}) { + $callback .= "&startdatefrom=$form->{startdatefrom}"; + $href .= "&startdatefrom=$form->{startdatefrom}"; + $fromdate = $locale->date(\%myconfig, $form->{startdatefrom}, 1); + } + if ($form->{startdateto}) { + $callback .= "&startdateto=$form->{startdateto}"; + $href .= "&startdateto=$form->{startdateto}"; + $todate = $locale->date(\%myconfig, $form->{startdateto}, 1); + } + if ($fromdate || $todate) { + $option .= "\n<br>".$locale->text('Startdate')." $fromdate - $todate"; + } + + if ($form->{notes}) { + $callback .= "¬es=".$form->escape($form->{notes},1); + $href .= "¬es=".$form->escape($form->{notes}); + $option .= "\n<br>".$locale->text('Notes')." : $form->{notes}"; + } + if ($form->{"$form->{db}number"}) { + $callback .= qq|&$form->{db}number=|.$form->escape($form->{"$form->{db}number"},1); + $href .= "&$form->{db}number=".$form->escape($form->{"$form->{db}number"}); + $option .= "\n<br>".$locale->text('Number').qq| : $form->{"$form->{db}number"}|; + } + if ($form->{phone}) { + $callback .= "&phone=".$form->escape($form->{phone},1); + $href .= "&phone=".$form->escape($form->{phone}); + $option .= "\n<br>".$locale->text('Phone')." : $form->{phone}"; + } + if ($form->{email}) { + $callback .= "&email=".$form->escape($form->{email},1); + $href .= "&email=".$form->escape($form->{email}); + $option .= "\n<br>".$locale->text('E-mail')." : $form->{email}"; + } + if ($form->{transdatefrom}) { + $callback .= "&transdatefrom=$form->{transdatefrom}"; + $href .= "&transdatefrom=$form->{transdatefrom}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1); + } + if ($form->{transdateto}) { + $callback .= "&transdateto=$form->{transdateto}"; + $href .= "&transdateto=$form->{transdateto}"; + if ($form->{transdatefrom}) { + $option .= " "; + } else { + $option .= "\n<br>" if ($option); + } + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{transdateto}, 1); + } + if ($form->{open}) { + $callback .= "&open=$form->{open}"; + $href .= "&open=$form->{open}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Open'); + } + if ($form->{closed}) { + $callback .= "&closed=$form->{closed}"; + $href .= "&closed=$form->{closed}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Closed'); + } + + + $form->{callback} = "$callback&sort=$form->{sort}"; + $callback = $form->escape($form->{callback}); + + $column_header{ndx} = qq|<th class=listheading> </th>|; + $column_header{id} = qq|<th class=listheading>|.$locale->text('ID').qq|</th>|; + $column_header{"$form->{db}number"} = qq|<th><a class=listheading href=$href&sort=$form->{db}number>|.$locale->text('Number').qq|</a></th>|; + $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>|.$locale->text('Name').qq|</a></th>|; + $column_header{address} = qq|<th class=listheading>|.$locale->text('Address').qq|</th>|; + $column_header{city} = qq|<th><a class=listheading href=$href&sort=city>|.$locale->text('City').qq|</a></th>|; + $column_header{state} = qq|<th><a class=listheading href=$href&sort=state>|.$locale->text('State/Province').qq|</a></th>|; + $column_header{zipcode} = qq|<th><a class=listheading href=$href&sort=zipcode>|.$locale->text('Zip/Postal Code').qq|</a></th>|; + $column_header{country} = qq|<th><a class=listheading href=$href&sort=country>|.$locale->text('Country').qq|</a></th>|; + $column_header{contact} = qq|<th><a class=listheading href=$href&sort=contact>|.$locale->text('Contact').qq|</a></th>|; + $column_header{phone} = qq|<th><a class=listheading href=$href&sort=phone>|.$locale->text('Phone').qq|</a></th>|; + $column_header{fax} = qq|<th><a class=listheading href=$href&sort=fax>|.$locale->text('Fax').qq|</a></th>|; + $column_header{email} = qq|<th><a class=listheading href=$href&sort=email>|.$locale->text('E-mail').qq|</a></th>|; + $column_header{cc} = qq|<th><a class=listheading href=$href&sort=cc>|.$locale->text('Cc').qq|</a></th>|; + $column_header{bcc} = qq|<th><a class=listheading href=$href&sort=cc>|.$locale->text('Bcc').qq|</a></th>|; + $column_header{notes} = qq|<th><a class=listheading href=$href&sort=notes>|.$locale->text('Notes').qq|</a></th>|; + $column_header{discount} = qq|<th class=listheading>%</th>|; + $column_header{terms} = qq|<th class=listheading>|.$locale->text('Terms').qq|</th>|; + + $column_header{taxnumber} = qq|<th><a class=listheading href=$href&sort=taxnumber>|.$locale->text('Tax Number').qq|</a></th>|; + $column_header{taxaccount} = qq|<th class=listheading>|.$locale->text('Tax Account').qq|</th>|; + $column_header{gifi_accno} = qq|<th><a class=listheading href=$href&sort=gifi_accno>|.$locale->text('GIFI').qq|</a></th>|; + $column_header{sic_code} = qq|<th><a class=listheading href=$href&sort=sic_code>|.$locale->text('SIC').qq|</a></th>|; + $column_header{business} = qq|<th><a class=listheading href=$href&sort=business>|.$locale->text('Type of Business').qq|</a></th>|; + $column_header{iban} = qq|<th class=listheading>|.$locale->text('IBAN').qq|</th>|; + $column_header{bic} = qq|<th class=listheading>|.$locale->text('BIC').qq|</th>|; + $column_header{startdate} = qq|<th><a class=listheading href=$href&sort=startdate>|.$locale->text('Startdate').qq|</a></th>|; + $column_header{enddate} = qq|<th><a class=listheading href=$href&sort=enddate>|.$locale->text('Enddate').qq|</a></th>|; + + $column_header{invnumber} = qq|<th><a class=listheading href=$href&sort=invnumber>|.$locale->text('Invoice').qq|</a></th>|; + $column_header{ordnumber} = qq|<th><a class=listheading href=$href&sort=ordnumber>|.$locale->text('Order').qq|</a></th>|; + $column_header{quonumber} = qq|<th><a class=listheading href=$href&sort=quonumber>|.$locale->text('Quotation').qq|</a></th>|; + + if ($form->{db} eq 'customer') { + $column_header{employee} = qq|<th><a class=listheading href=$href&sort=employee>|.$locale->text('Salesperson').qq|</a></th>|; + } else { + $column_header{employee} = qq|<th><a class=listheading href=$href&sort=employee>|.$locale->text('Employee').qq|</a></th>|; + } + $column_header{manager} = qq|<th><a class=listheading href=$href&sort=manager>|.$locale->text('Manager').qq|</a></th>|; + + $column_header{pricegroup} = qq|<th><a class=listheading href=$href&sort=pricegroup>|.$locale->text('Pricegroup').qq|</a></th>|; + $column_header{language} = qq|<th><a class=listheading href=$href&sort=language>|.$locale->text('Language').qq|</a></th>|; + + + $amount = $locale->text('Amount'); + $tax = $locale->text('Tax'); + $total = $locale->text('Total'); + + $column_header{invamount} = qq|<th class=listheading>$amount</th>|; + $column_header{ordamount} = qq|<th class=listheading>$amount</th>|; + $column_header{quoamount} = qq|<th class=listheading>$amount</th>|; + + $column_header{invtax} = qq|<th class=listheading>$tax</th>|; + $column_header{ordtax} = qq|<th class=listheading>$tax</th>|; + $column_header{quotax} = qq|<th class=listheading>$tax</th>|; + + $column_header{invtotal} = qq|<th class=listheading>$total</th>|; + $column_header{ordtotal} = qq|<th class=listheading>$total</th>|; + $column_header{quototal} = qq|<th class=listheading>$total</th>|; + + + if ($form->{status}) { + $label = ucfirst $form->{db}."s"; + $form->{title} = $locale->text($label); + } else { + $label = ucfirst $form->{db}; + $form->{title} = $locale->text($label ." Transactions"); + } + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + $ordertype = ($form->{db} eq 'customer') ? 'sales_order' : 'purchase_order'; + $quotationtype = ($form->{db} eq 'customer') ? 'sales_quotation' : 'request_quotation'; + $subtotal = 0; + + $i = 0; + foreach $ref (@{ $form->{CT} }) { + + if ($ref->{$form->{sort}} ne $sameitem && $form->{l_subtotal}) { + # print subtotal + if ($subtotal) { + for (@column_index) { $column_data{$_} = "<td> </td>" } + &list_subtotal; + } + } + + if ($ref->{id} eq $sameid) { + for (@column_index) { $column_data{$_} = "<td> </td>" } + } else { + + $i++; + + $ref->{notes} =~ s/\r?\n/<br>/g; + for (@column_index) { $column_data{$_} = "<td>$ref->{$_} </td>" } + + $column_data{ndx} = "<td align=right>$i</td>"; + + if ($ref->{$form->{sort}} eq $sameitem) { + $column_data{$form->{sort}} = "<td> </td>"; + } + + $column_data{address} = "<td>$ref->{address1} $ref->{address2} </td>"; + $column_data{name} = "<td><a href=$form->{script}?action=edit&id=$ref->{id}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}&callback=$callback>$ref->{name} </td>"; + + $email = ""; + if ($form->{sort} =~ /(email|cc)/) { + if ($ref->{$form->{sort}} ne $sameitem) { + $email = 1; + } + } else { + $email = 1; + } + + if ($email) { + foreach $item (qw(email cc bcc)) { + if ($ref->{$item}) { + $email = $ref->{$item}; + $email =~ s/</\</; + $email =~ s/>/\>/; + + $column_data{$item} = qq|<td><a href="mailto:$ref->{$item}">$email</a></td>|; + } + } + } + } + + if ($ref->{formtype} eq 'invoice') { + $column_data{invnumber} = "<td><a href=$ref->{module}.pl?action=edit&id=$ref->{invid}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{invnumber} </td>"; + + $column_data{invamount} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{netamount}, 2, " ")."</td>"; + $column_data{invtax} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount} - $ref->{netamount}, 2, " ")."</td>"; + $column_data{invtotal} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount}, 2, " ")."</td>"; + + $invamountsubtotal += $ref->{netamount}; + $invtaxsubtotal += ($ref->{amount} - $ref->{netamount}); + $invtotalsubtotal += $ref->{amount}; + $subtotal = 1; + } + + if ($ref->{formtype} eq 'order') { + $column_data{ordnumber} = "<td><a href=$ref->{module}.pl?action=edit&id=$ref->{invid}&type=$ordertype&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{ordnumber} </td>"; + + $column_data{ordamount} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{netamount}, 2, " ")."</td>"; + $column_data{ordtax} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount} - $ref->{netamount}, 2, " ")."</td>"; + $column_data{ordtotal} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount}, 2, " ")."</td>"; + + $ordamountsubtotal += $ref->{netamount}; + $ordtaxsubtotal += ($ref->{amount} - $ref->{netamount}); + $ordtotalsubtotal += $ref->{amount}; + $subtotal = 1; + } + + if ($ref->{formtype} eq 'quotation') { + $column_data{quonumber} = "<td><a href=$ref->{module}.pl?action=edit&id=$ref->{invid}&type=$quotationtype&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{quonumber} </td>"; + + $column_data{quoamount} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{netamount}, 2, " ")."</td>"; + $column_data{quotax} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount} - $ref->{netamount}, 2, " ")."</td>"; + $column_data{quototal} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount}, 2, " ")."</td>"; + + $quoamountsubtotal += $ref->{netamount}; + $quotaxsubtotal += ($ref->{amount} - $ref->{netamount}); + $quototalsubtotal += $ref->{amount}; + $subtotal = 1; + } + + if ($sameid ne "$ref->{id}") { + if ($form->{l_discount}) { + $column_data{discount} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{discount} * 100, "", " ")."</td>"; + } + if ($form->{l_terms}) { + $column_data{terms} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{terms}, "", " ")."</td>"; + } + } + + $j++; $j %= 2; + print " + <tr class=listrow$j> +"; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + $sameitem = "$ref->{$form->{sort}}"; + $sameid = $ref->{id}; + + } + + if ($form->{l_subtotal} && $subtotal) { + for (@column_index) { $column_data{$_} = "<td> </td>" } + &list_subtotal; + } + + $i = 1; + if ($myconfig{acs} !~ /AR--AR/) { + if ($form->{db} eq 'customer') { + $button{'AR--Customers--Add Customer'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Customer').qq|"> |; + $button{'AR--Customers--Add Customer'}{order} = $i++; + } + } + if ($myconfig{acs} !~ /AP--AP/) { + if ($form->{db} eq 'vendor') { + $button{'AP--Vendors--Add Vendor'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Vendor').qq|"> |; + $button{'AP--Vendors--Add Vendor'}{order} = $i++; + } + } + + foreach $item (split /;/, $myconfig{acs}) { + delete $button{$item}; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(callback db path login sessionid)); + + if ($form->{status}) { + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub list_subtotal { + + $column_data{invamount} = "<td align=right>".$form->format_amount(\%myconfig, $invamountsubtotal, 2, " ")."</td>"; + $column_data{invtax} = "<td align=right>".$form->format_amount(\%myconfig, $invtaxsubtotal, 2, " ")."</td>"; + $column_data{invtotal} = "<td align=right>".$form->format_amount(\%myconfig, $invtotalsubtotal, 2, " ")."</td>"; + + $invamountsubtotal = 0; + $invtaxsubtotal = 0; + $invtotalsubtotal = 0; + + $column_data{ordamount} = "<td align=right>".$form->format_amount(\%myconfig, $ordamountsubtotal, 2, " ")."</td>"; + $column_data{ordtax} = "<td align=right>".$form->format_amount(\%myconfig, $ordtaxsubtotal, 2, " ")."</td>"; + $column_data{ordtotal} = "<td align=right>".$form->format_amount(\%myconfig, $ordtotalsubtotal, 2, " ")."</td>"; + + $ordamountsubtotal = 0; + $ordtaxsubtotal = 0; + $ordtotalsubtotal = 0; + + $column_data{quoamount} = "<td align=right>".$form->format_amount(\%myconfig, $quoamountsubtotal, 2, " ")."</td>"; + $column_data{quotax} = "<td align=right>".$form->format_amount(\%myconfig, $quotaxsubtotal, 2, " ")."</td>"; + $column_data{quototal} = "<td align=right>".$form->format_amount(\%myconfig, $quototalsubtotal, 2, " ")."</td>"; + + $quoamountsubtotal = 0; + $quotaxsubtotal = 0; + $quototalsubtotal = 0; + + print " + <tr class=listsubtotal> +"; + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + +} + + +sub list_history { + + CT->get_history(\%myconfig, \%$form); + + $href = "$form->{script}?action=list_history&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$form->{type}&transdatefrom=$form->{transdatefrom}&transdateto=$form->{transdateto}&history=$form->{history}"; + + $form->sort_order(); + + $callback = "$form->{script}?action=list_history&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$form->{type}&transdatefrom=$form->{transdatefrom}&transdateto=$form->{transdateto}&history=$form->{history}"; + + $form->{l_fxsellprice} = $form->{l_curr}; + @columns = $form->sort_columns(partnumber, description, qty, unit, sellprice, fxsellprice, curr, discount, deliverydate, projectnumber, serialnumber); + + if ($form->{history} eq 'summary') { + @columns = $form->sort_columns(partnumber, description, qty, unit, sellprice, curr); + } + + foreach $item (@columns) { + if ($form->{"l_$item"} eq "Y") { + push @column_index, $item; + + # add column to href and callback + $callback .= "&l_$item=Y"; + $href .= "&l_$item=Y"; + } + } + + if ($form->{history} eq 'detail') { + $option = $locale->text('Detail'); + } + if ($form->{history} eq 'summary') { + $option .= $locale->text('Summary'); + } + if ($form->{name}) { + $callback .= "&name=".$form->escape($form->{name},1); + $href .= "&name=".$form->escape($form->{name}); + $option .= "\n<br>".$locale->text('Name')." : $form->{name}"; + } + if ($form->{contact}) { + $callback .= "&contact=".$form->escape($form->{contact},1); + $href .= "&contact=".$form->escape($form->{contact}); + $option .= "\n<br>".$locale->text('Contact')." : $form->{contact}"; + } + if ($form->{"$form->{db}number"}) { + $callback .= qq|&$form->{db}number=|.$form->escape($form->{"$form->{db}number"},1); + $href .= "&$form->{db}number=".$form->escape($form->{"$form->{db}number"}); + $option .= "\n<br>".$locale->text('Number').qq| : $form->{"$form->{db}number"}|; + } + if ($form->{email}) { + $callback .= "&email=".$form->escape($form->{email},1); + $href .= "&email=".$form->escape($form->{email}); + $option .= "\n<br>".$locale->text('E-mail')." : $form->{email}"; + } + if ($form->{transdatefrom}) { + $callback .= "&transdatefrom=$form->{transdatefrom}"; + $href .= "&transdatefrom=$form->{transdatefrom}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1); + } + if ($form->{transdateto}) { + $callback .= "&transdateto=$form->{transdateto}"; + $href .= "&transdateto=$form->{transdateto}"; + if ($form->{transdatefrom}) { + $option .= " "; + } else { + $option .= "\n<br>" if ($option); + } + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{transdateto}, 1); + } + if ($form->{open}) { + $callback .= "&open=$form->{open}"; + $href .= "&open=$form->{open}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Open'); + } + if ($form->{closed}) { + $callback .= "&closed=$form->{closed}"; + $href .= "&closed=$form->{closed}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Closed'); + } + + + $form->{callback} = "$callback&sort=$form->{sort}"; + $callback = $form->escape($form->{callback}); + + $column_header{partnumber} = qq|<th><a class=listheading href=$href&sort=partnumber>|.$locale->text('Part Number').qq|</a></th>|; + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + + if ($form->{history} eq 'summary') { + $column_header{sellprice} = qq|<th class=listheading>|.$locale->text('Total').qq|</th>|; + } else { + $column_header{sellprice} = qq|<th class=listheading>|.$locale->text('Sell Price').qq|</th>|; + } + $column_header{fxsellprice} = qq|<th> </th>|; + + $column_header{curr} = qq|<th class=listheading>|.$locale->text('Curr').qq|</th>|; + $column_header{discount} = qq|<th class=listheading>|.$locale->text('Discount').qq|</th>|; + $column_header{qty} = qq|<th class=listheading>|.$locale->text('Qty').qq|</th>|; + $column_header{unit} = qq|<th class=listheading>|.$locale->text('Unit').qq|</th>|; + $column_header{deliverydate} = qq|<th><a class=listheading href=$href&sort=deliverydate>|.$locale->text('Delivery Date').qq|</a></th>|; + $column_header{projectnumber} = qq|<th><a class=listheading href=$href&sort=projectnumber>|.$locale->text('Project Number').qq|</a></th>|; + $column_header{serialnumber} = qq|<th><a class=listheading href=$href&sort=serialnumber>|.$locale->text('Serial Number').qq|</a></th>|; + + +# $locale->text('Customer History') +# $locale->text('Vendor History') + + $label = ucfirst $form->{db}; + $form->{title} = $locale->text($label." History"); + + $colspan = $#column_index + 1; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + + $module = 'oe'; + if ($form->{db} eq 'customer') { + $invlabel = $locale->text('Sales Invoice'); + $ordlabel = $locale->text('Sales Order'); + $quolabel = $locale->text('Quotation'); + + $ordertype = 'sales_order'; + $quotationtype = 'sales_quotation'; + if ($form->{type} eq 'invoice') { + $module = 'is'; + } + } else { + $invlabel = $locale->text('Vendor Invoice'); + $ordlabel = $locale->text('Purchase Order'); + $quolabel = $locale->text('RFQ'); + + $ordertype = 'purchase_order'; + $quotationtype = 'request_quotation'; + if ($form->{type} eq 'invoice') { + $module = 'ir'; + } + } + + $ml = ($form->{db} eq 'vendor') ? -1 : 1; + + foreach $ref (@{ $form->{CT} }) { + + if ($ref->{id} ne $sameid) { + # print the header + print qq| + <tr class=listheading> + <th colspan=$colspan><a class=listheading href=$form->{script}?action=edit&id=$ref->{ctid}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{name} $ref->{address}</a></th> + </tr> +|; + } + + if ($form->{type} ne 'invoice') { + $ref->{fxsellprice} = $ref->{sellprice}; + $ref->{sellprice} *= $ref->{exchangerate}; + } + + if ($form->{history} eq 'detail' and $ref->{invid} ne $sameinvid) { + # print inv, ord, quo number + $i++; $i %= 2; + + print qq| + <tr class=listrow$i> +|; + + if ($form->{type} eq 'invoice') { + print qq|<th align=left colspan=$colspan><a href=${module}.pl?action=edit&id=$ref->{invid}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$invlabel $ref->{invnumber} / $ref->{employee}</a></th>|; + } + + if ($form->{type} eq 'order') { + print qq|<th align=left colspan=$colspan><a href=${module}.pl?action=edit&id=$ref->{invid}&type=$ordertype&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ordlabel $ref->{ordnumber} / $ref->{employee}</a></th>|; + } + + if ($form->{type} eq 'quotation') { + print qq|<th align=left colspan=$colspan><a href=${module}.pl?action=edit&id=$ref->{invid}&type=$quotationtype&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$quolabel $ref->{quonumber} / $ref->{employee}</a></th>|; + } + + print qq| + </tr> +|; + } + + for (@column_index) { $column_data{$_} = "<td>$ref->{$_} </td>" } + + if ($form->{l_curr}) { + $column_data{fxsellprice} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{fxsellprice}, 2)."</td>"; + } + $column_data{sellprice} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{sellprice}, 2)."</td>"; + + $column_data{qty} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{qty} * $ml)."</td>"; + $column_data{discount} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{discount} * 100, "", " ")."</td>"; + $column_data{partnumber} = qq|<td><a href=ic.pl?action=edit&id=$ref->{pid}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber}</td>|; + + + $i++; $i %= 2; + print qq| + <tr class=listrow$i> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + $sameid = $ref->{id}; + $sameinvid = $ref->{invid}; + + } + + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + + +sub edit { + +# $locale->text('Edit Customer') +# $locale->text('Edit Vendor') + + CT->create_links(\%myconfig, \%$form); + + for (keys %$form) { $form->{$_} = $form->quote($form->{$_}) } + + $form->{title} = "Edit"; + + # format discount + $form->{discount} *= 100; + + &form_header; + &form_footer; + +} + + +sub form_header { + + $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : ""; + $form->{creditlimit} = $form->format_amount(\%myconfig, $form->{creditlimit}, 0); + $form->{discount} = $form->format_amount(\%myconfig, $form->{discount}, ""); + $form->{terms} = $form->format_amount(\%myconfig, $form->{terms}, ""); + + if ($myconfig{role} =~ /(admin|manager)/) { + $bcc = qq| + <tr> + <th align=right nowrap>|.$locale->text('Bcc').qq|</th> + <td><input name=bcc size=35 value="$form->{bcc}"></td> + </tr> +|; + } + + if ($form->{currencies}) { + # currencies + for (split /:/, $form->{currencies}) { $form->{selectcurrency} .= "<option>$_\n" } + $form->{selectcurrency} =~ s/option>($form->{curr})/option selected>$1/; + $currency = qq| + <th>|.$locale->text('Currency').qq|</th> + <td><select name=curr>$form->{selectcurrency}</select></td> +|; + } + + foreach $item (split / /, $form->{taxaccounts}) { + if ($form->{tax}{$item}{taxable}) { + $taxable .= qq| <input name="tax_$item" value=1 class=checkbox type=checkbox checked> <b>$form->{tax}{$item}{description}</b>|; + } else { + $taxable .= qq| <input name="tax_$item" value=1 class=checkbox type=checkbox> <b>$form->{tax}{$item}{description}</b>|; + } + } + + if ($taxable) { + $tax = qq| + <tr> + <th align=right>|.$locale->text('Taxable').qq|</th> + <td colspan=5> + <table> + <tr> + <td>$taxable</td> + <td><input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td> + <th align=left>|.$locale->text('Tax Included').qq|</th> + </tr> + </table> + </td> + </tr> +|; + } + + $typeofbusiness = qq| + <th></th> + <td></td> +|; + + if (@{ $form->{all_business} }) { + $form->{selectbusiness} = qq|<option>\n|; + for (@{ $form->{all_business} }) { $form->{selectbusiness} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + + $form->{selectbusiness} =~ s/(<option value="\Q$form->{business}--$form->{business_id}\E")>/$1 selected>/; + + $typeofbusiness = qq| + <th align=right>|.$locale->text('Type of Business').qq|</th> + <td><select name=business>$form->{selectbusiness}</select></td> +|; + + + } + + $pricegroup = qq| + <th></th> + <td></td> +|; + + if (@{ $form->{all_pricegroup} } && $form->{db} eq 'customer') { + $form->{selectpricegroup} = qq|<option>\n|; + for (@{ $form->{all_pricegroup} }) { $form->{selectpricegroup} .= qq|<option value="$_->{pricegroup}--$_->{id}">$_->{pricegroup}\n| } + + $form->{selectpricegroup} =~ s/(<option value="\Q$form->{pricegroup}--$form->{pricegroup_id}\E")/$1 selected/; + + $pricegroup = qq| + <th align=right>|.$locale->text('Pricegroup').qq|</th> + <td><select name=pricegroup>$form->{selectpricegroup}</select></td> +|; + } + + $lang = qq| + <th></th> + <td></td> +|; + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = qq|<option>\n|; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{description}--$_->{code}">$_->{description}\n| } + + $form->{selectlanguage} =~ s/(<option value="\Q$form->{language}--$form->{language_code}\E")/$1 selected/; + + $lang = qq| + <th align=right>|.$locale->text('Language').qq|</th> + <td><select name=language>$form->{selectlanguage}</select></td> +|; + } + + $employeelabel = $locale->text('Salesperson'); + + $form->{selectemployee} = qq|<option>\n|; + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + + $form->{selectemployee} =~ s/(<option value="\Q$form->{employee}--$form->{employee_id}\E")/$1 selected/; + + if ($form->{db} eq 'vendor') { + $gifi = qq| + <th align=right>|.$locale->text('Sub-contract GIFI').qq|</th> + <td><input name=gifi_accno size=9 value="$form->{gifi_accno}"></td> +|; + $employeelabel = $locale->text('Employee'); + } + + + if (@{ $form->{all_employee} }) { + $employee = qq| + <th align=right>$employeelabel</th>|; + + if ($myconfig{role} ne 'user' || !$form->{id}) { + $employee .= qq| + <td><select name=employee>$form->{selectemployee}</select></td> +|; + } else { + $employee .= qq| + <td>$form->{employee}</td> + <input type=hidden name=employee value="$form->{employee}--$form->{employee_id}">|; + } + } + + +# $locale->text('Customer Number') +# $locale->text('Vendor Number') + + $label = ucfirst $form->{db}; + $form->{title} = $locale->text("$form->{title} $label"); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr valign=top> + <td width=50%> + <table width=100%> + <tr class=listheading> + <th class=listheading colspan=2 width=50%>|.$locale->text('Billing Address').qq|</th> + <tr> + <th align=right nowrap>|.$locale->text($label .' Number').qq|</th> + <td><input name="$form->{db}number" size=35 maxlength=32 value="$form->{"$form->{db}number"}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Company Name').qq|</th> + <td><input name=name size=35 maxlength=64 value="$form->{name}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Address').qq|</th> + <td><input name=address1 size=35 maxlength=32 value="$form->{address1}"></td> + </tr> + <tr> + <th></th> + <td><input name=address2 size=35 maxlength=32 value="$form->{address2}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('City').qq|</th> + <td><input name=city size=35 maxlength=32 value="$form->{city}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('State/Province').qq|</th> + <td><input name=state size=35 maxlength=32 value="$form->{state}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Zip/Postal Code').qq|</th> + <td><input name=zipcode size=10 maxlength=10 value="$form->{zipcode}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Country').qq|</th> + <td><input name=country size=35 maxlength=32 value="$form->{country}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Contact').qq|</th> + <td><input name=contact size=35 maxlength=64 value="$form->{contact}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Phone').qq|</th> + <td><input name=phone size=20 maxlength=20 value="$form->{phone}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Fax').qq|</th> + <td><input name=fax size=20 maxlength=20 value="$form->{fax}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('E-mail').qq|</th> + <td><input name=email size=35 value="$form->{email}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Cc').qq|</th> + <td><input name=cc size=35 value="$form->{cc}"></td> + </tr> + $bcc + </table> + </td> + <td width=50%> + <table width=100%> + <tr> + <th class=listheading colspan=2>|.$locale->text('Shipping Address').qq|</th> + </tr> + <tr> + <td><input name=none size=35 value=|. ("=" x 35) .qq|></td> + </tr> + <tr> + <td><input name=shiptoname size=35 maxlength=64 value="$form->{shiptoname}"></td> + </tr> + <tr> + <td><input name=shiptoaddress1 size=35 maxlength=32 value="$form->{shiptoaddress1}"></td> + </tr> + <tr> + <td><input name=shiptoaddress2 size=35 maxlength=32 value="$form->{shiptoaddress2}"></td> + </tr> + <tr> + <td><input name=shiptocity size=35 maxlength=32 value="$form->{shiptocity}"></td> + </tr> + <tr> + <td><input name=shiptostate size=35 maxlength=32 value="$form->{shiptostate}"></td> + </tr> + <tr> + <td><input name=shiptozipcode size=10 maxlength=10 value="$form->{shiptozipcode}"></td> + </tr> + <tr> + <td><input name=shiptocountry size=35 maxlength=32 value="$form->{shiptocountry}"></td> + </tr> + <tr> + <td><input name=shiptocontact size=35 maxlength=64 value="$form->{shiptocontact}"></td> + </tr> + <tr> + <td><input name=shiptophone size=20 maxlength=20 value="$form->{shiptophone}"></td> + </tr> + <tr> + <td><input name=shiptofax size=20 maxlength=20 value="$form->{shiptofax}"></td> + </tr> + <tr> + <td><input name=shiptoemail size=35 value="$form->{shiptoemail}"></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table> + $tax + <tr> + <th align=right>|.$locale->text('Startdate').qq|</th> + <td><input name=startdate size=11 title="$myconfig{dateformat}" value=$form->{startdate}></td> + <th align=right>|.$locale->text('Enddate').qq|</th> + <td><input name=enddate size=11 title="$myconfig{dateformat}" value=$form->{enddate}></td> + </tr> + <tr> + <th align=right>|.$locale->text('Credit Limit').qq|</th> + <td><input name=creditlimit size=9 value="$form->{creditlimit}"></td> + <th align=right>|.$locale->text('Terms').qq|</th> + <td><input name=terms size=2 value="$form->{terms}"> <b>|.$locale->text('days').qq|</b></td> + <th align=right>|.$locale->text('Discount').qq|</th> + <td><input name=discount size=4 value="$form->{discount}"> + <b>%</b></td> + </tr> + <tr> + <th align=right>|.$locale->text('Tax Number / SSN').qq|</th> + <td><input name=taxnumber size=20 value="$form->{taxnumber}"></td> + $gifi + <th align=right>|.$locale->text('SIC').qq|</th> + <td><input name=sic_code size=6 maxlength=6 value="$form->{sic_code}"></td> + </tr> + <tr> + $typeofbusiness + <th align=right>|.$locale->text('BIC').qq|</th> + <td><input name=bic size=11 maxlength=11 value="$form->{bic}"></td> + <th align=right>|.$locale->text('IBAN').qq|</th> + <td><input name=iban size=24 maxlength=34 value="$form->{iban}"></td> + </tr> + <tr> + $pricegroup + $lang + $currency + </tr> + <tr valign=top> + $employee + <td colspan=4> + <table> + <tr valign=top> + <th align=left nowrap>|.$locale->text('Notes').qq|</th> + <td><textarea name=notes rows=3 cols=40 wrap=soft>$form->{notes}</textarea></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + + +sub form_footer { + +# type=submit $locale->text('Save') +# type=submit $locale->text('Save as new') +# type=submit $locale->text('AR Transaction') +# type=submit $locale->text('Sales Invoice') +# type=submit $locale->text('Sales Order') +# type=submit $locale->text('Quotation') +# type=submit $locale->text('AP Transaction') +# type=submit $locale->text('Vendor Invoice') +# type=submit $locale->text('Purchase Order') +# type=submit $locale->text('RFQ') +# type=submit $locale->text('Pricelist') +# type=submit $locale->text('Delete') +# type=submit $locale->text('POS') + + %button = ('Save' => { ndx => 1, key => 'S', value => $locale->text('Save') }, + 'Save as new' => { ndx => 2, key => 'N', value => $locale->text('Save as new') }, + 'AR Transaction' => { ndx => 7, key => 'A', value => $locale->text('AR Transaction') }, + 'AP Transaction' => { ndx => 8, key => 'A', value => $locale->text('AP Transaction') }, + 'Sales Invoice' => { ndx => 9, key => 'I', value => $locale->text('Sales Invoice') }, + 'POS' => { ndx => 10, key => 'C', value => $locale->text('POS') }, + 'Sales Order' => { ndx => 11, key => 'O', value => $locale->text('Sales Order') }, + 'Quotation' => { ndx => 12, key => 'Q', value => $locale->text('Quotation') }, + 'Vendor Invoice' => { ndx => 13, key => 'I', value => $locale->text('Vendor Invoice') }, + 'Purchase Order' => { ndx => 14, key => 'O', value => $locale->text('Purchase Order') }, + 'RFQ' => { ndx => 15, key => 'Q', value => $locale->text('RFQ') }, + 'Pricelist' => { ndx => 16, key => 'P', value => $locale->text('Pricelist') }, + 'Delete' => { ndx => 17, key => 'D', value => $locale->text('Delete') }, + ); + + + %a = (); + + if ($form->{db} eq 'customer') { + if ($myconfig{acs} !~ /AR--Customers--Add Customer/) { + $a{'Save'} = 1; + + if ($form->{id}) { + $a{'Save as new'} = 1; + if ($form->{status} eq 'orphaned') { + $a{'Delete'} = 1; + } + } + } + + if ($myconfig{acs} !~ /AR--AR/) { + if ($myconfig{acs} !~ /AR--Add Transaction/) { + $a{'AR Transaction'} = 1; + } + if ($myconfig{acs} !~ /AR--Sales Invoice/) { + $a{'Sales Invoice'} = 1; + } + } + if ($myconfig{acs} !~ /POS--POS/) { + if ($myconfig{acs} !~ /POS--Sale/) { + $a{'POS'} = 1; + } + } + if ($myconfig{acs} !~ /Order Entry--Order Entry/) { + if ($myconfig{acs} !~ /Order Entry--Sales Order/) { + $a{'Sales Order'} = 1; + } + } + if ($myconfig{acs} !~ /Quotations--Quotations/) { + if ($myconfig{acs} !~ /Quotations--Quotation/) { + $a{'Quotation'} = 1; + } + } + } + + if ($form->{db} eq 'vendor') { + if ($myconfig{acs} !~ /AP--Vendors--Add Vendor/) { + $a{'Save'} = 1; + + if ($form->{id}) { + $a{'Save as new'} = 1; + if ($form->{status} eq 'orphaned') { + $a{'Delete'} = 1; + } + } + } + + if ($myconfig{acs} !~ /AP--AP/) { + if ($myconfig{acs} !~ /AP--Add Transaction/) { + $a{'AP Transaction'} = 1; + } + if ($myconfig{acs} !~ /AP--Vendor Invoice/) { + $a{'Vendor Invoice'} = 1; + } + } + if ($myconfig{acs} !~ /Order Entry--Order Entry/) { + if ($myconfig{acs} !~ /Order Entry--Purchase Order/) { + $a{'Purchase Order'} = 1; + } + } + if ($myconfig{acs} !~ /Quotations--Quotations/) { + if ($myconfig{acs} !~ /Quotations--RFQ/) { + $a{'RFQ'} = 1; + } + } + } + + if ($myconfig{acs} !~ /Goods & Services--Goods & Services/) { + $myconfig{acs} =~ s/(Goods & Services--)Add (Service|Assembly).*;/$1--Add Part/g; + if ($myconfig{acs} !~ /Goods & Services--Add Part/) { + $a{'Pricelist'} = 1; + } + } + + $form->hide_form(qw(id taxaccounts path login sessionid callback db)); + + for (keys %button) { delete $button{$_} if ! $a{$_} } + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + + </form> + +</body> +</html> +|; + +} + + +sub pricelist { + + $form->isblank("name", $locale->text('Name missing!')); + + $form->{display_form} ||= "display_pricelist"; + + CT->pricelist(\%myconfig, \%$form); + + foreach $ref (@{ $form->{"all_partspricelist"} }) { + $i++; + for (keys %$ref) { $form->{"${_}_$i"} = $ref->{$_} } + } + $form->{rowcount} = $i; + + # currencies + @curr = split /:/, $form->{currencies}; + for (@curr) { $form->{selectcurrency} .= "<option>$_\n" } + + if (@ { $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = ""; + foreach $ref (@ { $form->{all_partsgroup} }) { + $form->{selectpartsgroup} .= qq|$ref->{partsgroup}--$ref->{id}\n|; + } + } + + for (qw(currencies all_partsgroup all_partspricelist)) { delete $form->{$_} } + + foreach $i (1 .. $form->{rowcount}) { + + if ($form->{db} eq 'customer') { + + $form->{"pricebreak_$i"} = $form->format_amount(\%myconfig, $form->{"pricebreak_$i"}); + + $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, 2); + + } + + if ($form->{db} eq 'vendor') { + + $form->{"leadtime_$i"} = $form->format_amount(\%myconfig, $form->{"leadtime_$i"}); + + $form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, 2); + + } + } + + $form->{rowcount}++; + &{ "$form->{db}_pricelist" }; + +} + + +sub customer_pricelist { + + @flds = qw(runningnumber id partnumber description sellprice unit partsgroup pricebreak curr validfrom validto); + + $form->{rowcount}--; + + # remove empty rows + if ($form->{rowcount}) { + + foreach $i (1 .. $form->{rowcount}) { + + for (qw(pricebreak sellprice)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + ($a, $b) = split /\./, $form->{"pricebreak_$i"}; + $a = length $a; + $b = length $b; + $whole = ($whole > $a) ? $whole : $a; + $dec = ($dec > $b) ? $dec : $b; + } + $pad1 = '0' x $whole; + $pad2 = '0' x $dec; + + foreach $i (1 .. $form->{rowcount}) { + ($a, $b) = split /\./, $form->{"pricebreak_$i"}; + + $a = substr("$pad1$a", -$whole); + $b = substr("$b$pad2", 0, $dec); + $ndx{qq|$form->{"partnumber_$i"}_$form->{"id_$i"}_$a$b|} = $i; + } + + $i = 1; + for (sort keys %ndx) { $form->{"runningnumber_$ndx{$_}"} = $i++ } + + foreach $i (1 .. $form->{rowcount}) { + if ($form->{"partnumber_$i"} && $form->{"sellprice_$i"}) { + if ($form->{"id_$i"} eq $sameid) { + $j = $i + 1; + next if ($form->{"id_$j"} eq $sameid && !$form->{"pricebreak_$i"}); + } + + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + $sameid = $form->{"id_$i"}; + } + + $form->redo_rows(\@flds, \@a, $count, $form->{rowcount}); + $form->{rowcount} = $count; + + } + + $form->{rowcount}++; + + if ($form->{display_form}) { + &{ "$form->{display_form}" }; + } + +} + + +sub vendor_pricelist { + + @flds = qw(runningnumber id sku partnumber description lastcost unit partsgroup curr leadtime); + + $form->{rowcount}--; + + # remove empty rows + if ($form->{rowcount}) { + + foreach $i (1 .. $form->{rowcount}) { + + for (qw(leadtime lastcost)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + $var = ($form->{"partnumber_$i"}) ? $form->{"sku_$i"} : qq|_$form->{"sku_$i"}|; + $ndx{$var} = $i; + + } + + $i = 1; + for (sort keys %ndx) { $form->{"runningnumber_$ndx{$_}"} = $i++ } + + foreach $i (1 .. $form->{rowcount}) { + if ($form->{"sku_$i"}) { + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + + $form->redo_rows(\@flds, \@a, $count, $form->{rowcount}); + $form->{rowcount} = $count; + + } + + $form->{rowcount}++; + + if ($form->{display_form}) { + &{ "$form->{display_form}" }; + } + +} + + +sub display_pricelist { + + &pricelist_header; + delete $form->{action}; + $form->hide_form; + &pricelist_footer; + +} + + +sub pricelist_header { + + $form->{title} = $form->{name}; + + $form->header; + + print qq| +<body> + +<form method=post action="$form->{script}"> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> +|; + + if ($form->{db} eq 'customer') { + @column_index = qw(partnumber description); + push @column_index, "partsgroup" if $form->{selectpartsgroup}; + push @column_index, qw(pricebreak sellprice curr validfrom validto); + + $column_header{pricebreak} = qq|<th class=listheading nowrap>|.$locale->text('Break').qq|</th>|; + $column_header{sellprice} = qq|<th class=listheading nowrap>|.$locale->text('Sell Price').qq|</th>|; + $column_header{validfrom} = qq|<th class=listheading nowrap>|.$locale->text('From').qq|</th>|; + $column_header{validto} = qq|<th class=listheading nowrap>|.$locale->text('To').qq|</th>|; + } + + if ($form->{db} eq 'vendor') { + @column_index = qw(sku partnumber description); + push @column_index, "partsgroup" if $form->{selectpartsgroup}; + push @column_index, qw(lastcost curr leadtime); + + + $column_header{sku} = qq|<th class=listheading nowrap>|.$locale->text('SKU').qq|</th>|; + $column_header{leadtime} = qq|<th class=listheading nowrap>|.$locale->text('Leadtime').qq|</th>|; + $column_header{lastcost} = qq|<th class=listheading nowrap>|.$locale->text('Cost').qq|</th>|; + } + + $column_header{partnumber} = qq|<th class=listheading nowrap>|.$locale->text('Number').qq|</th>|; + $column_header{description} = qq|<th class=listheading nowrap width=80%>|.$locale->text('Description').qq|</th>|; + $column_header{partsgroup} = qq|<th class=listheading nowrap>|.$locale->text('Group').qq|</th>|; + $column_header{curr} = qq|<th class=listheading nowrap>|.$locale->text('Curr').qq|</th>|; + + print qq| + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + $sameid = ""; + foreach $i (1 .. $form->{rowcount}) { + + $selectcurrency = $form->{selectcurrency}; + $selectcurrency =~ s/option>\Q$form->{"curr_$i"}\E/option selected>$form->{"curr_$i"}/; + + if ($form->{selectpartsgroup}) { + if ($i < $form->{rowcount}) { + ($partsgroup) = split /--/, $form->{"partsgroup_$i"}; + $column_data{partsgroup} = qq|<td>$partsgroup</td> + <input type=hidden name="partsgroup_$i" value="|.$form->quote($form->{"partsgroup_$i"}).qq|">|; + } + } + + + if ($i < $form->{rowcount}) { + + if ($form->{"id_$i"} eq $sameid) { + for (qw(partnumber description partsgroup)) { $column_data{$_} = qq|<td> </td> + <input type=hidden name="${_}_$i" value="|.$form->quote($form->{"${_}_$i"}).qq|">| } + } else { + + $column_data{sku} = qq|<td><input name="sku_$i" value="$form->{"sku_$i"}"></td>|; + $column_data{partnumber} = qq|<td><input name="partnumber_$i" value="$form->{"partnumber_$i"}"></td>|; + + $column_data{description} = qq|<td>$form->{"description_$i"} </td> + <input type=hidden name="description_$i" value="|.$form->quote($form->{"description_$i"}).qq|">|; + + } + + $column_data{partnumber} .= qq| + <input type=hidden name="id_$i" value="$form->{"id_$i"}">|; + + } else { + + if ($form->{db} eq 'customer') { + $column_data{partnumber} = qq|<td><input name="partnumber_$i" value="$form->{"partnumber_$i"}"></td>|; + } else { + $column_data{partnumber} = qq|<td> </td>|; + } + + $column_data{partnumber} .= qq| + <input type=hidden name="id_$i" value="$form->{"id_$i"}">|; + + $column_data{sku} = qq|<td><input name="sku_$i" value="$form->{"sku_$i"}"></td>|; + $column_data{description} = qq|<td><input name="description_$i" value="$form->{"description_$i"}"></td>|; + + if ($form->{selectpartsgroup}) { + $selectpartsgroup = "<option>"; + foreach $line (split /\n/, $form->{selectpartsgroup}) { + $selectpartsgroup .= qq|\n<option value="|.$form->quote($line).qq|">| .(split /--/, $line)[0]; + } + $column_data{partsgroup} = qq|<td><select name="partsgroup_$i">$selectpartsgroup</select></td>|; + } + + } + + + if ($form->{db} eq 'customer') { + + $column_data{pricebreak} = qq|<td align=right><input name="pricebreak_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"pricebreak_$i"}).qq|></td>|; + $column_data{sellprice} = qq|<td align=right><input name="sellprice_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"sellprice_$i"}, 2).qq|></td>|; + + $column_data{validfrom} = qq|<td><input name="validfrom_$i" size=11 value=$form->{"validfrom_$i"}></td>|; + $column_data{validto} = qq|<td><input name="validto_$i" size=11 value=$form->{"validto_$i"}></td>|; + } + + if ($form->{db} eq 'vendor') { + $column_data{leadtime} = qq|<td align=right><input name="leadtime_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"leadtime_$i"}).qq|></td>|; + $column_data{lastcost} = qq|<td align=right><input name="lastcost_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"lastcost_$i"}, 2).qq|></td>|; + } + + + $column_data{curr} = qq|<td><select name="curr_$i">$selectcurrency</select></td>|; + + + print qq|<tr valign=top>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq|</tr>|; + + $sameid = $form->{"id_$i"}; + + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + # delete variables + foreach $i (1 .. $form->{rowcount}) { + for (@column_index, "id") { delete $form->{"${_}_$i"} } + } + for (qw(title titlebar script none)) { delete $form->{$_} } + +} + + +sub pricelist_footer { + +# type=submit $locale->text('Update') +# type=submit $locale->text('Save Pricelist') + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Save Pricelist' => { ndx => 3, key => 'S', value => $locale->text('Save Pricelist') }, + ); + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub update { + + $i = $form->{rowcount}; + $additem = 0; + + if ($form->{db} eq 'customer') { + $additem = 1 if ! (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")); + } + if ($form->{db} eq 'vendor') { + if (! (($form->{"sku_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq ""))) { + $additem = 1; + $form->{"partnumber_$i"} = $form->{"sku_$i"}; + } + } + + if ($additem) { + + CT->retrieve_item(\%myconfig, \%$form); + + $rows = scalar @{ $form->{item_list} }; + + if ($rows > 0) { + + if ($rows > 1) { + + &select_item; + exit; + + } else { + + $sellprice = $form->{"sellprice_$i"}; + $pricebreak = $form->{"pricebreak_$i"}; + $lastcost = $form->{"lastcost_$i"}; + + for (qw(partnumber description)) { $form->{item_list}[0]{$_} = $form->quote($form->{item_list}[0]{$_}) } + for (keys %{ $form->{item_list}[0] }) { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } + + if ($form->{db} eq 'customer') { + + if ($sellprice) { + $form->{"sellprice_$i"} = $sellprice; + } + + $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, 2); + + $form->{"pricebreak_$i"} = $pricebreak; + + } else { + + foreach $j (1 .. $form->{rowcount} - 1) { + if ($form->{"sku_$j"} eq $form->{"partnumber_$i"}) { + $form->error($locale->text('Item already on pricelist!')); + } + } + + if ($lastcost) { + $form->{"lastcost_$i"} = $lastcost; + } + + $form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, 2); + + $form->{"sku_$i"} = $form->{"partnumber_$i"}; +# delete $form->{"partnumber_$i"}; + + } + + $form->{rowcount}++; + + } + + } else { + + $form->error($locale->text('Item not on file!')); + + } + } + + &{ "$form->{db}_pricelist" }; + +} + + + +sub select_item { + + @column_index = qw(ndx partnumber description partsgroup unit sellprice lastcost); + + $column_data{ndx} = qq|<th> </th>|; + $column_data{partnumber} = qq|<th class=listheading>|.$locale->text('Number').qq|</th>|; + $column_data{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|; + $column_data{partsgroup} = qq|<th class=listheading>|.$locale->text('Group').qq|</th>|; + $column_data{unit} = qq|<th class=listheading>|.$locale->text('Unit').qq|</th>|; + $column_data{sellprice} = qq|<th class=listheading>|.$locale->text('Sell Price').qq|</th>|; + $column_data{lastcost} = qq|<th class=listheading>|.$locale->text('Cost').qq|</th>|; + + $form->header; + + $title = $locale->text('Select items'); + + print qq| +<body> + +<form method=post action="$form->{script}"> + +<table width=100%> + <tr> + <th class=listtop>$title</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + my $i = 0; + foreach $ref (@{ $form->{item_list} }) { + $i++; + + for (qw(partnumber description unit)) { $ref->{$_} = $form->quote($ref->{$_}) } + + $column_data{ndx} = qq|<td><input name="ndx_$i" class=checkbox type=checkbox value=$i></td>|; + + for (qw(partnumber description partsgroup unit)) { $column_data{$_} = qq|<td>$ref->{$_} </td>| } + + $column_data{sellprice} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{sellprice}, 2, " ").qq|</td>|; + $column_data{lastcost} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{lastcost}, 2, " ").qq|</td>|; + + $j++; $j %= 2; + + print qq| + <tr class=listrow$j>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + for (qw(partnumber description partsgroup partsgroup_id sellprice lastcost unit id)) { + print qq|<input type=hidden name="new_${_}_$i" value="$ref->{$_}">\n|; + } + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input name=lastndx type=hidden value=$i> + +|; + + # delete action variable + for (qw(nextsub item_list)) { delete $form->{$_} } + + $form->{action} = "item_selected"; + + $form->hide_form; + + print qq| +<input type=hidden name=nextsub value=item_selected> + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; +} + + + +sub item_selected { + + # add rows + $i = $form->{rowcount}; + + %id = (); + for $i (1 .. $form->{rowcount} - 1) { + $id{$form->{"id_$i"}} = 1; + } + + for $j (1 .. $form->{lastndx}) { + + if ($form->{"ndx_$j"}) { + + if ($id{$form->{"new_id_$j"}}) { + next if $form->{db} eq 'vendor'; + } + + for (qw(id partnumber description unit sellprice lastcost)) { + $form->{"${_}_$i"} = $form->{"new_${_}_$j"}; + } + + $form->{"partsgroup_$i"} = qq|$form->{"new_partsgroup_$j"}--$form->{"new_partsgroup_id_$j"}|; + $form->{"sku_$i"} = $form->{"new_partnumber_$j"}; + + $i++; + + } + } + + $form->{rowcount} = $i; + + # delete all the new_ variables + for $i (1 .. $form->{lastndx}) { + for (qw(id partnumber description unit sellprice lastcost partsgroup partsgroup_id)) { delete $form->{"new_${_}_$i"} } + delete $form->{"ndx_$i"}; + } + + for (qw(ndx lastndx nextsub)) { delete $form->{$_} } + + &{ "$form->{db}_pricelist" }; + +} + + + + +sub save_pricelist { + + &{ "CT::save_$form->{db}" }("", \%myconfig, \%$form); + + $callback = $form->{callback}; + $form->{callback} = "$form->{script}?action=edit"; + for (qw(db id login path sessionid)) { $form->{callback} .= "&$_=$form->{$_}" } + $form->{callback} .= "&callback=".$form->escape($callback,1); + + if (CT->save_pricelist(\%myconfig, \%$form)) { + $form->redirect; + } else { + $form->error($locale->text('Could not save pricelist!')); + } + +} + + + +sub add_transaction { + + $form->isblank("name", $locale->text("Name missing!")); + + &{ "CT::save_$form->{db}" }("", \%myconfig, \%$form); + + $form->{callback} = $form->escape($form->{callback},1); + $name = $form->escape($form->{name},1); + + $form->{callback} = "$form->{script}?login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}&action=add&vc=$form->{db}&$form->{db}_id=$form->{id}&$form->{db}=$name&type=$form->{type}&callback=$form->{callback}"; + + $form->redirect; + +} + +sub ap_transaction { + + $form->{script} = "ap.pl"; + $form->{type} = "ap_transaction"; + &add_transaction; + +} + + +sub ar_transaction { + + $form->{script} = "ar.pl"; + $form->{type} = "ar_transaction"; + &add_transaction; + +} + + +sub sales_invoice { + + $form->{script} = "is.pl"; + $form->{type} = "invoice"; + &add_transaction; + +} + + +sub pos { + + $form->{script} = "ps.pl"; + $form->{type} = "pos_invoice"; + &add_transaction; + +} + + +sub vendor_invoice { + + $form->{script} = "ir.pl"; + $form->{type} = "invoice"; + &add_transaction; + +} + + +sub rfq { + + $form->{script} = "oe.pl"; + $form->{type} = "request_quotation"; + &add_transaction; + +} + + +sub quotation { + + $form->{script} = "oe.pl"; + $form->{type} = "sales_quotation"; + &add_transaction; + +} + + +sub sales_order { + + $form->{script} = "oe.pl"; + $form->{type} = "sales_order"; + &add_transaction; + +} + + +sub purchase_order { + + $form->{script} = "oe.pl"; + $form->{type} = "purchase_order"; + &add_transaction; + +} + + +sub save_as_new { + + delete $form->{id}; + &save; + +} + + +sub save { + +# $locale->text('Customer saved!') +# $locale->text('Vendor saved!') + + $msg = ucfirst $form->{db}; + $msg .= " saved!"; + + $form->isblank("name", $locale->text("Name missing!")); + &{ "CT::save_$form->{db}" }("", \%myconfig, \%$form); + + $form->redirect($locale->text($msg)); + +} + + +sub delete { + +# $locale->text('Customer deleted!') +# $locale->text('Cannot delete customer!') +# $locale->text('Vendor deleted!') +# $locale->text('Cannot delete vendor!') + + CT->delete(\%myconfig, \%$form); + + $msg = ucfirst $form->{db}; + $msg .= " deleted!"; + $form->redirect($locale->text($msg)); + +} + + +sub continue { &{ $form->{nextsub} } }; + +sub add_customer { &add }; +sub add_vendor { &add }; + diff --git a/bin/lynx/gl.pl b/bin/lynx/gl.pl new file mode 100755 index 00000000..2cd298aa --- /dev/null +++ b/bin/lynx/gl.pl @@ -0,0 +1,1128 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Genereal Ledger +# +#====================================================================== + + +use SL::GL; +use SL::PE; + +require "$form->{path}/arap.pl"; + +1; +# end of main + + +# this is for our long dates +# $locale->text('January') +# $locale->text('February') +# $locale->text('March') +# $locale->text('April') +# $locale->text('May ') +# $locale->text('June') +# $locale->text('July') +# $locale->text('August') +# $locale->text('September') +# $locale->text('October') +# $locale->text('November') +# $locale->text('December') + +# this is for our short month +# $locale->text('Jan') +# $locale->text('Feb') +# $locale->text('Mar') +# $locale->text('Apr') +# $locale->text('May') +# $locale->text('Jun') +# $locale->text('Jul') +# $locale->text('Aug') +# $locale->text('Sep') +# $locale->text('Oct') +# $locale->text('Nov') +# $locale->text('Dec') + + +sub add { + + $form->{title} = "Add"; + + $form->{callback} = "$form->{script}?action=add&transfer=$form->{transfer}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &create_links; + + $form->{rowcount} = ($form->{transfer}) ? 3 : 9; + $form->{oldtransdate} = $form->{transdate}; + $form->{focus} = "reference"; + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + &display_form(1); + +} + + +sub edit { + + &create_links; + + $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto})); + + # readonly + if (! $form->{readonly}) { + $form->{readonly} = 1 if $myconfig{acs} =~ /General Ledger--Add Transaction/; + } + + $form->{title} = "Edit"; + + $i = 1; + foreach $ref (@{ $form->{GL} }) { + $form->{"accno_$i"} = "$ref->{accno}--$ref->{description}"; + + $form->{"projectnumber_$i"} = "$ref->{projectnumber}--$ref->{project_id}"; + for (qw(fx_transaction source memo)) { $form->{"${_}_$i"} = $ref->{$_} } + + if ($ref->{amount} < 0) { + $form->{totaldebit} -= $ref->{amount}; + $form->{"debit_$i"} = $ref->{amount} * -1; + } else { + $form->{totalcredit} += $ref->{amount}; + $form->{"credit_$i"} = $ref->{amount}; + } + + $i++; + } + + $form->{rowcount} = $i; + $form->{focus} = "debit_$i"; + + &form_header; + &display_rows; + &form_footer; + +} + + + +sub create_links { + + GL->transaction(\%myconfig, \%$form); + + for (@{ $form->{all_accno} }) { $form->{selectaccno} .= "<option>$_->{accno}--$_->{description}\n" } + + # projects + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + } + + # departments + if (@{ $form->{all_department} }) { + $form->{department} = "$form->{department}--$form->{department_id}"; + $form->{selectdepartment} = "<option>\n"; + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + +} + + +sub search { + + $form->{title} = $locale->text('General Ledger')." ".$locale->text('Reports'); + + $colspan = 5; + $form->all_departments(\%myconfig); + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + + $l_department = qq|<input name="l_department" class=checkbox type=checkbox value=Y> |.$locale->text('Department'); + + $department = qq| + <tr> + <th align=right nowrap>|.$locale->text('Department').qq|</th> + <td colspan=$colspan><select name=department>$form->{selectdepartment}</select></td> + </tr> +|; + } + + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=$colspan> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + @a = (); + push @a, qq|<input name="l_id" class=checkbox type=checkbox value=Y> |.$locale->text('ID'); + push @a, qq|<input name="l_transdate" class=checkbox type=checkbox value=Y checked> |.$locale->text('Date'); + push @a, qq|<input name="l_reference" class=checkbox type=checkbox value=Y checked> |.$locale->text('Reference'); + push @a, qq|<input name="l_description" class=checkbox type=checkbox value=Y checked> |.$locale->text('Description'); + push @a, qq|<input name="l_notes" class=checkbox type=checkbox value=Y> |.$locale->text('Notes'); + push @a, $l_department if $l_department; + push @a, qq|<input name="l_debit" class=checkbox type=checkbox value=Y checked> |.$locale->text('Debit'); + push @a, qq|<input name="l_credit" class=checkbox type=checkbox value=Y checked> |.$locale->text('Credit'); + push @a, qq|<input name="l_source" class=checkbox type=checkbox value=Y checked> |.$locale->text('Source'); + push @a, qq|<input name="l_memo" class=checkbox type=checkbox value=Y> |.$locale->text('Memo'); + push @a, qq|<input name="l_accno" class=checkbox type=checkbox value=Y checked> |.$locale->text('Account'); + push @a, qq|<input name="l_gifi_accno" class=checkbox type=checkbox value=Y> |.$locale->text('GIFI'); + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=sort value=transdate> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Reference').qq|</th> + <td><input name=reference size=20></td> + + </tr> + <tr> + <th align=right>|.$locale->text('Source').qq|</th> + <td><input name=source size=20></td> + <th align=right>|.$locale->text('Memo').qq|</th> + <td><input name=memo size=20></td> + </tr> + $department + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td colspan=$colspan><input name=description size=60></td> + </tr> + <tr> + <th align=right>|.$locale->text('Notes').qq|</th> + <td colspan=$colspan><input name=notes size=60></td> + </tr> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=datefrom size=11 title="$myconfig{dateformat}"></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=dateto size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + <tr> + <th align=right>|.$locale->text('Amount').qq| >=</th> + <td><input name=amountfrom size=11></td> + <th align=right>|.$locale->text('Amount').qq| <=</th> + <td><input name=amountto size=11></td> + </tr> + <tr> + <th align=right>|.$locale->text('Include in Report').qq|</th> + <td colspan=$colspan> + <table> + <tr> + <td> + <input name="category" class=radio type=radio value=X checked> |.$locale->text('All').qq| + <input name="category" class=radio type=radio value=A> |.$locale->text('Asset').qq| + <input name="category" class=radio type=radio value=L> |.$locale->text('Liability').qq| + <input name="category" class=radio type=radio value=Q> |.$locale->text('Equity').qq| + <input name="category" class=radio type=radio value=I> |.$locale->text('Income').qq| + <input name="category" class=radio type=radio value=E> |.$locale->text('Expense').qq| + </td> + </tr> + <tr> + <table> +|; + + while (@a) { + print qq|<tr>\n|; + for (1 .. 5) { + print qq|<td nowrap>|. shift @a; + print qq|</td>\n|; + } + print qq|</tr>\n|; + } + + print qq| + <tr> + <td nowrap><input name="l_subtotal" class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq|</td> + </tr> + </table> + </tr> + </table> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=nextsub value=generate_report> +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; +} + + +sub generate_report { + + $form->{sort} = "transdate" unless $form->{sort}; + + GL->all_transactions(\%myconfig, \%$form); + + $href = "$form->{script}?action=generate_report&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->sort_order(); + + $callback = "$form->{script}?action=generate_report&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + %acctype = ( 'A' => $locale->text('Asset'), + 'L' => $locale->text('Liability'), + 'Q' => $locale->text('Equity'), + 'I' => $locale->text('Income'), + 'E' => $locale->text('Expense'), + ); + + $form->{title} = $locale->text('General Ledger'); + + $ml = ($form->{category} =~ /(A|E)/) ? -1 : 1; + + unless ($form->{category} eq 'X') { + $form->{title} .= " : ".$locale->text($acctype{$form->{category}}); + } + if ($form->{accno}) { + $href .= "&accno=".$form->escape($form->{accno}); + $callback .= "&accno=".$form->escape($form->{accno},1); + $option = $locale->text('Account')." : $form->{accno} $form->{account_description}"; + } + if ($form->{gifi_accno}) { + $href .= "&gifi_accno=".$form->escape($form->{gifi_accno}); + $callback .= "&gifi_accno=".$form->escape($form->{gifi_accno},1); + $option .= "\n<br>" if $option; + $option .= $locale->text('GIFI')." : $form->{gifi_accno} $form->{gifi_account_description}"; + } + if ($form->{source}) { + $href .= "&source=".$form->escape($form->{source}); + $callback .= "&source=".$form->escape($form->{source},1); + $option .= "\n<br>" if $option; + $option .= $locale->text('Source')." : $form->{source}"; + } + if ($form->{memo}) { + $href .= "&memo=".$form->escape($form->{memo}); + $callback .= "&memo=".$form->escape($form->{memo},1); + $option .= "\n<br>" if $option; + $option .= $locale->text('Memo')." : $form->{memo}"; + } + if ($form->{reference}) { + $href .= "&reference=".$form->escape($form->{reference}); + $callback .= "&reference=".$form->escape($form->{reference},1); + $option .= "\n<br>" if $option; + $option .= $locale->text('Reference')." : $form->{reference}"; + } + if ($form->{department}) { + $href .= "&department=".$form->escape($form->{department}); + $callback .= "&department=".$form->escape($form->{department},1); + ($department) = split /--/, $form->{department}; + $option .= "\n<br>" if $option; + $option .= $locale->text('Department')." : $department"; + } + + if ($form->{description}) { + $href .= "&description=".$form->escape($form->{description}); + $callback .= "&description=".$form->escape($form->{description},1); + $option .= "\n<br>" if $option; + $option .= $locale->text('Description')." : $form->{description}"; + } + if ($form->{notes}) { + $href .= "¬es=".$form->escape($form->{notes}); + $callback .= "¬es=".$form->escape($form->{notes},1); + $option .= "\n<br>" if $option; + $option .= $locale->text('Notes')." : $form->{notes}"; + } + + if ($form->{datefrom}) { + $href .= "&datefrom=$form->{datefrom}"; + $callback .= "&datefrom=$form->{datefrom}"; + $option .= "\n<br>" if $option; + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{datefrom}, 1); + } + if ($form->{dateto}) { + $href .= "&dateto=$form->{dateto}"; + $callback .= "&dateto=$form->{dateto}"; + if ($form->{datefrom}) { + $option .= " "; + } else { + $option .= "\n<br>" if $option; + } + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{dateto}, 1); + } + + if ($form->{amountfrom}) { + $href .= "&amountfrom=$form->{amountfrom}"; + $callback .= "&amountfrom=$form->{amountfrom}"; + $option .= "\n<br>" if $option; + $option .= $locale->text('Amount')." >= ".$form->format_amount(\%myconfig, $form->{amountfrom}, 2); + } + if ($form->{amountto}) { + $href .= "&amountto=$form->{amountto}"; + $callback .= "&amountto=$form->{amountto}"; + if ($form->{amountfrom}) { + $option .= " <= "; + } else { + $option .= "\n<br>" if $option; + $option .= $locale->text('Amount')." <= "; + } + $option .= $form->format_amount(\%myconfig, $form->{amountto}, 2); + } + + + @columns = $form->sort_columns(qw(transdate id reference description notes source memo debit credit accno gifi_accno department)); + pop @columns if $form->{department}; + + if ($form->{link} =~ /_paid/) { + @columns = $form->sort_columns(qw(transdate id reference description notes source memo cleared debit credit accno gifi_accno)); + $form->{l_cleared} = "Y"; + } + + if ($form->{accno} || $form->{gifi_accno}) { + @columns = grep !/(accno|gifi_accno)/, @columns; + push @columns, "balance"; + $form->{l_balance} = "Y"; + } + + + foreach $item (@columns) { + if ($form->{"l_$item"} eq "Y") { + push @column_index, $item; + + # add column to href and callback + $callback .= "&l_$item=Y"; + $href .= "&l_$item=Y"; + } + } + + if ($form->{l_subtotal} eq 'Y') { + $callback .= "&l_subtotal=Y"; + $href .= "&l_subtotal=Y"; + } + + $callback .= "&category=$form->{category}"; + $href .= "&category=$form->{category}"; + + $column_header{id} = "<th><a class=listheading href=$href&sort=id>".$locale->text('ID')."</a></th>"; + $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>"; + $column_header{reference} = "<th><a class=listheading href=$href&sort=reference>".$locale->text('Reference')."</a></th>"; + $column_header{source} = "<th><a class=listheading href=$href&sort=source>".$locale->text('Source')."</a></th>"; + $column_header{memo} = "<th><a class=listheading href=$href&sort=memo>".$locale->text('Memo')."</a></th>"; + $column_header{description} = "<th><a class=listheading href=$href&sort=description>".$locale->text('Description')."</a></th>"; + $column_header{department} = "<th><a class=listheading href=$href&sort=department>".$locale->text('Department')."</a></th>"; + $column_header{notes} = "<th class=listheading>".$locale->text('Notes')."</th>"; + $column_header{debit} = "<th class=listheading>".$locale->text('Debit')."</th>"; + $column_header{credit} = "<th class=listheading>".$locale->text('Credit')."</th>"; + $column_header{accno} = "<th><a class=listheading href=$href&sort=accno>".$locale->text('Account')."</a></th>"; + $column_header{gifi_accno} = "<th><a class=listheading href=$href&sort=gifi_accno>".$locale->text('GIFI')."</a></th>"; + $column_header{balance} = "<th>".$locale->text('Balance')."</th>"; + $column_header{cleared} = qq|<th>|.$locale->text('R').qq|</th>|; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print " + </tr> +"; + + # add sort to callback + $form->{callback} = "$callback&sort=$form->{sort}"; + $callback = $form->escape($form->{callback}); + + $cml = 1; + # initial item for subtotals + if (@{ $form->{GL} }) { + $sameitem = $form->{GL}->[0]->{$form->{sort}}; + $cml = -1 if $form->{contra}; + } + + if (($form->{accno} || $form->{gifi_accno}) && $form->{balance}) { + + for (@column_index) { $column_data{$_} = "<td> </td>" } + $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml * $cml, 2, 0)."</td>"; + + $i++; $i %= 2; + print qq| + <tr class=listrow$i> +|; + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + # reverse href + $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC"; + $form->sort_order(); + $href =~ s/direction=$form->{direction}/direction=$direction/; + + $i = 0; + foreach $ref (@{ $form->{GL} }) { + + # if item ne sort print subtotal + if ($form->{l_subtotal} eq 'Y') { + if ($sameitem ne $ref->{$form->{sort}}) { + &gl_subtotal; + } + } + + $form->{balance} += $ref->{amount}; + + $subtotaldebit += $ref->{debit}; + $subtotalcredit += $ref->{credit}; + + $totaldebit += $ref->{debit}; + $totalcredit += $ref->{credit}; + + $ref->{debit} = $form->format_amount(\%myconfig, $ref->{debit}, 2, " "); + $ref->{credit} = $form->format_amount(\%myconfig, $ref->{credit}, 2, " "); + + for (qw(id transdate)) { $column_data{$_} = "<td>$ref->{$_}</td>" } + + $column_data{reference} = "<td><a href=$ref->{module}.pl?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{reference}</td>"; + + $ref->{notes} =~ s/\r?\n/<br>/g; + for (qw(description source memo notes department)) { $column_data{$_} = "<td>$ref->{$_} </td>" } + + $column_data{debit} = "<td align=right>$ref->{debit}</td>"; + $column_data{credit} = "<td align=right>$ref->{credit}</td>"; + + $column_data{accno} = "<td><a href=$href&accno=$ref->{accno}&callback=$callback>$ref->{accno}</a></td>"; + $column_data{gifi_accno} = "<td><a href=$href&gifi_accno=$ref->{gifi_accno}&callback=$callback>$ref->{gifi_accno}</a> </td>"; + $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml * $cml, 2, 0)."</td>"; + $column_data{cleared} = ($ref->{cleared}) ? "<td>*</td>" : "<td> </td>"; + + if ($ref->{id} != $sameid) { + $i++; $i %= 2; + } + print " + <tr class=listrow$i>"; + for (@column_index) { print "$column_data{$_}\n" } + print "</tr>"; + + $sameid = $ref->{id}; + } + + + &gl_subtotal if ($form->{l_subtotal} eq 'Y'); + + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{debit} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $totaldebit, 2, " ")."</th>"; + $column_data{credit} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $totalcredit, 2, " ")."</th>"; + $column_data{balance} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $form->{balance} * $ml * $cml, 2, 0)."</th>"; + + print qq| + <tr class=listtotal> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + $i = 1; + if ($myconfig{acs} !~ /General Ledger--General Ledger/) { + $button{'General Ledger--Add Transaction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('GL Transaction').qq|"> |; + $button{'General Ledger--Add Transaction'}{order} = $i++; + } + if ($myconfig{acs} !~ /AR--AR/) { + $button{'AR--Add Transaction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('AR Transaction').qq|"> |; + $button{'AR--Add Transaction'}{order} = $i++; + $button{'AR--Sales Invoice'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Sales Invoice ').qq|"> |; + $button{'AR--Sales Invoice'}{order} = $i++; + } + if ($myconfig{acs} !~ /AP--AP/) { + $button{'AP--Add Transaction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('AP Transaction').qq|"> |; + $button{'AP--Add Transaction'}{order} = $i++; + $button{'AP--Vendor Invoice'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Vendor Invoice ').qq|"> |; + $button{'AP--Vendor Invoice'}{order} = $i++; + } + + foreach $item (split /;/, $myconfig{acs}) { + delete $button{$item}; + } + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> + +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(callback path login sessionid)); + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</form> + +</body> +</html> +|; + +} + + +sub gl_subtotal { + + $subtotaldebit = $form->format_amount(\%myconfig, $subtotaldebit, 2, " "); + $subtotalcredit = $form->format_amount(\%myconfig, $subtotalcredit, 2, " "); + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{debit} = "<th align=right class=listsubtotal>$subtotaldebit</td>"; + $column_data{credit} = "<th align=right class=listsubtotal>$subtotalcredit</td>"; + + + print "<tr class=listsubtotal>"; + for (@column_index) { print "$column_data{$_}\n" } + print "</tr>"; + + $subtotaldebit = 0; + $subtotalcredit = 0; + + $sameitem = $ref->{$form->{sort}}; + +} + + +sub update { + + if ($form->{transdate} ne $form->{oldtransdate}) { + if ($form->{selectprojectnumber}) { + $form->all_projects(\%myconfig, undef, $form->{transdate}); + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + $form->{selectprojectnumber} = $form->escape($form->{selectprojectnumber},1); + } + } + $form->{oldtransdate} = $form->{transdate}; + } + + @a = (); + $count = 0; + @flds = qw(accno debit credit projectnumber fx_transaction source memo); + + for $i (1 .. $form->{rowcount}) { + unless (($form->{"debit_$i"} eq "") && ($form->{"credit_$i"} eq "")) { + for (qw(debit credit)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + + + for $i (1 .. $count) { + $j = $i - 1; + for (@flds) { $form->{"${_}_$i"} = $a[$j]->{$_} } + } + + for $i ($count + 1 .. $form->{rowcount}) { + for (@flds) { delete $form->{"${_}_$i"} } + } + + $form->{rowcount} = $count + 1; + + &display_form; + +} + + +sub display_form { + my ($init) = @_; + + &form_header; + &display_rows($init); + &form_footer; + +} + + +sub display_rows { + my ($init) = @_; + + $form->{selectprojectnumber} = $form->unescape($form->{selectprojectnumber}) if $form->{selectprojectnumber}; + + $form->{totaldebit} = 0; + $form->{totalcredit} = 0; + + for $i (1 .. $form->{rowcount}) { + + $source = qq| + <td><input name="source_$i" size=10 value="$form->{"source_$i"}"></td>|; + $memo = qq| + <td><input name="memo_$i" value="$form->{"memo_$i"}"></td>|; + + if ($init) { + $accno = qq| + <td><select name="accno_$i">$form->{selectaccno}</select></td>|; + + if ($form->{selectprojectnumber}) { + $project = qq| + <td><select name="projectnumber_$i">$form->{selectprojectnumber}</select></td>|; + } + + if ($form->{transfer}) { + $fx_transaction = qq| + <td><input name="fx_transaction_$i" class=checkbox type=checkbox value=1></td> + |; + } + + } else { + + $form->{totaldebit} += $form->{"debit_$i"}; + $form->{totalcredit} += $form->{"credit_$i"}; + + for (qw(debit credit)) { $form->{"${_}_$i"} = ($form->{"${_}_$i"}) ? $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) : "" } + + if ($i < $form->{rowcount}) { + + $accno = qq|<td>$form->{"accno_$i"}</td>|; + + if ($form->{selectprojectnumber}) { + $form->{"projectnumber_$i"} = "" if $form->{selectprojectnumber} !~ /$form->{"projectnumber_$i"}/; + + $project = $form->{"projectnumber_$i"}; + $project =~ s/--.*//; + $project = qq|<td>$project</td>|; + } + + if ($form->{transfer}) { + $checked = ($form->{"fx_transaction_$i"}) ? "1" : ""; + $x = ($checked) ? "x" : ""; + $fx_transaction = qq| + <td><input type=hidden name="fx_transaction_$i" value="$checked">$x</td> + |; + } + + $form->hide_form("accno_$i", "projectnumber_$i"); + + } else { + + $accno = qq| + <td><select name="accno_$i">$form->{selectaccno}</select></td>|; + + if ($form->{selectprojectnumber}) { + $project = qq| + <td><select name="projectnumber_$i">$form->{selectprojectnumber}</select></td>|; + } + + if ($form->{transfer}) { + $fx_transaction = qq| + <td><input name="fx_transaction_$i" class=checkbox type=checkbox value=1></td> + |; + } + } + } + + print qq|<tr valign=top> + $accno + $fx_transaction + <td><input name="debit_$i" size=12 value="$form->{"debit_$i"}" accesskey=$i></td> + <td><input name="credit_$i" size=12 value=$form->{"credit_$i"}></td> + $source + $memo + $project + </tr> + + |; + } + + $form->hide_form(qw(rowcount selectaccno)); + + print qq| +<input type=hidden name=selectprojectnumber value="|.$form->escape($form->{selectprojectnumber},1).qq|">|; + +} + + +sub form_header { + + $title = $form->{title}; + if ($form->{transfer}) { + $form->{title} = $locale->text("$title Cash Transfer Transaction"); + } else { + $form->{title} = $locale->text("$title General Ledger Transaction"); + } + +# $locale->text('Add Cash Transfer Transaction') +# $locale->text('Edit Cash Transfer Transaction') +# $locale->text('Add General Ledger Transaction') +# $locale->text('Edit General Ledger Transaction') + + + $form->{selectdepartment} = $form->unescape($form->{selectdepartment}); + $form->{selectdepartment} =~ s/ selected//; + $form->{selectdepartment} =~ s/(<option value="\Q$form->{department}\E")/$1 selected/; + + for (qw(reference description notes)) { $form->{$_} = $form->quote($form->{$_}) } + + if (($rows = $form->numtextrows($form->{description}, 50)) > 1) { + $description = qq|<textarea name=description rows=$rows cols=50 wrap=soft>$form->{description}</textarea>|; + } else { + $description = qq|<input name=description size=50 value="$form->{description}">|; + } + + if (($rows = $form->numtextrows($form->{notes}, 50)) > 1) { + $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|; + } else { + $notes = qq|<input name=notes size=50 value="$form->{notes}">|; + } + + $department = qq| + <tr> + <th align=right nowrap>|.$locale->text('Department').qq|</th> + <td><select name=department>$form->{selectdepartment}</select></td> + <input type=hidden name=selectdepartment value="|.$form->escape($form->{selectdepartment},1).qq|"> + </tr> +| if $form->{selectdepartment}; + + $project = qq| + <th class=listheading>|.$locale->text('Project').qq|</th> +| if $form->{selectprojectnumber}; + + if ($form->{transfer}) { + $fx_transaction = qq| + <th class=listheading>|.$locale->text('FX').qq|</th> +|; + } + + $focus = ($form->{focus}) ? $form->{focus} : "debit_$form->{rowcount}"; + + $form->header; + + print qq| +<body onload="document.forms[0].${focus}.focus()" /> + +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(id transfer selectaccno closedto locked oldtransdate recurring)); + + print qq| +<input type=hidden name=title value="$title"> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Reference').qq|</th> + <td><input name=reference size=20 value="$form->{reference}"></td> + <th align=right>|.$locale->text('Date').qq|</th> + <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td> + </tr> + $department + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td colspan=3>$description</td> + </tr> + <tr> + <th align=right>|.$locale->text('Notes').qq|</th> + <td colspan=3>$notes</td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> + <th class=listheading>|.$locale->text('Account').qq|</th> + $fx_transaction + <th class=listheading>|.$locale->text('Debit').qq|</th> + <th class=listheading>|.$locale->text('Credit').qq|</th> + <th class=listheading>|.$locale->text('Source').qq|</th> + <th class=listheading>|.$locale->text('Memo').qq|</th> + $project + </tr> +|; + +} + + +sub form_footer { + + for (qw(totaldebit totalcredit)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2, " ") } + + + $project = qq| + <th> </th> +| if $form->{selectprojectnumber}; + + if ($form->{transfer}) { + $fx_transaction = qq| + <th> </th> +|; + } + + print qq| + <tr class=listtotal> + <th> </th> + $fx_transaction + <th class=listtotal align=right>$form->{totaldebit}</th> + <th class=listtotal align=right>$form->{totalcredit}</th> + <th> </th> + <th> </th> + $project + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + $form->hide_form(qw(path login sessionid callback)); + + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + +# type=submit $locale->text('Update') +# type=submit $locale->text('Post') +# type=submit $locale->text('Schedule') +# type=submit $locale->text('Post as new') +# type=submit $locale->text('Delete') + + if (! $form->{readonly}) { + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Post' => { ndx => 3, key => 'O', value => $locale->text('Post') }, + 'Post as new' => { ndx => 6, key => 'N', value => $locale->text('Post as new') }, + 'Schedule' => { ndx => 7, key => 'H', value => $locale->text('Schedule') }, + 'Delete' => { ndx => 8, key => 'D', value => $locale->text('Delete') }, + ); + + %a = (); + + if ($form->{id}) { + for ('Update', 'Post as new', 'Schedule') { $a{$_} = 1 } + + if (! $form->{locked}) { + if ($transdate > $closedto) { + for ('Post', 'Delete') { $a{$_} = 1 } + } + } + + } else { + if ($transdate > $closedto) { + for ("Update", "Post", "Schedule") { $a{$_} = 1 } + } + } + + for (keys %button) { delete $button{$_} if ! $a{$_} } + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + } + + if ($form->{recurring}) { + print qq|<div align=right>|.$locale->text('Scheduled').qq|</div>|; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub delete { + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + delete $form->{action}; + + $form->hide_form; + + print qq| +<h2 class=confirm>|.$locale->text('Confirm!').qq|</h2> + +<h4>|.$locale->text('Are you sure you want to delete Transaction').qq| $form->{reference}</h4> + +<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|"> +</form> +|; + +} + + +sub yes { + + if (GL->delete_transaction(\%myconfig, \%$form)) { + $form->redirect($locale->text('Transaction deleted!')); + } else { + $form->error($locale->text('Cannot delete transaction!')); + } + +} + + +sub post { + + $form->isblank("transdate", $locale->text('Transaction Date missing!')); + + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + + $form->error($locale->text('Cannot post transaction for a closed period!')) if ($transdate <= $closedto); + + # add up debits and credits + for $i (1 .. $form->{rowcount}) { + $dr = $form->parse_amount(\%myconfig, $form->{"debit_$i"}); + $cr = $form->parse_amount(\%myconfig, $form->{"credit_$i"}); + + if ($dr && $cr) { + $form->error($locale->text('Cannot post transaction with a debit and credit entry for the same account!')); + } + $debit += $dr; + $credit += $cr; + } + + if ($form->round_amount($debit, 2) != $form->round_amount($credit, 2)) { + $form->error($locale->text('Out of balance transaction!')); + } + + if (! $form->{repost}) { + if ($form->{id}) { + &repost; + exit; + } + } + + if (GL->post_transaction(\%myconfig, \%$form)) { + $form->redirect($locale->text('Transaction posted!')); + } else { + $form->error($locale->text('Cannot post transaction!')); + } + +} + + diff --git a/bin/lynx/hr.pl b/bin/lynx/hr.pl new file mode 100755 index 00000000..9b86d86b --- /dev/null +++ b/bin/lynx/hr.pl @@ -0,0 +1,1246 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2004 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# payroll module +# +#====================================================================== + +use SL::HR; +use SL::User; + +1; +# end of main + + + +sub add { + + $label = "Add ".ucfirst $form->{db}; + $form->{title} = $locale->text($label); + + $form->{callback} = "$form->{script}?action=add&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &{ "$form->{db}_links" }; + +} + + +sub search { &{ "search_$form->{db}" } }; + + +sub search_employee { + + $form->{title} = $locale->text('Employees'); + + @a = (); + + push @a, qq|<input name="l_ndx" type=checkbox class=checkbox value=Y> |.$locale->text('Pos'); + push @a, qq|<input name="l_id" type=checkbox class=checkbox value=Y> |.$locale->text('ID'); + push @a, qq|<input name="l_employeenumber" type=checkbox class=checkbox value=Y checked> |.$locale->text('Employee Number'); + push @a, qq|<input name="l_name" type=checkbox class=checkbox value=Y checked> |.$locale->text('Employee Name'); + push @a, qq|<input name="l_address" type=checkbox class=checkbox value=Y> |.$locale->text('Address'); + push @a, qq|<input name="l_city" type=checkbox class=checkbox value=Y> |.$locale->text('City'); + push @a, qq|<input name="l_state" type=checkbox class=checkbox value=Y> |.$locale->text('State/Province'); + push @a, qq|<input name="l_zipcode" type=checkbox class=checkbox value=Y> |.$locale->text('Zip/Postal Code'); + push @a, qq|<input name="l_country" type=checkbox class=checkbox value=Y> |.$locale->text('Country'); + push @a, qq|<input name="l_workphone" type=checkbox class=checkbox value=Y checked> |.$locale->text('Work Phone'); + push @a, qq|<input name="l_homephone" type=checkbox class=checkbox value=Y checked> |.$locale->text('Home Phone'); + push @a, qq|<input name="l_startdate" type=checkbox class=checkbox value=Y checked> |.$locale->text('Startdate'); + push @a, qq|<input name="l_enddate" type=checkbox class=checkbox value=Y checked> |.$locale->text('Enddate'); + push @a, qq|<input name="l_sales" type=checkbox class=checkbox value=Y> |.$locale->text('Sales'); + push @a, qq|<input name="l_manager" type=checkbox class=checkbox value=Y> |.$locale->text('Manager'); + push @a, qq|<input name="l_role" type=checkbox class=checkbox value=Y checked> |.$locale->text('Role'); + push @a, qq|<input name="l_login" type=checkbox class=checkbox value=Y checked> |.$locale->text('Login'); + push @a, qq|<input name="l_email" type=checkbox class=checkbox value=Y> |.$locale->text('E-mail'); + push @a, qq|<input name="l_ssn" type=checkbox class=checkbox value=Y> |.$locale->text('SSN'); + push @a, qq|<input name="l_dob" type=checkbox class=checkbox value=Y> |.$locale->text('DOB'); + push @a, qq|<input name="l_iban" type=checkbox class=checkbox value=Y> |.$locale->text('IBAN'); + push @a, qq|<input name="l_bic" type=checkbox class=checkbox value=Y> |.$locale->text('BIC'); + push @a, qq|<input name="l_notes" type=checkbox class=checkbox value=Y> |.$locale->text('Notes'); + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Employee Number').qq|</th> + <td colspan=3><input name=employeenumber size=20></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Employee Name').qq|</th> + <td colspan=3><input name=name size=35></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Startdate').qq|</th> + <td>|.$locale->text('From').qq| <input name=startdatefrom size=11 title="$myconfig{dateformat}"> |.$locale->text('To').qq| <input name=startdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + <tr valign=top> + <th align=right nowrap>|.$locale->text('Notes').qq|</th> + <td colspan=3><input name=notes size=40></td> + </tr> + <tr> + <td></td> + <td colspan=3><input name=status class=radio type=radio value=all checked> |.$locale->text('All').qq| + <input name=status class=radio type=radio value=active> |.$locale->text('Active').qq| + <input name=status class=radio type=radio value=inactive> |.$locale->text('Inactive').qq| + <input name=status class=radio type=radio value=orphaned> |.$locale->text('Orphaned').qq| + <input name=sales class=checkbox type=checkbox value=Y> |.$locale->text('Sales').qq| + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td colspan=3> + <table> +|; + + while (@a) { + print qq|<tr>\n|; + for (1 .. 5) { + print qq|<td nowrap>|. shift @a; + print qq|</td>\n|; + } + print qq|</tr>\n|; + } + + print qq| + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=nextsub value=list_employees> +|; + + $form->hide_form(qw(db path login sessionid)); + + print qq| +<br> +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; +} + + +sub list_employees { + + HR->employees(\%myconfig, \%$form); + + $href = "$form->{script}?action=list_employees&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}"; + + $form->sort_order(); + + $callback = "$form->{script}?action=list_employees&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}"; + + @columns = $form->sort_columns(qw(id employeenumber name address city state zipcode country workphone homephone email startdate enddate ssn dob iban bic sales role manager login notes)); + unshift @columns, "ndx"; + + foreach $item (@columns) { + if ($form->{"l_$item"} eq "Y") { + push @column_index, $item; + + # add column to href and callback + $callback .= "&l_$item=Y"; + $href .= "&l_$item=Y"; + } + } + + %role = ( user => $locale->text('User'), + supervisor => $locale->text('Supervisor'), + manager => $locale->text('Manager'), + admin => $locale->text('Administrator') + ); + + $option = $locale->text('All'); + + if ($form->{status} eq 'sales') { + $option = $locale->text('Sales'); + } + if ($form->{status} eq 'orphaned') { + $option = $locale->text('Orphaned'); + } + if ($form->{status} eq 'active') { + $option = $locale->text('Active'); + } + if ($form->{status} eq 'inactive') { + $option = $locale->text('Inactive'); + } + + if ($form->{employeenumber}) { + $callback .= "&employeenumber=".$form->escape($form->{employeenumber},1); + $href .= "&employeenumber=".$form->escape($form->{employeenumber}); + $option .= "\n<br>".$locale->text('Employee Number')." : $form->{employeenumber}"; + } + if ($form->{name}) { + $callback .= "&name=".$form->escape($form->{name},1); + $href .= "&name=".$form->escape($form->{name}); + $option .= "\n<br>".$locale->text('Employee Name')." : $form->{name}"; + } + if ($form->{startdatefrom}) { + $callback .= "&startdatefrom=$form->{startdatefrom}"; + $href .= "&startdatefrom=$form->{startdatefrom}"; + $fromdate = $locale->date(\%myconfig, $form->{startdatefrom}, 1); + } + if ($form->{startdateto}) { + $callback .= "&startdateto=$form->{startdateto}"; + $href .= "&startdateto=$form->{startdateto}"; + $todate = $locale->date(\%myconfig, $form->{startdateto}, 1); + } + if ($fromdate || $todate) { + $option .= "\n<br>".$locale->text('Startdate')." $fromdate - $todate"; + } + + if ($form->{notes}) { + $callback .= "¬es=".$form->escape($form->{notes},1); + $href .= "¬es=".$form->escape($form->{notes}); + $option .= "\n<br>" if $option; + $option .= $locale->text('Notes')." : $form->{notes}"; + } + + $form->{callback} = "$callback&sort=$form->{sort}"; + $callback = $form->escape($form->{callback}); + + $column_header{ndx} = qq|<th class=listheading> </th>|; + $column_header{id} = qq|<th class=listheading>|.$locale->text('ID').qq|</th>|; + $column_header{employeenumber} = qq|<th><a class=listheading href=$href&sort=employeenumber>|.$locale->text('Number').qq|</a></th>|; + $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>|.$locale->text('Name').qq|</a></th>|; + $column_header{manager} = qq|<th><a class=listheading href=$href&sort=manager>|.$locale->text('Manager').qq|</a></th>|; + $column_header{address} = qq|<th class=listheading>|.$locale->text('Address').qq|</a></th>|; + $column_header{city} = qq|<th><a class=listheading href=$href&sort=city>|.$locale->text('City').qq|</a></th>|; + $column_header{state} = qq|<th><a class=listheading href=$href&sort=state>|.$locale->text('State/Province').qq|</a></th>|; + $column_header{zipcode} = qq|<th><a class=listheading href=$href&sort=zipcode>|.$locale->text('Zip/Postal Code').qq|</a></th>|; + $column_header{country} = qq|<th><a class=listheading href=$href&sort=country>|.$locale->text('Country').qq|</a></th>|; + $column_header{workphone} = qq|<th><a class=listheading href=$href&sort=workphone>|.$locale->text('Work Phone').qq|</a></th>|; + $column_header{homephone} = qq|<th><a class=listheading href=$href&sort=homephone>|.$locale->text('Home Phone').qq|</a></th>|; + + $column_header{startdate} = qq|<th><a class=listheading href=$href&sort=startdate>|.$locale->text('Startdate').qq|</a></th>|; + $column_header{enddate} = qq|<th><a class=listheading href=$href&sort=enddate>|.$locale->text('Enddate').qq|</a></th>|; + $column_header{notes} = qq|<th><a class=listheading href=$href&sort=notes>|.$locale->text('Notes').qq|</a></th>|; + $column_header{role} = qq|<th><a class=listheading href=$href&sort=role>|.$locale->text('Role').qq|</a></th>|; + $column_header{login} = qq|<th><a class=listheading href=$href&sort=login>|.$locale->text('Login').qq|</a></th>|; + + $column_header{sales} = qq|<th class=listheading>|.$locale->text('S').qq|</th>|; + $column_header{email} = qq|<th><a class=listheading href=$href&sort=email>|.$locale->text('E-mail').qq|</a></th>|; + $column_header{ssn} = qq|<th><a class=listheading href=$href&sort=ssn>|.$locale->text('SSN').qq|</a></th>|; + $column_header{dob} = qq|<th><a class=listheading href=$href&sort=dob>|.$locale->text('DOB').qq|</a></th>|; + $column_header{iban} = qq|<th><a class=listheading href=$href&sort=iban>|.$locale->text('IBAN').qq|</a></th>|; + $column_header{bic} = qq|<th><a class=listheading href=$href&sort=bic>|.$locale->text('BIC').qq|</a></th>|; + + $form->{title} = $locale->text('Employees'); + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + $i = 0; + foreach $ref (@{ $form->{all_employee} }) { + + $i++; + + $ref->{notes} =~ s/\r?\n/<br>/g; + for (@column_index) { $column_data{$_} = "<td>$ref->{$_} </td>" } + + $column_data{ndx} = "<td align=right>$i</td>"; + + $column_data{sales} = ($ref->{sales}) ? "<td>x</td>" : "<td> </td>"; + $column_data{role} = qq|<td>$role{"$ref->{role}"} </td>|; + $column_date{address} = qq|$ref->{address1} $ref->{address2}|; + + $column_data{name} = "<td><a href=$form->{script}?action=edit&db=employee&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}&callback=$callback>$ref->{name} </td>"; + + if ($ref->{email}) { + $email = $ref->{email}; + $email =~ s/</\</; + $email =~ s/>/\>/; + + $column_data{email} = qq|<td><a href="mailto:$ref->{email}">$email</a></td>|; + } + + $j++; $j %= 2; + print " + <tr class=listrow$j> +"; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + } + + $i = 1; + $button{'HR--Employees--Add Employee'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Employee').qq|"> |; + $button{'HR--Employees--Add Employee'}{order} = $i++; + + foreach $item (split /;/, $myconfig{acs}) { + delete $button{$item}; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(callback db path login sessionid)); + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub edit { + +# $locale->text('Edit Employee') +# $locale->text('Edit Deduction') + + $label = ucfirst $form->{db}; + $form->{title} = "Edit $label"; + + &{ "$form->{db}_links" }; + +} + + +sub employee_links { + +#$form->{deductions} = 1; + HR->get_employee(\%myconfig, \%$form); + + for (keys %$form) { $form->{$_} = $form->quote($form->{$_}) } + + if (@{ $form->{all_deduction} }) { + $form->{selectdeduction} = "<option>\n"; + for (@{ $form->{all_deduction} }) { $form->{selectdeduction} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + $form->{manager} = "$form->{manager}--$form->{managerid}"; + + if (@{ $form->{all_manager} }) { + $form->{selectmanager} = "<option>\n"; + for (@{ $form->{all_manager} }) { $form->{selectmanager} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + %role = ( user => $locale->text('User'), + supervisor => $locale->text('Supervisor'), + manager => $locale->text('Manager'), + admin => $locale->text('Administrator') + ); + + $form->{selectrole} = "<option>\n"; + for (qw(user supervisor manager admin)) { $form->{selectrole} .= "<option value=$_>$role{$_}\n" } + + $i = 1; + foreach $ref (@{ $form->{all_employeededuction} }) { + $form->{"deduction_$i"} = "$ref->{description}--$ref->{id}" if $ref->{id}; + for (qw(before after rate)) { $form->{"${_}_$i"} = $ref->{$_} } + $i++; + } + $form->{deduction_rows} = $i - 1; + + &employee_header; + &employee_footer; + +} + + +sub employee_header { + + $sales = qq|<input type=hidden name=sales value=$form->{sales}>|; + $form->{sales} = ($form->{sales}) ? "checked" : ""; + + $form->{selectrole} =~ s/ selected//; + $form->{selectrole} =~ s/option value=\Q$form->{role}\E>/option value=$form->{role} selected>/; + + $form->{selectdeduction} = $form->unescape($form->{selectdeduction}); + + $form->{selectmanager} = $form->unescape($form->{selectmanager}); + $form->{selectmanager} =~ s/ selected//; + $form->{selectmanager} =~ s/(<option value="\Q$form->{manager}\E")/$1 selected/; + + $sales .= qq| +<input type=hidden name=role value=$form->{role}> +<input type=hidden name=manager value=$form->{manager}> +|; + + if ($myconfig{role} ne 'user') { + $sales = qq| + <tr> + <th align=right>|.$locale->text('Sales').qq|</th> + <td><input name=sales class=checkbox type=checkbox value=1 $form->{sales}></td> + </tr> + <tr> + <th align=right>|.$locale->text('Role').qq|</th> + <td><select name=role>$form->{selectrole}</select></td> + </tr> +|; + + if ($form->{selectmanager}) { + $sales .= qq| + <tr> + <th align=right>|.$locale->text('Manager').qq|</th> + <td><select name=manager>$form->{selectmanager}</select></td> + </tr> +|; + } + } + + $form->{deduction_rows}++; + + for $i (1 .. $form->{deduction_rows}) { + $form->{"selectdeduction_$i"} = $form->{selectdeduction}; + if ($form->{"deduction_$i"}) { + $form->{"selectdeduction_$i"} =~ s/(<option value="\Q$form->{"deduction_$i"}\E")/$1 selected/; + } + } + + $form->{selectdeduction} = $form->escape($form->{selectdeduction},1); + $form->{selectmanager} = $form->escape($form->{selectmanager},1); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=selectdeduction value="$form->{selectdeduction}"> +<input type=hidden name=deduction_rows value=$form->{deduction_rows}> + +<input type=hidden name=selectmanager value="$form->{selectmanager}"> +<input type=hidden name=selectrole value="$form->{selectrole}"> + +<input type=hidden name=status value=$form->{status}> + +<input type=hidden name=title value="$form->{title}"> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr valign=top> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Number').qq|</th> + <td><input name=employeenumber size=32 maxlength=32 value="$form->{employeenumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Name').qq|</th> + <td><input name=name size=35 maxlength=64 value="$form->{name}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Address').qq|</th> + <td><input name=address1 size=35 maxlength=32 value="$form->{address1}"></td> + </tr> + <tr> + <th></th> + <td><input name=address2 size=35 maxlength=32 value="$form->{address2}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('City').qq|</th> + <td><input name=city size=35 maxlength=32 value="$form->{city}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('State/Province').qq|</th> + <td><input name=state size=35 maxlength=32 value="$form->{state}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Zip/Postal Code').qq|</th> + <td><input name=zipcode size=10 maxlength=10 value="$form->{zipcode}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Country').qq|</th> + <td><input name=country size=35 maxlength=32 value="$form->{country}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('E-mail').qq|</th> + <td><input name=email size=35 value="$form->{email}"></td> + </tr> + <tr> + $sales + </table> + </td> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Work Phone').qq|</th> + <td><input name=workphone size=20 maxlength=20 value="$form->{workphone}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Home Phone').qq|</th> + <td><input name=homephone size=20 maxlength=20 value="$form->{homephone}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Startdate').qq|</th> + <td><input name=startdate size=11 title="$myconfig{dateformat}" value=$form->{startdate}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Enddate').qq|</th> + <td><input name=enddate size=11 title="$myconfig{dateformat}" value=$form->{enddate}></td> + </tr> + + <tr> + <th align=right nowrap>|.$locale->text('SSN').qq|</th> + <td><input name=ssn size=20 maxlength=20 value="$form->{ssn}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('DOB').qq|</th> + <td><input name=dob size=11 title="$myconfig{dateformat}" value=$form->{dob}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('IBAN').qq|</th> + <td><input name=iban size=34 maxlength=34 value="$form->{iban}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('BIC').qq|</th> + <td><input name=bic size=11 maxlength=11 value="$form->{bic}"></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <th align=left nowrap>|.$locale->text('Notes').qq|</th> + </tr> + <tr> + <td><textarea name=notes rows=3 cols=60 wrap=soft>$form->{notes}</textarea></td> + </tr> +|; + + if ($form->{selectdeduction}) { + + print qq| + <tr> + <td> + <table width=100%> + <tr class=listheading> + <th class=listheading>|.$locale->text('Payroll Deduction').qq|</th> + <th class=listheading colspan=3>|.$locale->text('Allowances').qq|</th> + </tr> + + <tr class=listheading> + <th></th> + <th class=listheading>|.$locale->text('Before Deduction').qq|</th> + <th class=listheading>|.$locale->text('After Deduction').qq|</th> + <th class=listheading>|.$locale->text('Rate').qq|</th> + </tr> +|; + + for $i (1 .. $form->{deduction_rows}) { + print qq| + <tr> + <td><select name="deduction_$i">$form->{"selectdeduction_$i"}</select></td> + <td><input name="before_$i" value=|.$form->format_amount(\%myconfig, $form->{"before_$i"}, 2).qq|></td> + <td><input name="after_$i" value=|.$form->format_amount(\%myconfig, $form->{"after_$i"}, 2).qq|></td> + <td><input name="rate_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"rate_$i"}).qq|></td> + </tr> +|; + } + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + + +sub employee_footer { + + print qq| +<input name=id type=hidden value=$form->{id}> + +<input type=hidden name=db value=$form->{db}> +<input type=hidden name=employeelogin value=$form->{employeelogin}> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=hidden name=callback value="$form->{callback}"> + +<br> + +<input class=submit type=submit name=action value="|.$locale->text('Update').qq|"> +<input class=submit type=submit name=action value="|.$locale->text('Save').qq|"> +|; + + if ($form->{id}) { + print qq|<input class=submit type=submit name=action value="|.$locale->text('Save as new').qq|">\n|; + if ($form->{status} eq 'orphaned') { + print qq|<input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">\n|; + } + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + + </form> + +</body> +</html> +|; + +} + + +sub save { &{ "save_$form->{db}" } }; + + +sub save_employee { + + $form->isblank("name", $locale->text("Name missing!")); + HR->save_employee(\%myconfig, \%$form); + + # if it is a login change memberfile and .conf + if ($form->{employeelogin}) { + $user = new User $memberfile, $form->{employeelogin}; + + for (qw(name email role)) { $user->{$_} = $form->{$_} } + + # assign $myconfig for db + for (qw(dbconnect dbhost dbport dbpasswd)) { $user->{$_} = $myconfig{$_} } + + for (qw(dbpasswd password)) { $user->{"old_$_"} = $user->{$_} } + $user->{packpw} = 1; + + $user->save_member($memberfile, $userspath) if $user->{login}; + } + + $form->redirect($locale->text('Employee saved!')); + +} + + +sub delete { &{ "delete_$form->{db}" } }; + + +sub delete_employee { + + HR->delete_employee(\%myconfig, \%$form); + $form->redirect($locale->text('Employee deleted!')); + +} + + +sub continue { &{ $form->{nextsub} } }; + +sub add_employee { &add }; +sub add_deduction { &add }; + + +sub search_deduction { + + HR->deductions(\%myconfig, \%$form); + + $href = "$form->{script}?action=search_deduction&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->sort_order(); + + $callback = "$form->{script}?action=search_deduction&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"; + + @column_index = $form->sort_columns(qw(description rate amount above below employeepays employerpays ap_accno expense_accno)); + + + $form->{callback} = $callback; + $callback = $form->escape($form->{callback}); + + $column_header{description} = qq|<th class=listheading href=$href>|.$locale->text('Description').qq|</th>|; + $column_header{rate} = qq|<th class=listheading nowrap>|.$locale->text('Rate').qq|<br>%</th>|; + $column_header{amount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|; + $column_header{above} = qq|<th class=listheading>|.$locale->text('Above').qq|</th>|; + $column_header{below} = qq|<th class=listheading>|.$locale->text('Below').qq|</th>|; + $column_header{employerpays} = qq|<th class=listheading>|.$locale->text('Employer').qq|</th>|; + $column_header{employeepays} = qq|<th class=listheading>|.$locale->text('Employee').qq|</th>|; + + $column_header{ap_accno} = qq|<th class=listheading>|.$locale->text('AP').qq|</th>|; + $column_header{expense_accno} = qq|<th class=listheading>|.$locale->text('Expense').qq|</th>|; + + $form->{title} = $locale->text('Deductions'); + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + + foreach $ref (@{ $form->{all_deduction} }) { + + $rate = $form->format_amount(\%myconfig, $ref->{rate} * 100, "", " "); + + $column_data{rate} = "<td align=right>$rate</td>"; + + for (qw(amount below above)) { $column_data{$_} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{$_}, 2, " ")."</td>" } + + for (qw(ap_accno expense_accno)) { $column_data{$_} = "<td>$ref->{$_} </td>" } + + for (qw(employerpays employeepays)) { $column_data{$_} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{$_}, "", " ")."</td>" } + + if ($ref->{description} ne $sameitem) { + $column_data{description} = "<td><a href=$form->{script}?action=edit&db=$form->{db}&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{description}</a></td>"; + } else { + $column_data{description} = "<td> </td>"; + } + + $i++; $i %= 2; + print " + <tr class=listrow$i> +"; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + $sameitem = $ref->{description}; + + } + + $i = 1; + $button{'HR--Deductions--Add Deduction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Deduction').qq|"> |; + $button{'HR--Deductions--Add Deduction'}{order} = $i++; + + foreach $item (split /;/, $myconfig{acs}) { + delete $button{$item}; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> + +<input type=hidden name=db value=$form->{db}> + +<input name=callback type=hidden value="$form->{callback}"> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> +|; + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub deduction_links { + + HR->get_deduction(\%myconfig, \%$form); + + $i = 1; + foreach $ref (@{ $form->{deductionrate} }) { + for (keys %$ref) { $form->{"${_}_$i"} = $ref->{$_} } + $i++; + } + $form->{rate_rows} = $i - 1; + + $i = 1; + foreach $ref (@{ $form->{deductionbase} }) { + $form->{"base_$i"} = "$ref->{description}--$ref->{id}" if $ref->{id}; + $form->{"maximum_$i"} = $ref->{maximum}; + $i++; + } + $form->{base_rows} = $i - 1; + + $i = 1; + foreach $ref (@{ $form->{deductionafter} }) { + $form->{"after_$i"} = "$ref->{description}--$ref->{id}" if $ref->{id}; + $i++; + } + $form->{after_rows} = $i - 1; + + $form->{employeepays} = 1; + + $selectaccount = "<option>\n"; + for (@{ $form->{ap_accounts} }) { $selectaccount .= "<option>$_->{accno}--$_->{description}\n" } + + $form->{ap_accno} = qq|$form->{ap_accno}--$form->{ap_description}|; + $form->{selectap} = $selectaccount; + + $selectaccount = "<option>\n"; + for (@{ $form->{expense_accounts} }) { $selectaccount .= "<option>$_->{accno}--$_->{description}\n" } + + $form->{expense_accno} = qq|$form->{expense_accno}--$form->{expense_description}|; + $form->{selectexpense} = $selectaccount; + + for (1 .. $form->{rate_rows}) { $form->{"rate_$_"} *= 100 } + + $form->{selectbase} = "<option>\n"; + for (@{ $form->{all_deduction} }) { $form->{selectbase} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + + &deduction_header; + &deduction_footer; + +} + + +sub deduction_header { + + $selectap = $form->{selectap}; + $selectap =~ s/option>\Q$form->{ap_accno}\E/option selected>$form->{ap_accno}/; + $selectexpense = $form->{selectexpense}; + $selectexpense =~ s/option>\Q$form->{expense_accno}\E/option selected>$form->{expense_accno}/; + + + $form->{rate_rows}++; + $form->{base_rows}++; + $form->{after_rows}++; + + $form->{selectbase} = $form->unescape($form->{selectbase}); + + for $i (1 .. $form->{base_rows}) { + $form->{"selectbase_$i"} = $form->{selectbase}; + if ($form->{"base_$i"}) { + $form->{"selectbase_$i"} =~ s/(<option value="\Q$form->{"base_$i"}\E")/$1 selected/; + } + } + for $i (1 .. $form->{after_rows}) { + $form->{"selectafter_$i"} = $form->{selectbase}; + if ($form->{"after_$i"}) { + $form->{"selectafter_$i"} =~ s/(<option value="\Q$form->{"after_$i"}\E")/$1 selected/; + } + } + + + $form->header; + + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=title value="$form->{title}"> + +<input type=hidden name=selectap value="$form->{selectap}"> +<input type=hidden name=selectexpense value="$form->{selectexpense}"> +<input type=hidden name=selectbase value="|.$form->escape($form->{selectbase},1).qq|"> + +<input type=hidden name=rate_rows value=$form->{rate_rows}> +<input type=hidden name=base_rows value=$form->{base_rows}> +<input type=hidden name=after_rows value=$form->{after_rows}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Description').qq|</th> + <td><input name=description size=35 value="$form->{description}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('AP').qq|</th> + <td><select name=ap_accno>$selectap</select></td> + <th align=right nowrap>|.$locale->text('Employee pays').qq| x</th> + <td><input name=employeepays size=4 value=|.$form->format_amount(\%myconfig, $form->{employeepays}).qq|></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Expense').qq|</th> + <td><select name=expense_accno>$selectexpense</select></td> + <th align=right nowrap>|.$locale->text('Employer pays').qq| x</th> + <td><input name=employerpays size=4 value=|.$form->format_amount(\%myconfig, $form->{employerpays}).qq|></td> + </tr> + <tr> + <td></td> + <td></td> + <th align=right nowrap>|.$locale->text('Exempt age <').qq|</th> + <td><input name=fromage size=4 value=|.$form->format_amount(\%myconfig, $form->{fromage}).qq|></td> + <th align=right nowrap>></th> + <td><input name=toage size=4 value=|.$form->format_amount(\%myconfig, $form->{toage}).qq|> + </tr> + <tr> + <td></td> + <td> + <table> + <tr class=listheading> + <th class=listheading>|.$locale->text('Rate').qq| %</th> + <th class=listheading>|.$locale->text('Amount').qq|</th> + <th class=listheading>|.$locale->text('Above').qq|</th> + <th class=listheading>|.$locale->text('Below').qq|</th> + </tr> +|; + + for $i (1 .. $form->{rate_rows}) { + print qq| + <tr> + <td><input name="rate_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"rate_$i"}).qq|></td> + <td><input name="amount_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"amount_$i"}, 2).qq|></td> + <td><input name="above_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"above_$i"}, 2).qq|></td> + <td><input name="below_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"below_$i"}, 2).qq|></td> + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + </table> + </td> + </tr> +|; + + print qq| + <tr> + <td> + <table> +|; + + $basedon = $locale->text('Based on'); + $maximum = $locale->text('Maximum'); + + for $i (1 .. $form->{base_rows}) { + print qq| + <tr> + <th>$basedon</th> + <td><select name="base_$i">$form->{"selectbase_$i"}</select></td> + <th>$maximum</th> + <td><input name="maximum_$i" value=|.$form->format_amount(\%myconfig, $form->{"maximum_$i"}, 2).qq|></td> + </tr> +|; + $basedon = ""; + $maximum = ""; + } + + $deductafter = $locale->text('Deduct after'); + + for $i (1 .. $form->{after_rows}) { + print qq| + <tr> + <th>$deductafter</th> + <td><select name="after_$i">$form->{"selectafter_$i"}</select></td> + </tr> +|; + $deductafter = ""; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + + +sub deduction_footer { + + print qq| +<input name=id type=hidden value=$form->{id}> + +<input type=hidden name=db value=$form->{db}> + +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=hidden name=callback value="$form->{callback}"> + +<br> + +<input class=submit type=submit name=action value="|.$locale->text("Update").qq|"> +<input class=submit type=submit name=action value="|.$locale->text("Save").qq|"> +|; + + if ($form->{id}) { + print qq|<input class=submit type=submit name=action value="|.$locale->text('Save as new').qq|">\n|; + + if ($form->{status} eq 'orphaned') { + print qq|<input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">\n|; + } + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + + </form> + +</body> +</html> +|; + +} + + +sub update { &{ "update_$form->{db}" }; } +sub save { &{ "save_$form->{db}" } }; + + +sub update_deduction { + + # if rate or amount is blank remove row + @flds = qw(rate amount above below); + $count = 0; + @a = (); + for $i (1 .. $form->{rate_rows}) { + for (@flds) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + if ($form->{"rate_$i"} || $form->{"amount_$i"}) { + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + $form->redo_rows(\@flds, \@a, $count, $form->{rate_rows}); + $form->{rate_rows} = $count; + + + @flds = qw(base maximum); + $count = 0; + @a = (); + for $i (1 .. $form->{"base_rows"}) { + $form->{"maximum_$i"} = $form->parse_amount(\%myconfig, $form->{"maximum_$i"}); + if ($form->{"base_$i"}) { + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + $form->redo_rows(\@flds, \@a, $count, $form->{"base_rows"}); + $form->{"base_rows"} = $count; + + + @flds = qw(after); + $count = 0; + @a = (); + for $i (1 .. $form->{"after_rows"}) { + if ($form->{"after_$i"}) { + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + $form->redo_rows(\@flds, \@a, $count, $form->{"after_rows"}); + $form->{"after_rows"} = $count; + + &deduction_header; + &deduction_footer; + +} + + +sub update_employee { + + # if rate or amount is blank remove row + @flds = qw(before after); + $count = 0; + @a = (); + for $i (1 .. $form->{deduction_rows}) { + for (@flds) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + if ($form->{"deduction_$i"}) { + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + $form->redo_rows(\@flds, \@a, $count, $form->{deduction_rows}); + $form->{deduction_rows} = $count; + + &employee_header; + &employee_footer; + +} + + +sub save_as_new { + + $form->{id} = 0; + delete $form->{employeelogin}; + + &save; + +} + + +sub save_deduction { + + $form->isblank("description", $locale->text("Description missing!")); + + unless ($form->{"rate_1"} || $form->{"amount_1"}) { + $form->isblank("rate_1", $locale->text("Rate missing!")) unless $form->{"amount_1"}; + $form->isblank("amount_1", $locale->text("Amount missing!")); + } + + HR->save_deduction(\%myconfig, \%$form); + $form->redirect($locale->text('Deduction saved!')); + +} + + +sub delete_deduction { + + HR->delete_deduction(\%myconfig, \%$form); + $form->redirect($locale->text('Deduction deleted!')); + +} + + diff --git a/bin/lynx/ic.pl b/bin/lynx/ic.pl new file mode 100755 index 00000000..47e0304d --- /dev/null +++ b/bin/lynx/ic.pl @@ -0,0 +1,3238 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Inventory Control module +# +#====================================================================== + + +use SL::IC; + +require "$form->{path}/io.pl"; + +1; +# end of main + + + +sub add { + + %label = ( part => 'Part', + service => 'Service', + assembly => 'Assembly', + labor => 'Labor/Overhead', ); + +# $locale->text('Add Part') +# $locale->text('Add Service') +# $locale->text('Add Assembly') +# $locale->text('Add Labor/Overhead') + + $label = "Add $label{$form->{item}}"; + $form->{title} = $locale->text($label); + + $form->{callback} = "$form->{script}?action=add&item=$form->{item}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + $form->{orphaned} = 1; + + if ($form->{previousform}) { + $form->{callback} = ""; + } + + &link_part; + + &display_form; + +} + + +sub edit { + + %label = ( part => 'Part', + service => 'Service', + assembly => 'Assembly', + labor => 'Labor/Overhead', ); + +# $locale->text('Edit Part') +# $locale->text('Edit Service') +# $locale->text('Edit Assembly') +# $locale->text('Edit Labor/Overhead') + + IC->get_part(\%myconfig, \%$form); + + $label = "Edit $label{$form->{item}}"; + $form->{title} = $locale->text($label); + + $form->{previousform} = $form->escape($form->{previousform}, 1) if $form->{previousform}; + + &link_part; + + &display_form; + +} + + + +sub link_part { + + IC->create_links("IC", \%myconfig, \%$form); + + # currencies + $form->{selectcurrency} = ""; + for (split /:/, $form->{currencies}) { $form->{selectcurrency} .= "<option>$_\n" } + + # readonly + if ($form->{item} eq 'part') { + $form->{readonly} = 1 if $myconfig{acs} =~ /Goods \& Services--Add Part/; + $form->error($locale->text('Cannot create Part').";".$locale->text('Inventory account does not exist!')) if ! @{ $form->{IC_links}{IC} }; + $form->error($locale->text('Cannot create Part').";".$locale->text('Income account does not exist!')) if ! @{ $form->{IC_links}{IC_sale} }; + $form->error($locale->text('Cannot create Part').";".$locale->text('COGS account does not exist!')) if ! @{ $form->{IC_links}{IC_cogs} }; + } + + if ($form->{item} eq 'service') { + $form->{readonly} = 1 if $myconfig{acs} =~ /Goods \& Services--Add Service/; + $form->error($locale->text('Cannot create Service').";".$locale->text('Income account does not exist!')) if ! @{ $form->{IC_links}{IC_income} }; + $form->error($locale->text('Cannot create Service').";".$locale->text('Expense account does not exist!')) if ! @{ $form->{IC_links}{IC_expense} }; + } + + if ($form->{item} eq 'assembly') { + $form->{readonly} = 1 if $myconfig{acs} =~ /Goods \& Services--Add Assembly/; + $form->error($locale->text('Cannot create Assembly').";".$locale->text('Income account does not exist!')) if ! @{ $form->{IC_links}{IC_income} }; + } + if ($form->{item} eq 'labor') { + $form->{readonly} = 1 if $myconfig{acs} =~ /Goods \& Services--Add Labor\/Overhead/; + $form->error($locale->text('Cannot create Labor').";".$locale->text('Inventory account does not exist!')) if ! @{ $form->{IC_links}{IC} }; + $form->error($locale->text('Cannot create Labor').";".$locale->text('COGS account does not exist!')) if ! @{ $form->{IC_links}{IC_cogs} }; + } + + + # parts, assemblies , labor and overhead have the same links + $taxpart = ($form->{item} eq 'service') ? "service" : "part"; + + # build the popup menus + $form->{taxaccounts} = ""; + foreach $key (keys %{ $form->{IC_links} }) { + + $form->{"select$key"} = ""; + foreach $ref (@{ $form->{IC_links}{$key} }) { + # if this is a tax field + if ($key =~ /IC_tax/) { + if ($key =~ /$taxpart/) { + + $form->{taxaccounts} .= "$ref->{accno} "; + $form->{"IC_tax_$ref->{accno}_description"} = "$ref->{accno}--$ref->{description}"; + + if ($form->{id}) { + if ($form->{amount}{$ref->{accno}}) { + $form->{"IC_tax_$ref->{accno}"} = "checked"; + } + } else { + $form->{"IC_tax_$ref->{accno}"} = "checked"; + } + + } + } else { + + $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n"; + + } + } + } + chop $form->{taxaccounts}; + + if ($form->{item} !~ /service/) { + $form->{selectIC_inventory} = $form->{selectIC}; + $form->{selectIC_income} = $form->{selectIC_sale}; + $form->{selectIC_expense} = $form->{selectIC_cogs}; + $form->{IC_income} = $form->{IC_sale}; + $form->{IC_expense} = $form->{IC_cogs}; + } + + # set option + for (qw(IC_inventory IC_income IC_expense)) { $form->{$_} = "$form->{amount}{$_}{accno}--$form->{amount}{$_}{description}" if $form->{amount}{$_}{accno} } + + delete $form->{IC_links}; + delete $form->{amount}; + + $form->get_partsgroup(\%myconfig, {all => 1}); + if ($form->{partsgroup}) { + $form->{partsgroup} = $form->quote($form->{partsgroup})."--$form->{partsgroup_id}"; + } + + if (@{ $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = qq|<option>\n|; + + for (@{ $form->{all_partsgroup} }) { $form->{selectpartsgroup} .= qq|<option value="|.$form->quote($_->{partsgroup}).qq|--$_->{id}">$_->{partsgroup}\n| } + delete $form->{all_partsgroup}; + } + + if ($form->{item} eq 'assembly') { + + for (1 .. $form->{assembly_rows}) { + if ($form->{"partsgroup_id_$_"}) { + $form->{"partsgroup_$_"} = qq|$form->{"partsgroup_$_"}--$form->{"partsgroup_id_$_"}|; + } + } + + $form->get_partsgroup(\%myconfig); + + if (@{ $form->{all_partsgroup} }) { + $form->{selectassemblypartsgroup} = qq|<option>\n|; + + for (@{ $form->{all_partsgroup} }) { $form->{selectassemblypartsgroup} .= qq|<option value="$_->{partsgroup}--$_->{id}">$_->{partsgroup}\n| } + delete $form->{all_partsgroup}; + } + } + + # setup make and models + $i = 1; + foreach $ref (@{ $form->{makemodels} }) { + for (qw(make model)) { $form->{"${_}_$i"} = $ref->{$_} } + $i++; + } + $form->{makemodel_rows} = $i - 1; + delete $form->{makemodels}; + + + # setup vendors + if (@{ $form->{all_vendor} }) { + $form->{selectvendor} = "<option>\n"; + for (@{ $form->{all_vendor} }) { $form->{selectvendor} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + delete $form->{all_vendor}; + } + + # vendor matrix + $i = 1; + foreach $ref (@{ $form->{vendormatrix} }) { + $form->{"vendor_$i"} = qq|$ref->{name}--$ref->{id}|; + + for (qw(partnumber lastcost leadtime vendorcurr)) { $form->{"${_}_$i"} = $ref->{$_} } + $i++; + } + $form->{vendor_rows} = $i - 1; + delete $form->{vendormatrix}; + + # setup customers and groups + if (@{ $form->{all_customer} }) { + $form->{selectcustomer} = "<option>\n"; + for (@{ $form->{all_customer} }) { $form->{selectcustomer} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + delete $form->{all_customer}; + } + + if (@{ $form->{all_pricegroup} }) { + $form->{selectpricegroup} = "<option>\n"; + for (@{ $form->{all_pricegroup} }) { $form->{selectpricegroup} .= qq|<option value="$_->{pricegroup}--$_->{id}">$_->{pricegroup}\n| } + delete $form->{all_pricegroup}; + } + + $i = 1; + # customer matrix + foreach $ref (@{ $form->{customermatrix} }) { + + $form->{"customer_$i"} = "$ref->{name}--$ref->{cid}" if $ref->{cid}; + $form->{"pricegroup_$i"} = "$ref->{pricegroup}--$ref->{gid}" if $ref->{gid}; + + for (qw(validfrom validto pricebreak customerprice customercurr)) { $form->{"${_}_$i"} = $ref->{$_} } + + $i++; + + } + $form->{customer_rows} = $i - 1; + delete $form->{customermatrix}; + +} + + + +sub form_header { + + if ($form->{lastcost} > 0) { + $markup = $form->round_amount((($form->{sellprice}/$form->{lastcost} - 1) * 100), 1); + $form->{markup} = $form->format_amount(\%myconfig, $markup, 1); + } + + ($dec) = ($form->{sellprice} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + for (qw(listprice sellprice)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, $decimalplaces) } + + ($dec) = ($form->{lastcost} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + for (qw(lastcost avgcost)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, $decimalplaces) } + + for (qw(weight rop stock)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}) } + + for (qw(partnumber description unit notes)) { $form->{$_} = $form->quote($form->{$_}) } + + if (($rows = $form->numtextrows($form->{notes}, 40)) < 2) { + $rows = 2; + } + + $notes = qq|<textarea name=notes rows=$rows cols=40 wrap=soft>$form->{notes}</textarea>|; + + if (($rows = $form->numtextrows($form->{description}, 40)) > 1) { + $description = qq|<textarea name="description" rows=$rows cols=40 wrap=soft>$form->{description}</textarea>|; + } else { + $description = qq|<input name=description size=40 value="$form->{description}">|; + } + + for (split / /, $form->{taxaccounts}) { $form->{"IC_tax_$_"} = ($form->{"IC_tax_$_"}) ? "checked" : "" } + + $form->{selectIC_inventory} = $form->{selectIC}; + + # set option + for (qw(IC_inventory IC_income IC_expense)) { + if ($form->{$_}) { + if ($form->{orphaned}) { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/option>\Q$form->{$_}\E/option selected>$form->{$_}/; + } else { + $form->{"select$_"} = qq|<option selected>$form->{$_}|; + } + } + } + + if ($form->{selectpartsgroup}) { + $form->{selectpartsgroup} = $form->unescape($form->{selectpartsgroup}); + + $partsgroup = qq|<input type=hidden name=selectpartsgroup value="|.$form->escape($form->{selectpartsgroup},1).qq|">|; + + $form->{partsgroup} = $form->quote($form->{partsgroup}); + $form->{selectpartsgroup} =~ s/(<option value="\Q$form->{partsgroup}\E")/$1 selected/; + + $partsgroup .= qq|\n<select name=partsgroup>$form->{selectpartsgroup}</select>|; + $group = $locale->text('Group'); + } + + # tax fields + foreach $item (split / /, $form->{taxaccounts}) { + $tax .= qq| + <input class=checkbox type=checkbox name="IC_tax_$item" value=1 $form->{"IC_tax_$item"}> <b>$form->{"IC_tax_${item}_description"}</b> + <br><input type=hidden name=IC_tax_${item}_description value="$form->{"IC_tax_${item}_description"}"> +|; + } + + + $sellprice = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Sell Price').qq|</th> + <td><input name=sellprice size=11 value=$form->{sellprice}></td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('List Price').qq|</th> + <td><input name=listprice size=11 value=$form->{listprice}></td> + </tr> +|; + + $avgcost = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Average Cost').qq|</th> + <td><input type=hidden name=avgcost value=$form->{avgcost}>$form->{avgcost}</td> + </tr> +|; + + $lastcost = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Last Cost').qq|</th> + <td><input name=lastcost size=11 value=$form->{lastcost}></td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('Markup').qq| %</th> + <td><input name=markup size=5 value=$form->{markup}></td> + <input type=hidden name=oldmarkup value=$markup> + </tr> +|; + + + if ($form->{item} =~ /(part|assembly)/) { + $n = ($form->{onhand} > 0) ? "1" : "0"; + $onhand = qq| + <tr> + <th align="right" nowrap>|.$locale->text('On Hand').qq|</th> + <th align=left nowrap class="plus$n"> |.$form->format_amount(\%myconfig, $form->{onhand}).qq|</th> + </tr> +|; + + $rop = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('ROP').qq|</th> + <td><input name=rop size=10 value=$form->{rop}></td> + </tr> +|; + + $bin = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Bin').qq|</th> + <td><input name=bin size=10 value="$form->{bin}"></td> + </tr> +|; + + $imagelinks = qq| + <tr> + <td> + <table width=100%> + <tr> + <th align=right nowrap>|.$locale->text('Image').qq|</th> + <td><input name=image size=40 value="$form->{image}"></td> + <th align=right nowrap>|.$locale->text('Microfiche').qq|</th> + <td><input name=microfiche size=20 value="$form->{microfiche}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Drawing').qq|</th> + <td><input name=drawing size=40 value="$form->{drawing}"></td> + </tr> + </table> + </td> + </tr> +|; + } + + + if ($form->{item} eq "part") { + + $linkaccounts = qq| + <tr> + <th align=right>|.$locale->text('Inventory').qq|</th> + <td><select name=IC_inventory>$form->{selectIC_inventory}</select></td> + <input name=selectIC type=hidden value="$form->{selectIC}"> + </tr> + <tr> + <th align=right>|.$locale->text('Income').qq|</th> + <td><select name=IC_income>$form->{selectIC_income}</select></td> + <input name=selectIC_income type=hidden value="$form->{selectIC_income}"> + </tr> + <tr> + <th align=right>|.$locale->text('COGS').qq|</th> + <td><select name=IC_expense>$form->{selectIC_expense}</select></td> + <input name=selectIC_expense type=hidden value="$form->{selectIC_expense}"> + </tr> +|; + + if ($tax) { + $linkaccounts .= qq| + <tr> + <th align=right>|.$locale->text('Tax').qq|</th> + <td>$tax</td> + </tr> +|; + } + + $weight = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Weight').qq|</th> + <td> + <table> + <tr> + <td> + <input name=weight size=10 value=$form->{weight}> + </td> + <th> + + $form->{weightunit} + <input type=hidden name=weightunit value=$form->{weightunit}> + </th> + </tr> + </table> + </td> + </tr> +|; + + } + + + if ($form->{item} eq "assembly") { + + $avgcost = ""; + + if ($form->{project_id}) { + $weight = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Weight').qq|</th> + <td> + <table> + <tr> + <td> + <input name=weight size=10 value=$form->{weight}> + </td> + <th> + + $form->{weightunit} + <input type=hidden name=weightunit value=$form->{weightunit}> + </th> + </tr> + </table> + </td> + </tr> +|; + } else { + + $weight = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Weight').qq|</th> + <td> + <table> + <tr> + <td> + $form->{weight} + <input type=hidden name=weight value=$form->{weight}> + </td> + <th> + + $form->{weightunit} + <input type=hidden name=weightunit value=$form->{weightunit}> + </th> + </tr> + </table> + </td> + </tr> +|; + } + + + if ($form->{project_id}) { + $lastcost = ""; + $avgcost = ""; + $onhand = ""; + $rop = ""; + $form->{isassemblyitem} = 1; + + } else { + $stock = qq| + <tr> + <th align="right" nowrap>|.$locale->text('Stock').qq|</th> + <td><input name=stock size=10 value=$form->{stock}></td> + </tr> +|; + + $lastcost = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Last Cost').qq|</th> + <td><input type=hidden name=lastcost value=$form->{lastcost}>$form->{lastcost}</td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('Markup').qq| %</th> + <td><input name=markup size=5 value=$form->{markup}></td> + <input type=hidden name=oldmarkup value=$markup> + </tr> +|; + + } + + $linkaccounts = qq| + <tr> + <th align=right>|.$locale->text('Income').qq|</th> + <td><select name=IC_income>$form->{selectIC_income}</select></td> + <input name=selectIC_income type=hidden value="$form->{selectIC_income}"> + </tr> +|; + + if ($tax) { + $linkaccounts .= qq| + <tr> + <th align=right>|.$locale->text('Tax').qq|</th> + <td>$tax</td> + </tr> +|; + } + + } + + + if ($form->{item} eq "service") { + $avgcost = ""; + $linkaccounts = qq| + <tr> + <th align=right>|.$locale->text('Income').qq|</th> + <td><select name=IC_income>$form->{selectIC_income}</select></td> + <input name=selectIC_income type=hidden value="$form->{selectIC_income}"> + </tr> + <tr> + <th align=right>|.$locale->text('Expense').qq|</th> + <td><select name=IC_expense>$form->{selectIC_expense}</select></td> + <input name=selectIC_expense type=hidden value="$form->{selectIC_expense}"> + </tr> +|; + + if ($tax) { + $linkaccounts .= qq| + <tr> + <th align=right>|.$locale->text('Tax').qq|</th> + <td>$tax</td> + </tr> +|; + } + + } + + if ($form->{item} eq 'labor') { + $avgcost = ""; + + $n = ($form->{onhand} > 0) ? "1" : "0"; + $onhand = qq| + <tr> + <th align="right" nowrap>|.$locale->text('On Hand').qq|</th> + <th align=left nowrap class="plus$n"> |.$form->format_amount(\%myconfig, $form->{onhand}).qq|</th> + </tr> +|; + + $linkaccounts = qq| + <tr> + <th align=right>|.$locale->text('Labor/Overhead').qq|</th> + <td><select name=IC_inventory>$form->{selectIC_inventory}</select></td> + <input name=selectIC type=hidden value="$form->{selectIC}"> + </tr> + + <tr> + <th align=right>|.$locale->text('COGS').qq|</th> + <td><select name=IC_expense>$form->{selectIC_expense}</select></td> + <input name=selectIC_expense type=hidden value="$form->{selectIC_expense}"> + </tr> +|; + + } + + if ($form->{id}) { + $checked = ($form->{obsolete}) ? "checked" : ""; + $obsolete = qq| + <tr> + <th align="right" nowrap="true">|.$locale->text('Obsolete').qq|</th> + <td><input name=obsolete type=checkbox class=checkbox value=1 $checked></td> + </tr> +|; + $obsolete = "<input type=hidden name=obsolete value=$form->{obsolete}>" if $form->{project_id}; + } + + +# type=submit $locale->text('Edit Part') +# type=submit $locale->text('Edit Service') +# type=submit $locale->text('Edit Assembly') + + + $form->header; + + print qq| +<body> + +<form method=post action="$form->{script}"> +|; + + $form->hide_form(qw(id item title makemodel alternate onhand orphaned taxaccounts rowcount baseassembly project_id)); + + print qq| +<table width="100%"> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width="100%"> + <tr valign=top> + <th align=left>|.$locale->text('Number').qq|</th> + <th align=left>|.$locale->text('Description').qq|</th> + <th align=left>$group</th> + </tr> + <tr valign=top> + <td><input name=partnumber value="$form->{partnumber}" size=20></td> + <td>$description</td> + <td>$partsgroup</td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table width="100%" height="100%"> + <tr valign=top> + <td width=70%> + <table width="100%" height="100%"> + <tr class="listheading"> + <th class="listheading" align="center" colspan=2>|.$locale->text('Link Accounts').qq|</th> + </tr> + $linkaccounts + <tr> + <th align="left">|.$locale->text('Notes').qq|</th> + </tr> + <tr> + <td colspan=2> + $notes + </td> + </tr> + </table> + </td> + <td width="30%"> + <table width="100%"> + <tr> + <th align="right" nowrap="true">|.$locale->text('Updated').qq|</th> + <td><input name=priceupdate size=11 title="$myconfig{dateformat}" value=$form->{priceupdate}></td> + </tr> + $sellprice + $lastcost + $avgcost + <tr> + <th align="right" nowrap="true">|.$locale->text('Unit').qq|</th> + <td><input name=unit size=5 value="$form->{unit}"></td> + </tr> + $weight + $onhand + $stock + $rop + $bin + $obsolete + </table> + </td> + </tr> + </table> + </td> + </tr> + $imagelinks +|; +} + + +sub form_footer { + + print qq| + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + $form->hide_form(qw(customer_rows)); + + if ($form->{item} =~ /(part|assembly)/) { + $form->hide_form(qw(makemodel_rows)); + } + + if ($form->{item} =~ /(part|service)/) { + $form->hide_form(qw(vendor_rows)); + } + +# type=submit $locale->text('Update') +# type=submit $locale->text('Save') +# type=submit $locale->text('Save as new') +# type=submit $locale->text('Delete') + + if (! $form->{readonly}) { + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Save' => { ndx => 3, key => 'S', value => $locale->text('Save') }, + ); + + if ($form->{id}) { + + if (!$form->{isassemblyitem}) { + $button{'Save as new'} = { ndx => 7, key => 'N', value => $locale->text('Save as new') }; + } + + if ($form->{orphaned}) { + $button{'Delete'} = { ndx => 16, key => 'D', value => $locale->text('Delete') }; + } + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + &assembly_row(++$form->{assembly_rows}) if $form->{item} eq 'assembly'; + + $form->hide_form(qw(login path sessionid callback previousform isassemblyitem)); + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub search { + + $form->get_partsgroup(\%myconfig, { searchitems => $form->{searchitems}}); + + IC->get_warehouses(\%myconfig, \%$form) unless $form->{searchitems} =~ /(service|labor)/; + + if (@{ $form->{all_partsgroup} }) { + $partsgroup = qq|<option>\n|; + + for (@{ $form->{all_partsgroup} }) { $partsgroup .= qq|<option value="|.$form->quote($_->{partsgroup}).qq|--$_->{id}">$_->{partsgroup}\n| } + + $partsgroup = qq| + <th align=right nowrap>|.$locale->text('Group').qq|</th> + <td><select name=partsgroup>$partsgroup</select></td> +|; + + $l_partsgroup = qq|<input name=l_partsgroup class=checkbox type=checkbox value=Y> |.$locale->text('Group'); + } + + $l_listprice = qq|<input name=l_listprice class=checkbox type=checkbox value=Y> |.$locale->text('List Price'); + $l_sellprice = qq|<input name=l_sellprice class=checkbox type=checkbox value=Y checked> |.$locale->text('Sell Price'); + $l_lastcost = qq|<input name=l_lastcost class=checkbox type=checkbox value=Y checked> |.$locale->text('Last Cost'); + $l_avgcost = qq|<input name=l_avgcost class=checkbox type=checkbox value=Y checked> |.$locale->text('Average Cost'); + $l_linetotal = qq|<input name=l_linetotal class=checkbox type=checkbox value=Y> |.$locale->text('Line Total'); + $l_markup = qq|<input name=l_markup class=checkbox type=checkbox value=Y> |.$locale->text('Markup'); + $l_account = qq|<input name=l_account class=checkbox type=checkbox value=Y> |.$locale->text('Accounts'); + + $bought = qq| + <td> + <table> + <tr> + <td><input name=bought class=checkbox type=checkbox value=1></td> + <td nowrap>|.$locale->text('Vendor Invoices').qq|</td> + </tr> + <tr> + <td><input name=onorder class=checkbox type=checkbox value=1></td> + <td nowrap>|.$locale->text('Purchase Orders').qq|</td> + </tr> + <tr> + <td><input name=rfq class=checkbox type=checkbox value=1></td> + <td nowrap>|.$locale->text('RFQ').qq|</td> + </tr> + </table> + </td> +|; + + $sold = qq| + <td> + <table> + <tr> + <td><input name=sold class=checkbox type=checkbox value=1></td> + <td nowrap>|.$locale->text('Sales Invoices').qq|</td> + </tr> + <tr> + <td><input name=ordered class=checkbox type=checkbox value=1></td> + <td nowrap>|.$locale->text('Sales Orders').qq|</td> + </tr> + <tr> + <td><input name=quoted class=checkbox type=checkbox value=1></td> + <td nowrap>|.$locale->text('Quotations').qq|</td> + </tr> + </table> + </td> +|; + + $fromto = qq| + <td> + <table> + <tr> + <td nowrap><b>|.$locale->text('From').qq|</b> + <input name=transdatefrom size=11 title="$myconfig{dateformat}"> + <b>|.$locale->text('To').qq|</b> + <input name=transdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + <tr> + <td nowrap><input name=method class=radio type=radio value=accrual checked>|.$locale->text('Accrual').qq| + <input name=method class=radio type=radio value=cash>|.$locale->text('Cash').qq|</td> + </tr> + <tr> + <td nowrap> + <input name=open class=checkbox type=checkbox value=1 checked> |.$locale->text('Open').qq| + <input name=closed class=checkbox type=checkbox> |.$locale->text('Closed').qq| + <input name=summary type=radio class=radio value=1> |.$locale->text('Summary').qq| + <input name=summary type=radio class=radio value=0 checked> |.$locale->text('Detail').qq| + </td> + </tr> + </table> + </td> +|; + + $l_name = qq|<input name=l_name class=checkbox type=checkbox value=Y> |.$locale->text('Name'); + $l_curr = qq|<input name=l_curr class=checkbox type=checkbox value=Y> |.$locale->text('Currency'); + $l_employee = qq|<input name=l_employee class=checkbox type=checkbox value=Y> |.$locale->text('Employee'); + $l_serialnumber = qq|<input name=l_serialnumber class=checkbox type=checkbox value=Y> |.$locale->text('Serial Number'); + + $serialnumber = qq| + <th align=right nowrap>|.$locale->text('Serial Number').qq|</th> + <td><input name=serialnumber size=20></td> +|; + + $orphaned = qq| + <input name=itemstatus class=radio type=radio value=orphaned> |.$locale->text('Orphaned'); + + if ($form->{searchitems} =~ /(all|part|assembly)/) { + + $onhand = qq| + <input name=itemstatus class=radio type=radio value=onhand> |.$locale->text('On Hand').qq| + <input name=itemstatus class=radio type=radio value=short> |.$locale->text('Short').qq| +|; + + $makemodel = qq| + <tr> + <th align=right nowrap>|.$locale->text('Make').qq|</th> + <td><input name=make size=20></td> + <th align=right nowrap>|.$locale->text('Model').qq|</th> + <td><input name=model size=20></td> + </tr> +|; + + $l_make = qq|<input name=l_make class=checkbox type=checkbox value=Y> |.$locale->text('Make'); + $l_model = qq|<input name=l_model class=checkbox type=checkbox value=Y> |.$locale->text('Model'); + + $l_bin = qq|<input name=l_bin class=checkbox type=checkbox value=Y> |.$locale->text('Bin'); + + $l_rop = qq|<input name=l_rop class=checkbox type=checkbox value=Y> |.$locale->text('ROP'); + + $l_weight = qq|<input name=l_weight class=checkbox type=checkbox value=Y> |.$locale->text('Weight'); + + + if (@{ $form->{all_warehouse} }) { + $selectwarehouse = "<option>\n"; + + for (@{ $form->{all_warehouse} }) { $selectwarehouse .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + + $warehouse = qq| + <th align=right nowrap>|.$locale->text('Warehouse').qq|</th> + <td><select name=warehouse>$selectwarehouse</select></td> +|; + + $l_warehouse = qq|<input name=l_warehouse class=checkbox type=checkbox value=Y> |.$locale->text('Warehouse'); + + } + + $drawing = qq| + <tr> + <th align=right nowrap>|.$locale->text('Drawing').qq|</th> + <td><input name=drawing size=20></td> + <th align=right nowrap>|.$locale->text('Microfiche').qq|</th> + <td><input name=microfiche size=20></td> + </tr> +|; + + $l_image = qq|<input name=l_image class=checkbox type=checkbox value=Y> |.$locale->text('Image'); + + $l_drawing = qq|<input name=l_drawing class=checkbox type=checkbox value=Y> |.$locale->text('Drawing'); + $l_microfiche = qq|<input name=l_microfiche class=checkbox type=checkbox value=Y> |.$locale->text('Microfiche'); + + } + + if ($form->{searchitems} eq 'assembly') { + + $bought = ""; + + $toplevel = qq| + <tr> + <td></td> + <td colspan=3> + <input name=null class=radio type=radio checked> |.$locale->text('Top Level').qq| + <input name=individual class=checkbox type=checkbox value=1> |.$locale->text('Individual Items').qq| + </td> + </tr> +|; + $bom = qq|<input name=itemstatus type=radio value=bom> |.$locale->text('BOM'); + + } elsif ($form->{searchitems} eq 'component') { + + $bought = ""; + $sold = ""; + $fromto = ""; + $l_name = ""; + $l_curr = ""; + $l_employee = ""; + $l_serialnumber = ""; + + $warehouse = ""; + $serialnumber = ""; + $orphaned = ""; + $l_warehouse = ""; + $l_account = ""; + + } elsif ($form->{searchitems} eq 'labor') { + + $sold = ""; + + $warehouse = ""; + $serialnumber = ""; + $l_avgcost = ""; + + } + + + @a = (); + push @a, qq|<input name=l_runningnumber class=checkbox type=checkbox value=Y> |.$locale->text('No.'); + push @a, qq|<input name=l_partnumber class=checkbox type=checkbox value=Y checked> |.$locale->text('Number'); + push @a, qq|<input name=l_description class=checkbox type=checkbox value=Y checked> |.$locale->text('Description'); + push @a, qq|<input name=l_qty class=checkbox type=checkbox value=Y checked> |.$locale->text('Qty'); + push @a, qq|<input name=l_unit class=checkbox type=checkbox value=Y checked> |.$locale->text('Unit'); + push @a, qq|<input name=l_priceupdate class=checkbox type=checkbox value=Y> |.$locale->text('Updated'); + push @a, $l_partsgroup if $l_partsgroup; + push @a, $l_listprice if $l_listprice; + push @a, $l_sellprice if $l_sellprice; + push @a, $l_lastcost if $l_lastcost; + push @a, $l_avgcost if $l_avgcost; + push @a, $l_linetotal if $l_linetotal; + push @a, $l_markup if $l_markup; + push @a, $l_bin if $l_bin; + push @a, $l_rop if $l_rop; + push @a, $l_weight if $l_weight; + push @a, qq|<input name=l_notes class=checkbox type=checkbox value=Y> |.$locale->text('Notes'); + push @a, $l_image if $l_image; + push @a, $l_drawing if $l_drawing; + push @a, $l_microfiche if $l_microfiche; + push @a, $l_make if $l_make; + push @a, $l_model if $l_model; + push @a, $l_warehouse if $l_warehouse; + push @a, $l_account if $l_account; + push @a, $l_name if $l_name; + push @a, $l_curr if $l_curr; + push @a, $l_employee if $l_employee; + push @a, $l_serialnumber if $l_serialnumber; + + %title = ( all => 'Items', + part => 'Parts', + labor => 'Labor/Overhead', + service => 'Services', + assembly => 'Assemblies', + component => 'Components' + ); + +# $locale->text('Items') +# $locale->text('Parts') +# $locale->text('Labor/Overhead') +# $locale->text('Services') +# $locale->text('Assemblies') +# $locale->text('Components') + + $form->{title} = $locale->text($title{$form->{searchitems}}); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(searchitems title)); + + print qq| + +<table width="100%"> + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Number').qq|</th> + <td><input name=partnumber size=20></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Description').qq|</th> + <td colspan=3><input name=description size=40></td> + </tr> + <tr> + $warehouse + </tr> + <tr> + $partsgroup + $serialnumber + </tr> + $makemodel + $drawing + $toplevel + <tr> + <td></td> + <td colspan=3> + <input name=itemstatus class=radio type=radio value=active checked> |.$locale->text('Active').qq| + $onhand + <input name=itemstatus class=radio type=radio value=obsolete> |.$locale->text('Obsolete').qq| + $orphaned + $bom + </td> + </tr> + <tr> + <td></td> + <td colspan=3> + <hr size=1 noshade> + </td> + </tr> + <tr> + <td></td> + $bought + $sold + $fromto + <tr> + <td></td> + <td colspan=3> + <hr size=1 noshade> + </td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td colspan=3> + <table> + <tr> +|; + + while (@a) { + for (1 .. 5) { + print qq|<td nowrap>|. shift @a; + print qq|</td>\n|; + } + print qq|</tr>\n|; + } + + print qq| + </tr> + <tr> + <td><input name=l_subtotal class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq|</td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr><td colspan=4><hr size=3 noshade></td></tr> +</table> + +<input type=hidden name=nextsub value=generate_report> + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + + +sub generate_report { + + # setup $form->{sort} + unless ($form->{sort}) { + if ($form->{description} && !($form->{partnumber})) { + $form->{sort} = "description"; + } else { + $form->{sort} = "partnumber"; + } + } + + if ($form->{itemstatus} eq 'bom') { + $form->{l_perassembly} = "Y" if $form->{l_qty} eq "Y"; + $form->{individual} = 1; + $form->{title} = $locale->text('BOM'); + } + + $callback = "$form->{script}?action=generate_report"; + for (qw(path login sessionid searchitems itemstatus individual bom l_linetotal method)) { $callback .= qq|&$_=$form->{$_}| } + for (qw(warehouse partsgroup title)) { $callback .= qq|&$_=|.$form->escape($form->{$_},1) } + + # if we have a serialnumber limit search + if ($form->{serialnumber} || $form->{l_serialnumber}) { + $form->{l_serialnumber} = "Y"; + unless ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) { + if ($form->{searchitems} eq 'assembly') { + $form->{sold} = $form->{ordered} = 1; + } else { + $form->{bought} = $form->{sold} = $form->{onorder} = $form->{ordered} = 1; + } + } + } + + + if ($form->{itemstatus} eq 'active') { + $option .= $locale->text('Active')." : "; + } + if ($form->{itemstatus} eq 'obsolete') { + $form->{onhand} = $form->{short} = 0; + + $form->{l_qty} = 0; + $form->{warehouse} = ""; + $form->{l_warehouse} = 0; + + $option .= $locale->text('Obsolete')." : "; + } + if ($form->{itemstatus} eq 'orphaned') { + $form->{onhand} = $form->{short} = 0; + $form->{bought} = $form->{sold} = 0; + $form->{onorder} = $form->{ordered} = 0; + $form->{rfq} = $form->{quoted} = 0; + + $form->{l_qty} = 0; + $form->{warehouse} = ""; + $form->{l_warehouse} = 0; + + $form->{transdatefrom} = $form->{transdateto} = ""; + + $option .= $locale->text('Orphaned')." : "; + } + if ($form->{itemstatus} eq 'onhand') { + $option .= $locale->text('On Hand')." : "; + $form->{l_onhand} = "Y"; + } + if ($form->{itemstatus} eq 'short') { + $option .= $locale->text('Short')." : "; + $form->{l_onhand} = "Y"; + $form->{l_rop} = "Y" unless $form->{searchitems} eq 'labor'; + + $form->{warehouse} = ""; + $form->{l_warehouse} = 0; + } + + if ($form->{l_account}) { + for (qw(l_name l_curr l_employee)) { delete $form->{$_} } + } else { + $ok = 0; + foreach $l (qw(l_name l_curr l_employee)) { + if ($form->{$l}) { + foreach $v (qw(onorder ordered rfq quoted bought sold)) { + if ($form->{$v}) { + $ok = 1; + last; + } + } + if (!$ok) { + for (qw(onorder ordered rfq quoted bought sold)) { $form->{$_} = 1 } + } + last; + } + } + } + + if ($form->{onorder}) { + $form->{l_ordnumber} = "Y"; + $callback .= "&onorder=$form->{onorder}"; + $option .= $locale->text('Purchase Order')." : "; + } + if ($form->{ordered}) { + $form->{l_ordnumber} = "Y"; + $callback .= "&ordered=$form->{ordered}"; + $option .= $locale->text('Sales Order')." : "; + } + if ($form->{rfq}) { + $form->{l_quonumber} = "Y"; + $callback .= "&rfq=$form->{rfq}"; + $option .= $locale->text('RFQ')." : "; + } + if ($form->{quoted}) { + $form->{l_quonumber} = "Y"; + $callback .= ""ed=$form->{quoted}"; + $option .= $locale->text('Quotation')." : "; + } + if ($form->{bought}) { + $form->{l_invnumber} = "Y"; + $callback .= "&bought=$form->{bought}"; + $option .= $locale->text('Vendor Invoice')." : "; + } + if ($form->{sold}) { + $form->{l_invnumber} = "Y"; + $callback .= "&sold=$form->{sold}"; + $option .= $locale->text('Sales Invoice')." : "; + } + if ($form->{sold} || $form->{bought}) { + $label = ucfirst $form->{method}; + $option .= $locale->text($label) ." : "; + } + + if ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered} || $form->{rfq} || $form->{quoted}) { + + # warehouse stuff is meaningless + $form->{warehouse} = ""; + $form->{l_warehouse} = 0; + + $form->{l_account} = ""; + + if ($form->{open}) { + $callback .= "&open=$form->{open}"; + $option .= $locale->text('Open'); + } + if ($form->{closed}) { + $callback .= "&closed=$form->{closed}"; + if ($form->{open}) { + $option .= " : ".$locale->text('Closed'); + } else { + $option .= $locale->text('Closed'); + } + } + if ($form->{summary}) { + $callback .= "&summary=$form->{summary}"; + $option .= " : ".$locale->text('Summary'); + $form->{l_ordnumber} = ""; + $form->{l_quonumber} = ""; + $form->{l_invnumber} = ""; + } else { + $option .= " : ".$locale->text('Detail'); + } + + if ($form->{transdatefrom}) { + $callback .= "&transdatefrom=$form->{transdatefrom}"; + $option .= "\n<br>".$locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1); + } + if ($form->{transdateto}) { + $callback .= "&transdateto=$form->{transdateto}"; + $option .= "\n<br>".$locale->text('To')." ".$locale->date(\%myconfig, $form->{transdateto}, 1); + } + } + + if ($form->{warehouse}) { + ($warehouse) = split /--/, $form->{warehouse}; + $option .= "<br>".$locale->text('Warehouse')." : $warehouse"; + $form->{l_warehouse} = 0; + } + + $option .= "<br>"; + + if ($form->{partnumber}) { + $callback .= "&partnumber=".$form->escape($form->{partnumber},1); + $option .= $locale->text('Number').qq| : $form->{partnumber}<br>|; + } + if ($form->{partsgroup}) { + ($partsgroup) = split /--/, $form->{partsgroup}; + $option .= $locale->text('Group').qq| : $partsgroup<br>|; + } + if ($form->{serialnumber}) { + $callback .= "&serialnumber=".$form->escape($form->{serialnumber},1); + $option .= $locale->text('Serial Number').qq| : $form->{serialnumber}<br>|; + } + if ($form->{description}) { + $callback .= "&description=".$form->escape($form->{description},1); + $description = $form->{description}; + $description =~ s/\r?\n/<br>/g; + $option .= $locale->text('Description').qq| : $form->{description}<br>|; + } + if ($form->{make}) { + $callback .= "&make=".$form->escape($form->{make},1); + $option .= $locale->text('Make').qq| : $form->{make}<br>|; + } + if ($form->{model}) { + $callback .= "&model=".$form->escape($form->{model},1); + $option .= $locale->text('Model').qq| : $form->{model}<br>|; + } + if ($form->{drawing}) { + $callback .= "&drawing=".$form->escape($form->{drawing},1); + $option .= $locale->text('Drawing').qq| : $form->{drawing}<br>|; + } + if ($form->{microfiche}) { + $callback .= "µfiche=".$form->escape($form->{microfiche},1); + $option .= $locale->text('Microfiche').qq| : $form->{microfiche}<br>|; + } + + if ($form->{l_markup}) { + $form->{l_sellprice} = "Y"; + $form->{l_lastcostmarkup} = "Y" if $form->{l_lastcost}; + $form->{l_avgcostmarkup} = "Y" if $form->{l_avgcost}; + } + + + @columns = $form->sort_columns(qw(partnumber description notes assemblypartnumber partsgroup make model bin onhand perassembly rop unit listprice linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost lastcostmarkup avgcost linetotalavgcost avgcostmarkup curr priceupdate weight image drawing microfiche invnumber ordnumber quonumber name employee serialnumber warehouse)); + unshift @columns, "runningnumber"; + + if ($form->{l_linetotal}) { + $form->{l_onhand} = "Y"; + $form->{l_linetotalsellprice} = "Y" if $form->{l_sellprice}; + $form->{l_linetotallastcost} = "Y" if $form->{l_lastcost}; + $form->{l_linetotalavgcost} = "Y" if $form->{l_avgcost}; + $form->{l_linetotallistprice} = "Y" if $form->{l_listprice}; + } + + if ($form->{searchitems} eq 'service') { + # remove bin, weight and rop from list + for (qw(bin weight rop)) { $form->{"l_$_"} = "" } + + $form->{l_onhand} = ""; + # qty is irrelevant unless bought or sold + if ($form->{bought} || $form->{sold} || $form->{onorder} || + $form->{ordered} || $form->{rfq} || $form->{quoted}) { + $form->{l_onhand} = "Y"; + } else { + for (qw(sellprice lastcost avgcost listprice)) { $form->{"l_linetotal$_"} = "" } + } + } else { + $form->{l_onhand} = "Y" if $form->{l_qty}; + } + + foreach $item (@columns) { + if ($form->{"l_$item"} eq "Y") { + push @column_index, $item; + + # add column to callback + $callback .= "&l_$item=Y"; + } + } + + if ($form->{l_account} eq 'Y') { + if ($form->{searchitems} eq 'all' || $form->{searchitems} eq 'part') { + push @column_index, (qw(inventory income expense tax)); + } elsif ($form->{searchitems} eq 'service') { + push @column_index, (qw(income expense tax)); + } elsif ($form->{searchitems} eq 'assembly') { + push @column_index, (qw(income tax)); + } else { + push @column_index, (qw(inventory expense)); + } + + $callback .= "&l_account=Y"; + } + + if ($form->{l_subtotal} eq 'Y') { + $callback .= "&l_subtotal=Y"; + } + + IC->all_parts(\%myconfig, \%$form); + + $callback .= "&direction=$form->{direction}&oldsort=$form->{oldsort}"; + + $href = $callback; + + $form->sort_order(); + + $callback =~ s/(direction=).*?\&/$1$form->{direction}\&/; + + if ($form->{searchitems} eq 'assembly') { + if ($form->{l_partnumber}) { + # replace partnumber with partnumber_ + $ndx = 0; + foreach $item (@column_index) { + $ndx++; + last if $item eq 'partnumber'; + } + + splice @column_index, $ndx, 0, map { "partnumber_$_" } (1 .. $form->{pncol}); + $colspan = $form->{pncol} + 1; + } + } + + if ($form->{searchitems} eq 'component') { + if ($form->{l_partnumber}) { + # splice it in after the partnumber + $ndx = 0; + foreach $item (@column_index) { + $ndx++; + last if $item eq 'partnumber'; + } + + @a = splice @column_index, 0, $ndx; + unshift @column_index, "assemblypartnumber"; + unshift @column_index, @a; + } + } + + + $column_header{runningnumber} = qq|<th a class=listheading> </th>|; + $column_header{partnumber} = qq|<th nowrap colspan=$colspan><a class=listheading href=$href&sort=partnumber>|.$locale->text('Number').qq|</a></th>|; + $column_header{description} = qq|<th nowrap><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + $column_header{notes} = qq|<th nowrap class=listheading>|.$locale->text('Notes').qq|</th>|; + $column_header{partsgroup} = qq|<th nowrap><a class=listheading href=$href&sort=partsgroup>|.$locale->text('Group').qq|</a></th>|; + $column_header{bin} = qq|<th><a class=listheading href=$href&sort=bin>|.$locale->text('Bin').qq|</a></th>|; + $column_header{priceupdate} = qq|<th nowrap><a class=listheading href=$href&sort=priceupdate>|.$locale->text('Updated').qq|</a></th>|; + $column_header{onhand} = qq|<th class=listheading nowrap>|.$locale->text('Qty').qq|</th>|; + $column_header{perassembly} = qq|<th> </th>|; + $column_header{unit} = qq|<th class=listheading nowrap>|.$locale->text('Unit').qq|</th>|; + $column_header{listprice} = qq|<th class=listheading nowrap>|.$locale->text('List Price').qq|</th>|; + $column_header{lastcost} = qq|<th class=listheading nowrap>|.$locale->text('Last Cost').qq|</th>|; + $column_header{avgcost} = qq|<th class=listheading nowrap>|.$locale->text('Avg Cost').qq|</th>|; + $column_header{rop} = qq|<th class=listheading nowrap>|.$locale->text('ROP').qq|</th>|; + $column_header{weight} = qq|<th class=listheading nowrap>|.$locale->text('Weight').qq|</th>|; + $column_header{avgcostmarkup} = qq|<th class=listheading nowrap>%</th>|; + $column_header{lastcostmarkup} = qq|<th class=listheading nowrap>%</th>|; + + $column_header{make} = qq|<th nowrap><a class=listheading href=$href&sort=make>|.$locale->text('Make').qq|</a></th>|; + $column_header{model} = qq|<th nowrap><a class=listheading href=$href&sort=model>|.$locale->text('Model').qq|</a></th>|; + + $column_header{invnumber} = qq|<th nowrap><a class=listheading href=$href&sort=invnumber>|.$locale->text('Invoice Number').qq|</a></th>|; + $column_header{ordnumber} = qq|<th nowrap><a class=listheading href=$href&sort=ordnumber>|.$locale->text('Order Number').qq|</a></th>|; + $column_header{quonumber} = qq|<th nowrap><a class=listheading href=$href&sort=quonumber>|.$locale->text('Quotation').qq|</a></th>|; + + $column_header{name} = qq|<th nowrap><a class=listheading href=$href&sort=name>|.$locale->text('Name').qq|</a></th>|; + + $column_header{employee} = qq|<th nowrap><a class=listheading href=$href&sort=employee>|.$locale->text('Employee').qq|</a></th>|; + + $column_header{sellprice} = qq|<th class=listheading nowrap>|.$locale->text('Sell Price').qq|</th>|; + + for (qw(sellprice lastcost avgcost listprice)) { $column_header{"linetotal$_"} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>| } + + $column_header{curr} = qq|<th nowrap><a class=listheading href=$href&sort=curr>|.$locale->text('Curr').qq|</a></th>|; + + $column_header{image} = qq|<th class=listheading nowrap>|.$locale->text('Image').qq|</a></th>|; + $column_header{drawing} = qq|<th nowrap><a class=listheading href=$href&sort=drawing>|.$locale->text('Drawing').qq|</a></th>|; + $column_header{microfiche} = qq|<th nowrap><a class=listheading href=$href&sort=microfiche>|.$locale->text('Microfiche').qq|</a></th>|; + + $column_header{serialnumber} = qq|<th nowrap><a class=listheading href=$href&sort=serialnumber>|.$locale->text('Serial Number').qq|</a></th>|; + + $column_header{assemblypartnumber} = qq|<th nowrap><a class=listheading href=$href&sort=assemblypartnumber>|.$locale->text('Assembly').qq|</a></th>|; + + $column_header{warehouse} = qq|<th nowrap class=listheading>|.$locale->text('Warehouse').qq|</th>|; + + $column_header{inventory} = qq|<th nowrap class=listheading>|.$locale->text('Inventory').qq|</th>|; + $column_header{income} = qq|<th nowrap class=listheading>|.$locale->text('Income').qq|</th>|; + $column_header{expense} = qq|<th nowrap class=listheading>|.$locale->text('Expense').qq|</th>|; + $column_header{tax} = qq|<th nowrap class=listheading>|.$locale->text('Tax').qq|</th>|; + + $form->header; + + $i = 1; + if ($form->{searchitems} eq 'part') { + $button{'Goods & Services--Add Part'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Part').qq|"> |; + $button{'Goods & Services--Add Part'}{order} = $i++; + } + if ($form->{searchitems} eq 'service') { + $button{'Goods & Services--Add Service'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Service').qq|"> |; + $button{'Goods & Services--Add Service'}{order} = $i++; + } + if ($form->{searchitems} eq 'assembly') { + $button{'Goods & Services--Add Assembly'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Assembly').qq|"> |; + $button{'Goods & Services--Add Assembly'}{order} = $i++; + } + if ($form->{searchitems} eq 'labor') { + $button{'Goods & Services--Add Labor/Overhead'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Labor/Overhead').qq|"> |; + $button{'Goods & Services--Add Labor/Overhead'}{order} = $i++; + } + + foreach $item (split /;/, $myconfig{acs}) { + delete $button{$item}; + } + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + + <tr><td>$option</td></tr> + + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> + |; + + + # add order to callback + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + + $k = $#{@{ $form->{parts} }}; + @groupby = ($form->{sort}); + + if ($form->{summary}) { + @groupby = (); + for (qw(partnumber description notes partsgroup make model bin curr priceupdate image drawing microfiche invnumber ordnumber quonumber name employee serialnumber warehouse)) { $a{$_} = 1 }; + + for (@column_index) { + if ($a{$_}) { + push @groupby, $_; + } + } + push @groupby, "id"; + } + + if ($k > 0) { + $samegroup = ""; + for (@groupby) { $samegroup .= $form->{parts}->[0]->{$_} } + } + + $i = 0; + $n = 0; + + foreach $ref (@{ $form->{parts} }) { + + $ref->{exchangerate} ||= 1; + $ref->{discount} *= 1; + + if ($form->{summary}) { + + $summary{$ref->{id}}{total} += $ref->{sellprice} * $ref->{onhand}; + $summary{$ref->{id}}{onhand} += $ref->{onhand}; + + if ($n < $k) { + $nextgroup = ""; + for (@groupby) { $nextgroup .= $form->{parts}->[$n+1]->{$_} } + $n++; + + $form->{parts}->[$n]->{exchangerate} ||= 1; + + if ($samegroup eq $nextgroup) { + for (qw(exchangerate discount)) { $form->{parts}->[$n]->{$_} = ($ref->{$_} + $form->{parts}->[$n]->{$_}) / 2 } + next; + } + $samegroup = $nextgroup; + } + + $ref->{onhand} = $summary{$ref->{id}}{onhand}; + $ref->{sellprice} = ($ref->{onhand}) ? $summary{$ref->{id}}{total} / $ref->{onhand} : 0; + + $summary{$ref->{id}}{total} = 0; + $summary{$ref->{id}}{onhand} = 0; + + } + + if ($form->{l_subtotal} eq 'Y' && !$ref->{assemblyitem}) { + if ($sameitem ne $ref->{$form->{sort}}) { + &parts_subtotal; + $sameitem = $ref->{$form->{sort}}; + } + } + + $i++; + + if ($form->{l_curr}) { + if ($ref->{module} eq 'oe') { + $ref->{sellprice} = $ref->{sellprice} * (1 - $ref->{discount}); + } else { + for (qw(sellprice listprice lastcost avgcost)) { $ref->{$_} /= $ref->{exchangerate} } + } + } else { + if ($ref->{module} eq 'oe') { + $ref->{sellprice} = $ref->{sellprice} * (1 - $ref->{discount}); + for (qw(sellprice listprice lastcost avgcost)) { $ref->{$_} *= $ref->{exchangerate} } + } + } + + if (!$form->{summary}) { + for (qw(sellprice listprice lastcost avgcost)) { $ref->{$_} = $form->round_amount($ref->{$_}, 2) } + } + + if ($form->{l_markup}) { + $ref->{lastcostmarkup} = (($ref->{sellprice} / $ref->{lastcost}) - 1) * 100 if $ref->{lastcost} != 0; + $ref->{avgcostmarkup} = (($ref->{sellprice} / $ref->{avgcost}) - 1) * 100 if $ref->{avgcost} != 0; + } + + # use this for assemblies + $onhand = $ref->{onhand}; + + for (qw(description notes)) { $ref->{$_} =~ s/\r?\n/<br>/g } + + for (1 .. $form->{pncol}) { $column_data{"partnumber_$_"} = "<td> </td>" } + + $column_data{runningnumber} = "<td align=right>$i</td>"; + $column_data{partnumber} = "<td><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber} </a></td>"; + + if ($ref->{assemblypartnumber}) { + if ($sameid eq $ref->{id}) { + $i--; + for (qw(runningnumber partnumber)) { $column_data{$_} = "<td> </td>" } + } + } + + $column_data{assemblypartnumber} = "<td><a href=$form->{script}?action=edit&id=$ref->{assembly_id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{assemblypartnumber} </a></td>"; + + if ($ref->{assemblyitem}) { + $onhand = 0 if $form->{sold}; + $ref->{income} = ""; + + for (qw(runningnumber partnumber)) { $column_data{$_} = "<td> </td>" } + $i--; + + $column_data{"partnumber_$ref->{stagger}"} = "<td><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber} </a></td>"; + + } + + for (qw(description notes partsgroup employee curr)) { $column_data{$_} = "<td>$ref->{$_} </td>" } + + $column_data{onhand} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand}, '', " ")."</td>"; + $column_data{perassembly} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{perassembly}, '', " ")."</td>"; + + if ($form->{summary}) { + $column_data{sellprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{sellprice}, 4, " ") . "</td>"; + } else { + $column_data{sellprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{sellprice}, 2, " ") . "</td>"; + } + for (qw(listprice lastcost avgcost)) { $column_data{$_} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{$_}, 2, " ") . "</td>" } + + for (qw(lastcost avgcost)) { $column_data{"${_}markup"} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{"${_}markup"}, 1, " ")."</td>" } + + if ($form->{l_linetotal}) { + for (qw(sellprice lastcost avgcost listprice)) { $column_data{"linetotal$_"} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand} * $ref->{$_}, 2, " ")."</td>" } + } + + if ($ref->{assemblyitem} && $ref->{stagger} > 1) { + for (qw(sellprice lastcost avgcost listprice)) { $column_data{"linetotal$_"} = "<td> </td>" } + } + + if (!$ref->{assemblyitem}) { + $totalsellprice += $onhand * $ref->{sellprice}; + $totallastcost += $onhand * $ref->{lastcost}; + $totalavgcost += $onhand * $ref->{avgcost}; + $totallistprice += $onhand * $ref->{listprice}; + + $subtotalonhand += $onhand; + $subtotalsellprice += $onhand * $ref->{sellprice}; + $subtotallastcost += $onhand * $ref->{lastcost}; + $subtotalavgcost += $onhand * $ref->{avgcost}; + $subtotallistprice += $onhand * $ref->{listprice}; + } + + $column_data{rop} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{rop}, '', " ")."</td>"; + $column_data{weight} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{weight}, '', " ")."</td>"; + $column_data{unit} = "<td>$ref->{unit} </td>"; + $column_data{bin} = "<td>$ref->{bin} </td>"; + $column_data{priceupdate} = "<td>$ref->{priceupdate} </td>"; + + $ref->{module} = 'ps' if $ref->{till}; + $column_data{invnumber} = ($ref->{module} ne 'oe') ? "<td><a href=$ref->{module}.pl?action=edit&type=invoice&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{invnumber} </a></td>" : "<td>$ref->{invnumber} </td>"; + $column_data{ordnumber} = ($ref->{module} eq 'oe') ? "<td><a href=$ref->{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{ordnumber} </a></td>" : "<td>$ref->{ordnumber} </td>"; + $column_data{quonumber} = ($ref->{module} eq 'oe' && !$ref->{ordnumber}) ? "<td><a href=$ref->{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{quonumber} </a></td>" : "<td>$ref->{quonumber} </td>"; + + $column_data{name} = "<td>$ref->{name} </td>"; + + $column_data{image} = ($ref->{image}) ? "<td><a href=$ref->{image}><img src=$ref->{image} height=32 border=0></a></td>" : "<td> </td>"; + $column_data{drawing} = ($ref->{drawing}) ? "<td><a href=$ref->{drawing}>$ref->{drawing}</a></td>" : "<td> </td>"; + $column_data{microfiche} = ($ref->{microfiche}) ? "<td><a href=$ref->{microfiche}>$ref->{microfiche}</a></td>" : "<td> </td>"; + + for (qw(make model serialnumber warehouse inventory income expense tax)) { $column_data{$_} = "<td>$ref->{$_} </td>" } + + $j++; $j %= 2; + print "<tr class=listrow$j>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + $sameid = $ref->{id}; + + } + + + if ($form->{l_subtotal} eq 'Y') { + &parts_subtotal; + } + + if ($form->{"l_linetotal"}) { + for (@column_index) { $column_data{$_} = "<td> </td>" } + $column_data{linetotalsellprice} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalsellprice, 2, " ")."</th>"; + $column_data{linetotallastcost} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totallastcost, 2, " ")."</th>"; + $column_data{linetotalavgcost} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalavgcost, 2, " ")."</th>"; + $column_data{linetotallistprice} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totallistprice, 2, " ")."</th>"; + + print "<tr class=listtotal>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq|</tr> + |; + } + + print qq| + </table> + </td> + </tr> + <tr><td><hr size=3 noshade></td></tr> +</table> + +|; + + print qq| + +<br> + +<form method=post action=$form->{script}> + +<input type=hidden name=item value=$form->{searchitems}> +|; + + $form->hide_form(qw(callback path login sessionid)); + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub parts_subtotal { + + for (@column_index) { $column_data{$_} = "<td> </td>" } + $subtotalonhand = 0 if ($form->{searchitems} eq 'assembly' && $form->{individual}); + + $column_data{onhand} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalonhand, '', " ")."</th>"; + + $column_data{linetotalsellprice} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalsellprice, 2, " ")."</th>"; + $column_data{linetotallistprice} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotallistprice, 2, " ")."</th>"; + $column_data{linetotallastcost} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotallastcost, 2, " ")."</th>"; + $column_data{linetotalavgcost} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalavgcost, 2, " ")."</th>"; + + $subtotalonhand = 0; + $subtotalsellprice = 0; + $subtotallistprice = 0; + $subtotallastcost = 0; + $subtotalavgcost = 0; + + print "<tr class=listsubtotal>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + +} + + +sub requirements { + + $form->get_partsgroup(\%myconfig, { searchitems => 'parts'}); + $form->all_years(\%myconfig); + + if (@{ $form->{all_partsgroup} }) { + $partsgroup = qq|<option>\n|; + + for (@{ $form->{all_partsgroup} }) { $partsgroup .= qq|<option value="|.$form->quote($_->{partsgroup}).qq|--$_->{id}">$_->{partsgroup}\n| } + + $partsgroup = qq| + <th align=right nowrap>|.$locale->text('Group').qq|</th> + <td><select name=partsgroup>$partsgroup</select></td> +|; + + $l_partsgroup = qq|<input name=l_partsgroup class=checkbox type=checkbox value=Y> |.$locale->text('Group'); + } + + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = qq|<option>\n|; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <table> + <tr> + <td> + <select name=year>$form->{selectaccountingyear}</select> + </td> + <td> +|; + + $selectfrom .= qq| + <table> + <tr> +|; + + for (sort keys %{ $form->{all_month} }) { + $i = ($_ * 1) - 1; + if (($i % 3) == 0) { + $selectfrom .= qq| + </tr> + <tr> +|; + } + + $i = $_ * 1; + + $selectfrom .= qq| + <td nowrap><input name="l_month_$i" class checkbox type=checkbox value=Y> |.$locale->text($form->{all_month}{$_}).qq|</td>\n|; + } + + $selectfrom .= qq| + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> +|; + } else { + $form->error($locale->text('No History!')); + } + + $form->{title} = $locale->text('Parts Requirements'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +|; + + print qq| + +<table width="100%"> + + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Number').qq|</th> + <td><input name=partnumber size=20></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Description').qq|</th> + <td colspan=3><input name=description size=40></td> + </tr> + <tr> + $partsgroup + </tr> + $selectfrom + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=nextsub value=requirements_report> +<input type=hidden name=sort value=partnumber> + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + + +sub requirements_report { + + $callback = "$form->{script}?action=requirements_report"; + for (qw(path login sessionid year)) { $callback .= qq|&$_=$form->{$_}| } + for (qw(partsgroup)) { $callback .= qq|&$_=|.$form->escape($form->{$_},1) } + + if ($form->{partnumber}) { + $callback .= "&partnumber=".$form->escape($form->{partnumber},1); + $option .= $locale->text('Number').qq| : $form->{partnumber}<br>|; + } + if ($form->{partsgroup}) { + ($partsgroup) = split /--/, $form->{partsgroup}; + $option .= $locale->text('Group').qq| : $partsgroup<br>|; + } + if ($form->{description}) { + $callback .= "&description=".$form->escape($form->{description},1); + $description = $form->{description}; + $description =~ s/\r?\n/<br>/g; + $option .= $locale->text('Description').qq| : $form->{description}<br>|; + } + + + @column_index = $form->sort_columns(qw(partnumber description)); + unshift @column_index, "runningnumber"; + + for (1 .. 12) { + if ($form->{"l_month_$_"}) { + $callback .= qq|&l_month_$_=$form->{"l_month_$_"}|; + push @column_index, $_; + $month{$_} = 1; + } + } + + push @column_index, "year" unless %month; + push @column_index, qw(onhand so po order); + + IC->requirements(\%myconfig, \%$form); + + $form->sort_order(); + + $callback .= "&direction=$form->{direction}&oldsort=$form->{oldsort}"; + + $href = $callback; + + $callback =~ s/(direction=).*?\&/$1$form->{direction}\&/; + + if (%month) { + $option .= $locale->text('Year').qq| : $form->{year}<br>|; + } + + + $column_header{runningnumber} = qq|<th a class=listheading> </th>|; + $column_header{partnumber} = qq|<th nowrap colspan=$colspan><a class=listheading href=$href&sort=partnumber>|.$locale->text('Number').qq|</a></th>|; + $column_header{description} = qq|<th nowrap><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + $column_header{onhand} = qq|<th class=listheading nowrap>|.$locale->text('Onhand').qq|</th>|; + $column_header{so} = qq|<th class=listheading nowrap>|.$locale->text('SO').qq|</th>|; + $column_header{po} = qq|<th class=listheading nowrap>|.$locale->text('PO').qq|</th>|; + $column_header{order} = qq|<th class=listheading nowrap>|.$locale->text('Order').qq|</th>|; + $column_header{year} = qq|<th class=listheading nowrap>$form->{year}</th>|; + + for (sort { $a <=> $b } keys %month) { $column_header{$_} = qq|<th class=listheading nowrap>|.$locale->text($locale->{SHORT_MONTH}[$_-1]).qq|</th>| } + + $form->{title} = $locale->text('Parts Requirements'); + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + + <tr><td>$option</td></tr> + + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> + |; + + + # add order to callback + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + if (@{ $form->{parts} }) { + $sameid = $form->{parts}->[0]->{id}; + } + + for (keys %month) { $column_data{$_} = "<td> </td>" } + + $i = 0; + $qty = 0; + foreach $ref (@{ $form->{parts} }) { + + if ($ref->{id} != $sameid) { + + $i++; + $column_data{runningnumber} = "<td align=right>$i</td>"; + + $order = 0 if $order < 0; + $column_data{order} = "<td align=right>".$form->format_amount(\%myconfig, $order, '', "-")."</td>"; + $j++; $j %= 2; + print "<tr class=listrow$j>"; + + for (@column_index) { + print "\n$column_data{$_}"; + $column_data{$_} = "<td> </td>"; + } + + print qq| + </tr> +|; + $qty = 0; + } + + + $ref->{description} =~ s/\r?\n/<br>/g; + + $column_data{partnumber} = "<td><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber} </a></td>"; + + $column_data{description} = "<td>$ref->{description} </td>"; + + $column_data{onhand} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand}, '', " ")."</td>"; + $column_data{so} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{so}, '', " ")."</td>"; + $column_data{po} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{po}, '', " ")."</td>"; + + $column_data{$ref->{month}} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{qty}, '', " ")."</td>"; + if (%month) { + $qty += $ref->{qty} if exists $month{$ref->{month}}; + } else { + $qty += $ref->{qty}; + } + + $column_data{year} = "<td align=right>".$form->format_amount(\%myconfig, $qty, '', " ")."</td>"; + + $order = $qty + $ref->{so} - $ref->{po} - $ref->{onhand}; + + $sameid = $ref->{id}; + + } + + if (@{ $form->{parts} }) { + $i++; + $column_data{runningnumber} = "<td align=right>$i</td>"; + + $order = 0 if $order < 0; + $column_data{order} = "<td align=right>".$form->format_amount(\%myconfig, $order, '', "-")."</td>"; + $j++; $j %= 2; + print "<tr class=listrow$j>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + <tr><td><hr size=3 noshade></td></tr> +</table> + +|; + + print qq| + +<br> + +<form method=post action=$form->{script}> + +|; + + $form->hide_form(qw(callback path login sessionid)); + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub makemodel_row { + my ($numrows) = @_; + + for (qw(make model)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + + print qq| + <tr> + <td> + <table width=100%> + <tr> + <th class="listheading">|.$locale->text('Make').qq|</th> + <th class="listheading">|.$locale->text('Model').qq|</th> + </tr> +|; + + for $i (1 .. $numrows) { + print qq| + <tr> + <td><input name="make_$i" size=30 value="$form->{"make_$i"}"></td> + <td><input name="model_$i" size=30 value="$form->{"model_$i"}"></td> + </tr> +|; + } + + print qq| + </table> + </td> + </tr> +|; + +} + + +sub vendor_row { + my ($numrows) = @_; + + $form->{selectvendor} = $form->unescape($form->{selectvendor}); + + $currency = qq| + <th class="listheading">|.$locale->text('Curr').qq|</th>| if $form->{selectcurrency}; + + print qq| + <input type=hidden name=selectvendor value="|.$form->escape($form->{selectvendor},1).qq|"> + + <tr> + <td> + <table width=100%> + <tr> + <th class="listheading">|.$locale->text('Vendor').qq|</th> + <th class="listheading">|.$locale->text('Number').qq|</th> + <th class="listheading">|.$locale->text('Cost').qq|</th> + $currency + <th class="listheading">|.$locale->text('Leadtime').qq|</th> + </tr> +|; + + for $i (1 .. $numrows) { + + if ($form->{selectcurrency}) { + $form->{selectcurrency} =~ s/ selected//; + $form->{selectcurrency} =~ s/option>$form->{"vendorcurr_$i"}/option selected>$form->{"vendorcurr_$i"}/; + $currency = qq| + <td><select name="vendorcurr_$i">$form->{selectcurrency}</select></td>|; + } + + if ($i == $numrows) { + + $vendor = qq| + <td><input name="vendor_$i" size=35 value="$form->{"vendor_$i"}"></td> +|; + + if ($form->{selectvendor}) { + $vendor = qq| + <td width=99%><select name="vendor_$i">$form->{selectvendor}</select></td> +|; + } + + } else { + + ($vendor) = split /--/, $form->{"vendor_$i"}; + $vendor = qq| + <td>$vendor + <input type=hidden name="vendor_$i" value="$form->{"vendor_$i"}"> + </td> +|; + } + + $form->{"partnumber_$i"} = $form->quote($form->{"partnumber_$i"}); + print qq| + <tr> + $vendor + <td><input name="partnumber_$i" size=20 value="$form->{"partnumber_$i"}"></td> + <td><input name="lastcost_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"lastcost_$i"}, 2).qq|></td> + $currency + <td nowrap><input name="leadtime_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"leadtime_$i"}).qq|> <b>|.$locale->text('days').qq|</b></td> + </tr> +|; + + } + + print qq| + </table> + </td> + </tr> +|; + +} + + +sub customer_row { + my ($numrows) = @_; + + if ($form->{selectpricegroup}) { + $pricegroup = qq| + <th class="listheading">|.$locale->text('Pricegroup').qq| + </th> +|; + } + + $form->{selectcustomer} = $form->unescape($form->{selectcustomer}); + $form->{selectpricegroup} = $form->unescape($form->{selectpricegroup}); + + $form->hide_form(qw(selectcurrency)); + + $currency = qq|<th class="listheading">|.$locale->text('Curr').qq|</th>| if $form->{selectcurrency}; + + print qq| + <input type=hidden name=selectcustomer value="|.$form->escape($form->{selectcustomer},1).qq|"> + <input type=hidden name=selectpricegroup value="|.$form->escape($form->{selectpricegroup},1).qq|"> + + <tr> + <td> + <table width=100%> + <tr> + <th class="listheading">|.$locale->text('Customer').qq|</th> + $pricegroup + <th class="listheading">|.$locale->text('Break').qq|</th> + <th class="listheading">|.$locale->text('Sell Price').qq|</th> + $currency + <th class="listheading">|.$locale->text('From').qq|</th> + <th class="listheading">|.$locale->text('To').qq|</th> + </tr> +|; + + for $i (1 .. $numrows) { + + if ($form->{selectcurrency}) { + $form->{selectcurrency} =~ s/ selected//; + $form->{selectcurrency} =~ s/option>$form->{"customercurr_$i"}/option selected>$form->{"customercurr_$i"}/; + $currency = qq| + <td><select name="customercurr_$i">$form->{selectcurrency}</select></td>|; + } + + if ($i == $numrows) { + $customer = qq| + <td><input name="customer_$i" size=35 value="$form->{"customer_$i"}"></td> + |; + + if ($form->{selectcustomer}) { + $customer = qq| + <td><select name="customer_$i">$form->{selectcustomer}</select></td> +|; + } + + if ($form->{selectpricegroup}) { + $pricegroup = qq| + <td><select name="pricegroup_$i">$form->{selectpricegroup}</select></td> +|; + } + + } else { + ($customer) = split /--/, $form->{"customer_$i"}; + $customer = qq| + <td>$customer</td> + <input type=hidden name="customer_$i" value="$form->{"customer_$i"}"> + |; + + if ($form->{selectpricegroup}) { + ($pricegroup) = split /--/, $form->{"pricegroup_$i"}; + $pricegroup = qq| + <td>$pricegroup</td> + <input type=hidden name="pricegroup_$i" value="$form->{"pricegroup_$i"}"> +|; + } + } + + + print qq| + <tr> + $customer + $pricegroup + + <td><input name="pricebreak_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"pricebreak_$i"}).qq|></td> + <td><input name="customerprice_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"customerprice_$i"}, 2).qq|></td> + $currency + <td><input name="validfrom_$i" size=11 title="$myconfig{dateformat}" value="$form->{"validfrom_$i"}"></td> + <td><input name="validto_$i" size=11 title="$myconfig{dateformat}" value="$form->{"validto_$i"}"></td> + </tr> +|; + } + + print qq| + </table> + </td> + </tr> +|; + +} + + + +sub assembly_row { + my ($numrows) = @_; + + @column_index = qw(runningnumber qty unit bom adj partnumber description sellprice listprice lastcost); + + if ($form->{selectassemblypartsgroup}) { + $form->{selectassemblypartsgroup} = $form->unescape($form->{selectassemblypartsgroup}); + @column_index = qw(runningnumber qty unit bom adj partnumber description partsgroup sellprice listprice lastcost); + } + + delete $form->{previousform}; + + # change callback + $form->{old_callback} = $form->{callback}; + $callback = $form->{callback}; + $form->{callback} = "$form->{script}?action=display_form"; + + # delete action + for (qw(action header)) { delete $form->{$_} } + + $form->{baseassembly} = 0; + $previousform = ""; + # save form variables in a previousform variable + $form->{selectcustomer} = ""; # we seem to have run into a 40kb limit + foreach $key (sort keys %$form) { + # escape ampersands + $form->{$key} =~ s/&/%26/g; + $previousform .= qq|$key=$form->{$key}&| if $form->{$key}; + } + chop $previousform; + $form->{previousform} = $form->escape($previousform, 1); + + $form->{sellprice} = 0; + $form->{listprice} = 0; + $form->{lastcost} = 0; + $form->{weight} = 0; + + $form->{callback} = $callback; + + + $column_header{runningnumber} = qq|<th nowrap width=5%>|.$locale->text('Item').qq|</th>|; + $column_header{qty} = qq|<th align=left nowrap width=10%>|.$locale->text('Qty').qq|</th>|; + $column_header{unit} = qq|<th align=left nowrap width=5%>|.$locale->text('Unit').qq|</th>|; + $column_header{partnumber} = qq|<th align=left nowrap width=20%>|.$locale->text('Number').qq|</th>|; + $column_header{description} = qq|<th nowrap width=50%>|.$locale->text('Description').qq|</th>|; + $column_header{sellprice} = qq|<th align=right nowrap>|.$locale->text('Sell').qq|</th>|; + $column_header{listprice} = qq|<th align=right nowrap>|.$locale->text('List').qq|</th>|; + $column_header{lastcost} = qq|<th align=right nowrap>|.$locale->text('Cost').qq|</th>|; + $column_header{bom} = qq|<th>|.$locale->text('BOM').qq|</th>|; + $column_header{adj} = qq|<th>|.$locale->text('A').qq|</th>|; + $column_header{partsgroup} = qq|<th>|.$locale->text('Group').qq|</th>|; + + print qq| + <p> + + <table width=100%> + <tr class=listheading> + <th class=listheading>|.$locale->text('Individual Items').qq|</th> + </tr> + <tr> + <td> + <table width=100%> + <tr> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + $spc = ($form->{path} =~ /lynx/) ? "." : " "; + $numrows-- if $form->{project_id}; + + for $i (1 .. $numrows) { + for (qw(partnumber description)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + + $linetotalsellprice = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2); + $form->{sellprice} += $linetotalsellprice; + + $linetotallistprice = $form->round_amount($form->{"listprice_$i"} * $form->{"qty_$i"}, 2); + $form->{listprice} += $linetotallistprice; + + $linetotallastcost = $form->round_amount($form->{"lastcost_$i"} * $form->{"qty_$i"}, 2); + $form->{lastcost} += $linetotallastcost; + + + $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); + + $linetotalsellprice = $form->format_amount(\%myconfig, $linetotalsellprice, 2); + $linetotallistprice = $form->format_amount(\%myconfig, $linetotallistprice, 2); + $linetotallastcost = $form->format_amount(\%myconfig, $linetotallastcost, 2); + + if ($i == $numrows && !$form->{project_id}) { + + for (qw(runningnumber unit bom adj)) { $column_data{$_} = qq|<td></td>| } + + $column_data{qty} = qq|<td><input name="qty_$i" size=6 value="$form->{"qty_$i"}" accesskey="$i" title="[Alt-$i]"></td>|; + $column_data{partnumber} = qq|<td><input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}"></td>|; + $column_data{description} = qq|<td><input name="description_$i" size=30 value="$form->{"description_$i"}"></td>|; + $column_data{partsgroup} = qq|<td><select name="partsgroup_$i">$form->{selectassemblypartsgroup}</select></td>|; + + } else { + + $column_data{partnumber} = qq|<td><input class=submit type=submit name=action value="$spc$form->{"partnumber_$i"}"></td> + <input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}">|; + + $column_data{runningnumber} = qq|<td><input name="runningnumber_$i" size=3 value="$i"></td>|; + $column_data{qty} = qq|<td><input name="qty_$i" size=6 value="$form->{"qty_$i"}" accesskey="$i" title="[Alt-$i]"></td>|; + + for (qw(bom adj)) { $form->{"${_}_$i"} = ($form->{"${_}_$i"}) ? "checked" : "" } + $column_data{bom} = qq|<td align=center><input name="bom_$i" type=checkbox class=checkbox value=1 $form->{"bom_$i"}></td>|; + $column_data{adj} = qq|<td align=center><input name="adj_$i" type=checkbox class=checkbox value=1 $form->{"adj_$i"}></td>|; + + ($partsgroup) = split /--/, $form->{"partsgroup_$i"}; + $column_data{partsgroup} = qq|<td><input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">$partsgroup</td>|; + + $column_data{unit} = qq|<td><input type=hidden name="unit_$i" value="$form->{"unit_$i"}">$form->{"unit_$i"}</td>|; + $column_data{description} = qq|<td><input type=hidden name="description_$i" value="$form->{"description_$i"}">$form->{"description_$i"}</td>|; + + } + + $column_data{sellprice} = qq|<td align=right>$linetotalsellprice</td>|; + $column_data{listprice} = qq|<td align=right>$linetotallistprice</td>|; + $column_data{lastcost} = qq|<td align=right>$linetotallastcost</td>|; + + print qq| + <tr>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + $form->hide_form("id_$i","sellprice_$i","listprice_$i","lastcost_$i","weight_$i","assembly_$i"); + + } + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{sellprice} = "<th align=right>".$form->format_amount(\%myconfig, $form->{sellprice}, 2)."</th>"; + $column_data{listprice} = "<th align=right>".$form->format_amount(\%myconfig, $form->{listprice}, 2)."</th>"; + $column_data{lastcost} = "<th align=right>".$form->format_amount(\%myconfig, $form->{lastcost}, 2)."</th>"; + + print qq| + <tr>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> + </table> + <input type=hidden name=assembly_rows value=$form->{assembly_rows}> + <input type=hidden name=nextsub value=edit_assemblyitem> + <input type=hidden name=selectassemblypartsgroup value="|.$form->escape($form->{selectassemblypartsgroup},1).qq|"> +|; + +} + + +sub edit_assemblyitem { + + $pn = substr($form->{action}, 1); + + $i = 0; + for (1 .. $form->{assembly_rows} - 1) { + $i++; + last if $form->{"partnumber_$_"} eq $pn; + } + + $form->error($locale->text('unexpected error!')) unless $i; + + $form->{baseassembly} = ($form->{baseassembly}) ? $form->{baseassembly} : $form->{"assembly_$i"}; + + $form->{callback} = qq|$form->{script}?action=edit&id=$form->{"id_$i"}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&rowcount=$i&baseassembly=$form->{baseassembly}&isassemblyitem=1&previousform=$form->{previousform}|; + + $form->redirect; + +} + + +sub update { + + if ($form->{item} eq "assembly") { + + $i = $form->{assembly_rows}; + $i = $form->{assembly_rows} + 1 if $form->{project_id}; + + # if last row is empty check the form otherwise retrieve item + if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) { + + &check_form; + + } else { + + IC->assembly_item(\%myconfig, \%$form); + + $rows = scalar @{ $form->{item_list} }; + + if ($rows) { + $form->{"adj_$i"} = 1; + + if ($rows > 1) { + $form->{makemodel_rows}--; + $form->{customer_rows}--; + &select_item; + exit; + } else { + $form->{"qty_$i"} = 1; + $form->{"adj_$i"} = 1; + for (qw(partnumber description unit)) { $form->{item_list}[$i]{$_} = $form->quote($form->{item_list}[$i]{$_}) } + for (keys %{ $form->{item_list}[0] }) { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } + + if ($form->{item_list}[0]{partsgroup_id}) { + $form->{"partsgroup_$i"} = qq|$form->{item_list}[0]{partsgroup}--$form->{item_list}[0]{partsgroup_id}|; + } + + $form->{"runningnumber_$i"} = $form->{assembly_rows}; + $form->{assembly_rows}++; + + &check_form; + + } + + } else { + + $form->{rowcount} = $i; + $form->{assembly_rows}++; + + &new_item; + + } + } + + } else { + + &check_form; + + } + +} + + +sub check_vendor { + + @flds = qw(vendor partnumber lastcost leadtime vendorcurr); + @a = (); + $count = 0; + + for (qw(lastcost leadtime)) { $form->{"${_}_$form->{vendor_rows}"} = $form->parse_amount(\%myconfig, $form->{"${_}_$form->{vendor_rows}"}) } + + for $i (1 .. $form->{vendor_rows} - 1) { + + for (qw(lastcost leadtime)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + if ($form->{"lastcost_$i"} || $form->{"partnumber_$i"}) { + + push @a, {}; + $j = $#a; + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + + } + } + + $i = $form->{vendor_rows}; + + if (!$form->{selectvendor}) { + + if ($form->{"vendor_$i"} && !$form->{"vendor_id_$i"}) { + ($form->{vendor}) = split /--/, $form->{"vendor_$i"}; + if (($j = $form->get_name(\%myconfig, vendor)) > 1) { + &select_name(vendor, $i); + exit; + } + + if ($j == 1) { + # we got one name + $form->{"vendor_$i"} = qq|$form->{name_list}[0]->{name}--$form->{name_list}[0]->{id}|; + } else { + # name is not on file + $form->error(qq|$form->{"vendor_$i"} : |.$locale->text('Vendor not on file!')); + } + } + } + + if ($form->{"vendor_$i"}) { + push @a, {}; + $j = $#a; + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + + $form->redo_rows(\@flds, \@a, $count, $form->{vendor_rows}); + $form->{vendor_rows} = $count; + +} + + +sub check_customer { + + @flds = qw(customer validfrom validto pricebreak customerprice pricegroup customercurr); + @a = (); + $count = 0; + + for (qw(customerprice pricebreak)) { $form->{"${_}_$form->{customer_rows}"} = $form->parse_amount(\%myconfig, $form->{"${_}_$form->{customer_rows}"}) } + + for $i (1 .. $form->{customer_rows} - 1) { + + for (qw(customerprice pricebreak)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + if ($form->{"customerprice_$i"}) { + if ($form->{"pricebreak_$i"} || $form->{"customer_$i"} || $form->{"pricegroup_$i"}) { + + push @a, {}; + $j = $#a; + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + + } + } + } + + $i = $form->{customer_rows}; + + if (!$form->{selectcustomer}) { + + if ($form->{"customer_$i"} && !$form->{"customer_id_$i"}) { + ($form->{customer}) = split /--/, $form->{"customer_$i"}; + + if (($j = $form->get_name(\%myconfig, customer)) > 1) { + &select_name(customer, $i); + exit; + } + + if ($j == 1) { + # we got one name + $form->{"customer_$i"} = qq|$form->{name_list}[0]->{name}--$form->{name_list}[0]->{id}|; + } else { + # name is not on file + $form->error(qq|$form->{customer} : |.$locale->text('Customer not on file!')); + } + } + } + + if ($form->{"customer_$i"} || $form->{"pricegroup_$i"} || ($form->{"customerprice_$i"} || $form->{"pricebreak_$i"})) { + push @a, {}; + $j = $#a; + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + + $form->redo_rows(\@flds, \@a, $count, $form->{customer_rows}); + $form->{customer_rows} = $count; + +} + + + +sub select_name { + my ($table, $vr) = @_; + + @column_index = qw(ndx name address); + + $label = ucfirst $table; + $column_data{ndx} = qq|<th> </th>|; + $column_data{name} = qq|<th class=listheading>|.$locale->text($label).qq|</th>|; + $column_data{address} = qq|<th class=listheading colspan=5>|.$locale->text('Address').qq|</th>|; + + # list items with radio button on a form + $form->header; + + $title = $locale->text('Select from one of the names below'); + + print qq| +<body> + +<form method=post action="$form->{script}"> + +<input type=hidden name=vr value=$vr> + +<table width=100%> + <tr> + <th class=listtop>$title</th> + </tr> + <tr space=5></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + @column_index = qw(ndx name address city state zipcode country); + + my $i = 0; + foreach $ref (@{ $form->{name_list} }) { + $checked = ($i++) ? "" : "checked"; + + $ref->{name} = $form->quote($ref->{name}); + + $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|; + $column_data{name} = qq|<td><input name="new_name_$i" type=hidden value="$ref->{name}">$ref->{name}</td>|; + $column_data{address} = qq|<td>$ref->{address1} $ref->{address2}|; + for (qw(city state zipcode country)) { $column_data{$_} = qq|<td>$ref->{$_} </td>| } + + $j++; $j %= 2; + print qq| + <tr class=listrow$j>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> + +<input name="new_id_$i" type=hidden value=$ref->{id}> + +|; + + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input name=lastndx type=hidden value=$i> + +|; + + # delete variables + for (qw(action nextsub name_list)) { delete $form->{$_} } + + $form->hide_form; + + print qq| +<input type=hidden name=nextsub value=name_selected> +<input type=hidden name=vc value=$table> +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + + +sub name_selected { + + # replace the variable with the one checked + + # index for new item + $i = $form->{ndx}; + + $form->{"$form->{vc}_$form->{vr}"} = qq|$form->{"new_name_$i"}--$form->{"new_id_$i"}|; + $form->{"$form->{vc}_id_$form->{vr}"} = $form->{"new_id_$i"}; + + # delete all the new_ variables + for $i (1 .. $form->{lastndx}) { + for (qw(id name)) { delete $form->{"new_${_}_$i"} } + } + + for (qw(ndx lastndx nextsub)) { delete $form->{$_} } + + &update; + +} + + +sub save { + + if ($form->{obsolete}) { + $form->error($locale->text("Inventory quantity must be zero before you can set this $form->{item} obsolete!")) if ($form->{onhand}); + } + +# expand dynamic strings +# $locale->text('Inventory quantity must be zero before you can set this part obsolete!') +# $locale->text('Inventory quantity must be zero before you can set this assembly obsolete!') + + $olditem = $form->{id}; + + # save part + $rc = IC->save(\%myconfig, \%$form); + + $parts_id = $form->{id}; + + # load previous variables + if ($form->{previousform} && !$form->{callback}) { + # save the new form variables before splitting previousform + for (keys %$form) { $newform{$_} = $form->{$_} } + + $previousform = $form->unescape($form->{previousform}); + $baseassembly = $form->{baseassembly}; + + # don't trample on previous variables + for (keys %newform) { delete $form->{$_} } + + # now take it apart and restore original values + foreach $item (split /&/, $previousform) { + ($key, $value) = split /=/, $item, 2; + $value =~ s/%26/&/g; + $form->{$key} = $value; + } + + + if ($form->{item} eq 'assembly') { + + if ($baseassembly) { + #redo the assembly + $previousform =~ /\&id=(\d+)/; + $form->{id} = $1; + + # restore original callback + $form->{callback} = $form->unescape($form->{old_callback}); + + &edit; + exit; + } + + # undo number formatting + for (qw(weight listprice sellprice lastcost rop)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + $form->{assembly_rows}-- if $olditem; + $i = $newform{rowcount}; + $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"}); + + $form->{listprice} -= $form->{"listprice_$i"} * $form->{"qty_$i"}; + $form->{sellprice} -= $form->{"sellprice_$i"} * $form->{"qty_$i"}; + $form->{lastcost} -= $form->{"lastcost_$i"} * $form->{"qty_$i"}; + $form->{weight} -= $form->{"weight_$i"} * $form->{"qty_$i"}; + + # change/add values for assembly item + for (qw(partnumber description bin unit weight listprice sellprice lastcost)) { $form->{"${_}_$i"} = $newform{$_} } + + foreach $item (qw(listprice sellprice lastcost)) { + $form->{$item} += $form->{"${item}_$i"} * $form->{"qty_$i"}; + $form->{$item} = $form->round_amount($form->{$item}, 2); + } + + $form->{weight} += $form->{"weight_$i"} * $form->{"qty_$i"}; + + $form->{"adj_$i"} = 1 if !$olditem; + + $form->{customer_rows}--; + + } else { + # set values for last invoice/order item + $i = $form->{rowcount}; + $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"}); + + for (qw(partnumber description bin unit listprice sellprice partsgroup)) { $form->{"${_}_$i"} = $newform{$_} } + for (qw(inventory income expense)) { + $form->{"${_}_accno_id_$i"} = $newform{"IC_$_"}; + $form->{"${_}_accno_id_$i"} =~ s/--.*//; + } + $form->{"sellprice_$i"} = $newform{lastcost} if ($form->{vendor_id}); + + if ($form->{exchangerate} != 0) { + $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} / $form->{exchangerate}, 2); + } + + for (split / /, $newform{taxaccounts}) { $form->{"taxaccounts_$i"} .= "$_ " if ($newform{"IC_tax_$_"}) } + chop $form->{"taxaccounts_$i"}; + + # credit remaining calculation + $amount = $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * $form->{"qty_$i"}; + for (split / /, $form->{"taxaccounts_$i"}) { $form->{"${_}_base"} += $amount } + if (!$form->{taxincluded}) { + for (split / /, $form->{"taxaccounts_$i"}) { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } + } + + $ml = 1; + if ($form->{type} =~ /invoice/) { + $ml = -1 if $form->{type} =~ /_invoice/; + } + $form->{creditremaining} -= ($amount * $ml); + + } + + $form->{"id_$i"} = $parts_id; + delete $form->{action}; + + # restore original callback + $callback = $form->unescape($form->{callback}); + $form->{callback} = $form->unescape($form->{old_callback}); + delete $form->{old_callback}; + + $form->{makemodel_rows}--; + + # put callback together + foreach $key (keys %$form) { + # do single escape for Apache 2.0 + $value = $form->escape($form->{$key}, 1); + $callback .= qq|&$key=$value|; + } + $form->{callback} = $callback; + } + + # redirect + $form->redirect; + +} + + +sub save_as_new { + + $form->{id} = 0; + &save; + +} + + +sub delete { + + # redirect + if (IC->delete(\%myconfig, \%$form)) { + $form->redirect($locale->text('Item deleted!')); + } else { + $form->error($locale->text('Cannot delete item!')); + } + +} + + + +sub stock_assembly { + + $form->{title} = $locale->text('Stock Assembly'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width="100%"> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + <tr> + <th align="right" nowrap="true">|.$locale->text('Number').qq|</th> + <td><input name=partnumber size=20></td> + <td> </td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('Description').qq|</th> + <td><input name=description size=40></td> + </tr> + <tr> + <td></td> + <td><input name=checkinventory class=checkbox type=checkbox value=1> |.$locale->text('Check Inventory').qq|</td> + </tr> + </table> + </td> + </tr> + <tr><td><hr size=3 noshade></td></tr> +</table> + +<input type=hidden name=sort value=partnumber> +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +<input type=hidden name=nextsub value=list_assemblies> + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + + + +sub list_assemblies { + + IC->retrieve_assemblies(\%myconfig, \%$form); + + $callback = "$form->{script}?action=list_assemblies&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&checkinventory=$form->{checkinventory}"; + + $form->sort_order(); + $href = "$form->{script}?action=list_assemblies&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&checkinventory=$form->{checkinventory}"; + + if ($form->{partnumber}) { + $callback .= "&partnumber=".$form->escape($form->{partnumber},1); + $href .= "&partnumber=".$form->escape($form->{partnumber}); + $form->{sort} = "partnumber" unless $form->{sort}; + } + if ($form->{description}) { + $callback .= "&description=".$form->escape($form->{description},1); + $href .= "&description=".$form->escape($form->{description}); + $form->{sort} = "description" unless $form->{sort}; + } + + $column_header{partnumber} = qq|<th><a class=listheading href=$href&sort=partnumber>|.$locale->text('Number').qq|</th>|; + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</th>|; + $column_header{bin} = qq|<th><a class=listheading href=$href&sort=bin>|.$locale->text('Bin').qq|</th>|; + $column_header{onhand} = qq|<th class=listheading>|.$locale->text('Qty').qq|</th>|; + $column_header{rop} = qq|<th class=listheading>|.$locale->text('ROP').qq|</th>|; + $column_header{stock} = qq|<th class=listheading>|.$locale->text('Add').qq|</th>|; + + @column_index = $form->sort_columns(qw(partnumber description bin onhand rop stock)); + + $form->{title} = $locale->text('Stock Assembly'); + + + $form->header; + + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr size=5></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + # add sort and escape callback + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + + $i = 1; + foreach $ref (@{ $form->{assembly_items} }) { + + for (qw(partnumber description)) { $ref->{$_} = $form->quote($ref->{$_}) } + + $column_data{partnumber} = "<td width=20%><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber} </a></td>"; + + $column_data{description} = qq|<td width=50%>$ref->{description} </td>|; + $column_data{bin} = qq|<td>$ref->{bin} </td>|; + $column_data{onhand} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{onhand}, "", " ").qq|</td>|; + $column_data{rop} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{rop}, '', " ").qq|</td>|; + $column_data{stock} = qq|<td width=10%><input name="qty_$i" size=10 value=|.$form->format_amount(\%myconfig, $ref->{stock}).qq|></td> + <input type=hidden name="stock_$i" value=$ref->{stock}>|; + + $j++; $j %= 2; + print qq|<tr class=listrow$j><input name="id_$i" type=hidden value=$ref->{id}>\n|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + $i++; + + } + + $i--; + print qq| + </td> + </table> + <tr> + <td><hr size=3 noshade> + </tr> +</table> +|; + + $form->hide_form(qw(checkinventory path login sessionid callback)); + + print qq| +<input type=hidden name=rowcount value="$i"> +<input type=hidden name=nextsub value=restock_assemblies> + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> + +</form> + +</body> +</html> +|; + +} + + +sub restock_assemblies { + + + if ($form->{checkinventory}) { + for (1 .. $form->{rowcount}) { $form->error($locale->text('Quantity exceeds available units to stock!')) if $form->parse_amount($myconfig, $form->{"qty_$_"}) > $form->{"stock_$_"} } + } + + if (IC->restock_assemblies(\%myconfig, \%$form)) { + if ($form->{callback} =~ /(direction=)(.*?)\&/) { + $direction = ($2 eq 'ASC') ? 'DESC' : 'ASC'; + } + $form->{callback} =~ s/direction=(.*?)\&/direction=$direction\&/; + $form->redirect($locale->text('Assemblies restocked!')); + } else { + $form->error($locale->text('Cannot stock assemblies!')); + } + +} + + +sub continue { &{ $form->{nextsub} } }; + +sub add_part { &add }; +sub add_service { &add }; +sub add_assembly { &add }; +sub add_labor_overhead { &add }; + + diff --git a/bin/lynx/io.pl b/bin/lynx/io.pl new file mode 100755 index 00000000..fbc37ac7 --- /dev/null +++ b/bin/lynx/io.pl @@ -0,0 +1,1683 @@ +###################################################################### +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2002 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +####################################################################### +# +# common routines used in is, ir, oe +# +####################################################################### + +# any custom scripts for this one +if (-f "$form->{path}/custom_io.pl") { + eval { require "$form->{path}/custom_io.pl"; }; +} +if (-f "$form->{path}/$form->{login}_io.pl") { + eval { require "$form->{path}/$form->{login}_io.pl"; }; +} + + +1; +# end of main + + +# this is for our long dates +# $locale->text('January') +# $locale->text('February') +# $locale->text('March') +# $locale->text('April') +# $locale->text('May ') +# $locale->text('June') +# $locale->text('July') +# $locale->text('August') +# $locale->text('September') +# $locale->text('October') +# $locale->text('November') +# $locale->text('December') + +# this is for our short month +# $locale->text('Jan') +# $locale->text('Feb') +# $locale->text('Mar') +# $locale->text('Apr') +# $locale->text('May') +# $locale->text('Jun') +# $locale->text('Jul') +# $locale->text('Aug') +# $locale->text('Sep') +# $locale->text('Oct') +# $locale->text('Nov') +# $locale->text('Dec') + + +sub display_row { + my $numrows = shift; + + @column_index = qw(runningnumber partnumber description qty); + + if ($form->{type} eq "sales_order") { + push @column_index, "ship"; + $column_data{ship} = qq|<th class=listheading align=center width="auto">|.$locale->text('Ship').qq|</th>|; + } + if ($form->{type} eq "purchase_order") { + push @column_index, "ship"; + $column_data{ship} = qq|<th class=listheading align=center width="auto">|.$locale->text('Recd').qq|</th>|; + } + + for (qw(projectnumber partsgroup)) { + $form->{"select$_"} = $form->unescape($form->{"select$_"}) if $form->{"select$_"}; + } + + if ($form->{language_code} ne $form->{oldlanguage_code}) { + # rebuild partsgroup + $l{language_code} = $form->{language_code}; + $l{searchitems} = 'nolabor' if $form->{vc} eq 'customer'; + + $form->get_partsgroup(\%myconfig, \%l); + if (@ { $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = "<option>\n"; + foreach $ref (@ { $form->{all_partsgroup} }) { + if ($ref->{translation}) { + $form->{selectpartsgroup} .= qq|<option value="$ref->{partsgroup}--$ref->{id}">$ref->{translation}\n|; + } else { + $form->{selectpartsgroup} .= qq|<option value="$ref->{partsgroup}--$ref->{id}">$ref->{partsgroup}\n|; + } + } + } + $form->{oldlanguage_code} = $form->{language_code}; + } + + + push @column_index, qw(unit sellprice discount linetotal); + + my $colspan = $#column_index + 1; + + $form->{invsubtotal} = 0; + for (split / /, $form->{taxaccounts}) { $form->{"${_}_base"} = 0 } + + $column_data{runningnumber} = qq|<th class=listheading nowrap>|.$locale->text('Item').qq|</th>|; + $column_data{partnumber} = qq|<th class=listheading nowrap>|.$locale->text('Number').qq|</th>|; + $column_data{description} = qq|<th class=listheading nowrap>|.$locale->text('Description').qq|</th>|; + $column_data{qty} = qq|<th class=listheading nowrap>|.$locale->text('Qty').qq|</th>|; + $column_data{unit} = qq|<th class=listheading nowrap>|.$locale->text('Unit').qq|</th>|; + $column_data{sellprice} = qq|<th class=listheading nowrap>|.$locale->text('Price').qq|</th>|; + $column_data{discount} = qq|<th class=listheading>%</th>|; + $column_data{linetotal} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|; + $column_data{bin} = qq|<th class=listheading nowrap>|.$locale->text('Bin').qq|</th>|; + $column_data{onhand} = qq|<th class=listheading nowrap>|.$locale->text('OH').qq|</th>|; + + print qq| + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + + $deliverydate = $locale->text('Delivery Date'); + $serialnumber = $locale->text('Serial No.'); + $projectnumber = $locale->text('Project'); + $group = $locale->text('Group'); + $sku = $locale->text('SKU'); + + $delvar = 'deliverydate'; + + if ($form->{type} =~ /_(order|quotation)$/) { + $reqdate = $locale->text('Required by'); + $delvar = 'reqdate'; + } + + $exchangerate = $form->parse_amount(\%myconfig, $form->{exchangerate}); + $exchangerate = ($exchangerate) ? $exchangerate : 1; + + $spc = substr($myconfig{numberformat},-3,1); + for $i (1 .. $numrows) { + if ($spc eq '.') { + ($null, $dec) = split /\./, $form->{"sellprice_$i"}; + } else { + ($null, $dec) = split /,/, $form->{"sellprice_$i"}; + } + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + # undo formatting + for (qw(qty oldqty ship discount sellprice)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + if ($form->{"qty_$i"} != $form->{"oldqty_$i"}) { + # check pricematrix + @a = split / /, $form->{"pricematrix_$i"}; + if (scalar @a > 2) { + foreach $item (@a) { + ($q, $p) = split /:/, $item; + if (($p * 1) && ($form->{"qty_$i"} >= ($q * 1))) { + ($dec) = ($p =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + $form->{"sellprice_$i"} = $form->round_amount($p / $exchangerate, $decimalplaces); + } + } + } + } + + $discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}/100, $decimalplaces); + $linetotal = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces); + $linetotal = $form->round_amount($linetotal * $form->{"qty_$i"}, 2); + + + if (($rows = $form->numtextrows($form->{"description_$i"}, 46, 6)) > 1) { + $form->{"description_$i"} = $form->quote($form->{"description_$i"}); + $column_data{description} = qq|<td><textarea name="description_$i" rows=$rows cols=46 wrap=soft>$form->{"description_$i"}</textarea></td>|; + } else { + $form->{"description_$i"} = $form->quote($form->{"description_$i"}); + $column_data{description} = qq|<td><input name="description_$i" size=48 value="$form->{"description_$i"}"></td>|; + } + + for (qw(partnumber sku unit)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + + $skunumber = qq| + <p><b>$sku</b> $form->{"sku_$i"}| if ($form->{vc} eq 'vendor' && $form->{"sku_$i"}); + + + if ($form->{selectpartsgroup}) { + if ($i < $numrows) { + $partsgroup = qq| + <b>$group</b> + <input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">|; + ($form->{"partsgroup_$i"}) = split /--/, $form->{"partsgroup_$i"}; + $partsgroup .= $form->{"partsgroup_$i"}; + $partsgroup = "" unless $form->{"partsgroup_$i"}; + } + } + + $delivery = qq| + <td colspan=2 nowrap> + <b>${$delvar}</b> + <input name="${delvar}_$i" size=11 title="$myconfig{dateformat}" value="$form->{"${delvar}_$i"}"></td> +|; + + $column_data{runningnumber} = qq|<td><input name="runningnumber_$i" size=3 value=$i></td>|; + $column_data{partnumber} = qq|<td><input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}" accesskey="$i" title="[Alt-$i]">$skunumber</td>|; + $column_data{qty} = qq|<td align=right><input name="qty_$i" title="$form->{"onhand_$i"}" size=5 value=|.$form->format_amount(\%myconfig, $form->{"qty_$i"}).qq|></td>|; + $column_data{ship} = qq|<td align=right><input name="ship_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"ship_$i"}).qq|></td>|; + $column_data{unit} = qq|<td><input name="unit_$i" size=5 value="$form->{"unit_$i"}"></td>|; + $column_data{sellprice} = qq|<td align=right><input name="sellprice_$i" size=9 value=|.$form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces).qq|></td>|; + $column_data{discount} = qq|<td align=right><input name="discount_$i" size=3 value=|.$form->format_amount(\%myconfig, $form->{"discount_$i"}).qq|></td>|; + $column_data{linetotal} = qq|<td align=right>|.$form->format_amount(\%myconfig, $linetotal, 2).qq|</td>|; + $column_data{bin} = qq|<td>$form->{"bin_$i"}</td>|; + $column_data{onhand} = qq|<td>$form->{"onhand_$i"}</td>|; + + print qq| + <tr valign=top>|; + + for (@column_index) { + print "\n$column_data{$_}"; + } + + print qq| + </tr> +<input type=hidden name="oldqty_$i" value="$form->{"qty_$i"}"> +|; + + for (qw(orderitems_id id bin weight listprice lastcost taxaccounts pricematrix sku onhand assembly inventory_accno_id income_accno_id expense_accno_id)) { + $form->hide_form("${_}_$i"); + } + + $form->{selectprojectnumber} =~ s/ selected//; + $form->{selectprojectnumber} =~ s/(<option value="\Q$form->{"projectnumber_$i"}\E")/$1 selected/; + + $project = qq| + <b>$projectnumber</b> + <select name="projectnumber_$i">$form->{selectprojectnumber}</select> +| if $form->{selectprojectnumber}; + + + if (($rows = $form->numtextrows($form->{"notes_$i"}, 46, 6)) > 1) { + $form->{"notes_$i"} = $form->quote($form->{"notes_$i"}); + $notes = qq|<td><textarea name="notes_$i" rows=$rows cols=46 wrap=soft>$form->{"notes_$i"}</textarea></td>|; + } else { + $form->{"notes_$i"} = $form->quote($form->{"notes_$i"}); + $notes = qq|<td><input name="notes_$i" size=48 value="$form->{"notes_$i"}"></td>|; + } + + $serial = qq| + <td colspan=6 nowrap><b>$serialnumber</b> <input name="serialnumber_$i" value="$form->{"serialnumber_$i"}"></td>| if $form->{type} !~ /_quotation/; + + if ($i == $numrows) { + $partsgroup = ""; + if ($form->{selectpartsgroup}) { + $partsgroup = qq| + <b>$group</b> + <select name="partsgroup_$i">$form->{selectpartsgroup}</select> +|; + } + + $serial = ""; + $project = ""; + $delivery = ""; + $notes = ""; + } + + + # print second and third row + print qq| + <tr valign=top> + $delivery + $notes + $serial + </tr> + <tr valign=top> + <td colspan=$colspan> + $project + $partsgroup + </td> + </tr> + <tr> + <td colspan=$colspan><hr size=1 noshade></td> + </tr> +|; + + $skunumber = ""; + + for (split / /, $form->{"taxaccounts_$i"}) { + $form->{"${_}_base"} += $linetotal; + } + + $form->{invsubtotal} += $linetotal; + } + + print qq| + </table> + </td> + </tr> +|; + + $form->hide_form(qw(audittrail)); + + print qq| + +<input type=hidden name=oldcurrency value=$form->{currency}> + +<input type=hidden name=selectpartsgroup value="|.$form->escape($form->{selectpartsgroup},1).qq|"> +<input type=hidden name=selectprojectnumber value="|.$form->escape($form->{selectprojectnumber},1).qq|"> + +|; + +} + + +sub select_item { + + if ($form->{vc} eq "vendor") { + @column_index = qw(ndx partnumber sku description partsgroup onhand sellprice); + } else { + @column_index = qw(ndx partnumber description partsgroup onhand sellprice); + } + + $column_data{ndx} = qq|<th> </th>|; + $column_data{partnumber} = qq|<th class=listheading>|.$locale->text('Number').qq|</th>|; + $column_data{sku} = qq|<th class=listheading>|.$locale->text('SKU').qq|</th>|; + $column_data{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|; + $column_data{partsgroup} = qq|<th class=listheading>|.$locale->text('Group').qq|</th>|; + $column_data{sellprice} = qq|<th class=listheading>|.$locale->text('Price').qq|</th>|; + $column_data{onhand} = qq|<th class=listheading>|.$locale->text('Qty').qq|</th>|; + + $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1; + + # list items with radio button on a form + $form->header; + + $title = $locale->text('Select items'); + + print qq| +<body> + +<form method=post action="$form->{script}"> + +<table width=100%> + <tr> + <th class=listtop>$title</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + my $i = 0; + foreach $ref (@{ $form->{item_list} }) { + $i++; + + for (qw(sku partnumber description unit notes partsgroup)) { + $ref->{$_} = $form->quote($ref->{$_}); + } + + $column_data{ndx} = qq|<td><input name="ndx_$i" class=checkbox type=checkbox value=$i></td>|; + + for (qw(partnumber sku description partsgroup)) { $column_data{$_} = qq|<td>$ref->{$_} </td>| } + + $column_data{sellprice} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{sellprice} / $exchangerate, 2, " ").qq|</td>|; + $column_data{onhand} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{onhand}, '', " ").qq|</td>|; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j>|; + + for (@column_index) { + print "\n$column_data{$_}"; + } + + print qq| + </tr> +|; + + for (qw(partnumber sku description partsgroup partsgroup_id bin weight sellprice listprice lastcost onhand unit assembly taxaccounts inventory_accno_id income_accno_id expense_accno_id pricematrix id notes)) { + print qq|<input type=hidden name="new_${_}_$i" value="$ref->{$_}">\n|; + } + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input name=lastndx type=hidden value=$i> + +|; + + # delete variables + for (qw(nextsub item_list)) { delete $form->{$_} } + + $form->{action} = "item_selected"; + + $form->hide_form; + + print qq| +<input type=hidden name=nextsub value=item_selected> + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + + +sub item_selected { + + $i = $form->{rowcount} - 1; + $i = $form->{assembly_rows} - 1 if ($form->{item} eq 'assembly'); + $qty = ($form->{"qty_$form->{rowcount}"}) ? $form->{"qty_$form->{rowcount}"} : 1; + + for $j (1 .. $form->{lastndx}) { + + if ($form->{"ndx_$j"}) { + + $i++; + + $form->{"qty_$i"} = $qty; + $form->{"discount_$i"} = $form->{discount} * 100; + $form->{"reqdate_$i"} = $form->{reqdate} if $form->{type} !~ /_quotation/; + + for (qw(id partnumber sku description sellprice listprice lastcost bin unit weight assembly taxaccounts pricematrix onhand notes inventory_accno_id income_accno_id expense_accno_id)) { + $form->{"${_}_$i"} = $form->{"new_${_}_$j"}; + } + + $form->{"partsgroup_$i"} = qq|$form->{"new_partsgroup_$j"}--$form->{"new_partsgroup_id_$j"}|; + + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces1 = ($dec > 2) ? $dec : 2; + + ($dec) = ($form->{"lastcost_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces2 = ($dec > 2) ? $dec : 2; + + # if there is an exchange rate adjust sellprice + if (($form->{exchangerate} * 1)) { + for (qw(sellprice listprice lastcost)) { $form->{"${_}_$i"} /= $form->{exchangerate} } + # don't format list and cost + $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"}, $decimalplaces1); + } + + # this is for the assembly + if ($form->{item} eq 'assembly') { + $form->{"adj_$i"} = 1; + + for (qw(sellprice listprice weight)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + $form->{sellprice} += ($form->{"sellprice_$i"} * $form->{"qty_$i"}); + $form->{weight} += ($form->{"weight_$i"} * $form->{"qty_$i"}); + } + + $amount = $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * $form->{"qty_$i"}; + for (split / /, $form->{"taxaccounts_$i"}) { $form->{"${_}_base"} += $amount } + if (!$form->{taxincluded}) { + for (split / /, $form->{"taxaccounts_$i"}) { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } + } + + $form->{creditremaining} -= $amount; + + $form->{"runningnumber_$i"} = $i; + + # format amounts + if ($form->{item} ne 'assembly') { + for (qw(sellprice listprice)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces1) } + $form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces2); + } + $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"}); + + } + } + + $form->{rowcount} = $i; + $form->{assembly_rows} = $i if ($form->{item} eq 'assembly'); + + $form->{focus} = "description_$i"; + + # delete all the new_ variables + for $i (1 .. $form->{lastndx}) { + for (qw(id partnumber sku description sellprice listprice lastcost bin unit weight assembly taxaccounts pricematrix onhand notes inventory_accno_id income_accno_id expense_accno_id)) { + delete $form->{"new_${_}_$i"}; + } + } + + for (qw(ndx lastndx nextsub)) { delete $form->{$_} } + + &display_form; + +} + + +sub new_item { + + if ($form->{language_code} && $form->{"description_$form->{rowcount}"}) { + $form->error($locale->text('Translation not on file!')); + } + + # change callback + $form->{old_callback} = $form->escape($form->{callback},1); + $form->{callback} = $form->escape("$form->{script}?action=display_form",1); + + # delete action + delete $form->{action}; + + # save all other form variables in a previousform variable + if (!$form->{previousform}) { + foreach $key (keys %$form) { + # escape ampersands + $form->{$key} =~ s/&/%26/g; + $form->{previousform} .= qq|$key=$form->{$key}&|; + } + chop $form->{previousform}; + $form->{previousform} = $form->escape($form->{previousform}, 1); + } + + $i = $form->{rowcount}; + for (qw(partnumber description)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + + $form->header; + + print qq| +<body> + +<h4 class=error>|.$locale->text('Item not on file!').qq|</h4>|; + + if ($myconfig{acs} !~ /(Goods \& Services--Add Part|Goods \& Services--Add Service)/) { + + print qq| +<h4>|.$locale->text('What type of item is this?').qq|</h4> + +<form method=post action=ic.pl> + +<p> + + <input class=radio type=radio name=item value=part checked> |.$locale->text('Part') +.qq|<br> + <input class=radio type=radio name=item value=service> |.$locale->text('Service') + +.qq| +<input type=hidden name=partnumber value="$form->{"partnumber_$i"}"> +<input type=hidden name=description value="$form->{"description_$i"}"> +<input type=hidden name=nextsub value=add> +<input type=hidden name=action value=add> +|; + + $form->hide_form(qw(previousform rowcount path login sessionid)); + + print qq| +<p> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> +|; + } + + print qq| +</body> +</html> +|; + +} + + + +sub display_form { + + # if we have a display_form + if ($form->{display_form}) { + &{ "$form->{display_form}" }; + exit; + } + + &form_header; + + $numrows = ++$form->{rowcount}; + $subroutine = "display_row"; + + if ($form->{item} eq 'part') { + # create makemodel rows + &makemodel_row(++$form->{makemodel_rows}); + + &vendor_row(++$form->{vendor_rows}); + + $numrows = ++$form->{customer_rows}; + $subroutine = "customer_row"; + } + if ($form->{item} eq 'assembly') { + # create makemodel rows + &makemodel_row(++$form->{makemodel_rows}); + + $numrows = ++$form->{customer_rows}; + $subroutine = "customer_row"; + } + if ($form->{item} eq 'service') { + &vendor_row(++$form->{vendor_rows}); + + $numrows = ++$form->{customer_rows}; + $subroutine = "customer_row"; + } + if ($form->{item} eq 'labor') { + $numrows = 0; + } + + # create rows + &{ $subroutine }($numrows) if $numrows; + + &form_footer; + +} + + + +sub check_form { + + my @a = (); + my $count = 0; + my $i; + my $j; + my @flds = qw(id runningnumber partnumber description partsgroup qty ship unit sellprice discount oldqty orderitems_id bin weight listprice lastcost taxaccounts pricematrix sku onhand assembly inventory_accno_id income_accno_id expense_accno_id notes reqdate deliverydate serialnumber projectnumber); + + # remove any makes or model rows + if ($form->{item} eq 'part') { + for (qw(listprice sellprice lastcost avgcost weight rop markup)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + &calc_markup; + + @flds = qw(make model); + $count = 0; + @a = (); + for $i (1 .. $form->{makemodel_rows}) { + if (($form->{"make_$i"} ne "") || ($form->{"model_$i"} ne "")) { + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + + $form->redo_rows(\@flds, \@a, $count, $form->{makemodel_rows}); + $form->{makemodel_rows} = $count; + + &check_vendor; + &check_customer; + + } + + if ($form->{item} eq 'service') { + + for (qw(sellprice listprice lastcost avgcost markup)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + &calc_markup; + &check_vendor; + &check_customer; + + } + + if ($form->{item} eq 'assembly') { + + if (!$form->{project_id}) { + $form->{sellprice} = 0; + $form->{listprice} = 0; + $form->{lastcost} = 0; + $form->{weight} = 0; + } + + for (qw(rop stock markup)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + @flds = qw(id qty unit bom adj partnumber description sellprice listprice lastcost weight assembly runningnumber partsgroup); + $count = 0; + @a = (); + + for $i (1 .. ($form->{assembly_rows} - 1)) { + if ($form->{"qty_$i"}) { + push @a, {}; + my $j = $#a; + + $form->{"qty_$i"} = $form->parse_amount(\%myconfig, $form->{"qty_$i"}); + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + + if (! $form->{project_id}) { + for (qw(sellprice listprice weight lastcost)) { $form->{$_} += ($form->{"${_}_$i"} * $form->{"qty_$i"}) } + } + + $count++; + } + } + + if ($form->{markup} && $form->{markup} != $form->{oldmarkup}) { + $form->{sellprice} = 0; + &calc_markup; + } + + for (qw(sellprice lastcost listprice)) { $form->{$_} = $form->round_amount($form->{$_}, 2) } + + $form->redo_rows(\@flds, \@a, $count, $form->{assembly_rows}); + $form->{assembly_rows} = $count; + + $count = 0; + @flds = qw(make model); + @a = (); + + for $i (1 .. ($form->{makemodel_rows})) { + if (($form->{"make_$i"} ne "") || ($form->{"model_$i"} ne "")) { + push @a, {}; + my $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + + $form->redo_rows(\@flds, \@a, $count, $form->{makemodel_rows}); + $form->{makemodel_rows} = $count; + + &check_customer; + + } + + if ($form->{type}) { + + # this section applies to invoices and orders + # remove any empty numbers + + $count = 0; + @a = (); + if ($form->{rowcount}) { + for $i (1 .. $form->{rowcount} - 1) { + if ($form->{"partnumber_$i"}) { + push @a, {}; + my $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + + $form->redo_rows(\@flds, \@a, $count, $form->{rowcount}); + $form->{rowcount} = $count; + + $form->{creditremaining} -= &invoicetotal; + + } + } + + &display_form; + +} + + +sub calc_markup { + + if ($form->{markup}) { + if ($form->{markup} != $form->{oldmarkup}) { + if ($form->{lastcost}) { + $form->{sellprice} = $form->{lastcost} * (1 + $form->{markup}/100); + $form->{sellprice} = $form->round_amount($form->{sellprice}, 2); + } else { + $form->{lastcost} = $form->{sellprice} / (1 + $form->{markup}/100); + $form->{lastcost} = $form->round_amount($form->{lastcost}, 2); + } + } + } else { + if ($form->{lastcost}) { + $form->{markup} = $form->round_amount(((1 - $form->{sellprice} / $form->{lastcost}) * 100), 1); + } + $form->{markup} = "" if $form->{markup} == 0; + } + +} + + +sub invoicetotal { + + $form->{oldinvtotal} = 0; + # add all parts and deduct paid + for (split / /, $form->{taxaccounts}) { $form->{"${_}_base"} = 0 } + + my ($amount, $sellprice, $discount, $qty); + + for $i (1 .. $form->{rowcount}) { + $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"}); + $discount = $form->parse_amount(\%myconfig, $form->{"discount_$i"}); + $qty = $form->parse_amount(\%myconfig, $form->{"qty_$i"}); + + $amount = $sellprice * (1 - $discount / 100) * $qty; + for (split / /, $form->{"taxaccounts_$i"}) { $form->{"${_}_base"} += $amount } + $form->{oldinvtotal} += $amount; + } + + if (!$form->{taxincluded}) { + for (split / /, $form->{taxaccounts}) { $form->{oldinvtotal} += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } + } + + $form->{oldtotalpaid} = 0; + for $i (1 .. $form->{paidaccounts}) { + $form->{oldtotalpaid} += $form->{"paid_$i"}; + } + + # return total + ($form->{oldinvtotal} - $form->{oldtotalpaid}); + +} + + +sub validate_items { + + # check if items are valid + if ($form->{rowcount} == 1) { + &update; + exit; + } + + for $i (1 .. $form->{rowcount} - 1) { + $form->isblank("partnumber_$i", $locale->text('Number missing in Row') . " $i"); + } + +} + + + +sub purchase_order { + + $form->{title} = $locale->text('Add Purchase Order'); + $form->{vc} = 'vendor'; + $form->{type} = 'purchase_order'; + $buysell = 'sell'; + + &create_form; + +} + + +sub sales_order { + + $form->{title} = $locale->text('Add Sales Order'); + $form->{vc} = 'customer'; + $form->{type} = 'sales_order'; + $buysell = 'buy'; + + &create_form; + +} + + +sub rfq { + + $form->{title} = $locale->text('Add Request for Quotation'); + $form->{vc} = 'vendor'; + $form->{type} = 'request_quotation'; + $buysell = 'sell'; + + &create_form; + +} + + +sub quotation { + + $form->{title} = $locale->text('Add Quotation'); + $form->{vc} = 'customer'; + $form->{type} = 'sales_quotation'; + $buysell = 'buy'; + + &create_form; + +} + + +sub create_form { + + for (qw(id printed emailed queued)) { delete $form->{$_} } + + $form->{script} = 'oe.pl'; + + $form->{shipto} = 1; + + $form->{rowcount}-- if $form->{rowcount}; + $form->{rowcount} = 0 if ! $form->{"$form->{vc}_id"}; + + do "$form->{path}/$form->{script}"; + + for ("$form->{vc}", "currency") { $form->{"select$_"} = "" } + + for (qw(currency employee department intnotes notes language_code taxincluded)) { $temp{$_} = $form->{$_} } + + &order_links; + + for (keys %temp) { $form->{$_} = $temp{$_} if $temp{$_} } + + $form->{exchangerate} = ""; + $form->{forex} = ""; + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, $buysell))); + } + + &prepare_order; + + &display_form; + +} + + + +sub e_mail { + + $bcc = qq|<input type=hidden name=bcc value="$form->{bcc}">|; + if ($myconfig{role} =~ /(admin|manager)/) { + $bcc = qq| + <th align=right nowrap=true>|.$locale->text('Bcc').qq|</th> + <td><input name=bcc size=30 value="$form->{bcc}"></td> +|; + } + + if ($form->{formname} =~ /(pick|packing|bin)_list/) { + $form->{email} = $form->{shiptoemail} if $form->{shiptoemail}; + } + + $name = $form->{$form->{vc}}; + $name =~ s/--.*//g; + $title = $locale->text('E-mail')." $name"; + + $form->header; + + print qq| +<body> + +<form method=post action="$form->{script}"> + +<table width=100%> + <tr class=listtop> + <th class=listtop>$title</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr> + <th align=right nowrap>|.$locale->text('E-mail').qq|</th> + <td><input name=email size=30 value="$form->{email}"></td> + <th align=right nowrap>|.$locale->text('Cc').qq|</th> + <td><input name=cc size=30 value="$form->{cc}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Subject').qq|</th> + <td><input name=subject size=30 value="$form->{subject}"></td> + $bcc + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table width=100%> + <tr> + <th align=left nowrap>|.$locale->text('Message').qq|</th> + </tr> + <tr> + <td><textarea name=message rows=15 cols=60 wrap=soft>$form->{message}</textarea></td> + </tr> + </table> + </td> + </tr> + <tr> + <td> +|; + + $form->{oldmedia} = $form->{media}; + $form->{media} = "email"; + $form->{format} = "pdf"; + + &print_options; + + for (qw(email cc bcc subject message formname sendmode format language_code action nextsub)) { delete $form->{$_} } + + $form->hide_form; + + print qq| + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=nextsub value=send_email> + +<br> +<input name=action class=submit type=submit value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub send_email { + + $old_form = new Form; + + for (keys %$form) { $old_form->{$_} = $form->{$_} } + $old_form->{media} = $old_form->{oldmedia}; + + &print_form($old_form); + +} + + + +sub print_options { + + $form->{sendmode} = "attachment"; + $form->{copies} = 1 unless $form->{copies}; + + $form->{SM}{$form->{sendmode}} = "selected"; + + if ($form->{selectlanguage}) { + $form->{"selectlanguage"} = $form->unescape($form->{"selectlanguage"}); + $form->{"selectlanguage"} =~ s/ selected//; + $form->{"selectlanguage"} =~ s/(<option value="\Q$form->{language_code}\E")/$1 selected/; + + $lang = qq|<select name=language_code>$form->{selectlanguage}</select> + <input type=hidden name=oldlanguage_code value=$form->{oldlanguage_code}> + <input type=hidden name=selectlanguage value="|.$form->escape($form->{selectlanguage},1).qq|">|; + } + + $form->{selectformname} = $form->unescape($form->{selectformname}); + $form->{selectformname} =~ s/ selected//; + $form->{selectformname} =~ s/(<option value="\Q$form->{formname}\E")/$1 selected/; + + $type = qq|<select name=formname>$form->{selectformname}</select> + <input type=hidden name=selectformname value="|.$form->escape($form->{selectformname},1).qq|">|; + + + if ($form->{media} eq 'email') { + $media = qq|<select name=sendmode> + <option value=attachment $form->{SM}{attachment}>|.$locale->text('Attachment').qq| + <option value=inline $form->{SM}{inline}>|.$locale->text('In-line').qq|</select>|; + } else { + $media = qq|<select name=media> + <option value="screen">|.$locale->text('Screen'); + + if (%printer && $latex) { + for (sort keys %printer) { $media .= qq| + <option value="$_">$_| } + } + if ($latex) { + $media .= qq| + <option value="queue">|.$locale->text('Queue'); + } + $media .= qq|</select>|; + + # set option selected + $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/; + + } + + + $form->{selectformat} = qq|<option value="html">html\n|; +# <option value="txt">|.$locale->text('Text'); + + if ($latex) { + $form->{selectformat} .= qq| + <option value="postscript">|.$locale->text('Postscript').qq| + <option value="pdf">|.$locale->text('PDF'); + } + + $format = qq|<select name=format>$form->{selectformat}</select>|; + $format =~ s/(<option value="\Q$form->{format}\E")/$1 selected/; + $format .= qq| + <input type=hidden name=selectformat value="|.$form->escape($form->{selectformat},1).qq|">|; + + print qq| +<table width=100%> + <tr> + <td>$type</td> + <td>$lang</td> + <td>$format</td> + <td>$media</td> +|; + + if (%printer && $latex && $form->{media} ne 'email') { + print qq| + <td nowrap>|.$locale->text('Copies').qq| + <input name=copies size=2 value=$form->{copies}></td> +|; + } + +# $locale->text('Printed') +# $locale->text('E-mailed') +# $locale->text('Queued') +# $locale->text('Scheduled') + + %status = ( printed => 'Printed', + emailed => 'E-mailed', + queued => 'Queued', + recurring => 'Scheduled' ); + + print qq|<td align=right width=90%>|; + + for (qw(printed emailed queued recurring)) { + if ($form->{$_} =~ /$form->{formname}/) { + print $locale->text($status{$_}).qq|<br>|; + } + } + + print qq| + </td> + </tr> +|; + + $form->{groupprojectnumber} = "checked" if $form->{groupprojectnumber}; + $form->{grouppartsgroup} = "checked" if $form->{grouppartsgroup}; + + for (qw(runningnumber partnumber description bin)) { $sortby{$_} = "checked" if $form->{sortby} eq $_ } + + print qq| + <tr> + <td colspan=3>|.$locale->text('Group by').qq| -> + <input name=groupprojectnumber type=checkbox class=checkbox $form->{groupprojectnumber}> + |.$locale->text('Project').qq| + <input name=grouppartsgroup type=checkbox class=checkbox $form->{grouppartsgroup}> + |.$locale->text('Group').qq| + </td> + + <td colspan=3>|.$locale->text('Sort by').qq| -> + <input name=sortby type=radio class=radio value=runningnumber $sortby{runningnumber}> + |.$locale->text('Item').qq| + <input name=sortby type=radio class=radio value=partnumber $sortby{partnumber}> + |.$locale->text('Number').qq| + <input name=sortby type=radio class=radio value=description $sortby{description}> + |.$locale->text('Description').qq| + <input name=sortby type=radio class=radio value=bin $sortby{bin}> + |.$locale->text('Bin').qq| + </td> + + </tr> +</table> +|; + +} + + + +sub print { + + # if this goes to the printer pass through + if ($form->{media} !~ /(screen|email)/) { + $form->error($locale->text('Select txt, postscript or PDF!')) if ($form->{format} !~ /(txt|postscript|pdf)/); + + $old_form = new Form; + for (keys %$form) { $old_form->{$_} = $form->{$_} } + + } + + &print_form($old_form); + +} + + +sub print_form { + my ($old_form) = @_; + + $inv = "inv"; + $due = "due"; + + $numberfld = "sinumber"; + + $display_form = ($form->{display_form}) ? $form->{display_form} : "display_form"; + + if ($form->{formname} eq "invoice") { + $form->{label} = $locale->text('Invoice'); + } + if ($form->{formname} eq 'sales_order') { + $inv = "ord"; + $due = "req"; + $form->{label} = $locale->text('Sales Order'); + $numberfld = "sonumber"; + $order = 1; + } + if ($form->{formname} eq 'work_order') { + $inv = "ord"; + $due = "req"; + $form->{label} = $locale->text('Work Order'); + $numberfld = "sonumber"; + $order = 1; + } + if ($form->{formname} eq 'packing_list') { + # we use the same packing list as from an invoice + $form->{label} = $locale->text('Packing List'); + + if ($form->{type} ne 'invoice') { + $inv = "ord"; + $due = "req"; + $numberfld = "sonumber"; + $order = 1; + + $filled = 0; + for ($i = 1; $i < $form->{rowcount}; $i++) { + if ($form->{"ship_$i"}) { + $filled = 1; + last; + } + } + if (!$filled) { + for (1 .. $form->{rowcount}) { $form->{"ship_$_"} = $form->{"qty_$_"} } + } + } + } + if ($form->{formname} eq 'pick_list') { + $form->{label} = $locale->text('Pick List'); + if ($form->{type} ne 'invoice') { + $inv = "ord"; + $due = "req"; + $order = 1; + $numberfld = "sonumber"; + } + } + if ($form->{formname} eq 'purchase_order') { + $inv = "ord"; + $due = "req"; + $form->{label} = $locale->text('Purchase Order'); + $numberfld = "ponumber"; + $order = 1; + } + if ($form->{formname} eq 'bin_list') { + $inv = "ord"; + $due = "req"; + $form->{label} = $locale->text('Bin List'); + $numberfld = "ponumber"; + $order = 1; + } + if ($form->{formname} eq 'sales_quotation') { + $inv = "quo"; + $due = "req"; + $form->{label} = $locale->text('Quotation'); + $numberfld = "sqnumber"; + $order = 1; + } + if ($form->{formname} eq 'request_quotation') { + $inv = "quo"; + $due = "req"; + $form->{label} = $locale->text('Quotation'); + $numberfld = "rfqnumber"; + $order = 1; + } + + &validate_items; + + $form->{"${inv}date"} = $form->{transdate}; + + $form->isblank("email", $locale->text('E-mail address missing!')) if ($form->{media} eq 'email'); + $form->isblank("${inv}date", $locale->text($form->{label} .' Date missing!')); + + # get next number + if (! $form->{"${inv}number"}) { + $form->{"${inv}number"} = $form->update_defaults(\%myconfig, $numberfld); + if ($form->{media} eq 'screen') { + &update; + exit; + } + } + + +# $locale->text('Invoice Number missing!') +# $locale->text('Invoice Date missing!') +# $locale->text('Packing List Number missing!') +# $locale->text('Packing List Date missing!') +# $locale->text('Order Number missing!') +# $locale->text('Order Date missing!') +# $locale->text('Quotation Number missing!') +# $locale->text('Quotation Date missing!') + + &{ "$form->{vc}_details" }; + + @a = (); + foreach $i (1 .. $form->{rowcount}) { + push @a, ("partnumber_$i", "description_$i", "projectnumber_$i", "partsgroup_$i", "serialnumber_$i", "bin_$i", "unit_$i", "notes_$i"); + } + for (split / /, $form->{taxaccounts}) { push @a, "${_}_description" } + + $ARAP = ($form->{vc} eq 'customer') ? "AR" : "AP"; + push @a, $ARAP; + + # format payment dates + for $i (1 .. $form->{paidaccounts} - 1) { + if (exists $form->{longformat}) { + $form->{"datepaid_$i"} = $locale->date(\%myconfig, $form->{"datepaid_$i"}, $form->{longformat}); + } + + push @a, "${ARAP}_paid_$i", "source_$i", "memo_$i"; + } + + $form->format_string(@a); + + ($form->{employee}) = split /--/, $form->{employee}; + ($form->{warehouse}, $form->{warehouse_id}) = split /--/, $form->{warehouse}; + + # this is a label for the subtotals + $form->{groupsubtotaldescription} = $locale->text('Subtotal') if not exists $form->{groupsubtotaldescription}; + delete $form->{groupsubtotaldescription} if $form->{deletegroupsubtotal}; + + $duedate = $form->{"${due}date"}; + + # create the form variables + if ($order) { + OE->order_details(\%myconfig, \%$form); + } else { + IS->invoice_details(\%myconfig, \%$form); + } + + if (exists $form->{longformat}) { + $form->{"${due}date"} = $duedate; + for ("${inv}date", "${due}date", "shippingdate", "transdate") { $form->{$_} = $locale->date(\%myconfig, $form->{$_}, $form->{longformat}) } + } + + @a = qw(name address1 address2 city state zipcode country contact phone fax email); + + $shipto = 1; + # if there is no shipto fill it in from billto + foreach $item (@a) { + if ($form->{"shipto$item"}) { + $shipto = 0; + last; + } + } + + if ($shipto) { + if ($form->{formname} eq 'purchase_order' || $form->{formname} eq 'request_quotation') { + $form->{shiptoname} = $myconfig{company}; + $form->{shiptoaddress1} = $myconfig{address}; + $form->{shiptoaddress1} =~ s/\\n/\n/g; + } else { + if ($form->{formname} !~ /bin_list/) { + for (@a) { $form->{"shipto$_"} = $form->{$_} } + } + } + } + + # some of the stuff could have umlauts so we translate them + push @a, qw(contact shiptoname shiptoaddress1 shiptoaddress2 shiptocity shiptostate shiptozipcode shiptocountry shiptocontact shiptoemail shippingpoint shipvia notes intnotes employee warehouse); + + push @a, ("${inv}number", "${inv}date", "${due}date"); + + for (qw(company address tel fax businessnumber)) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/\n/g; + + for (qw(name email)) { $form->{"user$_"} = $myconfig{$_} } + + push @a, qw(company address tel fax businessnumber username useremail); + + for (qw(notes intnotes)) { $form->{$_} =~ s/^\s+//g } + + # before we format replace <%var%> + for (qw(notes intnotes message)) { $form->{$_} =~ s/<%(.*?)%>/$form->{$1}/g } + + $form->format_string(@a); + + + $form->{templates} = "$myconfig{templates}"; + $form->{IN} = "$form->{formname}.$form->{format}"; + + if ($form->{format} =~ /(postscript|pdf)/) { + $form->{IN} =~ s/$&$/tex/; + } + + + $form->{pre} = "<body bgcolor=#ffffff>\n<pre>" if $form->{format} eq 'txt'; + + if ($form->{media} !~ /(screen|queue|email)/) { + $form->{OUT} = "| $printer{$form->{media}}"; + + $form->{OUT} =~ s/<%(fax)%>/<%$form->{vc}$1%>/; + $form->{OUT} =~ s/<%(.*?)%>/$form->{$1}/g; + + if ($form->{printed} !~ /$form->{formname}/) { + + $form->{printed} .= " $form->{formname}"; + $form->{printed} =~ s/^ //; + + $form->update_status(\%myconfig); + } + + $old_form->{printed} = $form->{printed} if defined %$old_form; + + %audittrail = ( tablename => ($order) ? 'oe' : lc $ARAP, + reference => $form->{"${inv}number"}, + formname => $form->{formname}, + action => 'printed', + id => $form->{id} ); + + $old_form->{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail) if defined %$old_form; + + } + + + if ($form->{media} eq 'email') { + $form->{subject} = qq|$form->{label} $form->{"${inv}number"}| unless $form->{subject}; + + $form->{plainpaper} = 1; + $form->{OUT} = "$sendmail"; + + if ($form->{emailed} !~ /$form->{formname}/) { + $form->{emailed} .= " $form->{formname}"; + $form->{emailed} =~ s/^ //; + + # save status + $form->update_status(\%myconfig); + } + + $now = scalar localtime; + $cc = $locale->text('Cc').qq|: $form->{cc}\n| if $form->{cc}; + $bcc = $locale->text('Bcc').qq|: $form->{bcc}\n| if $form->{bcc}; + + if (defined %$old_form) { + $old_form->{intnotes} = qq|$old_form->{intnotes}\n\n| if $old_form->{intnotes}; + $old_form->{intnotes} .= qq|[email]\n| + .$locale->text('Date').qq|: $now\n| + .$locale->text('To').qq|: $form->{email}\n${cc}${bcc}| + .$locale->text('Subject').qq|: $form->{subject}\n|; + + $old_form->{intnotes} .= qq|\n|.$locale->text('Message').qq|: |; + $old_form->{intnotes} .= ($form->{message}) ? $form->{message} : $locale->text('sent'); + + $old_form->{message} = $form->{message}; + $old_form->{emailed} = $form->{emailed}; + + $old_form->{format} = "postscript" if $myconfig{printer}; + $old_form->{media} = $myconfig{printer}; + + $old_form->save_intnotes(\%myconfig, ($order) ? 'oe' : lc $ARAP); + } + + %audittrail = ( tablename => ($order) ? 'oe' : lc $ARAP, + reference => $form->{"${inv}number"}, + formname => $form->{formname}, + action => 'emailed', + id => $form->{id} ); + + $old_form->{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail) if defined %$old_form; + } + + + if ($form->{media} eq 'queue') { + %queued = split / /, $form->{queued}; + + if ($filename = $queued{$form->{formname}}) { + $form->{queued} =~ s/$form->{formname} $filename//; + unlink "$spool/$filename"; + $filename =~ s/\..*$//g; + } else { + $filename = time; + $filename .= $$; + } + + $filename .= ($form->{format} eq 'postscript') ? '.ps' : '.pdf'; + $form->{OUT} = ">$spool/$filename"; + + $form->{queued} .= " $form->{formname} $filename"; + $form->{queued} =~ s/^ //; + + # save status + $form->update_status(\%myconfig); + + $old_form->{queued} = $form->{queued}; + + %audittrail = ( tablename => ($order) ? 'oe' : lc $ARAP, + reference => $form->{"${inv}number"}, + formname => $form->{formname}, + action => 'queued', + id => $form->{id} ); + + $old_form->{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail); + + } + + + $form->format_string("email", "cc", "bcc"); + + $form->{fileid} = $form->{"${inv}number"}; + $form->{fileid} =~ s/(\s|\W)+//g; + + $form->parse_template(\%myconfig, $userspath); + + # if we got back here restore the previous form + if (defined %$old_form) { + + $old_form->{"${inv}number"} = $form->{"${inv}number"}; + + # restore and display form + for (keys %$old_form) { $form->{$_} = $old_form->{$_} } + delete $form->{pre}; + + $form->{rowcount}--; + + for (qw(exchangerate creditlimit creditremaining)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + for $i (1 .. $form->{paidaccounts}) { + for (qw(paid exchangerate)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + } + + &{ "$display_form" }; + + } + +} + + +sub customer_details { + + IS->customer_details(\%myconfig, \%$form); + +} + + +sub vendor_details { + + IR->vendor_details(\%myconfig, \%$form); + +} + + +sub ship_to { + + $title = $form->{title}; + $form->{title} = $locale->text('Ship to'); + + for (qw(exchangerate creditlimit creditremaining)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + for (1 .. $form->{paidaccounts}) { $form->{"paid_$_"} = $form->parse_amount(\%myconfig, $form->{"paid_$_"}) } + + # get details for name + &{ "$form->{vc}_details" }; + + $number = ($form->{vc} eq 'customer') ? $locale->text('Customer Number') : $locale->text('Vendor Number'); + + $nextsub = ($form->{display_form}) ? $form->{display_form} : "display_form"; + + $form->{rowcount}--; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <td> + <table> + <tr class=listheading> + <th class=listheading colspan=2 width=50%>|.$locale->text('Billing Address').qq|</th> + <th class=listheading width=50%>|.$locale->text('Shipping Address').qq|</th> + </tr> + <tr height="5"></tr> + <tr> + <th align=right nowrap>$number</th> + <td>$form->{"$form->{vc}number"}</td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Company Name').qq|</th> + <td>$form->{name}</td> + <td><input name=shiptoname size=35 maxlength=64 value="$form->{shiptoname}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Address').qq|</th> + <td>$form->{address1}</td> + <td><input name=shiptoaddress1 size=35 maxlength=32 value="$form->{shiptoaddress1}"></td> + </tr> + <tr> + <th></th> + <td>$form->{address2}</td> + <td><input name=shiptoaddress2 size=35 maxlength=32 value="$form->{shiptoaddress2}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('City').qq|</th> + <td>$form->{city}</td> + <td><input name=shiptocity size=35 maxlength=32 value="$form->{shiptocity}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('State/Province').qq|</th> + <td>$form->{state}</td> + <td><input name=shiptostate size=35 maxlength=32 value="$form->{shiptostate}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Zip/Postal Code').qq|</th> + <td>$form->{zipcode}</td> + <td><input name=shiptozipcode size=10 maxlength=10 value="$form->{shiptozipcode}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Country').qq|</th> + <td>$form->{country}</td> + <td><input name=shiptocountry size=35 maxlength=32 value="$form->{shiptocountry}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Contact').qq|</th> + <td>$form->{contact}</td> + <td><input name=shiptocontact size=35 maxlength=64 value="$form->{shiptocontact}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Phone').qq|</th> + <td>$form->{"$form->{vc}phone"}</td> + <td><input name=shiptophone size=20 value="$form->{shiptophone}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Fax').qq|</th> + <td>$form->{"$form->{vc}fax"}</td> + <td><input name=shiptofax size=20 value="$form->{shiptofax}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('E-mail').qq|</th> + <td>$form->{email}</td> + <td><input name=shiptoemail size=35 value="$form->{shiptoemail}"></td> + </tr> + </table> + </td> + </tr> +</table> + +<input type=hidden name=nextsub value=$nextsub> +|; + + # delete shipto + for (qw(action nextsub)) { delete $form->{$_} } + for (qw(name address1 address2 city state zipcode country contact phone fax email)) { delete $form->{"shipto$_"} } + $form->{title} = $title; + + $form->hide_form; + + print qq| + +<hr size=3 noshade> + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + diff --git a/bin/lynx/ir.pl b/bin/lynx/ir.pl new file mode 100755 index 00000000..3a4c9905 --- /dev/null +++ b/bin/lynx/ir.pl @@ -0,0 +1,845 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Inventory received module +# +#====================================================================== + + +use SL::IR; +use SL::PE; + +require "$form->{path}/io.pl"; +require "$form->{path}/arap.pl"; + +1; +# end of main + + + +sub add { + + $form->{title} = $locale->text('Add Vendor Invoice'); + + $form->{callback} = "$form->{script}?action=add&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}" unless $form->{callback}; + &invoice_links; + &prepare_invoice; + &display_form; + +} + + +sub edit { + + $form->{title} = $locale->text('Edit Vendor Invoice'); + + &invoice_links; + &prepare_invoice; + &display_form; + +} + + +sub invoice_links { + + $form->{vc} = "vendor"; + $form->{type} = "invoice"; + + # create links + $form->create_links("AP", \%myconfig, "vendor", 1); + + # currencies + @curr = split /:/, $form->{currencies}; + $form->{defaultcurrency} = $curr[0]; + chomp $form->{defaultcurrency}; + + for (@curr) { $form->{selectcurrency} .= "<option>$_\n" } + + if (@{ $form->{all_vendor} }) { + unless ($form->{vendor_id}) { + $form->{vendor_id} = $form->{all_vendor}->[0]->{id}; + } + } + + AA->get_name(\%myconfig, \%$form); + delete $form->{notes}; + IR->retrieve_invoice(\%myconfig, \%$form); + + $form->{oldlanguage_code} = $form->{language_code}; + + $form->get_partsgroup(\%myconfig, { language_code => $form->{language_code} }); + if (@ { $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = "<option>\n"; + foreach $ref (@ { $form->{all_partsgroup} }) { + if ($ref->{translation}) { + $form->{selectpartsgroup} .= qq|<option value="$ref->{partsgroup}--$ref->{id}">$ref->{translation}\n|; + } else { + $form->{selectpartsgroup} .= qq|<option value="$ref->{partsgroup}--$ref->{id}">$ref->{partsgroup}\n|; + } + } + } + + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + } + + $form->{oldvendor} = "$form->{vendor}--$form->{vendor_id}"; + $form->{oldtransdate} = $form->{transdate}; + + # vendors + $form->{selectvendor} = ""; + if (@{ $form->{all_vendor} }) { + $form->{vendor} = "$form->{vendor}--$form->{vendor_id}"; + for (@{ $form->{all_vendor} }) { $form->{selectvendor} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + $form->{department} = "$form->{department}--$form->{department_id}" if $form->{department_id}; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + # forex + $form->{forex} = $form->{exchangerate}; + $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1; + + foreach $key (keys %{ $form->{AP_links} }) { + + $form->{"select$key"} = ""; + foreach $ref (@{ $form->{AP_links}{$key} }) { + $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n"; + } + + if ($key eq "AP_paid") { + for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) { + $form->{"AP_paid_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; + # reverse paid + $form->{"paid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount}; + $form->{"datepaid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{transdate}; + $form->{"forex_$i"} = $form->{"exchangerate_$i"} = $form->{acc_trans}{$key}->[$i-1]->{exchangerate}; + $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i-1]->{source}; + $form->{"memo_$i"} = $form->{acc_trans}{$key}->[$i-1]->{memo}; + $form->{"cleared_$i"} = $form->{acc_trans}{$key}->[$i-1]->{cleared}; + + $form->{paidaccounts} = $i; + } + } else { + $form->{$key} = "$form->{acc_trans}{$key}->[0]->{accno}--$form->{acc_trans}{$key}->[0]->{description}" if $form->{acc_trans}{$key}->[0]->{accno}; + } + + } + + $form->{paidaccounts} = 1 unless (exists $form->{paidaccounts}); + + $form->{AP} = $form->{AP_1} unless $form->{id}; + + $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto})); + + if (! $form->{readonly}) { + $form->{readonly} = 1 if $myconfig{acs} =~ /AP--Vendor Invoice/; + } + +} + + + +sub prepare_invoice { + + $form->{type} = "invoice"; + $form->{currency} =~ s/ //g; + $form->{oldcurrency} = $form->{currency}; + + if ($form->{id}) { + + for (qw(invnumber ordnumber ponumber quonumber)) { $form->{$_} = $form->quote($form->{$_}) } + + foreach $ref (@{ $form->{invoice_details} }) { + $i++; + for (keys %$ref) { $form->{"${_}_$i"} = $ref->{$_} } + + $form->{"projectnumber_$i"} = qq|$ref->{projectnumber}--$ref->{project_id}| if $ref->{project_id}; + $form->{"partsgroup_$i"} = qq|$ref->{partsgroup}--$ref->{partsgroup_id}| if $ref->{partsgroup_id}; + + $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100); + + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces); + $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); + $form->{"oldqty_$i"} = $form->{"qty_$i"}; + + for (qw(partnumber sku description unit)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + + $form->{rowcount} = $i; + } + } + +} + + + +sub form_header { + + # set option selected + for (qw(AP currency)) { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/option>\Q$form->{$_}\E/option selected>$form->{$_}/; + } + + for (qw(vendor department)) { + $form->{"select$_"} = $form->unescape($form->{"select$_"}); + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + if ($form->{selectlanguage}) { + $form->{"selectlanguage"} = $form->unescape($form->{"selectlanguage"}); + $form->{"selectlanguage"} =~ s/ selected//; + $form->{"selectlanguage"} =~ s/(<option value="\Q$form->{language_code}\E")/$1 selected/; + + $lang = qq| + <tr> + <th align=right nowrap>|.$locale->text('Language').qq|</th> + <td><select name=language_code>$form->{selectlanguage}</select></td> + <input type=hidden name=oldlanguage_code value=$form->{oldlanguage_code}> + <input type=hidden name="selectlanguage" value="|. + $form->escape($form->{selectlanguage},1).qq|"> + </tr> +|; + + } + + + $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate}); + + $exchangerate = qq|<tr>|; + $exchangerate .= qq| + <th align=right nowrap>|.$locale->text('Currency').qq|</th> + <td><select name=currency>$form->{selectcurrency}</select></td> | if $form->{defaultcurrency}; + $exchangerate .= qq| + <input type=hidden name=selectcurrency value="$form->{selectcurrency}"> + <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}> +|; + + if ($form->{defaultcurrency} && $form->{currency} ne $form->{defaultcurrency}) { + if ($form->{forex}) { + $exchangerate .= qq| + <th align=right nowrap>|.$locale->text('Exchange Rate').qq|</th> + <td>$form->{exchangerate}<input type=hidden name=exchangerate value=$form->{exchangerate}></td> +|; + } else { + $exchangerate .= qq| + <th align=right nowrap>|.$locale->text('Exchange Rate').qq|</th> + <td><input name=exchangerate size=10 value=$form->{exchangerate}></td> +|; + } + } + $exchangerate .= qq| +<input type=hidden name=forex value=$form->{forex}> +</tr> +|; + + if ($form->{selectvendor}) { + $vendor = qq|<select name=vendor>$form->{selectvendor}</select> + <input type=hidden name="selectvendor" value="|. + $form->escape($form->{selectvendor},1).qq|">|; + } else { + $vendor = qq|<input name=vendor value="$form->{vendor}" size=35>|; + } + + $department = qq| + <tr> + <th align="right" nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select> + <input type=hidden name=selectdepartment value="|. + $form->escape($form->{selectdepartment},1).qq|"> + </td> + </tr> +| if $form->{selectdepartment}; + + $n = ($form->{creditremaining} < 0) ? "0" : "1"; + + $i = $form->{rowcount} + 1; + $focus = "partnumber_$i"; + + $form->header; + + print qq| +<body onLoad="document.forms[0].${focus}.focus()" /> + +<form method=post action="$form->{script}"> +|; + + $form->{vc} = "vendor"; + $form->hide_form(qw(id title vc type terms creditlimit creditremaining closedto locked shipped oldtransdate recurring)); + + print qq| +<table width=100%> + <tr class=listtop> + <th>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Vendor').qq|</th> + <td colspan=3>$vendor</td> + + <input type=hidden name=vendor_id value=$form->{vendor_id}> + <input type=hidden name=oldvendor value="$form->{oldvendor}"> + + </tr> + <tr> + <td></td> + <td colspan=3> + <table> + <tr> + <th nowrap>|.$locale->text('Credit Limit').qq|</th> + <td>|.$form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0").qq|</td> + <td width=20%></td> + <th nowrap>|.$locale->text('Remaining').qq|</th> + <td class="plus$n" nowrap>|.$form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0").qq|</td> + </tr> + </table> + </td> + <tr> + <th align=right>|.$locale->text('Record in').qq|</th> + <td colspan=3><select name=AP>$form->{selectAP}</select></td> + <input type=hidden name=selectAP value="$form->{selectAP}"> + </tr> + $department + $exchangerate + </table> + </td> + <td align=right> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th> + <td><input name=invnumber size=20 value="$form->{invnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Order Number').qq|</th> + <td><input name=ordnumber size=20 value="$form->{ordnumber}"></td> +<input type=hidden name=quonumber value="$form->{quonumber}"> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Invoice Date').qq|</th> + <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Due Date').qq|</th> + <td><input name=duedate size=11 title="$myconfig{dateformat}" value=$form->{duedate}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('PO Number').qq|</th> + <td><input name=ponumber size=20 value="$form->{ponumber}"></td> + </tr> + $lang + </table> + </td> + </tr> + </table> + </td> + </tr> +|; + + $form->hide_form(qw(selectcurrency defaultcurrency taxaccounts)); + + for (split / /, $form->{taxaccounts}) { $form->hide_form("${_}_rate", "${_}_description") } + +} + + + +sub form_footer { + + $form->{invtotal} = $form->{invsubtotal}; + + if (($rows = $form->numtextrows($form->{notes}, 35, 8)) < 2) { + $rows = 2; + } + if (($introws = $form->numtextrows($form->{intnotes}, 35, 8)) < 2) { + $introws = 2; + } + $rows = ($rows > $introws) ? $rows : $introws; + $notes = qq|<textarea name=notes rows=$rows cols=35 wrap=soft>$form->{notes}</textarea>|; + $intnotes = qq|<textarea name=intnotes rows=$rows cols=35 wrap=soft>$form->{intnotes}</textarea>|; + + $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : ""; + + $taxincluded = ""; + if ($form->{taxaccounts}) { + $taxincluded = qq| + <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}> <b>|.$locale->text('Tax Included').qq|</b> +|; + } + + if (!$form->{taxincluded}) { + + foreach $item (split / /, $form->{taxaccounts}) { + if ($form->{"${item}_base"}) { + $form->{invtotal} += $form->{"${item}_total"} = $form->round_amount($form->{"${item}_base"} * $form->{"${item}_rate"}, 2); + $form->{"${item}_total"} = $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2); + + $tax .= qq| + <tr> + <th align=right>$form->{"${item}_description"}</th> + <td align=right>$form->{"${item}_total"}</td> + </tr> +|; + } + } + + $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0); + + $subtotal = qq| + <tr> + <th align=right>|.$locale->text('Subtotal').qq|</th> + <td align=right>$form->{invsubtotal}</td> + </tr> +|; + + } + + $form->{oldinvtotal} = $form->{invtotal}; + $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0); + + print qq| + <tr> + <td> + <table width=100%> + <tr valign=bottom> + <td> + <table> + <tr> + <th align=left>|.$locale->text('Notes').qq|</th> + <th align=left>|.$locale->text('Internal Notes').qq|</th> + </tr> + <tr valign=top> + <td>$notes</td> + <td>$intnotes</td> + </tr> + </table> + </td> + <td align=right> + $taxincluded + <br> + <table> + $subtotal + $tax + <tr> + <th align=right>|.$locale->text('Total').qq|</th> + <td align=right>$form->{invtotal}</td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table width=100%> + <tr> + <th colspan=6 class=listheading>|.$locale->text('Payments').qq|</th> + </tr> +|; + + if ($form->{currency} eq $form->{defaultcurrency}) { + @column_index = qw(datepaid source memo paid AP_paid); + } else { + @column_index = qw(datepaid source memo paid exchangerate AP_paid); + } + + $column_data{datepaid} = "<th>".$locale->text('Date')."</th>"; + $column_data{paid} = "<th>".$locale->text('Amount')."</th>"; + $column_data{exchangerate} = "<th>".$locale->text('Exch')."</th>"; + $column_data{AP_paid} = "<th>".$locale->text('Account')."</th>"; + $column_data{source} = "<th>".$locale->text('Source')."</th>"; + $column_data{memo} = "<th>".$locale->text('Memo')."</th>"; + + print qq| + <tr> +|; + for (@column_index) { print "$column_data{$_}\n" } + print qq| + </tr> +|; + + $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"}); + for $i (1 .. $form->{paidaccounts}) { + + $form->hide_form("cleared_$i"); + + print qq| + <tr> +|; + + $form->{"selectAP_paid_$i"} = $form->{selectAP_paid}; + $form->{"selectAP_paid_$i"} =~ s/option>\Q$form->{"AP_paid_$i"}\E/option selected>$form->{"AP_paid_$i"}/; + + # format amounts + $totalpaid += $form->{"paid_$i"}; + $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2); + $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"}); + + $exchangerate = qq| |; + if ($form->{currency} ne $form->{defaultcurrency}) { + if ($form->{"forex_$i"}) { + $exchangerate = qq|<input type=hidden name="exchangerate_$i" value=$form->{"exchangerate_$i"}>$form->{"exchangerate_$i"}|; + } else { + $exchangerate = qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|; + } + } + $exchangerate .= qq| +<input type=hidden name="forex_$i" value=$form->{"forex_$i"}> +|; + + $column_data{"paid_$i"} = qq|<td align=center><input name="paid_$i" size=11 value=$form->{"paid_$i"}></td>|; + $column_data{"exchangerate_$i"} = qq|<td align=center>$exchangerate</td>|; + $column_data{"AP_paid_$i"} = qq|<td align=center><select name="AP_paid_$i">$form->{"selectAP_paid_$i"}</select></td>|; + $column_data{"datepaid_$i"} = qq|<td align=center><input name="datepaid_$i" size=11 title="$myconfig{dateformat}" value=$form->{"datepaid_$i"}></td>|; + $column_data{"source_$i"} = qq|<td align=center><input name="source_$i" size=11 value="$form->{"source_$i"}"></td>|; + $column_data{"memo_$i"} = qq|<td align=center><input name="memo_$i" size=11 value="$form->{"memo_$i"}"></td>|; + + for (@column_index) { print qq|$column_data{"${_}_$i"}\n| } + + print qq| + </tr> +|; + } + + $form->{oldtotalpaid} = $totalpaid; + $form->hide_form(qw(paidaccounts selectAP_paid oldinvtotal oldtotalpaid)); + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +<br> +|; + + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + +# type=submit $locale->text('Update') +# type=submit $locale->text('Post') +# type=submit $locale->text('Post as new') +# type=submit $locale->text('Schedule') +# type=submit $locale->text('Purchase Order') +# type=submit $locale->text('Delete') + + if (! $form->{readonly}) { + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Post' => { ndx => 3, key => 'O', value => $locale->text('Post') }, + 'Post as new' => { ndx => 5, key => 'N', value => $locale->text('Post as new') }, + 'Purchase Order' => { ndx => 6, key => 'L', value => $locale->text('Purchase Order') }, + 'Schedule' => { ndx => 7, key => 'H', value => $locale->text('Schedule') }, + 'Delete' => { ndx => 8, key => 'D', value => $locale->text('Delete') }, + ); + + if ($form->{id}) { + + if ($form->{locked}) { + for ("Post", "Delete") { delete $button{$_} } + } + + } else { + + if ($transdate > $closedto) { + for ('Update', 'Post', 'Schedule') { $a{$_} = 1 } + } + for (keys %button) { delete $button{$_} if ! $a{$_} } + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + $form->hide_form(qw(rowcount callback path login sessionid)); + +print qq| +</form> + +</body> +</html> +|; + +} + + + +sub update { + + $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate}); + + if ($newname = &check_name(vendor)) { + &rebuild_vc(vendor, AP, $form->{transdate}, 1); + } + if ($form->{transdate} ne $form->{oldtransdate}) { + $form->{duedate} = ($form->{terms}) ? $form->current_date(\%myconfig, $form->{transdate}, $form->{terms} * 1) : $form->{duedate}; + $form->{oldtransdate} = $form->{transdate}; + &rebuild_vc(vendor, AP, $form->{transdate}, 1) if ! $newname; + + if ($form->{currency} ne $form->{defaultcurrency}) { + delete $form->{exchangerate}; + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, 'sell'))); + $form->{oldcurrency} = $form->{currency}; + } + } + + if ($form->{currency} ne $form->{oldcurrency}) { + delete $form->{exchangerate}; + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, 'sell'))); + } + + + $j = 1; + for $i (1 .. $form->{paidaccounts}) { + if ($form->{"paid_$i"}) { + for (qw(datepaid source memo cleared)) { $form->{"${_}_$j"} = $form->{"${_}_$i"} } + for (qw(paid exchangerate)) { $form->{"${_}_$j"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + $form->{"exchangerate_$j"} = $exchangerate if ($form->{"forex_$j"} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$j"}, 'sell'))); + if ($j++ != $i) { + for (qw(datepaid source memo cleared paid exchangerate forex)) { delete $form->{"${_}_$i"} } + } + } else { + for (qw(datepaid source memo cleared paid exchangerate forex)) { delete $form->{"${_}_$i"} } + } + $form->{paidaccounts} = $j; + } + + $i = $form->{rowcount}; + $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1; + + for (qw(partsgroup projectnumber)) { + $form->{"select$_"} = $form->unescape($form->{"select$_"}) if $form->{"select$_"}; + } + + if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) { + + $form->{creditremaining} += ($form->{oldinvtotal} - $form->{oldtotalpaid}); + &check_form; + + } else { + + IR->retrieve_item(\%myconfig, \%$form); + + my $rows = scalar @{ $form->{item_list} }; + + if ($form->{language_code} && $rows == 0) { + $language_code = $form->{language_code}; + $form->{language_code} = ""; + IR->retrieve_item(\%myconfig, \%$form); + $form->{language_code} = $language_code; + $rows = scalar @{ $form->{item_list} }; + } + + if ($rows) { + + if ($rows > 1) { + + &select_item; + exit; + + } else { + + $form->{"qty_$i"} = ($form->{"qty_$i"} * 1) ? $form->{"qty_$i"} : 1; + + $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"}); + + for (qw(partnumber description unit)) { $form->{item_list}[$i]{$_} = $form->quote($form->{item_list}[$i]{$_}) } + + for (keys %{ $form->{item_list}[0] }) { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } + + $form->{"discount_$i"} = $form->{discount} * 100; + + if ($sellprice) { + $form->{"sellprice_$i"} = $sellprice; + + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + } else { + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + $form->{"sellprice_$i"} /= $exchangerate; + } + + $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100); + for (split / /, $form->{taxaccounts}) { $form->{"${_}_base"} = 0 } + for (split / /, $form->{"taxaccounts_$i"}) { $form->{"${_}_base"} += $amount } + if (!$form->{taxincluded}) { + for (split / /, $form->{"taxaccounts_$i"}) { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } + } + + $form->{creditremaining} -= $amount; + + $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces); + + $form->{"oldqty_$i"} = $form->{"qty_$i"}; + for (qw(qty discount)) { $form->{"{_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}) } + + } + + &display_form; + + } else { + # ok, so this is a new part + # ask if it is a part or service item + + if ($form->{"partsgroup_$i"} && ($form->{"partsnumber_$i"} eq "") && ($form->{"description_$i"} eq "")) { + $form->{"discount_$i"} = ""; + &display_form; + } else { + + $form->{"id_$i"} = 0; + $form->{"unit_$i"} = $locale->text('ea'); + + &new_item; + + } + } + } +} + + + +sub post { + + $form->isblank("transdate", $locale->text('Invoice Date missing!')); + $form->isblank("vendor", $locale->text('Vendor missing!')); + + # if the vendor changed get new values + if (&check_name(vendor)) { + &update; + exit; + } + + &validate_items; + + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + + $form->error($locale->text('Cannot post invoice for a closed period!')) if ($transdate <= $closedto); + + $form->isblank("exchangerate", $locale->text('Exchange rate missing!')) if ($form->{currency} ne $form->{defaultcurrency}); + + for $i (1 .. $form->{paidaccounts}) { + if ($form->{"paid_$i"}) { + $datepaid = $form->datetonum(\%myconfig, $form->{"datepaid_$i"}); + + $form->isblank("datepaid_$i", $locale->text('Payment date missing!')); + + $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto); + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->{"exchangerate_$i"} = $form->{exchangerate} if ($transdate == $datepaid); + $form->isblank("exchangerate_$i", $locale->text('Exchange rate for payment missing!')); + } + } + } + + if (! $form->{repost}) { + if ($form->{id}) { + &repost; + exit; + } + } + + ($form->{AP}) = split /--/, $form->{AP}; + ($form->{AP_paid}) = split /--/, $form->{AP_paid}; + + if (IR->post_invoice(\%myconfig, \%$form)) { + $form->redirect($locale->text('Invoice')." $form->{invnumber} ".$locale->text('posted!')); + } else { + $form->error($locale->text('Cannot post invoice!')); + } + +} + + + +sub delete { + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->{action} = "yes"; + $form->hide_form; + + print qq| +<h2 class=confirm>|.$locale->text('Confirm!').qq|</h2> + +<h4>|.$locale->text('Are you sure you want to delete Invoice Number').qq| $form->{invnumber}</h4> +<p> +<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|"> +</form> +|; + + +} + + + +sub yes { + + if (IR->delete_invoice(\%myconfig, \%$form)) { + $form->redirect($locale->text('Invoice deleted!')); + } else { + $form->error($locale->text('Cannot delete invoice!')); + } + +} + + diff --git a/bin/lynx/is.pl b/bin/lynx/is.pl new file mode 100755 index 00000000..1dde9d87 --- /dev/null +++ b/bin/lynx/is.pl @@ -0,0 +1,952 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Inventory invoicing module +# +#====================================================================== + + +use SL::IS; +use SL::PE; + +require "$form->{path}/arap.pl"; +require "$form->{path}/io.pl"; + + +1; +# end of main + + + +sub add { + + $form->{title} = $locale->text('Add Sales Invoice'); + + $form->{callback} = "$form->{script}?action=add&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &invoice_links; + &prepare_invoice; + &display_form; + +} + + +sub edit { + + $form->{title} = $locale->text('Edit Sales Invoice'); + + &invoice_links; + &prepare_invoice; + &display_form; + +} + + +sub invoice_links { + + $form->{vc} = "customer"; + $form->{type} = "invoice"; + + # create links + $form->create_links("AR", \%myconfig, "customer", 1); + + # currencies + @curr = split /:/, $form->{currencies}; + $form->{defaultcurrency} = $curr[0]; + chomp $form->{defaultcurrency}; + + for (@curr) { $form->{selectcurrency} .= "<option>$_\n" } + + if (@{ $form->{all_customer} }) { + unless ($form->{customer_id}) { + $form->{customer_id} = $form->{all_customer}->[0]->{id}; + } + } + + AA->get_name(\%myconfig, \%$form); + delete $form->{notes}; + IS->retrieve_invoice(\%myconfig, \%$form); + + $form->{oldlanguage_code} = $form->{language_code}; + + $form->get_partsgroup(\%myconfig, { language_code => $form->{language_code}, searchitems => 'nolabor' }); + + if (@{ $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = "<option>\n"; + foreach $ref (@ { $form->{all_partsgroup} }) { + if ($ref->{translation}) { + $form->{selectpartsgroup} .= qq|<option value="$ref->{partsgroup}--$ref->{id}">$ref->{translation}\n|; + } else { + $form->{selectpartsgroup} .= qq|<option value="$ref->{partsgroup}--$ref->{id}">$ref->{partsgroup}\n|; + } + } + } + + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + } + + $form->{oldcustomer} = "$form->{customer}--$form->{customer_id}"; + $form->{oldtransdate} = $form->{transdate}; + + $form->{selectcustomer} = ""; + if (@{ $form->{all_customer} }) { + $form->{customer} = "$form->{customer}--$form->{customer_id}"; + for (@{ $form->{all_customer} }) { $form->{selectcustomer} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + $form->{department} = "$form->{department}--$form->{department_id}" if $form->{department_id}; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + $form->{employee} = "$form->{employee}--$form->{employee_id}"; + # sales staff + if (@{ $form->{all_employee} }) { + $form->{selectemployee} = ""; + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + # forex + $form->{forex} = $form->{exchangerate}; + $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1; + + foreach $key (keys %{ $form->{AR_links} }) { + + $form->{"select$key"} = ""; + foreach $ref (@{ $form->{AR_links}{$key} }) { + $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n"; + } + + if ($key eq "AR_paid") { + for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) { + $form->{"AR_paid_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; + # reverse paid + $form->{"paid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount} * -1; + $form->{"datepaid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{transdate}; + $form->{"forex_$i"} = $form->{"exchangerate_$i"} = $form->{acc_trans}{$key}->[$i-1]->{exchangerate}; + $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i-1]->{source}; + $form->{"memo_$i"} = $form->{acc_trans}{$key}->[$i-1]->{memo}; + $form->{"cleared_$i"} = $form->{acc_trans}{$key}->[$i-1]->{cleared}; + + $form->{paidaccounts} = $i; + } + } else { + $form->{$key} = "$form->{acc_trans}{$key}->[0]->{accno}--$form->{acc_trans}{$key}->[0]->{description}" if $form->{acc_trans}{$key}->[0]->{accno}; + } + + } + + for (qw(AR_links acc_trans)) { delete $form->{$_} } + + $form->{paidaccounts} = 1 unless (exists $form->{paidaccounts}); + + $form->{AR} = $form->{AR_1} unless $form->{id}; + + $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto})); + + if (! $form->{readonly}) { + $form->{readonly} = 1 if $myconfig{acs} =~ /AR--Sales Invoice/; + } + +} + + +sub prepare_invoice { + + $form->{type} = "invoice"; + $form->{formname} = "invoice"; + $form->{sortby} ||= "runningnumber"; + $form->{format} = "postscript" if $myconfig{printer}; + $form->{media} = $myconfig{printer}; + + $form->{selectformname} = qq|<option value="invoice">|.$locale->text('Invoice').qq| +<option value="pick_list">|.$locale->text('Pick List').qq| +<option value="packing_list">|.$locale->text('Packing List'); + + $i = 0; + $form->{currency} =~ s/ //g; + $form->{oldcurrency} = $form->{currency}; + + if ($form->{id}) { + + for (qw(invnumber ordnumber ponumber quonumber shippingpoint shipvia notes intnotes)) { $form->{$_} = $form->quote($form->{$_}) } + + foreach $ref (@{ $form->{invoice_details} } ) { + $i++; + for (keys %$ref) { $form->{"${_}_$i"} = $ref->{$_} } + + $form->{"projectnumber_$i"} = qq|$ref->{projectnumber}--$ref->{project_id}| if $ref->{project_id}; + $form->{"partsgroup_$i"} = qq|$ref->{partsgroup}--$ref->{partsgroup_id}| if $ref->{partsgroup_id}; + + $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100); + + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces); + $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); + $form->{"oldqty_$i"} = $form->{"qty_$i"}; + + for (qw(partnumber sku description unit)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + $form->{rowcount} = $i; + } + } + +} + + + +sub form_header { + + # set option selected + for (qw(AR currency)) { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/option>\Q$form->{$_}\E/option selected>$form->{$_}/; + } + + for (qw(customer department employee)) { + $form->{"select$_"} = $form->unescape($form->{"select$_"}); + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate}); + + + $exchangerate = qq|<tr>|; + $exchangerate .= qq| + <th align=right nowrap>|.$locale->text('Currency').qq|</th> + <td><select name=currency>$form->{selectcurrency}</select></td> +| if $form->{defaultcurrency}; + $exchangerate .= qq| + <input type=hidden name=selectcurrency value="$form->{selectcurrency}"> + <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}> +|; + + if ($form->{defaultcurrency} && $form->{currency} ne $form->{defaultcurrency}) { + if ($form->{forex}) { + $exchangerate .= qq|<th align=right>|.$locale->text('Exchange Rate').qq|</th><td>$form->{exchangerate}<input type=hidden name=exchangerate value=$form->{exchangerate}></td>|; + } else { + $exchangerate .= qq|<th align=right>|.$locale->text('Exchange Rate').qq|</th><td><input name=exchangerate size=10 value=$form->{exchangerate}></td>|; + } + } + $exchangerate .= qq| +<input type=hidden name=forex value=$form->{forex}> +</tr> +|; + + if ($form->{selectcustomer}) { + $customer = qq|<select name=customer>$form->{selectcustomer}</select> + <input type=hidden name="selectcustomer" value="|. + $form->escape($form->{selectcustomer},1).qq|">|; + } else { + $customer = qq|<input name=customer value="$form->{customer}" size=35>|; + } + + $department = qq| + <tr> + <th align="right" nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select> + <input type=hidden name=selectdepartment value="|. + $form->escape($form->{selectdepartment},1).qq|"> + </td> + </tr> +| if $form->{selectdepartment}; + + + $n = ($form->{creditremaining} < 0) ? "0" : "1"; + + + if ($form->{business}) { + $business = qq| + <tr> + <th align=right nowrap>|.$locale->text('Business').qq|</th> + <td>$form->{business}</td> + <td width=10></td> + <th align=right nowrap>|.$locale->text('Trade Discount').qq|</th> + <td>|.$form->format_amount(\%myconfig, $form->{tradediscount} * 100).qq| %</td> + </tr> +|; + } + + $employee = qq| + <input type=hidden name=employee value="$form->{employee}"> +|; + + + $employee = qq| + <tr> + <th align=right nowrap>|.$locale->text('Salesperson').qq|</th> + <td><select name=employee>$form->{selectemployee}</select></td> + <input type=hidden name=selectemployee value="|. + $form->escape($form->{selectemployee},1).qq|"> + </tr> +| if $form->{selectemployee}; + + $i = $form->{rowcount} + 1; + $focus = "partnumber_$i"; + + $form->header; + + print qq| +<body onLoad="document.forms[0].${focus}.focus()" /> + +<form method=post action="$form->{script}"> +|; + + $form->hide_form(qw(id type media format printed emailed queued title vc terms discount creditlimit creditremaining tradediscount business closedto locked shipped oldtransdate recurring)); + + print qq| +<table width=100%> + <tr class=listtop> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Customer').qq|</th> + <td colspan=3>$customer</td> + <input type=hidden name=customer_id value=$form->{customer_id}> + <input type=hidden name=oldcustomer value="$form->{oldcustomer}"> + </tr> + <tr> + <td></td> + <td colspan=3> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Credit Limit').qq|</th> + <td>|.$form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0").qq|</td> + <td width=10></td> + <th align=right nowrap>|.$locale->text('Remaining').qq|</th> + <td class="plus$n" nowrap>|.$form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0").qq|</td> + </tr> + $business + </table> + </td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Record in').qq|</th> + <td colspan=3><select name=AR>$form->{selectAR}</select></td> + <input type=hidden name=selectAR value="$form->{selectAR}"> + </tr> + $department + $exchangerate + <tr> + <th align=right nowrap>|.$locale->text('Shipping Point').qq|</th> + <td colspan=3><input name=shippingpoint size=35 value="$form->{shippingpoint}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Ship via').qq|</th> + <td colspan=3><input name=shipvia size=35 value="$form->{shipvia}"></td> + </tr> + </table> + </td> + <td align=right> + <table> + $employee + <tr> + <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th> + <td><input name=invnumber size=20 value="$form->{invnumber}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Order Number').qq|</th> + <td><input name=ordnumber size=20 value="$form->{ordnumber}"></td> +<input type=hidden name=quonumber value="$form->{quonumber}"> + </tr> + <tr> + <th align=right>|.$locale->text('Invoice Date').qq|</th> + <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td> + </tr> + <tr> + <th align=right>|.$locale->text('Due Date').qq|</th> + <td><input name=duedate size=11 title="$myconfig{dateformat}" value=$form->{duedate}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('PO Number').qq|</th> + <td><input name=ponumber size=20 value="$form->{ponumber}"></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + </td> + </tr> +|; + + $form->hide_form(qw(shiptoname shiptoaddress1 shiptoaddress2 shiptocity shiptostate shiptozipcode shiptocountry shiptocontact shiptophone shiptofax shiptoemail message email subject cc bcc taxaccounts)); + + foreach $item (split / /, $form->{taxaccounts}) { + $form->hide_form("${item}_rate", "${item}_description", "${item}_taxnumber"); + } + +} + + + +sub form_footer { + + $form->{invtotal} = $form->{invsubtotal}; + + if (($rows = $form->numtextrows($form->{notes}, 35, 8)) < 2) { + $rows = 2; + } + if (($introws = $form->numtextrows($form->{intnotes}, 35, 8)) < 2) { + $introws = 2; + } + $rows = ($rows > $introws) ? $rows : $introws; + $notes = qq|<textarea name=notes rows=$rows cols=35 wrap=soft>$form->{notes}</textarea>|; + $intnotes = qq|<textarea name=intnotes rows=$rows cols=35 wrap=soft>$form->{intnotes}</textarea>|; + + $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : ""; + + $taxincluded = ""; + if ($form->{taxaccounts}) { + $taxincluded = qq| + <tr height="5"></tr> + <tr> + <td align=right> + <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td><th align=left>|.$locale->text('Tax Included').qq|</th> + </tr> +|; + } + + if (!$form->{taxincluded}) { + + for (split / /, $form->{taxaccounts}) { + if ($form->{"${_}_base"}) { + $form->{"${_}_total"} = $form->round_amount($form->{"${_}_base"} * $form->{"${_}_rate"}, 2); + $form->{invtotal} += $form->{"${_}_total"}; + $form->{"${_}_total"} = $form->format_amount(\%myconfig, $form->{"${_}_total"}, 2); + + $tax .= qq| + <tr> + <th align=right>$form->{"${_}_description"}</th> + <td align=right>$form->{"${_}_total"}</td> + </tr> +|; + } + } + + $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0); + + $subtotal = qq| + <tr> + <th align=right>|.$locale->text('Subtotal').qq|</th> + <td align=right>$form->{invsubtotal}</td> + </tr> +|; + + } + + $form->{oldinvtotal} = $form->{invtotal}; + $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0); + + print qq| + <tr> + <td> + <table width=100%> + <tr valign=bottom> + <td> + <table> + <tr> + <th align=left>|.$locale->text('Notes').qq|</th> + <th align=left>|.$locale->text('Internal Notes').qq|</th> + </tr> + <tr valign=top> + <td>$notes</td> + <td>$intnotes</td> + </tr> + </table> + </td> + <td align=right> + <table> + $subtotal + $tax + <tr> + <th align=right>|.$locale->text('Total').qq|</th> + <td align=right>$form->{invtotal}</td> + </tr> + $taxincluded + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> + <th colspan=6 class=listheading>|.$locale->text('Payments') + .qq|</th> + </tr> +|; + + if ($form->{currency} eq $form->{defaultcurrency}) { + @column_index = qw(datepaid source memo paid AR_paid); + } else { + @column_index = qw(datepaid source memo paid exchangerate AR_paid); + } + + $column_data{datepaid} = "<th>".$locale->text('Date')."</th>"; + $column_data{paid} = "<th>".$locale->text('Amount')."</th>"; + $column_data{exchangerate} = "<th>".$locale->text('Exch')."</th>"; + $column_data{AR_paid} = "<th>".$locale->text('Account')."</th>"; + $column_data{source} = "<th>".$locale->text('Source')."</th>"; + $column_data{memo} = "<th>".$locale->text('Memo')."</th>"; + + print " + <tr> +"; + for (@column_index) { print "$column_data{$_}\n" } + print " + </tr> +"; + + $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"}); + for $i (1 .. $form->{paidaccounts}) { + + $form->hide_form("cleared_$i"); + + print " + <tr>\n"; + + $form->{"selectAR_paid_$i"} = $form->{selectAR_paid}; + $form->{"selectAR_paid_$i"} =~ s/option>\Q$form->{"AR_paid_$i"}\E/option selected>$form->{"AR_paid_$i"}/; + + # format amounts + $totalpaid += $form->{"paid_$i"}; + $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2); + $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"}); + + $exchangerate = qq| |; + if ($form->{currency} ne $form->{defaultcurrency}) { + if ($form->{"forex_$i"}) { + $exchangerate = qq|<input type=hidden name="exchangerate_$i" value=$form->{"exchangerate_$i"}>$form->{"exchangerate_$i"}|; + } else { + $exchangerate = qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|; + } + } + + $exchangerate .= qq| +<input type=hidden name="forex_$i" value=$form->{"forex_$i"}> +|; + + $column_data{paid} = qq|<td align=center><input name="paid_$i" size=11 value=$form->{"paid_$i"}></td>|; + $column_data{exchangerate} = qq|<td align=center>$exchangerate</td>|; + $column_data{AR_paid} = qq|<td align=center><select name="AR_paid_$i">$form->{"selectAR_paid_$i"}</select></td>|; + $column_data{datepaid} = qq|<td align=center><input name="datepaid_$i" size=11 title="$myconfig{dateformat}" value=$form->{"datepaid_$i"}></td>|; + $column_data{source} = qq|<td align=center><input name="source_$i" size=11 value="$form->{"source_$i"}"></td>|; + $column_data{memo} = qq|<td align=center><input name="memo_$i" size=11 value="$form->{"memo_$i"}"></td>|; + + for (@column_index) { print qq|$column_data{$_}\n| } + print " + </tr>\n"; + } + + $form->{oldtotalpaid} = $totalpaid; + $form->hide_form(qw(paidaccounts selectAR_paid oldinvtotal oldtotalpaid)); + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> + <tr> + <td> +|; + + &print_options; + + print qq| + </td> + </tr> +</table> +<br> +|; + + + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + +# type=submit $locale->text('Update') +# type=submit $locale->text('Print') +# type=submit $locale->text('Post') +# type=submit $locale->text('Print and Post') +# type=submit $locale->text('Schedule') +# type=submit $locale->text('Ship to') +# type=submit $locale->text('Post as new') +# type=submit $locale->text('Print and Post as new') +# type=submit $locale->text('E-mail') +# type=submit $locale->text('Delete') +# type=submit $locale->text('Sales Order') + + if (! $form->{readonly}) { + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') }, + 'Post' => { ndx => 3, key => 'O', value => $locale->text('Post') }, + 'Ship to' => { ndx => 4, key => 'T', value => $locale->text('Ship to') }, + 'E-mail' => { ndx => 5, key => 'E', value => $locale->text('E-mail') }, + 'Print and Post' => { ndx => 6, key => 'R', value => $locale->text('Print and Post') }, + 'Post as new' => { ndx => 7, key => 'N', value => $locale->text('Post as new') }, + 'Print and Post as new' => { ndx => 8, key => 'W', value => $locale->text('Print and Post as new') }, + 'Sales Order' => { ndx => 9, key => 'L', value => $locale->text('Sales Order') }, + 'Schedule' => { ndx => 10, key => 'H', value => $locale->text('Schedule') }, + 'Delete' => { ndx => 11, key => 'D', value => $locale->text('Delete') }, + ); + + if ($form->{id}) { + + if ($form->{locked} || $transdate <= $closedto) { + for ("Post", "Print and Post", "Delete") { delete $button{$_} } + } + + if (!$latex) { + for ("Print and Post", "Print and Post as new") { delete $button{$_} } + } + + } else { + + if ($transdate > $closedto) { + + for ("Update", "Ship to", "Print", "E-mail", "Post", "Schedule") { $a{$_} = 1 } + $a{'Print and Post'} = 1 if $latex; + + } + for (keys %button) { delete $button{$_} if ! $a{$_} } + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + $form->hide_form(qw(rowcount callback path login sessionid)); + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub update { + + $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate}); + + if ($newname = &check_name(customer)) { + &rebuild_vc(customer, AR, $form->{transdate}, 1); + } + if ($form->{transdate} ne $form->{oldtransdate}) { + $form->{duedate} = ($form->{terms}) ? $form->current_date(\%myconfig, $form->{transdate}, $form->{terms} * 1) : $form->{duedate}; + $form->{oldtransdate} = $form->{transdate}; + &rebuild_vc(customer, AR, $form->{transdate}, 1) if ! $newname; + + if ($form->{currency} ne $form->{defaultcurrency}) { + delete $form->{exchangerate}; + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, 'buy'))); + } + + $form->{selectemployee} = ""; + if (@{ $form->{all_employee} }) { + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + } + + if ($form->{currency} ne $form->{oldcurrency}) { + delete $form->{exchangerate}; + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, 'buy'))); + } + + + $j = 1; + for $i (1 .. $form->{paidaccounts}) { + if ($form->{"paid_$i"}) { + for (qw(datepaid source memo cleared)) { $form->{"${_}_$j"} = $form->{"${_}_$i"} } + for (qw(paid exchangerate)) { $form->{"${_}_$j"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + + $form->{"exchangerate_$j"} = $exchangerate if ($form->{"forex_$j"} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$j"}, 'buy'))); + if ($j++ != $i) { + for (qw(datepaid source memo cleared paid exchangerate forex)) { delete $form->{"${_}_$i"} } + } + } else { + for (qw(datepaid source memo cleared paid exchangerate forex)) { delete $form->{"${_}_$i"} } + } + } + $form->{paidaccounts} = $j; + + $i = $form->{rowcount}; + $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1; + + for (qw(partsgroup projectnumber)) { + $form->{"select$_"} = $form->unescape($form->{"select$_"}) if $form->{"select$_"}; + } + + # if last row empty, check the form otherwise retrieve new item + if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) { + + $form->{creditremaining} += ($form->{oldinvtotal} - $form->{oldtotalpaid}); + &check_form; + + } else { + + IS->retrieve_item(\%myconfig, \%$form); + + $rows = scalar @{ $form->{item_list} }; + + if ($form->{language_code} && $rows == 0) { + $language_code = $form->{language_code}; + $form->{language_code} = ""; + IS->retrieve_item(\%myconfig, \%$form); + $form->{language_code} = $language_code; + $rows = scalar @{ $form->{item_list} }; + } + + if ($rows) { + + if ($rows > 1) { + + &select_item; + exit; + + } else { + + $form->{"qty_$i"} = ($form->{"qty_$i"} * 1) ? $form->{"qty_$i"} : 1; + + $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"}); + + for (qw(partnumber description unit)) { $form->{item_list}[$i]{$_} = $form->quote($form->{item_list}[$i]{$_}) } + for (keys %{ $form->{item_list}[0] }) { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } + + $form->{"discount_$i"} = $form->{discount} * 100; + + if ($sellprice) { + $form->{"sellprice_$i"} = $sellprice; + + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces1 = ($dec > 2) ? $dec : 2; + } else { + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces1 = ($dec > 2) ? $dec : 2; + + $form->{"sellprice_$i"} /= $exchangerate; + } + + ($dec) = ($form->{"lastcost_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces2 = ($dec > 2) ? $dec : 2; + + # if there is an exchange rate adjust sellprice + for (qw(listprice lastcost)) { $form->{"${_}_$i"} /= $exchangerate } + + $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100); + for (split / /, $form->{taxaccounts}) { $form->{"${_}_base"} = 0 } + for (split / /, $form->{"taxaccounts_$i"}) { $form->{"${_}_base"} += $amount } + if (!$form->{taxincluded}) { + for (split / /, $form->{"taxaccounts_$i"}) { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } + } + + $form->{creditremaining} -= $amount; + + for (qw(sellprice listprice)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces1) } + $form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces2); + + $form->{"oldqty_$i"} = $form->{"qty_$i"}; + for (qw(qty discount)) { $form->{"{_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}) } + + } + + &display_form; + + } else { + # ok, so this is a new part + # ask if it is a part or service item + + if ($form->{"partsgroup_$i"} && ($form->{"partsnumber_$i"} eq "") && ($form->{"description_$i"} eq "")) { + $form->{rowcount}--; + &display_form; + } else { + + $form->{"id_$i"} = 0; + $form->{"unit_$i"} = $locale->text('ea'); + + &new_item; + + } + } + } +} + + + +sub post { + + $form->isblank("transdate", $locale->text('Invoice Date missing!')); + $form->isblank("customer", $locale->text('Customer missing!')); + + # if oldcustomer ne customer redo form + if (&check_name(customer)) { + &update; + exit; + } + + &validate_items; + + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + + $form->error($locale->text('Cannot post invoice for a closed period!')) if ($transdate <= $closedto); + + $form->isblank("exchangerate", $locale->text('Exchange rate missing!')) if ($form->{currency} ne $form->{defaultcurrency}); + + for $i (1 .. $form->{paidaccounts}) { + if ($form->{"paid_$i"}) { + $datepaid = $form->datetonum(\%myconfig, $form->{"datepaid_$i"}); + + $form->isblank("datepaid_$i", $locale->text('Payment date missing!')); + + $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto); + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->{"exchangerate_$i"} = $form->{exchangerate} if ($transdate == $datepaid); + $form->isblank("exchangerate_$i", $locale->text('Exchange rate for payment missing!')); + } + } + } + + + $form->{label} = $locale->text('Invoice'); + + if (! $form->{repost}) { + if ($form->{id}) { + &repost; + exit; + } + } + + ($form->{AR}) = split /--/, $form->{AR}; + ($form->{AR_paid}) = split /--/, $form->{AR_paid}; + + if (IS->post_invoice(\%myconfig, \%$form)) { + $form->redirect($locale->text('Invoice')." $form->{invnumber} ".$locale->text('posted!')); + } else { + $form->error($locale->text('Cannot post invoice!')); + } + +} + + +sub print_and_post { + + $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/; + $form->error($locale->text('Select a Printer!')) if $form->{media} eq 'screen'; + + if (! $form->{repost}) { + if ($form->{id}) { + $form->{print_and_post} = 1; + &repost; + exit; + } + } + + $old_form = new Form; + $form->{display_form} = "post"; + for (keys %$form) { $old_form->{$_} = $form->{$_} } + $old_form->{rowcount}++; + + &print_form($old_form); + +} + + +sub delete { + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->{action} = "yes"; + $form->hide_form; + + print qq| +<h2 class=confirm>|.$locale->text('Confirm!').qq|</h2> + +<h4>|.$locale->text('Are you sure you want to delete Invoice Number').qq| $form->{invnumber} +</h4> + +<p> +<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|"> +</form> +|; + + +} + + + +sub yes { + + if (IS->delete_invoice(\%myconfig, \%$form, $spool)) { + $form->redirect($locale->text('Invoice deleted!')); + } else { + $form->error($locale->text('Cannot delete invoice!')); + } + +} + + diff --git a/bin/lynx/jc.pl b/bin/lynx/jc.pl new file mode 100755 index 00000000..2312dabc --- /dev/null +++ b/bin/lynx/jc.pl @@ -0,0 +1,1912 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2005 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Job Costing module +# +#====================================================================== + +use SL::JC; + +1; +# end of main + + + +sub add { + + if ($form->{type} eq 'timecard') { + $form->{title} = $locale->text('Add Time Card'); + } + if ($form->{type} eq 'storescard') { + $form->{title} = $locale->text('Add Stores Card'); + } + + $form->{callback} = "$form->{script}?action=add&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}&project=$form->{project}" unless $form->{callback}; + + &{ "prepare_$form->{type}" }; + + $form->{orphaned} = 1; + &display_form; + +} + + +sub edit { + + if ($form->{type} eq 'timecard') { + $form->{title} = $locale->text('Edit Time Card'); + } + if ($form->{type} eq 'storescard') { + $form->{title} = $locale->text('Add Stores Card'); + } + + &{ "prepare_$form->{type}" }; + + &display_form; + +} + + +sub jcitems_links { + + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + foreach $ref (@{ $form->{all_project} }) { + $form->{selectprojectnumber} .= qq|<option value="$ref->{projectnumber}--$ref->{id}">$ref->{projectnumber}\n|; + if ($form->{projectnumber} eq "$ref->{projectnumber}--$ref->{id}") { + $form->{projectdescription} = $ref->{description}; + } + } + } else { + if ($form->{project} eq 'job') { + $form->error($locale->text('No open Jobs!')); + } else { + $form->error($locale->text('No open Projects!')); + } + } + + if (@{ $form->{all_parts} }) { + $form->{selectpartnumber} = "<option>\n"; + foreach $ref (@{ $form->{all_parts} }) { + $form->{selectpartnumber} .= qq|<option value="$ref->{partnumber}--$ref->{id}">$ref->{partnumber}\n|; + if ($form->{partnumber} eq "$ref->{partnumber}--$ref->{id}") { + if ($form->{partnumber} ne $form->{oldpartnumber}) { + for (qw(description unit sellprice pricematrix)) { $form->{$_} = $ref->{$_} } + } + } + } + } else { + if ($form->{type} eq 'timecard') { + if ($form->{project} eq 'job') { + $form->error($locale->text('No Labor codes on file!')); + } else { + $form->error($locale->text('No Services on file!')); + } + } else { + $form->error($locale->text('No Parts on file!')); + } + } + + # employees + if (@{ $form->{all_employee} }) { + $form->{selectemployee} = "<option>\n"; + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } else { + $form->error($locale->text('No Employees on file!')); + } + +} + + +sub search { + + # accounting years + $form->all_years(\%myconfig); + + if (@{ $form->{all_years} }) { + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + $fromto = qq| + <tr> + <th align=right nowrap>|.$locale->text('Startdate').qq|</th> + <td>|.$locale->text('From').qq| <input name=startdatefrom size=11 title="$myconfig{dateformat}"> + |.$locale->text('To').qq| <input name=startdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom +|; + + + if ($form->{type} eq 'timecard') { + $form->{title} = $locale->text('Time Cards'); + JC->jcitems_links(\%myconfig, \%$form); + } + if ($form->{type} eq 'storescard') { + $form->{title} = $locale->text('Stores Cards'); + JC->jcitems_links(\%myconfig, \%$form); + } + + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + } + + if (@{ $form->{all_parts} }) { + $form->{selectpartnumber} = "<option>\n"; + foreach $ref (@{ $form->{all_parts} }) { + $form->{selectpartnumber} .= qq|<option value="$ref->{partnumber}--$ref->{id}">$ref->{partnumber}\n|; + } + } + + if ($form->{project} eq 'job') { + $joblabel = $locale->text('Job Number'); + $laborlabel = $locale->text('Labor Code'); + } elsif ($form->{project} eq 'project') { + $joblabel = $locale->text('Project Number'); + $laborlabel = $locale->text('Service Code'); + } else { + $joblabel = $locale->text('Project/Job Number'); + $laborlabel = $locale->text('Service/Labor Code'); + } + + if ($form->{selectprojectnumber}) { + $jobnumber = qq| + <tr> + <th align=right nowrap>$joblabel</th> + <td colspan=3><select name=projectnumber>$form->{selectprojectnumber}</select></td> + </tr> +|; + } + + + if ($form->{type} eq 'timecard') { + # employees + if (@{ $form->{all_employee} }) { + $form->{selectemployee} = "<option>\n"; + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } else { + $form->error($locale->text('No Employees on file!')); + } + + if ($form->{selectpartnumber}) { + $partnumber = qq| + <tr> + <th align=right nowrap>$laborlabel</th> + <td colspan=3><select name=partnumber>$form->{selectpartnumber}</select></td> + </tr> +|; + } + + $employee = qq| + <tr> + <th align=right nowrap>|.$locale->text('Employee').qq|</th> + <td colspan=3><select name=employee>$form->{selectemployee}</select></td> + </tr> +|; + + $l_time = qq|<td nowrap><input name=l_time class=checkbox type=checkbox value=Y> |.$locale->text('Time').qq|</td>|; + + } + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + $jobnumber + $partnumber + $employee + $fromto + + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td> + <table> + <tr> + <td nowrap><input name=open class=checkbox type=checkbox value=Y checked> |.$locale->text('Open').qq|</td> + <td nowrap><input name=closed class=checkbox type=checkbox value=Y> |.$locale->text('Closed').qq|</td> + </tr> + <tr> + $l_time + <td nowrap><input name=l_allocated class=checkbox type=checkbox value=Y> |.$locale->text('Allocated').qq|</td> + </tr> + <tr> + <td><input name=l_subtotal class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq|</td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=nextsub value="list_$form->{type}"> +<input type=hidden name=sort value="transdate"> +|; + + $form->hide_form(qw(db path login sessionid project type)); + + print qq| +<br> +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub display_form { + + &{ "$form->{type}_header" }; + &{ "$form->{type}_footer" }; + +} + + +sub form_header { + + &{ "$form->{type}_header" }; + +} + + +sub form_footer { + + &{ "form->{type}_footer" }; + +} + + +sub prepare_timecard { + + $form->{formname} = "timecard"; + $form->{format} = "postscript" if $myconfig{printer}; + $form->{media} = $myconfig{printer}; + + JC->get_jcitems(\%myconfig, \%$form); + + $form->{selectformname} = qq|<option value="timecard">|.$locale->text('Time Card'); + + foreach $item (qw(in out)) { + ($form->{"${item}hour"}, $form->{"${item}min"}, $form->{"${item}sec"}) = split /:/, $form->{"checked$item"}; + for (qw(hour min sec)) { + if (($form->{"$item$_"} *= 1) > 0) { + $form->{"$item$_"} = substr(qq|0$form->{"$item$_"}|,-2); + } else { + $form->{"$item$_"} ||= ""; + } + } + } + + $form->{checkedin} = $form->{inhour} * 3600 + $form->{inmin} * 60 + $form->{insec}; + $form->{checkedout} = $form->{outhour} * 3600 + $form->{outmin} * 60 + $form->{outsec}; + + if ($form->{checkedin} > $form->{checkedout}) { + $form->{checkedout} = 86400 - ($form->{checkedin} - $form->{checkedout}); + $form->{checkedin} = 0; + } + + $form->{clocked} = ($form->{checkedout} - $form->{checkedin}) / 3600; + if ($form->{clocked}) { + $form->{oldnoncharge} = $form->{clocked} - $form->{qty}; + } + $form->{oldqty} = $form->{qty}; + + $form->{noncharge} = $form->format_amount(\%myconfig, $form->{clocked} - $form->{qty}, 4) if $form->{checkedin} != $form->{checkedout}; + $form->{clocked} = $form->format_amount(\%myconfig, $form->{clocked}, 4); + + $form->{amount} = $form->{sellprice} * $form->{qty}; + for (qw(sellprice amount)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) } + $form->{qty} = $form->format_amount(\%myconfig, $form->{qty}, 4); + $form->{allocated} = $form->format_amount(\%myconfig, $form->{allocated}); + + $form->{employee} .= "--$form->{employee_id}"; + $form->{projectnumber} .= "--$form->{project_id}"; + $form->{partnumber} .= "--$form->{parts_id}"; + $form->{oldpartnumber} = $form->{partnumber}; + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + &jcitems_links; + + $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto})); + + $form->{readonly} = 1 if $myconfig{acs} =~ /Production--Add Time Card/; + + if ($form->{income_accno_id}) { + $form->{locked} = 1 if $form->{production} == $form->{completed}; + } + +} + + +sub timecard_header { + + # set option selected + for (qw(employee projectnumber partnumber)) { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + $rows = $form->numtextrows($form->{description}, 50, 8); + + for (qw(transdate checkedin checkedout partnumber)) { $form->{"old$_"} = $form->{$_} } + for (qw(partnumber description)) { $form->{$_} = $form->quote($form->{$_}) } + + if ($rows > 1) { + $description = qq|<textarea name=description rows=$rows cols=46 wrap=soft>$form->{description}</textarea>|; + } else { + $description = qq|<input name=description size=48 value="$form->{description}">|; + } + + if ($form->{project} eq 'job') { + + $projectlabel = $locale->text('Job Number'); + $laborlabel = $locale->text('Labor Code'); + $rate = qq|<input type=hidden name=sellprice value=$form->{sellprice}>|; + + } else { + + if ($form->{project} eq 'project') { + $projectlabel = $locale->text('Project Number'); + $laborlabel = $locale->text('Service Code'); + } else { + $projectlabel = $locale->text('Project/Job Number'); + $laborlabel = $locale->text('Service/Labor Code'); + } + + if ($myconfig{role} ne 'user') { + $rate = qq| + <tr> + <th align=right nowrap>|.$locale->text('Chargeout Rate').qq|</th> + <td><input name=sellprice value=$form->{sellprice}></td> + <th align=right nowrap>|.$locale->text('Total').qq|</th> + <td>$form->{amount}</td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Allocated').qq|</th> + <td><input name=allocated value=$form->{allocated}></td> + </tr> +|; + } else { + $rate = qq| + <tr> + <th align=right nowrap>|.$locale->text('Chargeout Rate').qq|</th> + <td>$form->{sellprice}</td> + <th align=right nowrap>|.$locale->text('Total').qq|</th> + <td>$form->{amount}</td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Allocated').qq|</th> + <td>$form->{allocated}</td> + </tr> + <input type=hidden name=sellprice value=$form->{sellprice}> + <input type=hidden name=allocated value=$form->{allocated}> +|; + } + } + + if ($myconfig{role} eq 'user') { + $charge = qq|<input type=hidden name=qty value=$form->{qty}>$form->{qty}|; + } else { + $charge = qq|<input name=qty value=$form->{qty}>|; + } + + if (($rows = $form->numtextrows($form->{notes}, 40, 6)) < 2) { + $rows = 2; + } + + $notes = qq|<tr> + <th align=right>|.$locale->text('Notes').qq|</th> + <td colspan=3><textarea name="notes" rows=$rows cols=46 wrap=soft>$form->{notes}</textarea> + </td> + </tr> +|; + +################## + ($null, $form->{oldproject_id}) = split /--/, $form->{projectnumber}; + + $form->header; + + print qq| +<body> + +<form method=post action="$form->{script}"> +|; + + $form->hide_form(qw(id type media format printed queued title closedto locked oldtransdate oldcheckedin oldcheckedout oldpartnumber project oldqty oldnoncharge pricematrix oldproject_id)); + + print qq| +<table width=100%> + <tr class=listtop> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Employee').qq|</th> + <td><select name=employee>$form->{selectemployee}</select></td> + </tr> + <tr> + <th align=right nowrap>$projectlabel</th> + <td><select name=projectnumber>$form->{selectprojectnumber}</select> + </td> + <td></td> + <td>$form->{projectdescription}</td> + <input type=hidden name=projectdescription value="|.$form->quote($form->{projectdescription}).qq|"> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Date worked').qq|</th> + <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td> + </tr> + <tr> + <th align=right nowrap>$laborlabel</th> + <td><select name=partnumber>$form->{selectpartnumber}</select></td> + </tr> + <tr valign=top> + <th align=right nowrap>|.$locale->text('Description').qq|</th> + <td colspan=3>$description</td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Time In').qq|</th> + <td> + <table> + <tr> + <td><input name=inhour title="hh" size=3 maxlength=2 value=$form->{inhour}></td> + <td><input name=inmin title="mm" size=3 maxlength=2 value=$form->{inmin}></td> + <td><input name=insec title="ss" size=3 maxlength=2 value=$form->{insec}></td> + </tr> + </table> + </td> + <th align=right nowrap>|.$locale->text('Time Out').qq|</th> + <td> + <table> + <tr> + <td><input name=outhour title="hh" size=3 maxlength=2 value=$form->{outhour}></td> + <td><input name=outmin title="mm" size=3 maxlength=2 value=$form->{outmin}></td> + <td><input name=outsec title="ss" size=3 maxlength=2 value=$form->{outsec}></td> + </tr> + </table> + </td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Clocked').qq|</th> + <td>$form->{clocked}</td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Non-chargeable').qq|</th> + <td><input name=noncharge value=$form->{noncharge}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Chargeable').qq|</th> + <td>$charge</td> + </tr> + $rate + $notes + </table> + </td> + </tr> + +|; + +} + + +sub timecard_footer { + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> + <tr> + <td> +|; + + &print_options; + + print qq| + </td> + </tr> +</table> +<br> +|; + + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + + if (! $form->{readonly}) { + +# type=submit $locale->text('Update') +# type=submit $locale->text('Print') +# type=submit $locale->text('Save') +# type=submit $locale->text('Print and Save') +# type=submit $locale->text('Save as new') +# type=submit $locale->text('Print and Save as new') +# type=submit $locale->text('Delete') + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') }, + 'Save' => { ndx => 3, key => 'S', value => $locale->text('Save') }, + 'Print and Save' => { ndx => 6, key => 'R', value => $locale->text('Print and Save') }, + 'Save as new' => { ndx => 7, key => 'N', value => $locale->text('Save as new') }, + 'Print and Save as new' => { ndx => 8, key => 'W', value => $locale->text('Print and Save as new') }, + + 'Delete' => { ndx => 16, key => 'D', value => $locale->text('Delete') }, + ); + + %a = (); + + if ($form->{id}) { + + if (!$form->{locked}) { + for ('Update', 'Print', 'Save', 'Save as new') { $a{$_} = 1 } + + if ($latex) { + for ('Print and Save', 'Print and Save as new') { $a{$_} = 1 } + } + + if ($form->{orphaned}) { + $a{'Delete'} = 1; + } + + } + + } else { + + if ($transdate > $closedto) { + + for ('Update', 'Print', 'Save') { $a{$_} = 1 } + + if ($latex) { + $a{'Print and Save'} = 1; + } + + } + } + } + + for (keys %button) { delete $button{$_} if ! $a{$_} } + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + $form->hide_form(qw(callback path login sessionid)); + + print qq| + +</form> + +</body> +</html> +|; + +} + + +sub prepare_storescard { + + $form->{formname} = "storescard"; + $form->{format} = "postscript" if $myconfig{printer}; + $form->{media} = $myconfig{printer}; + + JC->get_jcitems(\%myconfig, \%$form); + + $form->{selectformname} = qq|<option value="storescard">|.$locale->text('Stores Card'); + + $form->{amount} = $form->{sellprice} * $form->{qty}; + for (qw(sellprice amount)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) } + $form->{qty} = $form->format_amount(\%myconfig, $form->{qty}, 4); + + $form->{employee} .= "--$form->{employee_id}"; + $form->{projectnumber} .= "--$form->{project_id}"; + $form->{partnumber} .= "--$form->{parts_id}"; + $form->{oldpartnumber} = $form->{partnumber}; + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + &jcitems_links; + + $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto})); + + $form->{readonly} = 1 if $myconfig{acs} =~ /Production--Add Time Card/; + + if ($form->{income_accno_id}) { + $form->{locked} = 1 if $form->{production} == $form->{completed}; + } + +} + + +sub storescard_header { + + # set option selected + for (qw(employee projectnumber partnumber)) { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + $rows = $form->numtextrows($form->{description}, 50, 8); + + for (qw(transdate partnumber)) { $form->{"old$_"} = $form->{$_} } + for (qw(partnumber description)) { $form->{$_} = $form->quote($form->{$_}) } + + if ($rows > 1) { + $description = qq|<textarea name=description rows=$rows cols=46 wrap=soft>$form->{description}</textarea>|; + } else { + $description = qq|<input name=description size=48 value="$form->{description}">|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action="$form->{script}"> +|; + + $form->hide_form(qw(id type media format printed queued title closedto locked oldtransdate oldpartnumber project)); + + print qq| +<table width=100%> + <tr class=listtop> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Job Number').qq|</th> + <td><select name=projectnumber>$form->{selectprojectnumber}</select> + </td> + <td>$form->{projectdescription}</td> + <input type=hidden name=projectdescription value="|.$form->quote($form->{projectdescription}).qq|"> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Date').qq|</th> + <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Part Number').qq|</th> + <td><select name=partnumber>$form->{selectpartnumber}</td> + </tr> + <tr valign=top> + <th align=right nowrap>|.$locale->text('Description').qq|</th> + <td>$description</td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Qty').qq|</th> + <td><input name=qty size=6 value=$form->{qty}> + <b>|.$locale->text('Cost').qq|</b> + <input name=sellprice size=10 value=$form->{sellprice}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Total').qq|</th> + <td>$form->{amount}</td> + </tr> + </table> + </td> + </tr> + +|; + +} + + +sub storescard_footer { + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> + <tr> + <td> +|; + + &print_options; + + print qq| + </td> + </tr> +</table> +<br> +|; + + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + +# type=submit $locale->text('Update') +# type=submit $locale->text('Print') +# type=submit $locale->text('Save') +# type=submit $locale->text('Print and Save') +# type=submit $locale->text('Save as new') +# type=submit $locale->text('Print and Save as new') +# type=submit $locale->text('Delete') + + + if (! $form->{readonly}) { + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') }, + 'Save' => { ndx => 3, key => 'S', value => $locale->text('Save') }, + 'Print and Save' => { ndx => 6, key => 'R', value => $locale->text('Print and Save') }, + 'Save as new' => { ndx => 7, key => 'N', value => $locale->text('Save as new') }, + 'Print and Save as new' => { ndx => 8, key => 'W', value => $locale->text('Print and Save as new') }, + 'Delete' => { ndx => 16, key => 'D', value => $locale->text('Delete') }, + ); + + %a = (); + + if ($form->{id}) { + + if (!$form->{locked}) { + for ('Update', 'Print', 'Save', 'Save as new') { $a{$_} = 1 } + if ($latex) { + for ('Print and Save', 'Print and Save as new') { $a{$_} = 1 } + } + if ($form->{orphaned}) { + $a{'Delete'} = 1; + } + } + + } else { + + if ($transdate > $closedto) { + for ('Update', 'Print', 'Save') { $a{$_} = 1 } + + if ($latex) { + $a{'Print and Save'} = 1; + } + } + } + + for (keys %button) { delete $button{$_} if ! $a{$_} } + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + $form->hide_form(qw(callback path login sessionid)); + + print qq| + +</form> + +</body> +</html> +|; + +} + + + +sub update { + + ($null, $form->{project_id}) = split /--/, $form->{projectnumber}; + + # check labor/part + JC->jcitems_links(\%myconfig, \%$form); + + &jcitems_links; + + $checkmatrix = 1 if $form->{oldproject_id} != $form->{project_id}; + + if ($form->{type} eq 'timecard') { + + # time clocked + %hour = ( in => 0, out => 0 ); + for $t (qw(in out)) { + if ($form->{"${t}sec"} > 60) { + $form->{"${t}sec"} -= 60; + $form->{"${t}min"}++; + } + if ($form->{"${t}min"} > 60) { + $form->{"${t}min"} -= 60; + $form->{"${t}hour"}++; + } + $hour{$t} = $form->{"${t}hour"}; + } + + $form->{checkedin} = $hour{in} * 3600 + $form->{inmin} * 60 + $form->{insec}; + $form->{checkedout} = $hour{out} * 3600 + $form->{outmin} * 60 + $form->{outsec}; + + if ($form->{checkedin} > $form->{checkedout}) { + $form->{checkedout} = 86400 - ($form->{checkedin} - $form->{checkedout}); + $form->{checkedin} = 0; + } + + $form->{clocked} = ($form->{checkedout} - $form->{checkedin}) / 3600; + + for (qw(sellprice qty noncharge allocated)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + $checkmatrix = 1 if $form->{oldqty} != $form->{qty}; + + if (($form->{oldcheckedin} != $form->{checkedin}) || ($form->{oldcheckedout} != $form->{checkedout})) { + $checkmatrix = 1; + $form->{oldqty} = $form->{qty} = $form->{clocked} - $form->{noncharge}; + $form->{oldnoncharge} = $form->{noncharge}; + } + + if (($form->{qty} != $form->{oldqty}) && $form->{clocked}) { + $form->{oldnoncharge} = $form->{noncharge} = $form->{clocked} - $form->{qty}; + $checkmatrix = 1; + } + + if (($form->{oldnoncharge} != $form->{noncharge}) && $form->{clocked}) { + $form->{oldqty} = $form->{qty} = $form->{clocked} - $form->{noncharge}; + $checkmatrix = 1; + } + + if ($checkmatrix) { + @a = split / /, $form->{pricematrix}; + if (scalar @a > 2) { + for (@a) { + ($q, $p) = split /:/, $_; + if (($p * 1) && ($form->{qty} >= ($q * 1))) { + $form->{sellprice} = $p; + } + } + } + } + + $form->{amount} = $form->{sellprice} * $form->{qty}; + + $form->{clocked} = $form->format_amount(\%myconfig, $form->{clocked}, 4); + for (qw(sellprice amount)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) } + for (qw(qty noncharge)) { + $form->{"old$_"} = $form->{$_}; + $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 4); + } + + } else { + + for (qw(sellprice qty allocated)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + if ($form->{oldqty} != $form->{qty}) { + @a = split / /, $form->{pricematrix}; + if (scalar @a > 2) { + for (@a) { + ($q, $p) = split /:/, $_; + if (($p * 1) && ($form->{qty} >= ($q * 1))) { + $form->{sellprice} = $p; + } + } + } + } + + $form->{amount} = $form->{sellprice} * $form->{qty}; + for (qw(sellprice amount)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) } + + } + + $form->{allocated} = $form->format_amount(\%myconfig, $form->{allocated}); + + &display_form; + +} + + +sub save { + + $form->isblank("transdate", $locale->text('Date missing!')); + + if ($form->{project} eq 'project') { + $form->isblank("projectnumber", $locale->text('Project Number missing!')); + $form->isblank("partnumber", $locale->text('Service Code missing!')); + } else { + $form->isblank("projectnumber", $locale->text('Job Number missing!')); + $form->isblank("partnumber", $locale->text('Labor Code missing!')); + } + + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + + $msg = ($form->{type} eq 'timecard') ? $locale->text('Cannot save time card for a closed period!') : $locale->text('Cannot save stores card for a closed period!'); + $form->error($msg) if ($transdate <= $closedto); + + if (! $form->{resave}) { + if ($form->{id}) { + &resave; + exit; + } + } + + + $rc = JC->save(\%myconfig, \%$form); + + if ($form->{type} eq 'timecard') { + $form->error($locale->text('Cannot change time card for a completed job!')) if ($rc == -1); + $form->error($locale->text('Cannot add time card for a completed job!')) if ($rc == -2); + + if ($rc) { + $form->redirect($locale->text('Time Card saved!')); + } else { + $form->error($locale->text('Cannot save time card!')); + } + + } else { + $form->error($locale->text('Cannot change stores card for a completed job!')) if ($rc == -1); + $form->error($locale->text('Cannot add stores card for a completed job!')) if ($rc == -2); + + if ($rc) { + $form->redirect($locale->text('Stores Card saved!')); + } else { + $form->error($locale->text('Cannot save stores card!')); + } + } + +} + + +sub save_as_new { + + delete $form->{id}; + &save; + +} + + +sub print_and_save_as_new { + + delete $form->{id}; + &print_and_save; + +} + + +sub resave { + + if ($form->{print_and_save}) { + $form->{nextsub} = "print_and_save"; + $msg = $locale->text('You are printing and saving an existing transaction!'); + } else { + $form->{nextsub} = "save"; + $msg = $locale->text('You are saving an existing transaction!'); + } + + $form->{resave} = 1; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +|; + + delete $form->{action}; + + $form->hide_form; + + print qq| +<h2 class=confirm>|.$locale->text('Warning!').qq|</h2> + +<h4>$msg</h4> + +<input name=action class=submit type=submit value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub print_and_save { + + $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/; + $form->error($locale->text('Select a Printer!')) if $form->{media} eq 'screen'; + + if (! $form->{resave}) { + if ($form->{id}) { + $form->{print_and_save} = 1; + &resave; + exit; + } + } + + $old_form = new Form; + $form->{display_form} = "save"; + for (keys %$form) { $old_form->{$_} = $form->{$_} } + + &{ "print_$form->{formname}" }($old_form); + +} + + +sub delete_timecard { + + $form->header; + + $employee = $form->{employee}; + $employee =~ s/--.*//g; + $projectnumber = $form->{projectnumber}; + $projectnumber =~ s/--.*//g; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + delete $form->{action}; + + $form->hide_form; + + print qq| +<h2 class=confirm>|.$locale->text('Confirm!').qq|</h2> + +<h4>|.$locale->text('Are you sure you want to delete time card for').qq| +<p>$form->{transdate} +<br>$employee +<br>$projectnumber +</h4> + +<p> +<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|"> +</form> +|; + +} + + +sub delete { &{ "delete_$form->{type}" } }; +sub yes { &{ "yes_delete_$form->{type}" } }; + + +sub yes_delete_timecard { + + if (JC->delete_timecard(\%myconfig, \%$form)) { + $form->redirect($locale->text('Time Card deleted!')); + } else { + $form->error($locale->text('Cannot delete time card!')); + } + +} + + +sub list_timecard { + + $form->{type} = "timecard"; + + JC->jcitems(\%myconfig, \%$form); + + $form->{title} = $locale->text('Time Cards'); + + @a = qw(type direction oldsort path login sessionid project l_subtotal open closed l_time l_allocated); + $href = "$form->{script}?action=list_timecard"; + for (@a) { $href .= "&$_=$form->{$_}" } + + $href .= "&title=".$form->escape($form->{title}); + + $form->sort_order(); + + $callback = "$form->{script}?action=list_timecard"; + for (@a) { $callback .= "&$_=$form->{$_}" } + + $callback .= "&title=".$form->escape($form->{title},1); + + @column_index = (qw(transdate projectnumber projectdescription id partnumber description)); + + push @column_index, (qw(allocated)) if $form->{l_allocated}; + push @column_index, (qw(1 2 3 4 5 6 7)); + + @column_index = $form->sort_columns(@column_index); + + if ($form->{project} eq 'job') { + $joblabel = $locale->text('Job Number'); + $laborlabel = $locale->text('Labor Code'); + $desclabel = $locale->text('Job Name'); + } elsif ($form->{project} eq 'project') { + $joblabel = $locale->text('Project Number'); + $laborlabel = $locale->text('Service Code'); + $desclabel = $locale->text('Project Name'); + } else { + $joblabel = $locale->text('Project/Job Number'); + $laborlabel = $locale->text('Service/Labor Code'); + $desclabel = $locale->text('Project/Job Name'); + } + + if ($form->{projectnumber}) { + $callback .= "&projectnumber=".$form->escape($form->{projectnumber},1); + $href .= "&projectnumber=".$form->escape($form->{projectnumber}); + ($var) = split /--/, $form->{projectnumber}; + $option .= "\n<br>" if ($option); + $option .= "$joblabel : $var"; + @column_index = grep !/projectnumber/, @column_index; + } + if ($form->{partnumber}) { + $callback .= "&partnumber=".$form->escape($form->{partnumber},1); + $href .= "&partnumber=".$form->escape($form->{partnumber}); + ($var) = split /--/, $form->{partnumber}; + $option .= "\n<br>" if ($option); + $option .= "$laborlabel : $var"; + @column_index = grep !/partnumber/, @column_index; + } + if ($form->{employee}) { + $callback .= "&employee=".$form->escape($form->{employee},1); + $href .= "&employee=".$form->escape($form->{employee}); + } + + if ($form->{startdatefrom}) { + $callback .= "&startdatefrom=$form->{startdatefrom}"; + $href .= "&startdatefrom=$form->{startdatefrom}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{startdatefrom}, 1); + } + if ($form->{startdateto}) { + $callback .= "&startdateto=$form->{startdateto}"; + $href .= "&startdateto=$form->{startdateto}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{startdateto}, 1); + } + if ($form->{open}) { + $callback .= "&open=$form->{open}"; + $href .= "&open=$form->{open}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Open'); + } + if ($form->{closed}) { + $callback .= "&closed=$form->{closed}"; + $href .= "&closed=$form->{closed}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Closed'); + } + + %weekday = ( 1 => $locale->text('Sunday'), + 2 => $locale->text('Monday'), + 3 => $locale->text('Tuesday'), + 4 => $locale->text('Wednesday'), + 5 => $locale->text('Thursday'), + 6 => $locale->text('Friday'), + 7 => $locale->text('Saturday'), + ); + + for (keys %weekday) { $column_header{$_} = "<th class=listheading width=25>".substr($weekday{$_},0,3)."</th>" } + + $column_header{id} = "<th><a class=listheading href=$href&sort=id>".$locale->text('ID')."</a></th>"; + $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>"; + $column_header{description} = "<th><a class=listheading href=$href&sort=description>" . $locale->text('Description') . "</th>"; + $column_header{projectnumber} = "<th><a class=listheading href=$href&sort=projectnumber>$joblabel</a></th>"; + $column_header{partnumber} = "<th><a class=listheading href=$href&sort=partnumber>$laborlabel</a></th>"; + $column_header{projectdescription} = "<th><a class=listheading href=$href&sort=projectdescription>$desclabel</a></th>"; + $column_header{allocated} = "<th class=listheading></th>"; + + + $form->header; + + if (@{ $form->{transactions} }) { + $sameitem = $form->{transactions}->[0]->{$form->{sort}}; + $sameemployeenumber = $form->{transactions}->[0]->{employeenumber}; + $employee = $form->{transactions}->[0]->{employee}; + $sameweek = $form->{transactions}->[0]->{workweek}; + } + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr> + <th colspan=2 align=left> + $employee + </th> + <th align=left> + $sameemployeenumber + </th> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + # add sort and escape callback, this one we use for the add sub + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + # flip direction + $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC"; + $href =~ s/&direction=(\w+)&/&direction=$direction&/; + + %total = (); + + foreach $ref (@{ $form->{transactions} }) { + + if ($sameemployeenumber ne $ref->{employeenumber}) { + $sameemployeenumber = $ref->{employeenumber}; + $sameweek = $ref->{workweek}; + + if ($form->{l_subtotal}) { + print qq| + <tr class=listsubtotal> +|; + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $weektotal = 0; + for (keys %weekday) { + $column_data{$_} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotal{$_}, "", " ")."</th>"; + $weektotal += $subtotal{$_}; + $subtotal{$_} = 0; + } + + $column_data{$form->{sort}} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $weektotal, "", " ")."</th>"; + + for (@column_index) { print "\n$column_data{$_}" } + } + + # print total + print qq| + <tr class=listtotal> +|; + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $total = 0; + for (keys %weekday) { + $column_data{$_} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $total{$_}, "", " ")."</th>"; + $total += $total{$_}; + $total{$_} = 0; + } + + $column_data{$form->{sort}} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $total, "", " ")."</th>"; + + for (@column_index) { print "\n$column_data{$_}" } + + + print qq| + <tr height=30 valign=bottom> + <th colspan=2 align=left> + $ref->{employee} + </th> + <th align=left> + $ref->{employeenumber} + </th> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + } + + if ($form->{l_subtotal}) { + if ($ref->{workweek} != $sameweek) { + for (@column_index) { $column_data{$_} = "<td> </td>" } + $weektotal = 0; + for (keys %weekday) { + $column_data{$_} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotal{$_}, "", " ")."</th>"; + $weektotal += $subtotal{$_}; + $subtotal{$_} = 0 + } + $column_data{$form->{sort}} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $weektotal, "", " ")."</th>"; + $sameweek = $ref->{workweek}; + + print qq| + <tr class=listsubtotal> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + } + } + + for (@column_index) { $column_data{$_} = "<td>$ref->{$_} </td>" } + for (keys %weekday) { $column_data{$_} = "<td> </td>" } + + $column_data{allocated} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{allocated}, "", " ")."</td>"; + $column_data{$ref->{weekday}} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{qty}, "", " "); + + if ($form->{l_time}) { + $column_data{$ref->{weekday}} .= "<br>$ref->{checkedin}<br>$ref->{checkedout}"; + } + $column_data{$ref->{weekday}} .= "</td>"; + + $column_data{id} = "<td><a href=$form->{script}?action=edit&id=$ref->{id}&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&project=$form->{project}&callback=$callback>$ref->{id}</a></td>"; + + $subtotal{$ref->{weekday}} += $ref->{qty}; + $total{$ref->{weekday}} += $ref->{qty}; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + } + + # print last subtotal + if ($form->{l_subtotal}) { + print qq| + <tr class=listsubtotal> +|; + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $weektotal = 0; + for (keys %weekday) { + $column_data{$_} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotal{$_}, "", " ")."</th>"; + $weektotal += $subtotal{$_}; + } + + $column_data{$form->{sort}} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $weektotal, "", " ")."</th>"; + + for (@column_index) { print "\n$column_data{$_}" } + } + + # print last total + print qq| + <tr class=listtotal> +|; + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $total = 0; + for (keys %weekday) { + $column_data{$_} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $total{$_}, "", " ")."</th>"; + $total += $total{$_}; + $total{$_} = 0; + } + + $column_data{$form->{sort}} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $total, "", " ")."</th>"; + + for (@column_index) { print "\n$column_data{$_}" } + + if ($form->{project} eq 'job') { + if ($myconfig{acs} !~ /Production--Production/) { + $i = 1; + $button{'Production--Add Time Card'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Time Card').qq|"> |; + $button{'Production--Add Time Card'}{order} = $i++; + } + } elsif ($form->{project} eq 'project') { + if ($myconfig{acs} !~ /Projects--Projects/) { + $i = 1; + $button{'Projects--Add Time Card'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Time Card').qq|"> |; + $button{'Projects--Add Time Card'}{order} = $i++; + } + } else { + if ($myconfig{acs} !~ /Time Cards--Time Cards/) { + $i = 1; + $button{'Time Cards--Add Time Card'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Time Card').qq|"> |; + $button{'Time Cards--Add Time Card'}{order} = $i++; + } + } + + for (split /;/, $myconfig{acs}) { delete $button{$_} } + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(callback path login sessionid project)); + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub list_storescard { + + $form->{type} = "storescard"; + + JC->jcitems(\%myconfig, \%$form); + + $form->{title} = $locale->text('Stores Cards'); + + $href = "$form->{script}?action=list_storescard"; + for (qw(type direction oldsort path login sessionid project)) { $href .= "&$_=$form->{$_}" } + + $href .= "&title=".$form->escape($form->{title}); + + $form->sort_order(); + + $callback = "$form->{script}?action=list_storescard"; + for (qw(type direction oldsort path login sessionid project)) { $callback .= "&$_=$form->{$_}" } + + $callback .= "&title=".$form->escape($form->{title},1); + + @column_index = $form->sort_columns(qw(transdate projectnumber projectdescription id partnumber description qty amount)); + + + if ($form->{projectnumber}) { + $callback .= "&projectnumber=".$form->escape($form->{projectnumber},1); + $href .= "&projectnumber=".$form->escape($form->{projectnumber}); + ($var) = split /--/, $form->{projectnumber}; + $option .= "\n<br>" if ($option); + $option .= "$joblabel : $var"; + @column_index = grep !/projectnumber/, @column_index; + } + if ($form->{partnumber}) { + $callback .= "&partnumber=".$form->escape($form->{partnumber},1); + $href .= "&partnumber=".$form->escape($form->{partnumber}); + ($var) = split /--/, $form->{partnumber}; + $option .= "\n<br>" if ($option); + $option .= "$laborlabel : $var"; + @column_index = grep !/partnumber/, @column_index; + } + if ($form->{startdatefrom}) { + $callback .= "&startdatefrom=$form->{startdatefrom}"; + $href .= "&startdatefrom=$form->{startdatefrom}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{startdatefrom}, 1); + } + if ($form->{startdateto}) { + $callback .= "&startdateto=$form->{startdateto}"; + $href .= "&startdateto=$form->{startdateto}"; + $option .= "\n<br>" if ($option); + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{startdateto}, 1); + } + + $column_header{id} = "<th><a class=listheading href=$href&sort=id>" . $locale->text('ID') . "</a></th>"; + $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>"; + $column_header{projectnumber} = "<th><a class=listheading href=$href&sort=projectnumber>" . $locale->text('Job Number') . "</a></th>"; + $column_header{projectdescription} = "<th><a class=listheading href=$href&sort=projectdescription>" . $locale->text('Job Description') . "</a></th>"; + $column_header{partnumber} = "<th><a class=listheading href=$href&sort=partnumber>" . $locale->text('Part Number') . "</a></th>"; + $column_header{description} = "<th><a class=listheading href=$href&sort=description>" . $locale->text('Description') . "</a></th>"; + $column_header{qty} = "<th class=listheading>" . $locale->text('Qty') . "</th>"; + $column_header{amount} = "<th class=listheading>" . $locale->text('Amount') . "</th>"; + + + $form->header; + + if (@{ $form->{transactions} }) { + $sameitem = $form->{transactions}->[0]->{$form->{sort}}; + } + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + # add sort and escape callback, this one we use for the add sub + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + # flip direction + $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC"; + $href =~ s/&direction=(\w+)&/&direction=$direction&/; + + $total = 0; + foreach $ref (@{ $form->{transactions} }) { + + for (@column_index) { $column_data{$_} = "<td>$ref->{$_} </td>" } + $column_data{qty} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{qty}, "", " ")."</td>"; + $column_data{amount} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{qty} * $ref->{sellprice}, 2)."</td>"; + + $column_data{id} = "<td><a href=$form->{script}?action=edit&id=$ref->{id}&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&project=$form->{project}&callback=$callback>$ref->{id}</a></td>"; + + $total += ($ref->{qty} * $ref->{sellprice}); + + $j++; $j %= 2; + print qq| + <tr class=listrow$j> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + } + + # print total + print qq| + <tr class=listtotal> +|; + + for (@column_index) { $column_data{$_} = "<td> </td>" } + $column_data{amount} = qq|<th align=right>|.$form->format_amount(\%myconfig, $total, 2)."</th"; + + for (@column_index) { print "\n$column_data{$_}" } + + if ($form->{project} eq 'job') { + if ($myconfig{acs} !~ /Production--Production/) { + $i = 1; + $button{'Production--Add Stores Card'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Stores Card').qq|"> |; + $button{'Production--Add Stores Card'}{order} = $i++; + } + } + + for (split /;/, $myconfig{acs}) { delete $button{$_} } + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(callback path login sessionid project)); + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + + +sub continue { &{ $form->{nextsub} } }; + +sub add_time_card { + + $form->{type} = "timecard"; + &add; + +} + + +sub add_stores_card { + + $form->{type} = "storescard"; + &add; + +} + + +sub print_options { + + if ($form->{selectlanguage}) { + $form->{"selectlanguage"} = $form->unescape($form->{"selectlanguage"}); + $form->{"selectlanguage"} =~ s/ selected//; + $form->{"selectlanguage"} =~ s/(<option value="\Q$form->{language_code}\E")/$1 selected/; + $lang = qq|<select name=language_code>$form->{selectlanguage}</select> + <input type=hidden name=selectlanguage value="|. + $form->escape($form->{selectlanguage},1).qq|">|; + } + + $form->{selectformname} = $form->unescape($form->{selectformname}); + $form->{selectformname} =~ s/ selected//; + $form->{selectformname} =~ s/(<option value="\Q$form->{formname}\E")/$1 selected/; + + $type = qq|<select name=formname>$form->{selectformname}</select> + <input type=hidden name=selectformname value="|.$form->escape($form->{selectformname},1).qq|">|; + + $media = qq|<select name=media> + <option value="screen">|.$locale->text('Screen'); + + $form->{selectformat} = qq|<option value="html">html\n|; + + if (%printer && $latex) { + for (sort keys %printer) { $media .= qq| + <option value="$_">$_| } + } + + if ($latex) { + $media .= qq| + <option value="queue">|.$locale->text('Queue'); + + $form->{selectformat} .= qq| + <option value="postscript">|.$locale->text('Postscript').qq| + <option value="pdf">|.$locale->text('PDF'); + } + + $format = qq|<select name=format>$form->{selectformat}</select>|; + $format =~ s/(<option value="\Q$form->{format}\E")/$1 selected/; + $format .= qq| + <input type=hidden name=selectformat value="|.$form->escape($form->{selectformat},1).qq|">|; + $media .= qq|</select>|; + $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/; + + print qq| + <table width=100%> + <tr> + <td>$type</td> + <td>$lang</td> + <td>$format</td> + <td>$media</td> + <td align=right width=90%> + |; + + if ($form->{printed} =~ /$form->{formname}/) { + print $locale->text('Printed').qq|<br>|; + } + + if ($form->{queued} =~ /$form->{formname}/) { + print $locale->text('Queued'); + } + + print qq| + </td> + </tr> + </table> +|; + +} + + +sub print { + + if ($form->{media} !~ /screen/) { + $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/; + $old_form = new Form; + for (keys %$form) { $old_form->{$_} = $form->{$_} } + } + + &{ "print_$form->{formname}" }($old_form); + +} + + +sub print_timecard { + my ($old_form) = @_; + + $display_form = ($form->{display_form}) ? $form->{display_form} : "update"; + + $form->{description} =~ s/^\s+//g; + + for (qw(partnumber projectnumber)) { $form->{$_} =~ s/--.*// } + + @a = qw(hour min sec); + foreach $item (qw(in out)) { + for (@a) { $form->{"$item$_"} = substr(qq|00$form->{"$item$_"}|, -2) } + $form->{"checked$item"} = qq|$form->{"${item}hour"}:$form->{"${item}min"}:$form->{"${item}sec"}|; + } + + @a = (); + for (qw(company address tel fax businessnumber)) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/\n/g; + + push @a, qw(partnumber description projectnumber projectdescription); + push @a, qw(company address tel fax businessnumber username useremail); + + $form->format_string(@a); + + $form->{total} = $form->format_amount(\%myconfig, $form->parse_amount(\%myconfig, $form->{qty}) * $form->parse_amount(\%myconfig, $form->{sellprice}), 2); + + + ($form->{employee}, $form->{employee_id}) = split /--/, $form->{employee}; + + $form->{templates} = "$myconfig{templates}"; + $form->{IN} = "$form->{formname}.html"; + + if ($form->{format} =~ /(postscript|pdf)/) { + $form->{IN} =~ s/html$/tex/; + } + + if ($form->{media} !~ /(screen|queue)/) { + $form->{OUT} = "| $printer{$form->{media}}"; + + if ($form->{printed} !~ /$form->{formname}/) { + $form->{printed} .= " $form->{formname}"; + $form->{printed} =~ s/^ //; + + $form->update_status(\%myconfig); + } + + %audittrail = ( tablename => jcitems, + reference => $form->{id}, + formname => $form->{formname}, + action => 'printed', + id => $form->{id} ); + + %status = (); + for (qw(printed queued audittrail)) { $status{$_} = $form->{$_} } + + $status{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail); + + } + + if ($form->{media} eq 'queue') { + %queued = split / /, $form->{queued}; + + if ($filename = $queued{$form->{formname}}) { + $form->{queued} =~ s/$form->{formname} $filename//; + unlink "$spool/$filename"; + $filename =~ s/\..*$//g; + } else { + $filename = time; + $filename .= $$; + } + + $filename .= ($form->{format} eq 'postscript') ? '.ps' : '.pdf'; + $form->{OUT} = ">$spool/$filename"; + + $form->{queued} = "$form->{formname} $filename"; + $form->update_status(\%myconfig); + + %audittrail = ( tablename => jcitems, + reference => $form->{id}, + formname => $form->{formname}, + action => 'queued', + id => $form->{id} ); + + %status = (); + for (qw(printed queued audittrail)) { $status{$_} = $form->{$_} } + + $status{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail); + } + + $form->parse_template(\%myconfig, $userspath); + + if (defined %$old_form) { + + for (keys %$old_form) { $form->{$_} = $old_form->{$_} } + for (qw(printed queued audittrail)) { $form->{$_} = $status{$_} } + + &{ "$display_form" }; + + } + +} + + diff --git a/bin/lynx/login.pl b/bin/lynx/login.pl new file mode 100755 index 00000000..b674b03f --- /dev/null +++ b/bin/lynx/login.pl @@ -0,0 +1,350 @@ +###################################################################### +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2000 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +###################################################################### +# +# login frontend +# +####################################################################### + + +use DBI; +use SL::User; +use SL::Form; + + +$form = new Form; + + +$locale = new Locale $language, "login"; +$form->{charset} = $locale->{charset}; + +# customization +if (-f "$form->{path}/custom_$form->{script}") { + eval { require "$form->{path}/custom_$form->{script}"; }; + $form->error($@) if ($@); +} + +# per login customization +if (-f "$form->{path}/$form->{login}_$form->{script}") { + eval { require "$form->{path}/$form->{login}_$form->{script}"; }; + $form->error($@) if ($@); +} + +# window title bar, user info +$form->{titlebar} = "LedgerSMB ".$locale->text('Version'). " $form->{version}"; + +if ($form->{action}) { + $form->{titlebar} .= " - $myconfig{name} - $myconfig{dbname}"; + &{ $locale->findsub($form->{action}) }; +} else { + &login_screen; +} + + +1; + + +sub login_screen { + + $form->{stylesheet} = "sql-ledger.css"; + $form->{favicon} = "sql-ledger.ico"; + + $form->{endsession} = 1; + $form->header(1); + + if ($form->{login}) { + $sf = qq|function sf() { document.login.password.focus(); }|; + } else { + $sf = qq|function sf() { document.login.login.focus(); }|; + } + + print qq| +<script language="JavaScript" type="text/javascript"> +<!-- +var agt = navigator.userAgent.toLowerCase(); +var is_major = parseInt(navigator.appVersion); +var is_nav = ((agt.indexOf('mozilla') != -1) && (agt.indexOf('spoofer') == -1) + && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera') == -1) + && (agt.indexOf('webtv') == -1)); +var is_nav4lo = (is_nav && (is_major <= 4)); + +function jsp() { + if (is_nav4lo) + document.login.js.value = "0" + else + document.login.js.value = "1" +} +$sf +// End --> +</script> +|; + + print qq| + +<body class=login onload="jsp(); sf()"> + +<pre> + +</pre> + +<center> +<table class=login border=3 cellpadding=20> + <tr> + <td class=login align=center><a href="http://sourceforge.net/projects/ledger-smb/" target=_top><img src=ledger-smb.png border=0></a> +<h1 class=login align=center>|.$locale->text('Version').qq| $form->{version} +</h1> + +<p> + +<form method=post action=$form->{script} name=login> + + <table width=100%> + <tr> + <td align=center> + <table> + <tr> + <th align=right>|.$locale->text('Name').qq|</th> + <td><input class=login name=login size=30 value=$form->{login}></td> + </tr> + <tr> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input class=login type=password name=password size=30></td> + </tr> + <input type=hidden name=path value=$form->{path}> + <input type=hidden name=js value=$form->{js}> + </table> + + <br> + <input type=submit name=action value="|.$locale->text('Login').qq|"> + </td> + </tr> + </table> + +</form> + + </td> + </tr> +</table> + +</body> +</html> +|; + +} + + +sub selectdataset { + my ($login) = @_; + + if (-f "css/sql-ledger.css") { + $form->{stylesheet} = "sql-ledger.css"; + } + + $form->header(1); + + print qq| +<body class=login onload="document.forms[0].password.focus()" /> + +<pre> + +</pre> + +<center> +<table class=login border=3 cellpadding=20> + <tr> + <td class=login align=center><a href="http://sourceforge.net/projects/ledger-smb/" target=_top><img src=ledger-smb.png border=0></a> +<h1 class=login align=center>|.$locale->text('Version').qq| $form->{version} +</h1> + +<p> + +<form method=post action=$form->{script}> + +<input type=hidden name=beenthere value=1> + + <table width=100%> + <tr> + <td align=center> + <table> + <tr> + <th align=right>|.$locale->text('Name').qq|</th> + <td>$form->{login}</td> + </tr> + <tr> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input class=login type=password name=password size=30 value=$form->{password}></td> + </tr> + <input type=hidden name=js value=$form->{js}> + <input type=hidden name=path value=$form->{path}> + <tr> + <th align=right>|.$locale->text('Company').qq|</th> + <td>|; + + $checked = "checked"; + foreach $login (sort { $login{$a} cmp $login{$b} } keys %{ $login }) { + print qq| + <br><input class=login type=radio name=login value=$login $checked>$login{$login} + |; + $checked = ""; + } + + print qq| + </td> + </tr> + </table> + <br> + <input type=submit name=action value="|.$locale->text('Login').qq|"> + </td> + </tr> + </table> + +</form> + + </td> + </tr> +</table> + +</body> +</html> +|; + + +} + + +sub login { + + $form->{stylesheet} = "sql-ledger.css"; + $form->{favicon} = "sql-ledger.ico"; + + $form->error($locale->text('You did not enter a name!')) unless ($form->{login}); + + if (! $form->{beenthere}) { + open(FH, "$memberfile") or $form->error("$memberfile : $!"); + @a = <FH>; + close(FH); + + foreach $item (@a) { + + if ($item =~ /^\[(.*?)\]/) { + $login = $1; + $found = 1; + } + + if ($item =~ /^company=/) { + if ($login =~ /$form->{login}\@/ && $found) { + ($null, $name) = split /=/, $item, 2; + $login{$login} = $name; + } + $found = 0; + } + + } + + if (keys %login > 1) { + &selectdataset(\%login); + exit; + } + } + + + $user = new User $memberfile, $form->{login}; + + # if we get an error back, bale out + if (($errno = $user->login(\%$form, $userspath)) <= -1) { + + $errno *= -1; + $err[1] = $locale->text('Access Denied!'); + $err[2] = $locale->text('Incorrect Dataset version!'); + $err[3] = $locale->text('Dataset is newer than version!'); + + if ($errno == 4) { + # upgrade dataset and log in again + open FH, ">$userspath/nologin" or $form->error($!); + + for (qw(dbname dbhost dbport dbdriver dbuser dbpasswd)) { $form->{$_} = $user->{$_} } + + $form->{dbpasswd} = unpack 'u', $form->{dbpasswd}; + + $form->{dbupdate} = "db$user->{dbname}"; + $form->{$form->{dbupdate}} = 1; + + $form->header; + print $locale->text('Upgrading to Version')." $form->{version} ... "; + + # required for Oracle + $form->{dbdefault} = $sid; + + $user->dbupdate(\%$form); + + # remove lock file + unlink "$userspath/nologin"; + + print $locale->text('done'); + + print "<p><a href=menu.pl?login=$form->{login}&sessionid=$form->{sessionid}&path=$form->{path}&action=display&main=company_logo&js=$form->{js}>".$locale->text('Continue')."</a>"; + + exit; + } + + $form->error($err[$errno]); + } + + # made it this far, setup callback for the menu + $form->{callback} = "menu.pl?action=display"; + for (qw(login path js)) { $form->{callback} .= "&$_=$form->{$_}" } + + # check for recurring transactions + if ($user->{acs} !~ /Recurring Transactions/) { + if ($user->check_recurring(\%$form)) { + $form->{callback} .= "&main=recurring_transactions"; + } else { + $form->{callback} .= "&main=company_logo"; + } + } else { + if ($user->{role} eq 'user') { + $form->{callback} .= "&main=company_logo"; + } else { + if ($user->check_recurring(\%$form)) { + $form->{callback} .= "&main=recurring_transactions"; + } else { + $form->{callback} .= "&main=company_logo"; + } + } + } + + $form->redirect; + +} + + + +sub logout { + + $form->{callback} = "$form->{script}?path=$form->{path}&login=$form->{login}"; + + $form->{endsession} = 1; + + $form->redirect; + +} + + diff --git a/bin/lynx/menu.pl b/bin/lynx/menu.pl new file mode 100755 index 00000000..58d75511 --- /dev/null +++ b/bin/lynx/menu.pl @@ -0,0 +1,153 @@ +###################################################################### +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2000 +# +# Author: Dieter Simader +# Email: dsimader@sql-ledger.org +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: Christopher Browne <cbrowne@acm.org> +# Tony Fraser <tony@sybaspace.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +####################################################################### +# +# menu for text based browsers (lynx) +# +####################################################################### + +$menufile = "menu.ini"; +use SL::Menu; + + +1; +# end of main + + + +sub display { + + $menu = new Menu "$menufile"; + $menu->add_file("custom_$menufile") if -f "custom_$menufile"; + $menu->add_file("$form->{login}_$menufile") if -f "$form->{login}_$menufile"; + + @menuorder = $menu->access_control(\%myconfig); + + $form->{title} = "LedgerSMB $form->{version}"; + + $form->header(1); + + $offset = int (21 - $#menuorder)/2; + + print "<pre>"; + print "\n" x $offset; + print "</pre>"; + + print qq|<center><table>|; + + map { print "<tr><td>".$menu->menuitem(\%myconfig, \%$form, $_).$locale->text($_).qq|</a></td></tr>|; } @menuorder; + + print qq' +</table> + +</body> +</html> +'; + +} + + +sub section_menu { + + $menu = new Menu "$menufile", $form->{level}; + + $menu->add_file("custom_$menufile") if -f "custom_$menufile"; + $menu->add_file("$form->{login}_$menufile") if -f "$form->{login}_$menufile"; + + # build tiered menus + @menuorder = $menu->access_control(\%myconfig, $form->{level}); + + foreach $item (@menuorder) { + $a = $item; + $item =~ s/^$form->{level}--//; + push @neworder, $a unless ($item =~ /--/); + } + @menuorder = @neworder; + + $level = $form->{level}; + $level =~ s/--/ /g; + + $form->{title} = $locale->text($level); + + $form->header; + + $offset = int (21 - $#menuorder)/2; + print "<pre>"; + print "\n" x $offset; + print "</pre>"; + + print qq|<center><table>|; + + foreach $item (@menuorder) { + $label = $item; + $label =~ s/$form->{level}--//g; + + # remove target + $menu->{$item}{target} = ""; + + print "<tr><td>".$menu->menuitem(\%myconfig, \%$form, $item, $form->{level}).$locale->text($label)."</a></td></tr>"; + } + + print qq'</table> + +</body> +</html> +'; + +} + + +sub acc_menu { + + §ion_menu; + +} + + +sub menubar { + $menu = new Menu "$menufile", ""; + + # build menubar + @menuorder = $menu->access_control(\%myconfig, ""); + + @neworder = (); + map { push @neworder, $_ unless ($_ =~ /--/) } @menuorder; + @menuorder = @neworder; + + print "<p>"; + $form->{script} = "menu.pl"; + + print "| "; + foreach $item (@menuorder) { + $label = $item; + + # remove target + $menu->{$item}{target} = ""; + + print $menu->menuitem(\%myconfig, \%$form, $item, "").$locale->text($label)."</a> | "; + } + +} + + diff --git a/bin/lynx/oe.pl b/bin/lynx/oe.pl new file mode 100755 index 00000000..6d369ef5 --- /dev/null +++ b/bin/lynx/oe.pl @@ -0,0 +1,3023 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Order entry module +# Quotation module +# +#====================================================================== + + +use SL::OE; +use SL::IR; +use SL::IS; +use SL::PE; + +require "$form->{path}/arap.pl"; +require "$form->{path}/io.pl"; + + +1; +# end of main + + +sub add { + + if ($form->{type} eq 'purchase_order') { + $form->{title} = $locale->text('Add Purchase Order'); + $form->{vc} = 'vendor'; + } + if ($form->{type} eq 'sales_order') { + $form->{title} = $locale->text('Add Sales Order'); + $form->{vc} = 'customer'; + } + if ($form->{type} eq 'request_quotation') { + $form->{title} = $locale->text('Add Request for Quotation'); + $form->{vc} = 'vendor'; + } + if ($form->{type} eq 'sales_quotation') { + $form->{title} = $locale->text('Add Quotation'); + $form->{vc} = 'customer'; + } + + $form->{callback} = "$form->{script}?action=add&type=$form->{type}&vc=$form->{vc}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}" unless $form->{callback}; + + $form->{rowcount} = 0; + + &order_links; + &prepare_order; + &display_form; + +} + + +sub edit { + + if ($form->{type} =~ /(purchase_order|bin_list)/) { + $form->{title} = $locale->text('Edit Purchase Order'); + $form->{vc} = 'vendor'; + $form->{type} = 'purchase_order'; + } + if ($form->{type} =~ /((sales|work)_order|(packing|pick)_list)/) { + $form->{title} = $locale->text('Edit Sales Order'); + $form->{vc} = 'customer'; + $form->{type} = 'sales_order'; + } + if ($form->{type} eq 'request_quotation') { + $form->{title} = $locale->text('Edit Request for Quotation'); + $form->{vc} = 'vendor'; + } + if ($form->{type} eq 'sales_quotation') { + $form->{title} = $locale->text('Edit Quotation'); + $form->{vc} = 'customer'; + } + + &order_links; + &prepare_order; + &display_form; + +} + + + +sub order_links { + + # retrieve order/quotation + OE->retrieve(\%myconfig, \%$form); + + # get customer/vendor + $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP", undef, $form->{transdate}, 1); + + # currencies + @curr = split /:/, $form->{currencies}; + $form->{defaultcurrency} = $curr[0]; + chomp $form->{defaultcurrency}; + $form->{currency} = $form->{defaultcurrency} unless $form->{currency}; + + for (@curr) { $form->{selectcurrency} .= "<option>$_\n" } + + $form->{oldlanguage_code} = $form->{language_code}; + + $l{language_code} = $form->{language_code}; + $l{searchitems} = 'nolabor' if $form->{vc} eq 'customer'; + + $form->get_partsgroup(\%myconfig, \%l); + + if (@{ $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = "<option>\n"; + foreach $ref (@ { $form->{all_partsgroup} }) { + if ($ref->{translation}) { + $form->{selectpartsgroup} .= qq|<option value="$ref->{partsgroup}--$ref->{id}">$ref->{translation}\n|; + } else { + $form->{selectpartsgroup} .= qq|<option value="$ref->{partsgroup}--$ref->{id}">$ref->{partsgroup}\n|; + } + } + } + + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + } + + if (@{ $form->{"all_$form->{vc}"} }) { + unless ($form->{"$form->{vc}_id"}) { + $form->{"$form->{vc}_id"} = $form->{"all_$form->{vc}"}->[0]->{id}; + } + } + + for (qw(terms taxincluded)) { $temp{$_} = $form->{$_} } + $form->{shipto} = 1 if $form->{id}; + + # get customer / vendor + AA->get_name(\%myconfig, \%$form); + + if ($form->{id}) { + for (qw(terms taxincluded)) { $form->{$_} = $temp{$_} } + } + + ($form->{$form->{vc}}) = split /--/, $form->{$form->{vc}}; + $form->{"old$form->{vc}"} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|; + + # build selection list + $form->{"select$form->{vc}"} = ""; + if (@{ $form->{"all_$form->{vc}"} }) { + $form->{$form->{vc}} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|; + for (@{ $form->{"all_$form->{vc}"} }) { $form->{"select$form->{vc}"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + $form->{department} = "$form->{department}--$form->{department_id}" if $form->{department_id}; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + $form->{employee} = "$form->{employee}--$form->{employee_id}"; + + # sales staff + if (@{ $form->{all_employee} }) { + $form->{selectemployee} = ""; + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + if (@{ $form->{all_language} }) { + $form->{selectlanguage} = "<option>\n"; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + # forex + $form->{forex} = $form->{exchangerate}; + +} + + +sub prepare_order { + + $form->{format} = "postscript" if $myconfig{printer}; + $form->{media} = $myconfig{printer}; + $form->{formname} = $form->{type}; + $form->{sortby} ||= "runningnumber"; + $form->{currency} =~ s/ //g; + $form->{oldcurrency} = $form->{currency}; + + if ($form->{id}) { + + for (qw(ordnumber quonumber shippingpoint shipvia notes intnotes shiptoname shiptoaddress1 shiptoaddress2 shiptocity shiptostate shiptozipcode shiptocountry shiptocontact)) { $form->{$_} = $form->quote($form->{$_}) } + + foreach $ref (@{ $form->{form_details} } ) { + $i++; + for (keys %$ref) { $form->{"${_}_$i"} = $ref->{$_} } + + $form->{"projectnumber_$i"} = qq|$ref->{projectnumber}--$ref->{project_id}| if $ref->{project_id}; + $form->{"partsgroup_$i"} = qq|$ref->{partsgroup}--$ref->{partsgroup_id}| if $ref->{partsgroup_id}; + + $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100); + + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + for (map { "${_}_$i" } qw(sellprice listprice)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, $decimalplaces) } + + ($dec) = ($form->{"lastcost_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + $form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces); + + $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); + $form->{"oldqty_$i"} = $form->{"qty_$i"}; + + for (qw(partnumber sku description unit)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + $form->{rowcount} = $i; + } + } + + $form->{oldtransdate} = $form->{transdate}; + + if ($form->{type} eq 'sales_quotation') { + if (! $form->{readonly}) { + $form->{readonly} = 1 if $myconfig{acs} =~ /Quotations--Quotation/; + } + + $form->{selectformname} = qq|<option value="sales_quotation">|.$locale->text('Quotation'); + } + + if ($form->{type} eq 'request_quotation') { + if (! $form->{readonly}) { + $form->{readonly} = 1 if $myconfig{acs} =~ /Quotations--RFQ/; + } + + $form->{selectformname} = qq|<option value="request_quotation">|.$locale->text('RFQ'); + } + + if ($form->{type} eq 'sales_order') { + if (! $form->{readonly}) { + $form->{readonly} = 1 if $myconfig{acs} =~ /Order Entry--Sales Order/; + } + + $form->{selectformname} = qq|<option value="sales_order">|.$locale->text('Sales Order').qq| + <option value="work_order">|.$locale->text('Work Order').qq| + <option value="pick_list">|.$locale->text('Pick List').qq| + <option value="packing_list">|.$locale->text('Packing List'); + } + + if ($form->{type} eq 'purchase_order') { + if (! $form->{readonly}) { + $form->{readonly} = 1 if $myconfig{acs} =~ /Order Entry--Purchase Order/; + } + + $form->{selectformname} = qq|<option value="purchase_order">|.$locale->text('Purchase Order').qq| + <option value="bin_list">|.$locale->text('Bin List'); + } + + if ($form->{type} eq 'ship_order') { + $form->{selectformname} = qq|<option value="pick_list">|.$locale->text('Pick List').qq| + <option value="packing_list">|.$locale->text('Packing List'); + } + + if ($form->{type} eq 'receive_order') { + $form->{selectformname} = qq|<option value="bin_list">|.$locale->text('Bin List'); + } + +} + + +sub form_header { + + $checkedopen = ($form->{closed}) ? "" : "checked"; + $checkedclosed = ($form->{closed}) ? "checked" : ""; + + if ($form->{id}) { + $openclosed = qq| + <tr> + <th nowrap align=right><input name=closed type=radio class=radio value=0 $checkedopen> |.$locale->text('Open').qq|</th> + <th nowrap align=left><input name=closed type=radio class=radio value=1 $checkedclosed> |.$locale->text('Closed').qq|</th> + </tr> +|; + } + + # set option selected + $form->{selectcurrency} =~ s/ selected//; + $form->{selectcurrency} =~ s/option>\Q$form->{currency}\E/option selected>$form->{currency}/; + + for ("$form->{vc}", "department", "employee") { + $form->{"select$_"} = $form->unescape($form->{"select$_"}); + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + + $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate}); + + $exchangerate = qq|<tr>|; + $exchangerate .= qq| + <th align=right nowrap>|.$locale->text('Currency').qq|</th> + <td><select name=currency>$form->{selectcurrency}</select></td> | if $form->{defaultcurrency}; + $exchangerate .= qq| + <input type=hidden name=selectcurrency value="$form->{selectcurrency}"> + <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}> +|; + + if ($form->{defaultcurrency} && $form->{currency} ne $form->{defaultcurrency}) { + if ($form->{forex}) { + $exchangerate .= qq|<th align=right>|.$locale->text('Exchange Rate').qq|</th><td>$form->{exchangerate}</td> + <input type=hidden name=exchangerate value=$form->{exchangerate}> +|; + } else { + $exchangerate .= qq|<th align=right>|.$locale->text('Exchange Rate').qq|</th><td><input name=exchangerate size=10 value=$form->{exchangerate}></td>|; + } + } + $exchangerate .= qq| +<input type=hidden name=forex value=$form->{forex}> +</tr> +|; + + + + $vclabel = ucfirst $form->{vc}; + $vclabel = $locale->text($vclabel); + + $terms = qq| + <tr> + <th align=right nowrap>|.$locale->text('Terms').qq|</th> + <td nowrap><input name=terms size="3" maxlength="3" value=$form->{terms}> |.$locale->text('days').qq|</td> + </tr> +|; + + + if ($form->{business}) { + $business = qq| + <tr> + <th align=right nowrap>|.$locale->text('Business').qq|</th> + <td colspan=3>$form->{business} + |; + $business .= qq| + <b>|.$locale->text('Trade Discount').qq|</b> + |.$form->format_amount(\%myconfig, $form->{tradediscount} * 100).qq| %| if $form->{vc} eq 'customer'; + $business .= qq|</td> + </tr> +|; + } + + if ($form->{type} !~ /_quotation$/) { + $ordnumber = qq| + <tr> + <th width=70% align=right nowrap>|.$locale->text('Order Number').qq|</th> + <td><input name=ordnumber size=20 value="$form->{ordnumber}"></td> + <input type=hidden name=quonumber value="$form->{quonumber}"> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Order Date').qq|</th> + <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td> + </tr> + <tr> + <th align=right nowrap=true>|.$locale->text('Required by').qq|</th> + <td><input name=reqdate size=11 title="$myconfig{dateformat}" value=$form->{reqdate}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('PO Number').qq|</th> + <td><input name=ponumber size=20 value="$form->{ponumber}"></td> + </tr> +|; + + $n = ($form->{creditremaining} < 0) ? "0" : "1"; + + $creditremaining = qq| + <tr> + <td></td> + <td colspan=3> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Credit Limit').qq|</th> + <td>|.$form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0").qq|</td> + <td width=10></td> + <th align=right nowrap>|.$locale->text('Remaining').qq|</th> + <td class="plus$n" nowrap>|.$form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0").qq|</td> + </tr> + </table> + </td> + </tr> +|; + } else { + $reqlabel = ($form->{type} eq 'sales_quotation') ? $locale->text('Valid until') : $locale->text('Required by'); + if ($form->{type} eq 'sales_quotation') { + $ordnumber = qq| + <tr> + <th width=70% align=right nowrap>|.$locale->text('Quotation Number').qq|</th> + <td><input name=quonumber size=20 value="$form->{quonumber}"></td> + <input type=hidden name=ordnumber value="$form->{ordnumber}"> + </tr> +|; + } else { + $ordnumber = qq| + <tr> + <th width=70% align=right nowrap>|.$locale->text('RFQ Number').qq|</th> + <td><input name=quonumber size=20 value="$form->{quonumber}"></td> + <input type=hidden name=ordnumber value="$form->{ordnumber}"> + </tr> +|; + + $terms = ""; + } + + + $ordnumber .= qq| + <tr> + <th align=right nowrap>|.$locale->text('Quotation Date').qq|</th> + <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td> + </tr> + <tr> + <th align=right nowrap=true>$reqlabel</th> + <td><input name=reqdate size=11 title="$myconfig{dateformat}" value=$form->{reqdate}></td> + </tr> +|; + + } + + $ordnumber .= qq| +<input type=hidden name=oldtransdate value=$form->{oldtransdate}>|; + + if ($form->{"select$form->{vc}"}) { + $vc = qq|<select name=$form->{vc}>$form->{"select$form->{vc}"}</select> + <input type=hidden name="select$form->{vc}" value="| + .$form->escape($form->{"select$form->{vc}"},1).qq|">|; + } else { + $vc = qq|<input name=$form->{vc} value="$form->{$form->{vc}}" size=35>|; + } + + $department = qq| + <tr> + <th align="right" nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select> + <input type=hidden name=selectdepartment value="| + .$form->escape($form->{selectdepartment},1).qq|"> + </td> + </tr> +| if $form->{selectdepartment}; + + $employee = qq| + <input type=hidden name=employee value="$form->{employee}"> +|; + + if ($form->{type} eq 'sales_order') { + if ($form->{selectemployee}) { + $employee = qq| + <tr> + <th align=right nowrap>|.$locale->text('Salesperson').qq|</th> + <td><select name=employee>$form->{selectemployee}</select></td> + <input type=hidden name=selectemployee value="|. + $form->escape($form->{selectemployee},1).qq|" + </tr> +|; + } + } else { + if ($form->{selectemployee}) { + $employee = qq| + <tr> + <th align=right nowrap>|.$locale->text('Employee').qq|</th> + <td><select name=employee>$form->{selectemployee}</select></td> + <input type=hidden name=selectemployee value="|. + $form->escape($form->{selectemployee},1).qq|" + </tr> +|; + } + } + + $i = $form->{rowcount} + 1; + $focus = "partnumber_$i"; + + $form->header; + + print qq| +<body onLoad="document.forms[0].${focus}.focus()" /> + +<form method=post action="$form->{script}"> +|; + + $form->hide_form(qw(id type formname media format printed emailed queued vc title discount creditlimit creditremaining tradediscount business recurring)); + + print qq| +<table width=100%> + <tr class=listtop> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width="100%"> + <tr valign=top> + <td> + <table width=100%> + <tr> + <th align=right>$vclabel</th> + <td colspan=3>$vc</td> + <input type=hidden name=$form->{vc}_id value=$form->{"$form->{vc}_id"}> + <input type=hidden name="old$form->{vc}" value="$form->{"old$form->{vc}"}"> + </tr> + $creditremaining + $business + $department + $exchangerate + <tr> + <th align=right>|.$locale->text('Shipping Point').qq|</th> + <td colspan=3><input name=shippingpoint size=35 value="$form->{shippingpoint}"></td> + </tr> + <tr> + <th align=right>|.$locale->text('Ship via').qq|</th> + <td colspan=3><input name=shipvia size=35 value="$form->{shipvia}"></td> + </tr> + </table> + </td> + <td align=right> + <table> + $openclosed + $employee + $ordnumber + $terms + </table> + </td> + </tr> + </table> + </td> + </tr> + +|; + + $form->hide_form(qw(shiptoname shiptoaddress1 shiptoaddress2 shiptocity shiptostate shiptozipcode shiptocountry shiptocontact shiptophone shiptofax shiptoemail message email subject cc bcc taxaccounts)); + + for (split / /, $form->{taxaccounts}) { + print qq| +<input type=hidden name="${_}_rate" value=$form->{"${_}_rate"}> +<input type=hidden name="${_}_description" value="$form->{"${_}_description"}"> +|; + } + +} + + +sub form_footer { + + $form->{invtotal} = $form->{invsubtotal}; + + if (($rows = $form->numtextrows($form->{notes}, 35, 8)) < 2) { + $rows = 2; + } + if (($introws = $form->numtextrows($form->{intnotes}, 35, 8)) < 2) { + $introws = 2; + } + $rows = ($rows > $introws) ? $rows : $introws; + $notes = qq|<textarea name=notes rows=$rows cols=35 wrap=soft>$form->{notes}</textarea>|; + $intnotes = qq|<textarea name=intnotes rows=$rows cols=35 wrap=soft>$form->{intnotes}</textarea>|; + + + $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : ""; + + $taxincluded = ""; + if ($form->{taxaccounts}) { + $taxincluded = qq| + <tr height="5"></tr> + <tr> + <td align=right> + <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td> + <th align=left>|.$locale->text('Tax Included').qq|</th> + </tr> +|; + } + + if (!$form->{taxincluded}) { + + for (split / /, $form->{taxaccounts}) { + if ($form->{"${_}_base"}) { + $form->{invtotal} += $form->{"${_}_total"} = $form->round_amount($form->{"${_}_base"} * $form->{"${_}_rate"}, 2); + $form->{"${_}_total"} = $form->format_amount(\%myconfig, $form->{"${_}_total"}, 2); + + $tax .= qq| + <tr> + <th align=right>$form->{"${_}_description"}</th> + <td align=right>$form->{"${_}_total"}</td> + </tr> +|; + } + } + + $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0); + + $subtotal = qq| + <tr> + <th align=right>|.$locale->text('Subtotal').qq|</th> + <td align=right>$form->{invsubtotal}</td> + </tr> +|; + + } + + $form->{oldinvtotal} = $form->{invtotal}; + $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0); + + + print qq| + <tr> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> + <th align=left>|.$locale->text('Notes').qq|</th> + <th align=left>|.$locale->text('Internal Notes').qq|</th> + </tr> + <tr valign=top> + <td>$notes</td> + <td>$intnotes</td> + </tr> + </table> + </td> + <td align=right> + <table> + $subtotal + $tax + <tr> + <th align=right>|.$locale->text('Total').qq|</th> + <td align=right>$form->{invtotal}</td> + </tr> + $taxincluded + </table> + </td> + </tr> + </table> + </td> + </tr> +<input type=hidden name=oldinvtotal value=$form->{oldinvtotal}> +<input type=hidden name=oldtotalpaid value=$totalpaid> + <tr> + <td><hr size=3 noshade></td> + </tr> + <tr> + <td> +|; + + &print_options; + + print qq| + </td> + </tr> +</table> + +<br> +|; + +# type=submit $locale->text('Update') +# type=submit $locale->text('Print') +# type=submit $locale->text('Schedule') +# type=submit $locale->text('Save') +# type=submit $locale->text('Print and Save') +# type=submit $locale->text('Ship to') +# type=submit $locale->text('Save as new') +# type=submit $locale->text('Print and Save as new') +# type=submit $locale->text('E-mail') +# type=submit $locale->text('Delete') +# type=submit $locale->text('Sales Invoice') +# type=submit $locale->text('Vendor Invoice') +# type=submit $locale->text('Quotation') +# type=submit $locale->text('RFQ') +# type=submit $locale->text('Sales Order') +# type=submit $locale->text('Purchase Order') + + if (! $form->{readonly}) { + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') }, + 'Save' => { ndx => 3, key => 'S', value => $locale->text('Save') }, + 'Ship to' => { ndx => 4, key => 'T', value => $locale->text('Ship to') }, + 'E-mail' => { ndx => 5, key => 'E', value => $locale->text('E-mail') }, + 'Print and Save' => { ndx => 6, key => 'R', value => $locale->text('Print and Save') }, + 'Save as new' => { ndx => 7, key => 'N', value => $locale->text('Save as new') }, + 'Print and Save as new' => { ndx => 8, key => 'W', value => $locale->text('Print and Save as new') }, + 'Sales Invoice' => { ndx => 9, key => 'I', value => $locale->text('Sales Invoice') }, + 'Sales Order' => { ndx => 10, key => 'O', value => $locale->text('Sales Order') }, + 'Quotation' => { ndx => 11, key => 'Q', value => $locale->text('Quotation') }, + 'Vendor Invoice' => { ndx => 12, key => 'I', value => $locale->text('Vendor Invoice') }, + 'Purchase Order' => { ndx => 13, key => 'O', value => $locale->text('Purchase Order') }, + 'RFQ' => { ndx => 14, key => 'Q', value => $locale->text('RFQ') }, + 'Schedule' => { ndx => 15, key => 'H', value => $locale->text('Schedule') }, + 'Delete' => { ndx => 16, key => 'D', value => $locale->text('Delete') }, + ); + + + %a = (); + for ("Update", "Ship to", "Print", "E-mail", "Save") { $a{$_} = 1 } + $a{'Print and Save'} = 1 if $latex; + + if ($form->{id}) { + + $a{'Delete'} = 1; + $a{'Save as new'} = 1; + $a{'Print and Save as new'} = 1 if $latex; + + if ($form->{type} =~ /sales_/) { + if ($myconfig{acs} !~ /AR--Sales Invoice/) { + $a{'Sales Invoice'} = 1; + } + } else { + if ($myconfig{acs} !~ /AP--Vendor Invoice/) { + $a{'Vendor Invoice'} = 1; + } + } + + if ($form->{type} eq 'sales_order') { + if ($myconfig{acs} !~ /Quotations--RFQ/) { + $a{'Quotation'} = 1; + } + } + + if ($form->{type} eq 'purchase_order') { + if ($myconfig{acs} !~ /Quotations--RFQ/) { + $a{'RFQ'} = 1; + } + } + + if ($form->{type} eq 'sales_quotation') { + if ($myconfig{acs} !~ /Order Entry--Sales Order/) { + $a{'Sales Order'} = 1; + } + } + + if ($myconfig{acs} !~ /Order Entry--Purchase Order/) { + if ($form->{type} eq 'request_quotation') { + $a{'Purchase Order'} = 1; + } + } + } + + if ($form->{type} =~ /_order/) { + $a{'Schedule'} = 1; + } + + } + + for (keys %button) { delete $button{$_} if ! $a{$_} } + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + $form->hide_form(qw(rowcount callback path login sessionid)); + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub update { + + if ($form->{type} eq 'generate_purchase_order') { + + for (1 .. $form->{rowcount}) { + if ($form->{"ndx_$_"}) { + $form->{"$form->{vc}_id_$_"} = $form->{"$form->{vc}_id"}; + $form->{"$form->{vc}_$_"} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|; + } + } + + &po_orderitems; + exit; + } + + $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate}); + + if ($form->{vc} eq 'customer') { + $buysell = "buy"; + $ARAP = "AR"; + } else { + $buysell = "sell"; + $ARAP = "AP"; + } + + if ($newname = &check_name($form->{vc})) { + &rebuild_vc($form->{vc}, $ARAP, $form->{transdate}, 1); + } + + if ($form->{transdate} ne $form->{oldtransdate}) { + $form->{reqdate} = ($form->{terms}) ? $form->current_date(\%myconfig, $form->{transdate}, $form->{terms} * 1) : $form->{reqdate}; + $form->{oldtransdate} = $form->{transdate}; + &rebuild_vc($form->{vc}, $ARAP, $form->{transdate}, 1) if ! $newname; + + if ($form->{currency} ne $form->{defaultcurrency}) { + delete $form->{exchangerate}; + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, $buysell))); + } + + $form->{selectemployee} = ""; + if (@{ $form->{all_employee} }) { + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + } + + + if ($form->{currency} ne $form->{oldcurrency}) { + delete $form->{exchangerate}; + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, $buysell))); + } + + my $i = $form->{rowcount}; + $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1; + + for (qw(partsgroup projectnumber)) { + $form->{"select$_"} = $form->unescape($form->{"select$_"}) if $form->{"select$_"}; + } + + if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) { + + $form->{creditremaining} += ($form->{oldinvtotal} - $form->{oldtotalpaid}); + &check_form; + + } else { + + $retrieve_item = ""; + if ($form->{type} eq 'purchase_order' || $form->{type} eq 'request_quotation') { + $retrieve_item = "IR::retrieve_item"; + } + if ($form->{type} eq 'sales_order' || $form->{type} eq 'sales_quotation') { + $retrieve_item = "IS::retrieve_item"; + } + + &{ "$retrieve_item" }("", \%myconfig, \%$form); + + $rows = scalar @{ $form->{item_list} }; + + if ($form->{language_code} && $rows == 0) { + $language_code = $form->{language_code}; + $form->{language_code} = ""; + if ($retrieve_item) { + &{ "$retrieve_item" }("", \%myconfig, \%$form); + } + $form->{language_code} = $language_code; + $rows = scalar @{ $form->{item_list} }; + } + + if ($rows) { + + if ($rows > 1) { + + &select_item; + exit; + + } else { + + $form->{"qty_$i"} = ($form->{"qty_$i"} * 1) ? $form->{"qty_$i"} : 1; + $form->{"reqdate_$i"} = $form->{reqdate} if $form->{type} ne 'sales_quotation'; + $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"}); + + for (qw(partnumber description unit)) { $form->{item_list}[$i]{$_} = $form->quote($form->{item_list}[$i]{$_}) } + for (keys %{ $form->{item_list}[0] }) { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } + + $form->{"discount_$i"} = $form->{discount} * 100; + + if ($sellprice) { + $form->{"sellprice_$i"} = $sellprice; + + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces1 = ($dec > 2) ? $dec : 2; + } else { + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces1 = ($dec > 2) ? $dec : 2; + + $form->{"sellprice_$i"} /= $exchangerate; + } + + ($dec) = ($form->{"lastcost_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces2 = ($dec > 2) ? $dec : 2; + + for (qw(listprice lastcost)) { $form->{"${_}_$i"} /= $exchangerate } + + $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100); + for (split / /, $form->{taxaccounts}) { $form->{"${_}_base"} = 0 } + for (split / /, $form->{"taxaccounts_$i"}) { $form->{"${_}_base"} += $amount } + if (!$form->{taxincluded}) { + for (split / /, $form->{taxaccounts}) { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } + } + + $form->{creditremaining} -= $amount; + + for (qw(sellprice listprice)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces1) } + $form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces2); + + $form->{"oldqty_$i"} = $form->{"qty_$i"}; + for (qw(qty discount)) { $form->{"{_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}) } + + } + + &display_form; + + } else { + # ok, so this is a new part + # ask if it is a part or service item + + if ($form->{"partsgroup_$i"} && ($form->{"partsnumber_$i"} eq "") && ($form->{"description_$i"} eq "")) { + $form->{rowcount}--; + &display_form; + } else { + + $form->{"id_$i"} = 0; + $form->{"unit_$i"} = $locale->text('ea'); + &new_item; + + } + } + } + +} + + + +sub search { + + $requiredby = $locale->text('Required by'); + + if ($form->{type} eq 'purchase_order') { + $form->{title} = $locale->text('Purchase Orders'); + $form->{vc} = 'vendor'; + $ordlabel = $locale->text('Order Number'); + $ordnumber = 'ordnumber'; + $employee = $locale->text('Employee'); + } + + if ($form->{type} eq 'receive_order') { + $form->{title} = $locale->text('Receive Merchandise'); + $form->{vc} = 'vendor'; + $ordlabel = $locale->text('Order Number'); + $ordnumber = 'ordnumber'; + $employee = $locale->text('Employee'); + } + + if ($form->{type} eq 'generate_sales_order') { + $form->{title} = $locale->text('Generate Sales Order from Purchase Orders'); + $form->{vc} = 'vendor'; + $ordlabel = $locale->text('Order Number'); + $ordnumber = 'ordnumber'; + $employee = $locale->text('Employee'); + } + + if ($form->{type} eq 'consolidate_sales_order') { + $form->{title} = $locale->text('Consolidate Sales Orders'); + $form->{vc} = 'customer'; + $ordlabel = $locale->text('Order Number'); + $ordnumber = 'ordnumber'; + $employee = $locale->text('Salesperson'); + } + + if ($form->{type} eq 'request_quotation') { + $form->{title} = $locale->text('Request for Quotations'); + $form->{vc} = 'vendor'; + $ordlabel = $locale->text('RFQ Number'); + $ordnumber = 'quonumber'; + $employee = $locale->text('Employee'); + } + + if ($form->{type} eq 'sales_order') { + $form->{title} = $locale->text('Sales Orders'); + $form->{vc} = 'customer'; + $ordlabel = $locale->text('Order Number'); + $ordnumber = 'ordnumber'; + $employee = $locale->text('Salesperson'); + } + + if ($form->{type} eq 'ship_order') { + $form->{title} = $locale->text('Ship Merchandise'); + $form->{vc} = 'customer'; + $ordlabel = $locale->text('Order Number'); + $ordnumber = 'ordnumber'; + $employee = $locale->text('Salesperson'); + } + + if ($form->{type} eq 'sales_quotation') { + $form->{title} = $locale->text('Quotations'); + $form->{vc} = 'customer'; + $ordlabel = $locale->text('Quotation Number'); + $ordnumber = 'quonumber'; + $employee = $locale->text('Employee'); + $requiredby = $locale->text('Valid until'); + } + + if ($form->{type} eq 'generate_purchase_order') { + $form->{title} = $locale->text('Generate Purchase Orders from Sales Order'); + $form->{vc} = 'customer'; + $ordlabel = $locale->text('Order Number'); + $ordnumber = 'ordnumber'; + $employee = $locale->text('Salesperson'); + } + + if ($form->{type} eq 'consolidate_purchase_order') { + $form->{title} = $locale->text('Consolidate Purchase Orders'); + $form->{vc} = 'vendor'; + $ordlabel = $locale->text('Order Number'); + $ordnumber = 'ordnumber'; + $employee = $locale->text('Employee'); + } + + $l_employee = qq|<input name="l_employee" class=checkbox type=checkbox value=Y> $employee|; + $l_manager = qq|<input name="l_manager" class=checkbox type=checkbox value=Y> |.$locale->text('Manager'); + + if ($form->{type} =~ /(ship|receive)_order/) { + OE->get_warehouses(\%myconfig, \%$form); + + $l_manager = ""; + + # warehouse + if (@{ $form->{all_warehouse} }) { + $form->{selectwarehouse} = "<option>\n"; + $form->{warehouse} = qq|$form->{warehouse}--$form->{warehouse_id}|; + + for (@{ $form->{all_warehouse} }) { $form->{selectwarehouse} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + + $warehouse = qq| + <tr> + <th align=right>|.$locale->text('Warehouse').qq|</th> + <td><select name=warehouse>$form->{selectwarehouse}</select></td> + <input type=hidden name=selectwarehouse value="|. + $form->escape($form->{selectwarehouse},1).qq|"> + </tr> +|; + + } + } + + # setup vendor / customer selection + $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP"); + + for (@{ $form->{"all_$form->{vc}"} }) { $vc .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + + $selectemployee = ""; + if (@{ $form->{all_employee} }) { + $selectemployee = "<option>\n"; + for (@{ $form->{all_employee} }) { $selectemployee .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + + $selectemployee = qq| + <tr> + <th align=right>$employee</th> + <td colspan=3><select name=employee>$selectemployee</select></td> + </tr> +|; + } else { + $l_employee = $l_manager = ""; + } + + $vclabel = ucfirst $form->{vc}; + $vclabel = $locale->text($vclabel); + +# $locale->text('Vendor') +# $locale->text('Customer') + + $vc = ($vc) ? qq|<select name=$form->{vc}><option>\n$vc</select>| : qq|<input name=$form->{vc} size=35>|; + + # departments + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + $department = qq| + <tr> + <th align=right nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select></td> + </tr> +| if $form->{selectdepartment}; + + if ($form->{type} =~ /(consolidate.*|generate.*|ship|receive)_order/) { + + $openclosed = qq| + <input type=hidden name="open" value=1> +|; + + } else { + + $openclosed = qq| + <tr> + <td nowrap><input name="open" class=checkbox type=checkbox value=1 checked> |.$locale->text('Open').qq|</td> + <td nowrap><input name="closed" class=checkbox type=checkbox value=1 $form->{closed}> |.$locale->text('Closed').qq|</td> + </tr> +|; + } + + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + if ($form->{type} =~ /_order/) { + $ponumber = qq| + <tr> + <th align=right>|.$locale->text('PO Number').qq|</th> + <td colspan=3><input name="ponumber" size=20></td> + </tr> +|; + + + $l_ponumber = qq|<input name="l_ponumber" class=checkbox type=checkbox value=Y> |.$locale->text('PO Number'); + } + + @a = (); + push @a, qq|<input name="l_runningnumber" class=checkbox type=checkbox value=Y> |.$locale->text('No.'); + push @a, qq|<input name="l_id" class=checkbox type=checkbox value=Y> |.$locale->text('ID'); + push @a, qq|<input name="l_$ordnumber" class=checkbox type=checkbox value=Y checked> $ordlabel|; + push @a, qq|<input name="l_transdate" class=checkbox type=checkbox value=Y checked> |.$locale->text('Date'); + push @a, $l_ponumber if $l_ponumber; + push @a, qq|<input name="l_reqdate" class=checkbox type=checkbox value=Y checked> $requiredby|; + push @a, qq|<input name="l_name" class=checkbox type=checkbox value=Y checked> $vclabel|; + push @a, $l_employee if $l_employee; + push @a, $l_manager if $l_manager; + push @a, qq|<input name="l_shipvia" class=checkbox type=checkbox value=Y> |.$locale->text('Ship via'); + push @a, qq|<input name="l_netamount" class=checkbox type=checkbox value=Y> |.$locale->text('Amount'); + push @a, qq|<input name="l_tax" class=checkbox type=checkbox value=Y> |.$locale->text('Tax'); + push @a, qq|<input name="l_amount" class=checkbox type=checkbox value=Y checked> |.$locale->text('Total'); + push @a, qq|<input name="l_curr" class=checkbox type=checkbox value=Y checked> |.$locale->text('Currency'); + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>$vclabel</th> + <td colspan=3>$vc</td> + </tr> + $warehouse + $department + $selectemployee + <tr> + <th align=right>$ordlabel</th> + <td colspan=3><input name="$ordnumber" size=20></td> + </tr> + $ponumber + <tr> + <th align=right>|.$locale->text('Ship via').qq|</th> + <td colspan=3><input name="shipvia" size=40></td> + </tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td colspan=3><input name="description" size=40></td> + </tr> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + <input type=hidden name=sort value=transdate> + $selectfrom + <tr> + <th align=right>|.$locale->text('Include in Report').qq|</th> + <td colspan=3> + <table> + $openclosed +|; + + while (@a) { + for (1 .. 5) { + print qq|<td nowrap>|. shift @a; + print qq|</td>\n|; + } + print qq|</tr>\n|; + } + + print qq| + <tr> + <td><input name="l_subtotal" class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq|</td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr><td colspan=4><hr size=3 noshade></td></tr> +</table> + +<br> +<input type=hidden name=nextsub value=transactions> +|; + + $form->hide_form(qw(path login sessionid vc type)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub transactions { + + # split vendor / customer + ($form->{$form->{vc}}, $form->{"$form->{vc}_id"}) = split(/--/, $form->{$form->{vc}}); + + OE->transactions(\%myconfig, \%$form); + + $ordnumber = ($form->{type} =~ /_order/) ? 'ordnumber' : 'quonumber'; + $name = $form->escape($form->{$form->{vc}}); + $name .= qq|--$form->{"$form->{vc}_id"}| if $form->{"$form->{vc}_id"}; + + # construct href + $href = qq|$form->{script}?action=transactions|; + for ("oldsort", "direction", "path", "type", "vc", "login", "sessionid", "transdatefrom", "transdateto", "open", "closed") { $href .= qq|&$_=$form->{$_}| } + for ("$ordnumber", "department", "warehouse", "shipvia", "ponumber", "description", "employee") { $href .= qq|&$_=|.$form->escape($form->{$_}) } + $href .= "&$form->{vc}=$name"; + + # construct callback + $name = $form->escape($form->{$form->{vc}},1); + $name .= qq|--$form->{"$form->{vc}_id"}| if $form->{"$form->{vc}_id"}; + + # flip direction + $form->sort_order(); + + $callback = qq|$form->{script}?action=transactions|; + for ("oldsort", "direction", "path", "type", "vc", "login", "sessionid", "transdatefrom", "transdateto", "open", "closed") { $callback .= qq|&$_=$form->{$_}| } + for ("$ordnumber", "department", "warehouse", "shipvia", "ponumber", "description", "employee") { $callback .= qq|&$_=|.$form->escape($form->{$_},1) } + $callback .= "&$form->{vc}=$name"; + + + @columns = $form->sort_columns("transdate", "reqdate", "id", "$ordnumber", "ponumber", "name", "netamount", "tax", "amount", "curr", "employee", "manager", "shipvia", "open", "closed"); + unshift @columns, "runningnumber"; + + $form->{l_open} = $form->{l_closed} = "Y" if ($form->{open} && $form->{closed}) ; + + for (@columns) { + if ($form->{"l_$_"} eq "Y") { + push @column_index, $_; + + if ($form->{l_curr} && $_ =~ /(amount|tax)/) { + push @column_index, "fx_$_"; + } + + # add column to href and callback + $callback .= "&l_$_=Y"; + $href .= "&l_$_=Y"; + } + } + + if ($form->{l_subtotal} eq 'Y') { + $callback .= "&l_subtotal=Y"; + $href .= "&l_subtotal=Y"; + } + + $requiredby = $locale->text('Required by'); + + $i = 1; + if ($form->{vc} eq 'vendor') { + if ($form->{type} eq 'receive_order') { + $form->{title} = $locale->text('Receive Merchandise'); + } + if ($form->{type} eq 'purchase_order') { + $form->{title} = $locale->text('Purchase Orders'); + if ($myconfig{acs} !~ /Order Entry--Order Entry/) { + $button{'Order Entry--Purchase Order'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Purchase Order').qq|"> |; + $button{'Order Entry--Purchase Order'}{order} = $i++; + } + } + if ($form->{type} eq 'generate_sales_order') { + $form->{title} = $locale->text('Purchase Orders'); + $form->{type} = "purchase_order"; + unshift @column_index, "ndx"; + if ($myconfig{acs} !~ /Order Entry--Order Entry/) { + $button{'Order Entry--Sales Order'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Generate Sales Order').qq|"> |; + $button{'Order Entry--Sales Order'}{order} = $i++; + } + } + if ($form->{type} eq 'consolidate_purchase_order') { + $form->{title} = $locale->text('Purchase Orders'); + $form->{type} = "purchase_order"; + unshift @column_index, "ndx"; + if ($myconfig{acs} !~ /Order Entry--Order Entry/) { + $button{'Order Entry--Purchase Order'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Consolidate Orders').qq|"> |; + $button{'Order Entry--Purchase Order'}{order} = $i++; + } + } + + if ($form->{type} eq 'request_quotation') { + $form->{title} = $locale->text('Request for Quotations'); + $quotation = $locale->text('RFQ'); + + if ($myconfig{acs} !~ /Quotations--Quotations/) { + $button{'Quotations--RFQ'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('RFQ ').qq|"> |; + $button{'Quotations--RFQ'}{order} = $i++; + } + + } + $name = $locale->text('Vendor'); + $employee = $locale->text('Employee'); + } + if ($form->{vc} eq 'customer') { + if ($form->{type} eq 'sales_order') { + $form->{title} = $locale->text('Sales Orders'); + $employee = $locale->text('Salesperson'); + + if ($myconfig{acs} !~ /Order Entry--Order Entry/) { + $button{'Order Entry--Sales Order'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Sales Order').qq|"> |; + $button{'Order Entry--Sales Order'}{order} = $i++; + } + + } + if ($form->{type} eq 'generate_purchase_order') { + $form->{title} = $locale->text('Sales Orders'); + $form->{type} = "sales_order"; + $employee = $locale->text('Salesperson'); + unshift @column_index, "ndx"; + if ($myconfig{acs} !~ /Order Entry--Order Entry/) { + $button{'Order Entry--Purchase Order'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Generate Purchase Orders').qq|"> |; + $button{'Order Entry--Purchase Order'}{order} = $i++; + } + } + if ($form->{type} eq 'consolidate_sales_order') { + $form->{title} = $locale->text('Sales Orders'); + $form->{type} = "sales_order"; + unshift @column_index, "ndx"; + if ($myconfig{acs} !~ /Order Entry--Order Entry/) { + $button{'Order Entry--Sales Order'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Consolidate Orders').qq|"> |; + $button{'Order Entry--Sales Order'}{order} = $i++; + } + } + + if ($form->{type} eq 'ship_order') { + $form->{title} = $locale->text('Ship Merchandise'); + $employee = $locale->text('Salesperson'); + } + if ($form->{type} eq 'sales_quotation') { + $form->{title} = $locale->text('Quotations'); + $employee = $locale->text('Employee'); + $requiredby = $locale->text('Valid until'); + $quotation = $locale->text('Quotation'); + + if ($myconfig{acs} !~ /Quotations--Quotations/) { + $button{'Quotations--Quotation'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Quotation ').qq|"> |; + $button{'Quotations--Quotation'}{order} = $i++; + } + + } + $name = $locale->text('Customer'); + } + + for (split /;/, $myconfig{acs}) { delete $button{$_} } + + $column_header{ndx} = qq|<th class=listheading> </th>|; + $column_header{runningnumber} = qq|<th class=listheading> </th>|; + $column_header{id} = qq|<th><a class=listheading href=$href&sort=id>|.$locale->text('ID').qq|</a></th>|; + $column_header{transdate} = qq|<th><a class=listheading href=$href&sort=transdate>|.$locale->text('Date').qq|</a></th>|; + $column_header{reqdate} = qq|<th><a class=listheading href=$href&sort=reqdate>$requiredby</a></th>|; + $column_header{ordnumber} = qq|<th><a class=listheading href=$href&sort=ordnumber>|.$locale->text('Order').qq|</a></th>|; + $column_header{ponumber} = qq|<th><a class=listheading href=$href&sort=ponumber>|.$locale->text('PO Number').qq|</a></th>|; + $column_header{quonumber} = qq|<th><a class=listheading href=$href&sort=quonumber>$quotation</a></th>|; + $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>$name</a></th>|; + $column_header{netamount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|; + $column_header{tax} = qq|<th class=listheading>|.$locale->text('Tax').qq|</th>|; + $column_header{amount} = qq|<th class=listheading>|.$locale->text('Total').qq|</th>|; + $column_header{curr} = qq|<th><a class=listheading href=$href&sort=curr>|.$locale->text('Curr').qq|</a></th>|; + $column_header{shipvia} = qq|<th><a class=listheading href=$href&sort=shipvia>|.$locale->text('Ship via').qq|</a></th>|; + $column_header{open} = qq|<th class=listheading>|.$locale->text('O').qq|</th>|; + $column_header{closed} = qq|<th class=listheading>|.$locale->text('C').qq|</th>|; + + $column_header{employee} = qq|<th><a class=listheading href=$href&sort=employee>$employee</a></th>|; + $column_header{manager} = qq|<th><a class=listheading href=$href&sort=manager>|.$locale->text('Manager').qq|</a></th>|; + + for (qw(amount tax netamount)) { $column_header{"fx_$_"} = "<th> </th>" } + + if ($form->{$form->{vc}}) { + $option = $locale->text(ucfirst $form->{vc}); + $option .= " : $form->{$form->{vc}}"; + } + if ($form->{warehouse}) { + ($warehouse) = split /--/, $form->{warehouse}; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Warehouse'); + $option .= " : $warehouse"; + } + if ($form->{department}) { + $option .= "\n<br>" if ($option); + ($department) = split /--/, $form->{department}; + $option .= $locale->text('Department')." : $department"; + } + if ($form->{employee}) { + ($employee) = split /--/, $form->{employee}; + $option .= "\n<br>" if ($option); + if ($form->{vc} eq 'customer') { + $option .= $locale->text('Salesperson'); + } else { + $option .= $locale->text('Employee'); + } + $option .= " : $employee"; + } + if ($form->{ordnumber}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('Order Number')." : $form->{ordnumber}"; + } + if ($form->{quonumber}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('Quotation Number')." : $form->{quonumber}"; + } + if ($form->{ponumber}) { + $option = $locale->text('PO Number'); + $option .= " : $form->{ponumber}"; + } + if ($form->{shipvia}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('Ship via')." : $form->{shipvia}"; + } + if ($form->{description}) { + $option .= "\n<br>" if $option; + $option .= $locale->text('Description')." : $form->{description}"; + } + if ($form->{transdatefrom}) { + $option .= "\n<br>".$locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1); + } + if ($form->{transdateto}) { + $option .= "\n<br>".$locale->text('To')." ".$locale->date(\%myconfig, $form->{transdateto}, 1); + } + if ($form->{open}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('Open'); + } + if ($form->{closed}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('Closed'); + } + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + # add sort and escape callback + $callback .= "&sort=$form->{sort}"; + $form->{callback} = $callback; + $callback = $form->escape($callback); + + # flip direction + $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC"; + $href =~ s/&direction=(\w+)&/&direction=$direction&/; + + if (@{ $form->{OE} }) { + $sameitem = $form->{OE}->[0]->{$form->{sort}}; + } + + $action = "edit"; + $action = "ship_receive" if ($form->{type} =~ /(ship|receive)_order/); + + $warehouse = $form->escape($form->{warehouse}); + + $i = 0; + foreach $oe (@{ $form->{OE} }) { + + $i++; + + if ($form->{l_subtotal} eq 'Y') { + if ($sameitem ne $oe->{$form->{sort}}) { + &subtotal; + $sameitem = $oe->{$form->{sort}}; + } + } + + if ($form->{l_curr}) { + for (qw(netamount amount)) { $oe->{"fx_$_"} = $oe->{$_} } + $oe->{fx_tax} = $oe->{fx_amount} - $oe->{fx_netamount}; + for (qw(netamount amount)) { $oe->{$_} *= $oe->{exchangerate} } + + for (qw(netamount amount)) { $column_data{"fx_$_"} = "<td align=right>".$form->format_amount(\%myconfig, $oe->{"fx_$_"}, 2, " ")."</td>" } + $column_data{fx_tax} = "<td align=right>".$form->format_amount(\%myconfig, $oe->{fx_amount} - $oe->{fx_netamount}, 2, " ")."</td>"; + + $totalfxnetamount += $oe->{fx_netamount}; + $totalfxamount += $oe->{fx_amount}; + + $subtotalfxnetamount += $oe->{fx_netamount}; + $subtotalfxamount += $oe->{fx_amount}; + } + + for (qw(netamount amount)) { $column_data{$_} = "<td align=right>".$form->format_amount(\%myconfig, $oe->{$_}, 2, " ")."</td>" } + $column_data{tax} = "<td align=right>".$form->format_amount(\%myconfig, $oe->{amount} - $oe->{netamount}, 2, " ")."</td>"; + + $totalnetamount += $oe->{netamount}; + $totalamount += $oe->{amount}; + + $subtotalnetamount += $oe->{netamount}; + $subtotalamount += $oe->{amount}; + + + $column_data{id} = "<td>$oe->{id}</td>"; + $column_data{transdate} = "<td>$oe->{transdate} </td>"; + $column_data{reqdate} = "<td>$oe->{reqdate} </td>"; + + $column_data{runningnumber} = qq|<td align=right>$i</td>|; + $column_data{ndx} = qq|<td><input name="ndx_$i" class=checkbox type=checkbox value=$oe->{id} checked></td>|; + $column_data{$ordnumber} = "<td><a href=$form->{script}?path=$form->{path}&action=$action&type=$form->{type}&id=$oe->{id}&warehouse=$warehouse&vc=$form->{vc}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$oe->{$ordnumber}</a></td>"; + + $name = $form->escape($oe->{name}); + $column_data{name} = qq|<td><a href=ct.pl?path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&action=edit&id=$oe->{"$form->{vc}_id"}&db=$form->{vc}&callback=$callback>$oe->{name}</a></td>|; + + for (qw(employee manager shipvia curr ponumber)) { $column_data{$_} = "<td>$oe->{$_} </td>" } + + if ($oe->{closed}) { + $column_data{closed} = "<td align=center>*</td>"; + $column_data{open} = "<td> </td>"; + } else { + $column_data{closed} = "<td> </td>"; + $column_data{open} = "<td align=center>*</td>"; + } + + $j++; $j %= 2; + print " + <tr class=listrow$j>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + } + + if ($form->{l_subtotal} eq 'Y') { + &subtotal; + } + + # print totals + print qq| + <tr class=listtotal>|; + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{netamount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalnetamount, 2, " ")."</th>"; + $column_data{tax} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount - $totalnetamount, 2, " ")."</th>"; + $column_data{amount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount, 2, " ")."</th>"; + + if ($form->{l_curr} && $form->{sort} eq 'curr' && $form->{l_subtotal}) { + $column_data{fx_netamount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalfxnetamount, 2, " ")."</th>"; + $column_data{fx_tax} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalfxamount - $totalfxnetamount, 2, " ")."</th>"; + $column_data{fx_amount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalfxamount, 2, " ")."</th>"; + } + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> + </td> + </table> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +|; + + $form->hide_form(qw(callback type vc path login sessionid department ordnumber ponumber shipvia)); + + print qq| + +<input type=hidden name=rowcount value=$i> + +<input type=hidden name=$form->{vc} value="$form->{$form->{vc}}"> +<input type=hidden name="$form->{vc}_id" value=$form->{"$form->{vc}_id"}> + +|; + + if ($form->{type} !~ /(ship|receive)_order/) { + for (sort { $a->{order} <=> $b->{order} } %button) { print $_->{code} } + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + + +sub subtotal { + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{netamount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalnetamount, 2, " ")."</th>"; + $column_data{tax} = "<td class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount - $subtotalnetamount, 2, " ")."</th>"; + $column_data{amount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount, 2, " ")."</th>"; + + if ($form->{l_curr} && $form->{sort} eq 'curr' && $form->{l_subtotal}) { + $column_data{fx_netamount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalfxnetamount, 2, " ")."</th>"; + $column_data{fx_tax} = "<td class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalfxamount - $subtotalfxnetamount, 2, " ")."</th>"; + $column_data{fx_amount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalfxamount, 2, " ")."</th>"; + } + + $subtotalnetamount = 0; + $subtotalamount = 0; + + $subtotalfxnetamount = 0; + $subtotalfxamount = 0; + + print " + <tr class=listsubtotal> +"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + +} + + +sub save { + + if ($form->{type} =~ /_order$/) { + $msg = $locale->text('Order Date missing!'); + } else { + $msg = $locale->text('Quotation Date missing!'); + } + + $form->isblank("transdate", $msg); + + $msg = ucfirst $form->{vc}; + $form->isblank($form->{vc}, $locale->text($msg . " missing!")); + +# $locale->text('Customer missing!'); +# $locale->text('Vendor missing!'); + + $form->isblank("exchangerate", $locale->text('Exchange rate missing!')) if ($form->{currency} ne $form->{defaultcurrency}); + + &validate_items; + + # if the name changed get new values + if (&check_name($form->{vc})) { + &update; + exit; + } + + + # this is for the internal notes section for the [email] Subject + if ($form->{type} =~ /_order$/) { + if ($form->{type} eq 'sales_order') { + $form->{label} = $locale->text('Sales Order'); + + $numberfld = "sonumber"; + $ordnumber = "ordnumber"; + } else { + $form->{label} = $locale->text('Purchase Order'); + + $numberfld = "ponumber"; + $ordnumber = "ordnumber"; + } + + $err = $locale->text('Cannot save order!'); + + } else { + if ($form->{type} eq 'sales_quotation') { + $form->{label} = $locale->text('Quotation'); + + $numberfld = "sqnumber"; + $ordnumber = "quonumber"; + } else { + $form->{label} = $locale->text('Request for Quotation'); + + $numberfld = "rfqnumber"; + $ordnumber = "quonumber"; + } + + $err = $locale->text('Cannot save quotation!'); + + } + + if (! $form->{repost}) { + if ($form->{id}) { + &repost("Save"); + exit; + } + } + + if (OE->save(\%myconfig, \%$form)) { + $form->redirect($locale->text('Order saved!')); + } else { + $form->error($err); + } + +} + + +sub print_and_save { + + $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/; + $form->error($locale->text('Select a Printer!')) if $form->{media} eq 'screen'; + + $old_form = new Form; + $form->{display_form} = "save"; + for (keys %$form) { $old_form->{$_} = $form->{$_} } + $old_form->{rowcount}++; + + &print_form($old_form); + +} + + +sub delete { + + $form->header; + + if ($form->{type} =~ /_order$/) { + $msg = $locale->text('Are you sure you want to delete Order Number'); + $ordnumber = 'ordnumber'; + } else { + $msg = $locale->text('Are you sure you want to delete Quotation Number'); + $ordnumber = 'quonumber'; + } + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->{action} = "yes"; + $form->hide_form; + + print qq| +<h2 class=confirm>|.$locale->text('Confirm!').qq|</h2> + +<h4>$msg $form->{$ordnumber}</h4> +<p> +<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|"> +</form> + +</body> +</html> +|; + + +} + + + +sub yes { + + if ($form->{type} =~ /_order$/) { + $msg = $locale->text('Order deleted!'); + $err = $locale->text('Cannot delete order!'); + } else { + $msg = $locale->text('Quotation deleted!'); + $err = $locale->text('Cannot delete quotation!'); + } + + if (OE->delete(\%myconfig, \%$form, $spool)) { + $form->redirect($msg); + } else { + $form->error($err); + } + +} + + +sub vendor_invoice { &invoice }; +sub sales_invoice { &invoice }; + +sub invoice { + + if ($form->{type} =~ /_order$/) { + $form->isblank("ordnumber", $locale->text('Order Number missing!')); + $form->isblank("transdate", $locale->text('Order Date missing!')); + + } else { + $form->isblank("quonumber", $locale->text('Quotation Number missing!')); + $form->isblank("transdate", $locale->text('Quotation Date missing!')); + $form->{ordnumber} = ""; + } + + # if the name changed get new values + if (&check_name($form->{vc})) { + &update; + exit; + } + + + if ($form->{type} =~ /_order/ && $form->{currency} ne $form->{defaultcurrency}) { + # check if we need a new exchangerate + $buysell = ($form->{type} eq 'sales_order') ? "buy" : "sell"; + + $orddate = $form->current_date(\%myconfig); + $exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $orddate, $buysell); + + if (!$exchangerate) { + &backorder_exchangerate($orddate, $buysell); + exit; + } + } + + + # close orders/quotations + $form->{closed} = 1; + + OE->save(\%myconfig, \%$form); + + $form->{transdate} = $form->current_date(\%myconfig); + $form->{duedate} = $form->current_date(\%myconfig, $form->{transdate}, $form->{terms} * 1); + + $form->{id} = ''; + $form->{closed} = 0; + $form->{rowcount}--; + $form->{shipto} = 1; + + + if ($form->{type} =~ /_order$/) { + $form->{exchangerate} = $exchangerate; + &create_backorder; + } + + + if ($form->{type} eq 'purchase_order' || $form->{type} eq 'request_quotation') { + $form->{title} = $locale->text('Add Vendor Invoice'); + $form->{script} = 'ir.pl'; + + $script = "ir"; + $buysell = 'sell'; + } + if ($form->{type} eq 'sales_order' || $form->{type} eq 'sales_quotation') { + $form->{title} = $locale->text('Add Sales Invoice'); + $form->{script} = 'is.pl'; + $script = "is"; + $buysell = 'buy'; + } + + for (qw(id subject message cc bcc printed emailed queued)) { delete $form->{$_} } + $form->{$form->{vc}} =~ s/--.*//g; + $form->{type} = "invoice"; + + # locale messages + $locale = new Locale "$myconfig{countrycode}", "$script"; + + require "$form->{path}/$form->{script}"; + + # customized scripts + if (-f "$form->{path}/custom_$form->{script}") { + eval { require "$form->{path}/custom_$form->{script}"; }; + } + + # customized scripts for login + if (-f "$form->{path}/$form->{login}_$form->{script}") { + eval { require "$form->{path}/$form->{login}_$form->{script}"; }; + } + + for ("$form->{vc}", "currency") { $form->{"select$_"} = "" } + for (qw(currency oldcurrency employee department intnotes notes taxincluded)) { $temp{$_} = $form->{$_} } + + &invoice_links; + + $form->{creditremaining} -= ($form->{oldinvtotal} - $form->{ordtotal}); + + &prepare_invoice; + + for (keys %temp) { $form->{$_} = $temp{$_} } + + $form->{exchangerate} = ""; + $form->{forex} = ""; + $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, $buysell))); + + for $i (1 .. $form->{rowcount}) { + $form->{"deliverydate_$i"} = $form->{"reqdate_$i"}; + for (qw(qty sellprice discount)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}) } + } + + for (qw(id subject message cc bcc printed emailed queued audittrail)) { delete $form->{$_} } + + &display_form; + +} + + + +sub backorder_exchangerate { + my ($orddate, $buysell) = @_; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + # delete action variable + for (qw(action nextsub exchangerate)) { delete $form->{$_} } + + $form->hide_form; + + $form->{title} = $locale->text('Add Exchange Rate'); + + print qq| + +<input type=hidden name=exchangeratedate value=$orddate> +<input type=hidden name=buysell value=$buysell> + +<table width=100%> + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Currency').qq|</th> + <td>$form->{currency}</td> + </tr> + <tr> + <th align=right>|.$locale->text('Date').qq|</th> + <td>$orddate</td> + </tr> + <tr> + <th align=right>|.$locale->text('Exchange Rate').qq|</th> + <td><input name=exchangerate size=11></td> + </tr> + </table> + </td> + </tr> +</table> + +<hr size=3 noshade> + +<br> +<input type=hidden name=nextsub value=save_exchangerate> + +<input name=action class=submit type=submit value="|.$locale->text('Continue').qq|"> + +</form> + +</body> +</html> +|; + + +} + + +sub save_exchangerate { + + $form->isblank("exchangerate", $locale->text('Exchange rate missing!')); + $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate}); + $form->save_exchangerate(\%myconfig, $form->{currency}, $form->{exchangeratedate}, $form->{exchangerate}, $form->{buysell}); + + &invoice; + +} + + +sub create_backorder { + + $form->{shipped} = 1; + + # figure out if we need to create a backorder + # items aren't saved if qty != 0 + + $dec1 = $dec2 = 0; + for $i (1 .. $form->{rowcount}) { + ($dec) = ($form->{"qty_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $dec1 = ($dec > $dec1) ? $dec : $dec1; + + ($dec) = ($form->{"ship_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $dec2 = ($dec > $dec2) ? $dec : $dec2; + + $totalqty += $qty = $form->{"qty_$i"}; + $totalship += $ship = $form->{"ship_$i"}; + + $form->{"qty_$i"} = $qty - $ship; + } + + $totalqty = $form->round_amount($totalqty, $dec1); + $totalship = $form->round_amount($totalship, $dec2); + + if ($totalship == 0) { + for (1 .. $form->{rowcount}) { $form->{"ship_$_"} = $form->{"qty_$_"} } + $form->{ordtotal} = 0; + $form->{shipped} = 0; + return; + } + + if ($totalqty == $totalship) { + for (1 .. $form->{rowcount}) { $form->{"qty_$_"} = $form->{"ship_$_"} } + $form->{ordtotal} = 0; + return; + } + + @flds = qw(partnumber description qty ship unit sellprice discount oldqty orderitems_id id bin weight listprice lastcost taxaccounts pricematrix sku onhand deliverydate reqdate projectnumber partsgroup assembly); + + for $i (1 .. $form->{rowcount}) { + for (qw(qty sellprice discount)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}) } + + $form->{"oldship_$i"} = $form->{"ship_$i"}; + $form->{"ship_$i"} = 0; + } + + # clear flags + for (qw(id subject message cc bcc printed emailed queued audittrail)) { delete $form->{$_} } + + OE->save(\%myconfig, \%$form); + + # rebuild rows for invoice + @a = (); + $count = 0; + + for $i (1 .. $form->{rowcount}) { + $form->{"qty_$i"} = $form->{"oldship_$i"}; + $form->{"oldqty_$i"} = $form->{"qty_$i"}; + + $form->{"orderitems_id_$i"} = ""; + + if ($form->{"qty_$i"}) { + push @a, {}; + $j = $#a; + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + + $form->redo_rows(\@flds, \@a, $count, $form->{rowcount}); + $form->{rowcount} = $count; + +} + + + +sub save_as_new { + + for (qw(closed id printed emailed queued)) { delete $form->{$_} } + &save; + +} + + +sub print_and_save_as_new { + + for (qw(closed id printed emailed queued)) { delete $form->{$_} } + &print_and_save; + +} + + +sub ship_receive { + + &order_links; + + &prepare_order; + + OE->get_warehouses(\%myconfig, \%$form); + + # warehouse + if (@{ $form->{all_warehouse} }) { + $form->{selectwarehouse} = "<option>\n"; + + for (@{ $form->{all_warehouse} }) { $form->{selectwarehouse} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + + if ($form->{warehouse}) { + $form->{selectwarehouse} = qq|<option value="$form->{warehouse}">|; + $form->{warehouse} =~ s/--.*//; + $form->{selectwarehouse} .= $form->{warehouse}; + } + } + + $form->{shippingdate} = $form->current_date(\%myconfig); + $form->{"$form->{vc}"} =~ s/--.*//; + $form->{"old$form->{vc}"} = qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|; + + @flds = (); + @a = (); + $count = 0; + foreach $key (keys %$form) { + if ($key =~ /_1$/) { + $key =~ s/_1//; + push @flds, $key; + } + } + + for $i (1 .. $form->{rowcount}) { + # undo formatting from prepare_order + for (qw(qty ship)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } + $n = ($form->{"qty_$i"} -= $form->{"ship_$i"}); + if (abs($n) > 0) { + $form->{"ship_$i"} = ""; + $form->{"serialnumber_$i"} = ""; + + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + + $form->redo_rows(\@flds, \@a, $count, $form->{rowcount}); + $form->{rowcount} = $count; + + &display_ship_receive; + +} + + +sub display_ship_receive { + + $vclabel = ucfirst $form->{vc}; + $vclabel = $locale->text($vclabel); + + $form->{rowcount}++; + + if ($form->{vc} eq 'customer') { + $form->{title} = $locale->text('Ship Merchandise'); + $shipped = $locale->text('Shipping Date'); + } else { + $form->{title} = $locale->text('Receive Merchandise'); + $shipped = $locale->text('Date Received'); + } + + # set option selected + for (qw(warehouse employee)) { + $form->{"select$_"} = $form->unescape($form->{"select$_"}); + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + + $warehouse = qq| + <tr> + <th align=right>|.$locale->text('Warehouse').qq|</th> + <td><select name=warehouse>$form->{selectwarehouse}</select></td> + <input type=hidden name=selectwarehouse value="|. + $form->escape($form->{selectwarehouse},1).qq|"> + </tr> +| if $form->{selectwarehouse}; + + $employee = qq| + <tr> + <th align=right nowrap>|.$locale->text('Contact').qq|</th> + <td><select name=employee>$form->{selectemployee}</select></td> + <input type=hidden name=selectemployee value="|. + $form->escape($form->{selectemployee},1).qq|"> + </tr> +|; + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=display_form value=display_ship_receive> +|; + + $form->hide_form(qw(id type media format printed emailed queued vc)); + + print qq| +<input type=hidden name="old$form->{vc}" value="$form->{"old$form->{vc}"}"> + +<table width=100%> + <tr class=listtop> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width="100%"> + <tr valign=top> + <td> + <table width=100%> + <tr> + <th align=right>$vclabel</th> + <td colspan=3>$form->{$form->{vc}}</td> + <input type=hidden name=$form->{vc} value="$form->{$form->{vc}}"> + <input type=hidden name="$form->{vc}_id" value=$form->{"$form->{vc}_id"}> + </tr> + $department + <tr> + <th align=right>|.$locale->text('Shipping Point').qq|</th> + <td colspan=3> + <input name=shippingpoint size=35 value="$form->{shippingpoint}"> + </tr> + <tr> + <th align=right>|.$locale->text('Ship via').qq|</th> + <td colspan=3> + <input name=shipvia size=35 value="$form->{shipvia}"> + </tr> + $warehouse + </table> + </td> + <td align=right> + <table> + $employee + <tr> + <th align=right nowrap>|.$locale->text('Order Number').qq|</th> + <td>$form->{ordnumber}</td> + <input type=hidden name=ordnumber value="$form->{ordnumber}"> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Order Date').qq|</th> + <td>$form->{transdate}</td> + <input type=hidden name=transdate value=$form->{transdate}> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('PO Number').qq|</th> + <td>$form->{ponumber}</td> + <input type=hidden name=ponumber value="$form->{ponumber}"> + </tr> + <tr> + <th align=right nowrap>$shipped</th> + <td><input name=shippingdate size=11 value=$form->{shippingdate}></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + +|; + + $form->hide_form(qw(shiptoname shiptoaddress1 shiptoaddress2 shiptocity shiptostate shiptozipcode shiptocountry shiptocontact shiptophone shiptofax shiptoemail message email subject cc bcc)); + + @column_index = qw(partnumber); + + if ($form->{type} eq "ship_order") { + $column_data{ship} = qq|<th class=listheading>|.$locale->text('Ship').qq|</th>|; + } + if ($form->{type} eq "receive_order") { + $column_data{ship} = qq|<th class=listheading>|.$locale->text('Recd').qq|</th>|; + $column_data{sku} = qq|<th class=listheading>|.$locale->text('SKU').qq|</th>|; + push @column_index, "sku"; + } + push @column_index, qw(description qty ship unit bin serialnumber); + + my $colspan = $#column_index + 1; + + $column_data{partnumber} = qq|<th class=listheading nowrap>|.$locale->text('Number').qq|</th>|; + $column_data{description} = qq|<th class=listheading nowrap>|.$locale->text('Description').qq|</th>|; + $column_data{qty} = qq|<th class=listheading nowrap>|.$locale->text('Qty').qq|</th>|; + $column_data{unit} = qq|<th class=listheading nowrap>|.$locale->text('Unit').qq|</th>|; + $column_data{bin} = qq|<th class=listheading nowrap>|.$locale->text('Bin').qq|</th>|; + $column_data{serialnumber} = qq|<th class=listheading nowrap>|.$locale->text('Serial No.').qq|</th>|; + + print qq| + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + + for $i (1 .. $form->{rowcount} - 1) { + + # undo formatting + $form->{"ship_$i"} = $form->parse_amount(\%myconfig, $form->{"ship_$i"}); + + for (qw(partnumber sku description unit bin serialnumber)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + + $description = $form->{"description_$i"}; + $description =~ s/\r?\n/<br>/g; + + $column_data{partnumber} = qq|<td>$form->{"partnumber_$i"}<input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}"></td>|; + $column_data{sku} = qq|<td>$form->{"sku_$i"}<input type=hidden name="sku_$i" value="$form->{"sku_$i"}"></td>|; + $column_data{description} = qq|<td>$description<input type=hidden name="description_$i" value="$form->{"description_$i"}"></td>|; + $column_data{qty} = qq|<td align=right>|.$form->format_amount(\%myconfig, $form->{"qty_$i"}).qq|<input type=hidden name="qty_$i" value="$form->{"qty_$i"}"></td>|; + $column_data{ship} = qq|<td align=right><input name="ship_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"ship_$i"}).qq|></td>|; + $column_data{unit} = qq|<td>$form->{"unit_$i"}<input type=hidden name="unit_$i" value="$form->{"unit_$i"}"></td>|; + $column_data{bin} = qq|<td>$form->{"bin_$i"}<input type=hidden name="bin_$i" value="$form->{"bin_$i"}"></td>|; + + $column_data{serialnumber} = qq|<td><input name="serialnumber_$i" size=15 value="$form->{"serialnumber_$i"}"></td>|; + + print qq| + <tr valign=top>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + $form->hide_form("orderitems_id_$i","id_$i","partsgroup_$i"); + + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> + <tr> + <td> +|; + + $form->{copies} = 1; + + &print_options; + + print qq| + </td> + </tr> +</table> +<br> +|; + +# type=submit $locale->text('Done') + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') }, + 'Ship to' => { ndx => 4, key => 'T', value => $locale->text('Ship to') }, + 'E-mail' => { ndx => 5, key => 'E', value => $locale->text('E-mail') }, + 'Done' => { ndx => 11, key => 'D', value => $locale->text('Done') }, + ); + + for ("Update", "Print") { $form->print_button(\%button, $_) } + + if ($form->{type} eq 'ship_order') { + for ('Ship to', 'E-mail') { $form->print_button(\%button, $_) } + } + + $form->print_button(\%button, 'Done'); + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + $form->hide_form(qw(rowcount callback path login sessionid)); + + print qq| + +</form> + +</body> +</html> +|; + + +} + + +sub done { + + if ($form->{type} eq 'ship_order') { + $form->isblank("shippingdate", $locale->text('Shipping Date missing!')); + } else { + $form->isblank("shippingdate", $locale->text('Date received missing!')); + } + + $total = 0; + for (1 .. $form->{rowcount} - 1) { $total += $form->{"ship_$_"} = $form->parse_amount(\%myconfig, $form->{"ship_$_"}) } + + $form->error($locale->text('Nothing entered!')) unless $total; + + if (OE->save_inventory(\%myconfig, \%$form)) { + $form->redirect($locale->text('Inventory saved!')); + } else { + $form->error($locale->text('Could not save!')); + } + +} + + +sub search_transfer { + + OE->get_warehouses(\%myconfig, \%$form); + + # warehouse + if (@{ $form->{all_warehouse} }) { + $form->{selectwarehouse} = "<option>\n"; + $form->{warehouse} = qq|$form->{warehouse}--$form->{warehouse_id}| if $form->{warehouse_id}; + + for (@{ $form->{all_warehouse} }) { $form->{selectwarehouse} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } else { + $form->error($locale->text('Nothing to transfer!')); + } + + $form->get_partsgroup(\%myconfig, { searchitems => 'part'}); + if (@{ $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = "<option>\n"; + for (@{ $form->{all_partsgroup} }) { $form->{selectpartsgroup} .= qq|<option value="$_->{partsgroup}--$_->{id}">$_->{partsgroup}\n| } + } + + $form->{title} = $locale->text('Transfer Inventory'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Transfer from').qq|</th> + <td><select name=fromwarehouse>$form->{selectwarehouse}</select></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Transfer to').qq|</th> + <td><select name=towarehouse>$form->{selectwarehouse}</select></td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('Part Number').qq|</th> + <td><input name=partnumber size=20></td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('Description').qq|</th> + <td><input name=description size=40></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Group').qq|</th> + <td><select name=partsgroup>$form->{selectpartsgroup}</select></td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<input type=hidden name=nextsub value=list_transfer> + +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub list_transfer { + + $form->{sort} = "partnumber" unless $form->{sort}; + + OE->get_inventory(\%myconfig, \%$form); + + # construct href + $href = "$form->{script}?action=list_transfer"; + for (qw(direction oldsort path login sessionid)) { $href .= "&$_=$form->{$_}" } + for (qw(partnumber fromwarehouse towarehouse description partsgroup)) { $href .= "&$_=".$form->escape($form->{$_}) } + + $form->sort_order(); + + # construct callback + $callback = "$form->{script}?action=list_transfer"; + for (qw(direction oldsort path login sessionid)) { $callback .= "&$_=$form->{$_}" } + for (qw(partnumber fromwarehouse towarehouse description partsgroup)) { $callback .= "&$_=".$form->escape($form->{$_},1) } + + @column_index = $form->sort_columns(qw(partnumber description partsgroup make model fromwarehouse qty towarehouse transfer)); + + $column_header{partnumber} = qq|<th><a class=listheading href=$href&sort=partnumber>|.$locale->text('Part Number').qq|</a></th>|; + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + $column_header{partsgroup} = qq|<th><a class=listheading href=$href&sort=partsgroup>|.$locale->text('Group').qq|</a></th>|; + $column_header{fromwarehouse} = qq|<th><a class=listheading href=$href&sort=warehouse>|.$locale->text('From').qq|</a></th>|; + $column_header{towarehouse} = qq|<th class=listheading>|.$locale->text('To').qq|</th>|; + $column_header{qty} = qq|<th class=listheading>|.$locale->text('Qty').qq|</a></th>|; + $column_header{transfer} = qq|<th class=listheading>|.$locale->text('Transfer').qq|</a></th>|; + + + ($warehouse, $warehouse_id) = split /--/, $form->{fromwarehouse}; + + if ($form->{fromwarehouse}) { + $option .= "\n<br>"; + $option .= $locale->text('From Warehouse')." : $warehouse"; + } + ($warehouse, $warehouse_id) = split /--/, $form->{towarehouse}; + if ($form->{towarehouse}) { + $option .= "\n<br>"; + $option .= $locale->text('To Warehouse')." : $warehouse"; + } + if ($form->{partnumber}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('Part Number')." : $form->{partnumber}"; + } + if ($form->{description}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('Description')." : $form->{description}"; + } + if ($form->{partsgroup}) { + ($partsgroup) = split /--/, $form->{partsgroup}; + $option .= "\n<br>" if ($option); + $option .= $locale->text('Group')." : $partsgroup"; + } + + $form->{title} = $locale->text('Transfer Inventory'); + + $callback .= "&sort=$form->{sort}"; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=warehouse_id value=$warehouse_id> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + +for (@column_index) { print "\n$column_header{$_}" } + +print qq| + </tr> +|; + + if (@{ $form->{all_inventory} }) { + $sameitem = $form->{all_inventory}->[0]->{$form->{sort}}; + } + + $i = 0; + foreach $ref (@{ $form->{all_inventory} }) { + + $i++; + + $column_data{partnumber} = qq|<td><input type=hidden name="id_$i" value=$ref->{id}>$ref->{partnumber}</td>|; + $column_data{description} = "<td>$ref->{description} </td>"; + $column_data{partsgroup} = "<td>$ref->{partsgroup} </td>"; + $column_data{fromwarehouse} = qq|<td><input type=hidden name="warehouse_id_$i" value=$ref->{warehouse_id}>$ref->{warehouse} </td>|; + $column_data{towarehouse} = qq|<td>$warehouse </td>|; + $column_data{qty} = qq|<td><input type=hidden name="qty_$i" value=$ref->{qty}>|.$form->format_amount(\%myconfig, $ref->{qty}).qq|</td>|; + $column_data{transfer} = qq|<td><input name="transfer_$i" size=4></td>|; + + $j++; $j %= 2; + print " + <tr class=listrow$j>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + } + + print qq| + </table> + </td> + </tr> + + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> + +<input name=callback type=hidden value="$callback"> + +<input type=hidden name=rowcount value=$i> +|; + + $form->{action} = "transfer"; + $form->hide_form(qw(path login sessionid action)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Transfer').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + + +} + + +sub transfer { + + if (OE->transfer(\%myconfig, \%$form)) { + $form->redirect($locale->text('Inventory transferred!')); + } else { + $form->error($locale->text('Could not transfer Inventory!')); + } + +} + + +sub rfq_ { &add }; +sub quotation_ { &add }; + + +sub generate_purchase_orders { + + for (1 .. $form->{rowcount}) { + if ($form->{"ndx_$_"}) { + $ok = 1; + last; + } + } + + $form->error($locale->text('Nothing selected!')) unless $ok; + + ($null, $argv) = split /\?/, $form->{callback}; + + for (split /\&/, $argv) { + ($key, $value) = split /=/, $_; + $form->{$key} = $value; + } + + $form->{vc} = "vendor"; + + OE->get_soparts(\%myconfig, \%$form); + + # flatten array + $i = 0; + foreach $parts_id (sort { $form->{orderitems}{$a}{partnumber} cmp $form->{orderitems}{$b}{partnumber} } keys %{ $form->{orderitems} }) { + + $required = $form->{orderitems}{$parts_id}{required}; + next if $required <= 0; + + $i++; + + $form->{"required_$i"} = $form->format_amount(\%myconfig, $required); + $form->{"id_$i"} = $parts_id; + $form->{"sku_$i"} = $form->{orderitems}{$parts_id}{partnumber}; + + $form->{"curr_$i"} = $form->{defaultcurrency}; + $form->{"description_$i"} = $form->{orderitems}{$parts_id}{description}; + + $form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{orderitems}{$parts_id}{lastcost}, 2); + + $form->{"qty_$i"} = $required; + + if (exists $form->{orderitems}{$parts_id}{"parts$form->{vc}"}) { + $form->{"qty_$i"} = ""; + + foreach $id (sort { $form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$a}{lastcost} * $form->{$form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$a}{curr}} <=> $form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$b}{lastcost} * $form->{$form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$b}{curr}} } keys %{ $form->{orderitems}{$parts_id}{"parts$form->{vc}"} }) { + $i++; + + $form->{"qty_$i"} = $form->format_amount(\%myconfig, $required); + + $form->{"description_$i"} = ""; + for (qw(partnumber curr)) { $form->{"${_}_$i"} = $form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$id}{$_} } + + $form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$id}{lastcost}, 2); + $form->{"leadtime_$i"} = $form->format_amount(\%myconfig, $form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$id}{leadtime}); + $form->{"fx_$i"} = $form->format_amount(\%myconfig, $form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$id}{lastcost} * $form->{$form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$id}{curr}}, 2); + + $form->{"id_$i"} = $parts_id; + + $form->{"$form->{vc}_$i"} = qq|$form->{orderitems}{$parts_id}{"parts$form->{vc}"}{$id}{name}--$id|; + $form->{"$form->{vc}_id_$i"} = $id; + + $required = ""; + } + } + $form->{"blankrow_$i"} = 1; + } + + $form->{rowcount} = $i; + + &po_orderitems; + +} + + +sub po_orderitems { + + @column_index = qw(sku description partnumber leadtime fx lastcost curr required qty name); + + $column_header{sku} = qq|<th class=listheading>|.$locale->text('SKU').qq|</th>|; + $column_header{partnumber} = qq|<th class=listheading>|.$locale->text('Part Number').qq|</th>|; + $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|; + $column_header{name} = qq|<th class=listheading>|.$locale->text('Vendor').qq|</th>|; + $column_header{qty} = qq|<th class=listheading>|.$locale->text('Order').qq|</th>|; + $column_header{required} = qq|<th class=listheading>|.$locale->text('Req').qq|</th>|; + $column_header{lastcost} = qq|<th class=listheading>|.$locale->text('Cost').qq|</th>|; + $column_header{fx} = qq|<th class=listheading> </th>|; + $column_header{leadtime} = qq|<th class=listheading>|.$locale->text('Lead').qq|</th>|; + $column_header{curr} = qq|<th class=listheading>|.$locale->text('Curr').qq|</th>|; + + + $form->{title} = $locale->text('Generate Purchase Orders'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + for $i (1 .. $form->{rowcount}) { + + for (qw(sku partnumber description curr)) { $column_data{$_} = qq|<td>$form->{"${_}_$i"} </td>| } + + for (qw(required leadtime lastcost fx)) { $column_data{$_} = qq|<td align=right>$form->{"${_}_$i"}</td>| } + + $column_data{qty} = qq|<td align=right><input name="qty_$i" size=6 value=$form->{"qty_$i"}></td>|; + + if ($form->{"$form->{vc}_id_$i"}) { + $name = $form->{"$form->{vc}_$i"}; + $name =~ s/--.*//; + $column_data{name} = qq|<td>$name</td>|; + $form->hide_form("$form->{vc}_id_$i", "$form->{vc}_$i"); + } else { + $column_data{name} = qq|<td><input name="ndx_$i" class=checkbox type=checkbox value="1"></td>|; + } + + $form->hide_form(map { "${_}_$i" } qw(id sku partnumber description curr required leadtime lastcost fx name blankrow)); + + $blankrow = $form->{"blankrow_$i"}; + +BLANKROW: + $j++; $j %= 2; + print " + <tr class=listrow$j>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + if ($blankrow) { + for (@column_index) { $column_data{$_} = "<td> </td>" } + $blankrow = 0; + + goto BLANKROW; + } + + } + + print qq| + </table> + </td> + </tr> + + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +|; + + $form->hide_form(qw(callback department ponumber path login sessionid employee_id vc nextsub rowcount type)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Generate Orders').qq|">|; + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Select Vendor').qq|">|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub generate_orders { + + if (OE->generate_orders(\%myconfig, \%$form)) { + $form->redirect; + } else { + $form->error($locale->text('Order generation failed!')); + } + +} + + + +sub consolidate_orders { + + for (1 .. $form->{rowcount}) { + if ($form->{"ndx_$_"}) { + $ok = 1; + last; + } + } + + $form->error($locale->text('Nothing selected!')) unless $ok; + + ($null, $argv) = split /\?/, $form->{callback}; + + for (split /\&/, $argv) { + ($key, $value) = split /=/, $_; + $form->{$key} = $value; + } + + if (OE->consolidate_orders(\%myconfig, \%$form)) { + $form->redirect; + } else { + $form->error($locale->text('Order generation failed!')); + } + +} + + +sub select_vendor { + + for (1 .. $form->{rowcount}) { + last if ($ok = $form->{"ndx_$_"}); + } + + $form->error($locale->text('Nothing selected!')) unless $ok; + + $form->header; + + print qq| +<body onload="document.forms[0].vendor.focus()" /> + +<form method=post action=$form->{script}> + +<b>|.$locale->text('Vendor').qq|</b> <input name=vendor size=40> + +|; + + $form->{nextsub} = "vendor_selected"; + $form->{action} = "vendor_selected"; + + $form->hide_form; + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> + +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub vendor_selected { + + if (($rv = $form->get_name(\%myconfig, $form->{vc}, $form->{transdate})) > 1) { + &select_name($form->{vc}); + exit; + } + + if ($rv == 1) { + for (1 .. $form->{rowcount}) { + if ($form->{"ndx_$_"}) { + $form->{"$form->{vc}_id_$_"} = $form->{name_list}[0]->{id}; + $form->{"$form->{vc}_$_"} = "$form->{name_list}[0]->{name}--$form->{name_list}[0]->{id}"; + } + } + } else { + $msg = ucfirst $form->{vc} . " not on file!" unless $msg; + $form->error($locale->text($msg)); + } + + &po_orderitems; + +} + + diff --git a/bin/lynx/pe.pl b/bin/lynx/pe.pl new file mode 100755 index 00000000..bc7b108f --- /dev/null +++ b/bin/lynx/pe.pl @@ -0,0 +1,2578 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2002 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# project/job administration +# partsgroup administration +# translation maintainance +# +#====================================================================== + + +use SL::PE; +use SL::AA; +use SL::OE; + +1; +# end of main + + + +sub add { + + # construct callback + $form->{callback} = "$form->{script}?action=add&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &{ "prepare_$form->{type}" }; + + $form->{orphaned} = 1; + &display_form; + +} + + +sub edit { + + &{ "prepare_$form->{type}" }; + &display_form; + +} + + +sub prepare_partsgroup { PE->get_partsgroup(\%myconfig, \%$form) if $form->{id} } +sub prepare_pricegroup { PE->get_pricegroup(\%myconfig, \%$form) if $form->{id} } + +sub prepare_job { + +# $locale->text('Add Job') +# $locale->text('Edit Job') + + $form->{vc} = 'customer'; + + PE->get_job(\%myconfig, \%$form); + + $form->{taxaccounts} = ""; + for (keys %{ $form->{IC_links} }) { + + $form->{"select$_"} = ""; + foreach $ref (@{ $form->{IC_links}{$_} }) { + if (/IC_tax/) { + if (/taxpart/) { + $form->{taxaccounts} .= "$ref->{accno} "; + $form->{"IC_tax_$ref->{accno}_description"} = "$ref->{accno}--$ref->{description}"; + if ($form->{id}) { + if ($form->{amount}{$ref->{accno}}) { + $form->{"IC_tax_$ref->{accno}"} = "checked"; + } + } else { + $form->{"IC_tax_$ref->{accno}"} = "checked"; + } + } + } else { + $form->{"select$_"} .= "<option>$ref->{accno}--$ref->{description}\n"; + } + } + } + chop $form->{taxaccounts}; + + $form->{selectIC_income} = $form->{selectIC_sale}; + $form->{IC_income} = $form->{IC_sale}; + + $form->{IC_income} = qq|$form->{income_accno}--$form->{income_description}|; + + delete $form->{IC_links}; + + $form->{"old$form->{vc}"} = qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|; + + if (@{ $form->{"all_$form->{vc}"} }) { + $form->{"$form->{vc}"} = qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|; + $form->{"select$form->{vc}"} = qq|<option>\n|; + for (@{ $form->{"all_$form->{vc}"} }) { $form->{"select$form->{vc}"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + + $form->get_partsgroup(\%myconfig, {all => 1}); + $form->{partsgroup} = $form->quote($form->{partsgroup})."--$form->{partsgroup_id}"; + if (@{ $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = qq|<option>\n|; + for (@{ $form->{all_partsgroup} }) { $form->{selectpartsgroup} .= qq|<option value="|.$form->quote($_->{partsgroup}).qq|--$_->{id}">$_->{partsgroup}\n| } + } + + $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto})); + + $form->{readonly} = 1 if $myconfig{acs} =~ /Job Costing--Add Job/; + +} + + +sub job_header { + + for (qw(partnumber partdescription description notes unit)) { $form->{$_} = $form->quote($form->{$_}) } + + for (qw(production weight)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}) } + for (qw(listprice sellprice)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) } + + if (($rows = $form->numtextrows($form->{partdescription}, 60)) > 1) { + $partdescription = qq|<textarea name="partdescription" rows=$rows cols=60 style="width: 100%" wrap=soft>$form->{partdescription}</textarea>|; + } else { + $partdescription = qq|<input name=partdescription size=60 value="$form->{partdescription}">|; + } + + if (($rows = $form->numtextrows($form->{description}, 60)) > 1) { + $description = qq|<textarea name="description" rows=$rows cols=60 style="width: 100%" wrap=soft>$form->{description}</textarea>|; + } else { + $description = qq|<input name=description size=60 value="$form->{description}">|; + } + + if (($rows = $form->numtextrows($form->{notes}, 40)) < 2) { + $rows = 2; + } + + $notes = qq|<textarea name=notes rows=$rows cols=40 wrap=soft>$form->{notes}</textarea>|; + + $form->{selectIC_income} = $form->unescape($form->{selectIC_income}); + $form->{"select$form->{vc}"} = $form->unescape($form->{"select$form->{vc}"}); + $form->{"select$form->{vc}"} =~ s/ selected//; + $form->{"select$form->{vc}"} =~ s/(<option value="\Q$form->{"$form->{vc}"}\E")/$1 selected/; + + + $label = ucfirst $form->{vc}; + if ($form->{"select$form->{vc}"}) { + $name = qq| + <tr> + <th align=right nowrap>|.$locale->text($label).qq|</th> + <td colspan=3><select name="$form->{vc}">$form->{"select$form->{vc}"}</select></td> + <input type=hidden name="select$form->{vc}" value="|. + $form->escape($form->{"select$form->{vc}"},1).qq|"> + </tr> +|; + } else { + $name = qq| + <tr> + <th align=right nowrap>|.$locale->text($label).qq|</th> + <td colspan=3><input name="$form->{vc}" value="$form->{"$form->{vc}"}" size=35></td> + <input type=hidden name="select$form->{vc}" value="|. + $form->escape($form->{"select$form->{vc}"},1).qq|"> + </tr> +|; + } + + if ($form->{orphaned}) { + + for (qw(income)) { + $form->{"selectIC_$_"} =~ s/ selected//; + $form->{"selectIC_$_"} =~ s/option>\Q$form->{"IC_$_"}\E/option selected>$form->{"IC_$_"}/; + } + + $production = qq| + <tr> + <th align=right nowrap>|.$locale->text('Production').qq|</th> + <td><input name=production size=10 value="$form->{production}"></td> + <th align=right nowrap>|.$locale->text('Completed').qq|</th> + <td>$form->{completed}</td> + </tr> +|; + + } else { + + $form->{selectIC_income} = qq|<option selected>$form->{IC_income}|; + + $production = qq| + <tr> + <th align=right nowrap>|.$locale->text('Production').qq|</th> + <td><input type=hidden name=production value="$form->{production}">$form->{production}</td> + <th align=right nowrap>|.$locale->text('Completed').qq|</th> + <td>$form->{completed}</td> + </tr> +|; + + } + + for (split / /, $form->{taxaccounts}) { $form->{"IC_tax_$_"} = ($form->{"IC_tax_$_"}) ? "checked" : "" } + + if ($form->{selectpartsgroup}) { + $form->{selectpartsgroup} = $form->unescape($form->{selectpartsgroup}); + + $partsgroup = qq|<input type=hidden name=selectpartsgroup value="|.$form->escape($form->{selectpartsgroup},1).qq|">|; + $form->{partsgroup} = $form->quote($form->{partsgroup}); + $form->{selectpartsgroup} =~ s/(<option value="\Q$form->{partsgroup}\E")/$1 selected/; + + $partsgroup .= qq|\n<select name=partsgroup>$form->{selectpartsgroup}</select>|; + $group = $locale->text('Group'); + } + + $linkaccounts = qq| + <tr> + <th align=right nowrap>|.$locale->text('Income').qq|</th> + <td><select name=IC_income>$form->{selectIC_income}</select></td> + </tr> +|; + + for (split / /, $form->{taxaccounts}) { + $tax .= qq| + <input class=checkbox type=checkbox name="IC_tax_$_" value=1 $form->{"IC_tax_$_"}> <b>$form->{"IC_tax_${_}_description"}</b> + <br><input type=hidden name=IC_tax_${_}_description value="$form->{"IC_tax_${_}_description"}"> +|; + } + + if ($tax) { + $linkaccounts .= qq| + <tr> + <th align=right>|.$locale->text('Tax').qq|</th> + <td>$tax</td> + </tr> +|; + } + + $partnumber = qq| + <tr> + <td> + <table> + <tr valign=top> + <th align=left>|.$locale->text('Number').qq|</th> + <th align=left>|.$locale->text('Description').qq|</th> + <th align=left>$group</th> + </tr> + <tr valign=top> + <td><input name=partnumber value="$form->{partnumber}" size=20></td> + <td>$partdescription</td> + <td>$partsgroup</td> + </tr> + </table> + </td> + </tr> +|; + + $form->{title} = ($form->{id}) ? $locale->text('Edit Job') : $locale->text('Add Job'); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + for (qw(partnumber startdate enddate)) { $form->{"old$_"} = $form->{$_} } + + print qq|<input type=hidden name="selectIC_income" value="|.$form->escape($form->{"selectIC_income"},1).qq|">\n|; + + $form->hide_form("id", "type", "old$form->{vc}", "$form->{vc}_id", "orphaned", "taxaccounts", "vc", "project"); + + print qq| + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Number').qq|</th> + <td><input name=projectnumber size=20 value="$form->{projectnumber}"></td> + <th align=right>|.$locale->text('Description').qq|</th> + <td>$description</td> + </tr> + $name + <tr> + <th align=right>|.$locale->text('Startdate').qq|</th> + <td><input name=startdate size=11 title="($myconfig{dateformat})" value=$form->{startdate}></td> + <th align=right>|.$locale->text('Enddate').qq|</th> + <td><input name=enddate size=11 title="($myconfig{dateformat})" value=$form->{enddate}></td> + </tr> + $production + </table> + </td> + </tr> + <tr class="listheading"> + <th class="listheading" align="center">|.$locale->text('Assembly').qq|</th> + </tr> + <tr> + <td> + <table width=100%> + $partnumber + <tr> + <td colspan=3> + <table width=100%> + <tr> + <td width=70%> + <table width=100%> + <tr class="listheading"> + <th class="listheading" align="center" colspan=2>|.$locale->text('Link Accounts').qq|</th> + </tr> + $linkaccounts + <tr> + <th align="left">|.$locale->text('Notes').qq|</th> + </tr> + <tr> + <td colspan=2> + $notes + </td> + </tr> + </table> + </td> + <td align=right> + <table> + <tr> + <th align="right" nowrap="true">|.$locale->text('Updated').qq|</th> + <td><input name=priceupdate size=11 title="$myconfig{dateformat}" value=$form->{priceupdate}></td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('List Price').qq|</th> + <td><input name=listprice size=11 value=$form->{listprice}></td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('Sell Price').qq|</th> + <td><input name=sellprice size=11 value=$form->{sellprice}></td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('Weight').qq|</th> + <td> + <table> + <tr> + <td> + <input name=weight size=10 value=$form->{weight}> + </td> + <th> + + $form->{weightunit} + <input type=hidden name=weightunit value=$form->{weightunit}> + </th> + </tr> + </table> + </td> + <tr> + <th align="right" nowrap="true">|.$locale->text('Bin').qq|</th> + <td><input name=bin size=10 value="$form->{bin}"></td> + </tr> + <tr> + <th align="right" nowrap="true">|.$locale->text('Unit').qq|</th> + <td><input name=unit size=5 value="$form->{unit}"></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub job_footer { + + $form->hide_form(qw(callback path login sessionid)); + +# type=submit $locale->text('Update') +# type=submit $locale->text('Save') +# type=submit $locale->text('Delete') + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + ); + + if ($myconfig{acs} !~ /Job Costing--Add Job/) { + $button{'Save'} = { ndx => 3, key => 'S', value => $locale->text('Save') }; + + if ($form->{id} && $form->{orphaned}) { + $button{'Delete'} = { ndx => 16, key => 'D', value => $locale->text('Delete') }; + } + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub list_stock { + + PE->list_stock(\%myconfig, \%$form); + + $form->{title} = $locale->text('Stock Finished Goods'); + $form->{action} = "list_stock"; + + $href = "$form->{script}?"; + for (qw(action direction oldsort type path login sessionid status)) { $href .= "$_=$form->{$_}&" } + + $form->sort_order(); + + $callback = "$form->{script}?"; + for (qw(action direction oldsort type path login sessionid status)) { $callback .= "$_=$form->{$_}&" } + + @column_index = $form->sort_columns(qw(projectnumber description startdate partnumber production completed stock)); + + if ($form->{projectnumber}) { + $href .= "&projectnumber=".$form->escape($form->{projectnumber}); + $callback .= "&projectnumber=$form->{projectnumber}"; + ($var) = split /--/, $form->{projectnumber}; + $option .= "\n<br>".$locale->text('Job Number')." : $var"; + } + if ($form->{stockingdate}) { + $href .= "&stockingdate=$form->{stockingdate}"; + $option .= "\n<br>".$locale->text('As of')." : ".$locale->date(\%myconfig, $form->{stockingdate}, 1); + } + + $column_header{projectnumber} = qq|<th width=30%><a class=listheading href=$href&sort=projectnumber>|.$locale->text('Number').qq|</a></th>|; + $column_header{description} = qq|<th width=50%><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + $column_header{startdate} = qq|<th width=10%><a class=listheading href=$href&sort=startdate>|.$locale->text('Startdate').qq|</a></th>|; + $column_header{partnumber} = "<th><a class=listheading href=$href&sort=partnumber>" . $locale->text('Assembly') . "</a></th>"; + $column_header{production} = "<th class=listheading>" . $locale->text('Production') . "</a></th>"; + $column_header{completed} = "<th class=listheading>" . $locale->text('Completed') . "</a></th>"; + $column_header{stock} = "<th class=listheading>" . $locale->text('Add') . "</a></th>"; + + + $form->header; + + if (@{ $form->{all_project} }) { + $sameitem = $form->{all_project}->[0]->{$form->{sort}}; + } + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + # escape callback + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + # flip direction + $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC"; + $href =~ s/&direction=(\w+)&/&direction=$direction&/; + + $i = 0; + foreach $ref (@{ $form->{all_project} }) { + + $i++; + + for (qw(projectnumber description startdate enddate partnumber)) { $column_data{$_} = qq|<td>$ref->{$_} </td>| } + for (qw(production completed)) { $column_data{$_} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{$_}).qq|</td>| } + $column_data{stock} = qq|<td><input name="stock_$i" size=6></td>|; + + $j++; $j %= 2; + + print qq| + <tr valign=top class=listrow$j> + <input type=hidden name="id_$i" value=$ref->{id}> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print " + </tr> +"; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + $form->hide_form(qw(callback type path login sessionid status)); + + print qq| +<input type=hidden name=nextsub value="stock"> +<br> +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub stock { + + if (PE->stock_assembly(\%myconfig, \%$form)) { + $form->redirect($locale->text('Assembly stocked!')); + } else { + $form->error($locale->text('Cannot stock Assembly!')); + } + +} + + +sub prepare_project { + + $form->{vc} = 'customer'; + + PE->get_project(\%myconfig, \%$form); + + $form->{title} = ($form->{id}) ? $locale->text('Edit Project') : $locale->text('Add Project'); + + $form->{"old$form->{vc}"} = qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|; + + if (@{ $form->{"all_$form->{vc}"} }) { + $form->{"$form->{vc}"} = qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|; + $form->{"select$form->{vc}"} = qq|<option>\n|; + for (@{ $form->{"all_$form->{vc}"} }) { $form->{"select$form->{vc}"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + +} + + +sub search { + + # accounting years + $form->all_years(\%myconfig); + + if (@{ $form->{all_years} }) { + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $fromto = qq| + <tr> + <th align=right>|.$locale->text('Startdate').qq|</th> + <td>|.$locale->text('From').qq| <input name=startdatefrom size=11 title="($myconfig{'dateformat'})">|.$locale->text('To').qq| + <input name=startdateto size=11 title="($myconfig{'dateformat'})"></td> + </tr> +|; + + $selectperiod = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + + $orphaned = qq| + <input name=status class=radio type=radio value=orphaned> |.$locale->text('Orphaned'); + + if ($form->{type} eq 'project') { + $report = "project_report"; + $sort = "projectnumber"; + $form->{title} = $locale->text('Projects'); + + $number = qq| + <tr> + <th align=right width=1%>|.$locale->text('Number').qq|</th> + <td><input name=projectnumber size=20></td> + </tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td><input name=description size=60></td> + </tr> +|; + } + + if ($form->{type} eq 'stock') { + $report = "list_stock"; + $form->{title} = $locale->text('Stock Finished Goods'); + PE->list_stock(\%myconfig, \%$form); + + $selectperiod = ""; + $orphaned = ""; + $fromto = qq| + <tr> + <th align=right nowrap>|.$locale->text('As of').qq|</th> + <td><input name=stockingdate size=11 title="$myconfig{dateformat}"></td> + </tr> +|; + + $number = qq| + <tr> + <th align=right width=1%>|.$locale->text('Job Number').qq|</th> + <td><input name=projectnumber size=20></td> + </tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td><input name=description size=60></td> + </tr> +|; + } + + if ($form->{type} eq 'job') { + $report = "job_report"; + $sort = "projectnumber"; + $form->{title} = $locale->text('Jobs'); + + $number = qq| + <tr> + <th align=right width=1%>|.$locale->text('Number').qq|</th> + <td><input name=projectnumber size=20></td> + </tr> + <tr> + <th align=right>|.$locale->text('Description').qq|</th> + <td><input name=description size=60></td> + </tr> +|; + } + + if ($form->{type} eq 'partsgroup') { + $report = "partsgroup_report"; + $sort = 'partsgroup'; + $form->{title} = $locale->text('Groups'); + + $fromto = ""; + $selectperiod = ""; + $number = qq| + <tr> + <th align=right width=1%>|.$locale->text('Group').qq|</th> + <td><input name=partsgroup size=20></td> + </tr> +|; + } + + if ($form->{type} eq 'pricegroup') { + $report = "pricegroup_report"; + $sort = 'pricegroup'; + $form->{title} = $locale->text('Pricegroups'); + + $fromto = ""; + $selectperiod = ""; + $number = qq| + <tr> + <th align=right width=1%>|.$locale->text('Pricegroup').qq|</th> + <td><input name=pricegroup size=20></td> + </tr> +|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=sort value=$sort> +<input type=hidden name=type value=$form->{type}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + $number + $fromto + $selectperiod + <tr> + <td></td> + <td><input name=status class=radio type=radio value=all checked> |.$locale->text('All').qq| + <input name=status class=radio type=radio value=active> |.$locale->text('Active').qq| + <input name=status class=radio type=radio value=inactive> |.$locale->text('Inactive').qq| + $orphaned</td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=nextsub value=$report> +|; + + $form->hide_form(qw(path login sessionid title)); + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub job_report { + + for (qw(projectnumber description)) { $form->{$_} = $form->unescape($form->{$_}) } + PE->jobs(\%myconfig, \%$form); + + $form->{action} = "job_report"; + &list_projects; + +} + + +sub project_report { + + for (qw(projectnumber description)) { $form->{$_} = $form->unescape($form->{$_}) } + PE->projects(\%myconfig, \%$form); + + $form->{action} = "project_report"; + &list_projects; + +} + + +sub list_projects { + + $href = "$form->{script}?"; + for (qw(action direction oldsort type path login sessionid status startdatefrom startdateto)) { $href .= "$_=$form->{$_}&" } + + $form->sort_order(); + + $callback = "$form->{script}?"; + for (qw(action direction oldsort type path login sessionid status startdatefrom startdateto)) { $callback .= "$_=$form->{$_}&" } + + @column_index = $form->sort_columns(qw(projectnumber description name startdate enddate)); + + if ($form->{status} eq 'all') { + $option = $locale->text('All'); + } + if ($form->{status} eq 'orphaned') { + $option .= $locale->text('Orphaned'); + } + if ($form->{status} eq 'active') { + $option = $locale->text('Active'); + @column_index = $form->sort_columns(qw(projectnumber description name startdate)); + } + if ($form->{status} eq 'inactive') { + $option = $locale->text('Inactive'); + } + + if ($form->{type} eq 'project') { + $label = $locale->text('Project'); + $form->{title} = $locale->text('Projects'); + } else { + $label = $locale->text('Job'); + push @column_index, qw(partnumber production completed); + $form->{title} = $locale->text('Jobs'); + } + + if ($form->{projectnumber}) { + $href .= "&projectnumber=".$form->escape($form->{projectnumber}); + $callback .= "&projectnumber=$form->{projectnumber}"; + $option .= "\n<br>$label : $form->{projectnumber}"; + } + if ($form->{description}) { + $href .= "&description=".$form->escape($form->{description}); + $callback .= "&description=$form->{description}"; + $option .= "\n<br>".$locale->text('Description')." : $form->{description}"; + } + if ($form->{startdatefrom}) { + $href .= "&startdatefrom=$form->{startdatefrom}"; + $option .= "\n<br>".$locale->text('From')." ".$locale->date(\%myconfig, $form->{startdatefrom}, 1); + } + if ($form->{startdateto}) { + $href .= "&startdateto=$form->{startdateto}"; + if ($form->{startdatefrom}) { + $option .= " "; + } else { + $option .= "\n<br>" if ($option); + } + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{startdateto}, 1); + } + + + $column_header{projectnumber} = qq|<th><a class=listheading href=$href&sort=projectnumber>|.$locale->text('Number').qq|</a></th>|; + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + $column_header{startdate} = qq|<th width=10><a class=listheading href=$href&sort=startdate>|.$locale->text('Startdate').qq|</a></th>|; + $column_header{enddate} = qq|<th width=10><a class=listheading href=$href&sort=enddate>|.$locale->text('Enddate').qq|</a></th>|; + + $column_header{partnumber} = "<th><a class=listheading href=$href&sort=partnumber>" . $locale->text('Assembly') . "</a></th>"; + $column_header{production} = "<th width=10 class=listheading>" . $locale->text('Production') . "</th>"; + $column_header{completed} = "<th width=10 class=listheading>" . $locale->text('Completed') . "</th>"; + $column_header{name} = "<th class=listheading>" . $locale->text('Customer') . "</th>"; + + + $form->header; + + if (@{ $form->{all_project} }) { + $sameitem = $form->{all_project}->[0]->{$form->{sort}}; + } + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + # escape callback + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + # flip direction + $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC"; + $href =~ s/&direction=(\w+)&/&direction=$direction&/; + + foreach $ref (@{ $form->{all_project} }) { + + for (qw(description startdate enddate name)) { $column_data{$_} = qq|<td>$ref->{$_} </td>| } + + for (qw(production completed)) { $column_data{$_} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{$_}) } + + $column_data{projectnumber} = qq|<td><a href=$form->{script}?action=edit&type=$form->{type}&status=$form->{status}&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&project=$form->{project}&callback=$callback>$ref->{projectnumber}</td>|; + $column_data{partnumber} = qq|<td><a href=ic.pl?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber}</td>|; + + $j++; $j %= 2; + + print qq| + <tr valign=top class=listrow$j> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print " + </tr> +"; + } + + $i = 1; + if ($form->{type} eq 'project') { + if ($myconfig{acs} !~ /Projects--Projects/) { + $button{'Projects--Add Project'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Project').qq|"> |; + $button{'Projects--Add Project'}{order} = $i++; + + for (split /;/, $myconfig{acs}) { + delete $button{$_}; + } + } + } else { + if ($myconfig{acs} !~ /Job Costing--Job Costing/) { + $button{'Job Costing--Add Job'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Job').qq|"> |; + $button{'Job Costing--Add Job'}{order} = $i++; + + for (split /;/, $myconfig{acs}) { + delete $button{$_}; + } + } + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(callback type path login sessionid)); + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub project_header { + + $form->{description} = $form->quote($form->{description}); + + if (($rows = $form->numtextrows($form->{description}, 60)) > 1) { + $description = qq|<textarea name="description" rows=$rows cols=60 style="width: 100%" wrap=soft>$form->{description}</textarea>|; + } else { + $description = qq|<input name=description size=60 value="$form->{description}">|; + } + + $form->{"select$form->{vc}"} = $form->unescape($form->{"select$form->{vc}"}); + $form->{"select$form->{vc}"} =~ s/ selected//; + $form->{"select$form->{vc}"} =~ s/(<option value="\Q$form->{"$form->{vc}"}\E")/$1 selected/; + + $label = ucfirst $form->{vc}; + if ($form->{"select$form->{vc}"}) { + $name = qq| + <tr> + <th align=right nowrap>|.$locale->text($label).qq|</th> + <td colspan=3><select name="$form->{vc}">$form->{"select$form->{vc}"}</select></td> + <input type=hidden name="select$form->{vc}" value="|. + $form->escape($form->{"select$form->{vc}"},1).qq|"> + </tr> +|; + } else { + $name = qq| + <tr> + <th align=right nowrap>|.$locale->text($label).qq|</th> + <td colspan=3><input name="$form->{vc}" value="$form->{"$form->{vc}"}" size=35></td> + <input type=hidden name="select$form->{vc}" value="|. + $form->escape($form->{"select$form->{vc}"},1).qq|"> + </tr> +|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->hide_form("id", "type", "old$form->{vc}", "$form->{vc}_id", "orphaned","vc", "title"); + + print qq| +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Number').qq|</th> + <td><input name=projectnumber size=20 value="$form->{projectnumber}"></td> + <th align=right>|.$locale->text('Description').qq|</th> + <td>$description</td> + </tr> + $name + <tr> + <th align=right>|.$locale->text('Startdate').qq|</th> + <td><input name=startdate size=11 title="($myconfig{dateformat})" value=$form->{startdate}></td> + <th align=right>|.$locale->text('Enddate').qq|</th> + <td><input name=enddate size=11 title="($myconfig{dateformat})" value=$form->{enddate}></td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub project_footer { + + $form->hide_form(qw(callback path login sessionid)); + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + ); + + if ($myconfig{acs} !~ /Projects--Add Project/) { + $button{'Save'} = { ndx => 3, key => 'S', value => $locale->text('Save') }; + + if ($form->{id} && $form->{orphaned}) { + $button{'Delete'} = { ndx => 16, key => 'D', value => $locale->text('Delete') }; + } + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub save { + + if ($form->{translation}) { + PE->save_translation(\%myconfig, \%$form); + $form->redirect($locale->text('Translations saved!')); + exit; + } + + if ($form->{type} eq 'project') { + if ($form->{"select$form->{vc}"}) { + ($null, $form->{"$form->{vc}_id"}) = split /--/, $form->{"$form->{vc}"}; + } else { + if ($form->{"old$form->{vc}"} ne qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|) { + + if (($rv = $form->get_name(\%myconfig, $form->{vc}, $form->{startdate})) > 1) { + &select_name; + exit; + } + + if ($rv == 1) { + $form->{"$form->{vc}_id"} = $form->{name_list}[0]->{id}; + $form->{"$form->{vc}"} = $form->{name_list}[0]->{name}; + $form->{"old$form->{vc}"} = qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|; + } + } + } + + PE->save_project(\%myconfig, \%$form); + $form->redirect($locale->text('Project saved!')); + } + + if ($form->{type} eq 'partsgroup') { + $form->isblank("partsgroup", $locale->text('Group missing!')); + PE->save_partsgroup(\%myconfig, \%$form); + $form->redirect($locale->text('Group saved!')); + } + + if ($form->{type} eq 'pricegroup') { + $form->isblank("pricegroup", $locale->text('Pricegroup missing!')); + PE->save_pricegroup(\%myconfig, \%$form); + $form->redirect($locale->text('Pricegroup saved!')); + } + + + if ($form->{type} eq 'job') { + if ($form->{"select$form->{vc}"}) { + ($null, $form->{"$form->{vc}_id"}) = split /--/, $form->{"$form->{vc}"}; + } else { + if ($form->{"old$form->{vc}"} ne qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|) { + + if (($rv = $form->get_name(\%myconfig, $form->{vc}, $form->{startdate})) > 1) { + &select_name; + exit; + } + + if ($rv == 1) { + $form->{"$form->{vc}_id"} = $form->{name_list}[0]->{id}; + $form->{"$form->{vc}"} = $form->{name_list}[0]->{name}; + $form->{"old$form->{vc}"} = qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|; + } + } + } + + PE->save_job(\%myconfig, \%$form); + $form->redirect($locale->text('Job saved!')); + } + +} + + +sub delete { + + if ($form->{translation}) { + PE->delete_translation(\%myconfig, \%$form); + $form->redirect($locale->text('Translation deleted!')); + + } else { + + if ($form->{type} eq 'project') { + PE->delete_project(\%myconfig, \%$form); + $form->redirect($locale->text('Project deleted!')); + } + if ($form->{type} eq 'job') { + PE->delete_job(\%myconfig, \%$form); + $form->redirect($locale->text('Job deleted!')); + } + if ($form->{type} eq 'partsgroup') { + PE->delete_partsgroup(\%myconfig, \%$form); + $form->redirect($locale->text('Group deleted!')); + } + if ($form->{type} eq 'pricegroup') { + PE->delete_pricegroup(\%myconfig, \%$form); + $form->redirect($locale->text('Pricegroup deleted!')); + } + } + +} + + +sub partsgroup_report { + + $form->{partsgroup} = $form->unescape($form->{partsgroup}); + PE->partsgroups(\%myconfig, \%$form); + + $href = "$form->{script}?action=partsgroup_report&direction=$form->{direction}&oldsort=$form->{oldsort}&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}"; + + $form->sort_order(); + + $callback = "$form->{script}?action=partsgroup_report&direction=$form->{direction}&oldsort=$form->{oldsort}&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}"; + + if ($form->{status} eq 'all') { + $option = $locale->text('All'); + } + if ($form->{status} eq 'orphaned') { + $option .= $locale->text('Orphaned'); + } + if ($form->{partsgroup}) { + $callback .= "&partsgroup=$form->{partsgroup}"; + $option .= "\n<br>".$locale->text('Group')." : $form->{partsgroup}"; + } + + + @column_index = $form->sort_columns(qw(partsgroup)); + + $column_header{partsgroup} = qq|<th><a class=listheading href=$href&sort=partsgroup width=90%>|.$locale->text('Group').qq|</a></th>|; + + $form->{title} = $locale->text('Groups'); + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + # escape callback + $form->{callback} = $callback; + + # escape callback for href + $callback = $form->escape($callback); + + foreach $ref (@{ $form->{item_list} }) { + + $i++; $i %= 2; + + print qq| + <tr valign=top class=listrow$i> +|; + + $column_data{partsgroup} = qq|<td><a href=$form->{script}?action=edit&type=$form->{type}&status=$form->{status}&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partsgroup}</td>|; + for (@column_index) { print "$column_data{$_}\n" } + + print " + </tr> +"; + } + + $i = 1; + if ($myconfig{acs} !~ /Goods \& Services--Goods \& Services/) { + $button{'Goods & Services--Add Group'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Group').qq|"> |; + $button{'Goods & Services--Add Group'}{order} = $i++; + + foreach $item (split /;/, $myconfig{acs}) { + delete $button{$item}; + } + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(callback type path login sessionid)); + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub partsgroup_header { + + $form->{action} =~ s/_.*//; + $form->{title} = $locale->text(ucfirst $form->{action} . " Group"); + +# $locale->text('Add Group') +# $locale->text('Edit Group') + + $form->{partsgroup} = $form->quote($form->{partsgroup}); + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=id value=$form->{id}> +<input type=hidden name=type value=$form->{type}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr> + <th align=right>|.$locale->text('Group').qq|</th> + + <td><input name=partsgroup size=30 value="$form->{partsgroup}"></td> + </tr> + </table> + </td> + </tr> + <tr> + <td colspan=2><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub partsgroup_footer { + + $form->hide_form(qw(callback path login sessionid)); + + if ($myconfig{acs} !~ /Goods \& Services--Add Group/) { + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Save').qq|"> +|; + + if ($form->{id} && $form->{orphaned}) { + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Delete').qq|">|; + } + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub pricegroup_report { + + $form->{pricegroup} = $form->unescape($form->{pricegroup}); + PE->pricegroups(\%myconfig, \%$form); + + $href = "$form->{script}?action=pricegroup_report&direction=$form->{direction}&oldsort=$form->{oldsort}&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}"; + + $form->sort_order(); + + $callback = "$form->{script}?action=pricegroup_report&direction=$form->{direction}&oldsort=$form->{oldsort}&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}"; + + if ($form->{status} eq 'all') { + $option = $locale->text('All'); + } + if ($form->{status} eq 'orphaned') { + $option .= $locale->text('Orphaned'); + } + if ($form->{pricegroup}) { + $callback .= "&pricegroup=$form->{pricegroup}"; + $option .= "\n<br>".$locale->text('Pricegroup')." : $form->{pricegroup}"; + } + + + @column_index = $form->sort_columns(qw(pricegroup)); + + $column_header{pricegroup} = qq|<th><a class=listheading href=$href&sort=pricegroup width=90%>|.$locale->text('Pricegroup').qq|</th>|; + + $form->{title} = $locale->text('Pricegroups'); + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + # escape callback + $form->{callback} = $callback; + + # escape callback for href + $callback = $form->escape($callback); + + foreach $ref (@{ $form->{item_list} }) { + + $i++; $i %= 2; + + print qq| + <tr valign=top class=listrow$i> +|; + + $column_data{pricegroup} = qq|<td><a href=$form->{script}?action=edit&type=$form->{type}&status=$form->{status}&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{pricegroup}</td>|; + for (@column_index) { print "$column_data{$_}\n" } + + print " + </tr> +"; + } + + $i = 1; + if ($myconfig{acs} !~ /Goods \& Services--Goods \& Services/) { + $button{'Goods & Services--Add Pricegroup'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Pricegroup').qq|"> |; + $button{'Goods & Services--Add Pricegroup'}{order} = $i++; + + foreach $item (split /;/, $myconfig{acs}) { + delete $button{$item}; + } + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(callback type path login sessionid)); + + foreach $item (sort { $a->{order} <=> $b->{order} } %button) { + print $item->{code}; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub pricegroup_header { + + $form->{title} = $locale->text(ucfirst $form->{action} ." Pricegroup"); + +# $locale->text('Add Pricegroup') +# $locale->text('Edit Pricegroup') + + $form->{pricegroup} = $form->quote($form->{pricegroup}); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=id value=$form->{id}> +<input type=hidden name=type value=$form->{type}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr> + <th align=right>|.$locale->text('Pricegroup').qq|</th> + + <td><input name=pricegroup size=30 value="$form->{pricegroup}"></td> + </tr> + </table> + </td> + </tr> + <tr> + <td colspan=2><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub pricegroup_footer { + + $form->hide_form(qw(callback path login sessionid)); + + if ($myconfig{acs} !~ /Goods \& Services--Add Pricegroup/) { + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Save').qq|"> +|; + + if ($form->{id} && $form->{orphaned}) { + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Delete').qq|">|; + } + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub translation { + + if ($form->{translation} eq 'description') { + $form->{title} = $locale->text('Description Translations'); + $sort = qq|<input type=hidden name=sort value=partnumber>|; + $form->{number} = "partnumber"; + $number = qq| + <tr> + <th align=right nowrap>|.$locale->text('Number').qq|</th> + <td><input name=partnumber size=20></td> + </tr> +|; + } + + if ($form->{translation} eq 'partsgroup') { + $form->{title} = $locale->text('Group Translations'); + $sort = qq|<input type=hidden name=sort value=partsgroup>|; + } + + if ($form->{translation} eq 'project') { + $form->{title} = $locale->text('Project Description Translations'); + $form->{number} = "projectnumber"; + $sort = qq|<input type=hidden name=sort value=projectnumber>|; + $number = qq| + <tr> + <th align=right nowrap>|.$locale->text('Project Number').qq|</th> + <td><input name=projectnumber size=20></td> + </tr> +|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> +|; + + $form->hide_form(qw(translation title number)); + + print qq| + +<table width="100%"> + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + $number + <tr> + <th align=right nowrap>|.$locale->text('Description').qq|</th> + <td colspan=3><input name=description size=40></td> + </tr> + </table> + </td> + </tr> + <tr><td><hr size=3 noshade></td></tr> +</table> + +<input type=hidden name=nextsub value=list_translations> +$sort +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| + +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub list_translations { + + $title = $form->escape($form->{title},1); + + $callback = "$form->{script}?action=list_translations&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&translation=$form->{translation}&number=$form->{number}&title=$title"; + + if ($form->{"$form->{number}"}) { + $callback .= qq|&$form->{number}=$form->{"$form->{number}"}|; + $option .= $locale->text('Number').qq| : $form->{"$form->{number}"}<br>|; + } + if ($form->{description}) { + $callback .= "&description=$form->{description}"; + $description = $form->{description}; + $description =~ s/\r?\n/<br>/g; + $option .= $locale->text('Description').qq| : $form->{description}<br>|; + } + + if ($form->{translation} eq 'partsgroup') { + @column_index = qw(description language translation); + $form->{sort} = ""; + } else { + @column_index = $form->sort_columns("$form->{number}", "description", "language", "translation"); + } + + &{ "PE::$form->{translation}_translations" }("", \%myconfig, \%$form); + + $callback .= "&direction=$form->{direction}&oldsort=$form->{oldsort}"; + + $href = $callback; + + $form->sort_order(); + + $callback =~ s/(direction=).*\&{1}/$1$form->{direction}\&/; + + $column_header{"$form->{number}"} = qq|<th nowrap><a class=listheading href=$href&sort=$form->{number}>|.$locale->text('Number').qq|</a></th>|; + $column_header{description} = qq|<th nowrap width=40%><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|; + $column_header{language} = qq|<th nowrap class=listheading>|.$locale->text('Language').qq|</a></th>|; + $column_header{translation} = qq|<th nowrap width=40% class=listheading>|.$locale->text('Translation').qq|</a></th>|; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + + <tr><td>$option</td></tr> + + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> + |; + + + # add order to callback + $form->{callback} = $callback .= "&sort=$form->{sort}"; + + # escape callback for href + $callback = $form->escape($callback); + + if (@{ $form->{translations} }) { + $sameitem = $form->{translations}->[0]->{$form->{sort}}; + } + + foreach $ref (@{ $form->{translations} }) { + + $ref->{description} =~ s/\r?\n/<br>/g; + + for (@column_index) { $column_data{$_} = "<td>$ref->{$_} </td>" } + + $column_data{description} = "<td><a href=$form->{script}?action=edit_translation&translation=$form->{translation}&number=$form->{number}&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{description} </a></td>"; + + $i++; $i %= 2; + print "<tr class=listrow$i>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + } + + print qq| + </table> + </td> + </tr> + <tr><td><hr size=3 noshade></td></tr> +</table> + +|; + + print qq| + +<br> + +<form method=post action=$form->{script}> + +<input name=callback type=hidden value="$form->{callback}"> +|; + + $form->hide_form(qw(path login sessionid)); + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + </form> + +</body> +</html> +|; + +} + + +sub edit_translation { + + &{ "PE::$form->{translation}_translations" }("", \%myconfig, \%$form); + + $form->error($locale->text('Languages not defined!')) unless @{ $form->{all_language} }; + + $form->{selectlanguage} = qq|<option>\n|; + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + + $form->{"$form->{number}"} = $form->{translations}->[0]->{"$form->{number}"}; + $form->{description} = $form->{translations}->[0]->{description}; + $form->{description} =~ s/\r?\n/<br>/g; + + shift @{ $form->{translations} }; + + $i = 1; + foreach $row (@{ $form->{translations} }) { + $form->{"language_code_$i"} = $row->{code}; + $form->{"translation_$i"} = $row->{translation}; + $i++; + } + $form->{translation_rows} = $i - 1; + + $form->{title} = $locale->text('Edit Description Translations'); + + &translation_header; + &translation_footer; + +} + + +sub translation_header { + + $form->{translation_rows}++; + + $form->{selectlanguage} = $form->unescape($form->{selectlanguage}); + for $i (1 .. $form->{translation_rows}) { + $form->{"selectlanguage_$i"} = $form->{selectlanguage}; + if ($form->{"language_code_$i"}) { + $form->{"selectlanguage_$i"} =~ s/(<option value="\Q$form->{"language_code_$i"}\E")/$1 selected/; + } + } + + $form->{selectlanguage} = $form->escape($form->{selectlanguage},1); + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=$form->{number} value="|.$form->quote($form->{"$form->{number}"}).qq|"> +<input type=hidden name=description value="|.$form->quote($form->{description}).qq|"> +|; + + $form->hide_form(qw(id trans_id selectlanguage translation_rows number translation title)); + + print qq| + +<table width="100%"> + <tr><th class=listtop>$form->{title}</th></tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table width=100%> + <tr> + <td align=left>$form->{"$form->{number}"}</th> + <td align=left>$form->{description}</th> + </tr> + <tr> + <tr> + <th class=listheading>|.$locale->text('Language').qq|</th> + <th class=listheading>|.$locale->text('Translation').qq|</th> + </tr> +|; + + for $i (1 .. $form->{translation_rows}) { + + if (($rows = $form->numtextrows($form->{"translation_$i"}, 40)) > 1) { + $translation = qq|<textarea name="translation_$i" rows=$rows cols=40 wrap=soft>$form->{"translation_$i"}</textarea>|; + } else { + $translation = qq|<input name="translation_$i" size=40 value="$form->{"translation_$i"}">|; + } + + print qq| + <tr valign=top> + <td><select name="language_code_$i">$form->{"selectlanguage_$i"}</select></td> + <td>$translation</td> + </tr> +|; + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + +} + + +sub translation_footer { + + $form->hide_form(qw(path login sessionid callback)); + + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Save' => { ndx => 3, key => 'S', value => $locale->text('Save') }, + 'Delete' => { ndx => 16, key => 'D', value => $locale->text('Delete') }, + ); + + if (! $form->{trans_id}) { + delete $button{'Delete'}; + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + + </form> + +</body> +</html> +|; + +} + + +sub update { + + if ($form->{translation}) { + @flds = qw(language translation); + $count = 0; + @a = (); + for $i (1 .. $form->{translation_rows}) { + if ($form->{"language_code_$i"} ne "") { + push @a, {}; + $j = $#a; + + for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} } + $count++; + } + } + $form->redo_rows(\@flds, \@a, $count, $form->{translation_rows}); + $form->{translation_rows} = $count; + + &translation_header; + &translation_footer; + + exit; + + } + + if ($form->{type} =~ /(job|project)/) { + +# $locale->text('Customer not on file!') +# $locale->text('Vendor not on file!') + + for (qw(production listprice sellprice weight)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + + $form->{projectnumber} = $form->update_defaults(\%myconfig, "projectnumber") unless $form->{projectnumber}; + + if ($form->{"select$form->{vc}"}) { + if ($form->{startdate} ne $form->{oldstartdate} || $form->{enddate} ne $form->{oldenddate}) { + + PE->get_customer(\%myconfig, \%$form); + + if (@{ $form->{"all_$form->{vc}"} }) { + $form->{"select$form->{vc}"} = qq|<option>\n|; + for (@{ $form->{"all_$form->{vc}"} }) { $form->{"select$form->{vc}"} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + } + } + + $form->{"old$form->{vc}"} = $form->{"$form->{vc}"}; + ($null, $form->{"$form->{vc}_id"}) = split /--/, $form->{"$form->{vc}"}; + + } else { + + if ($form->{"old$form->{vc}"} ne qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|) { + + if (($rv = $form->get_name(\%myconfig, $form->{vc}, $form->{startdate})) > 1) { + &select_name; + exit; + } + + if ($rv == 1) { + $form->{"$form->{vc}_id"} = $form->{name_list}[0]->{id}; + $form->{"$form->{vc}"} = $form->{name_list}[0]->{name}; + $form->{"old$form->{vc}"} = qq|$form->{"$form->{vc}"}--$form->{"$form->{vc}_id"}|; + } else { + $msg = ucfirst $form->{vc} ." not on file!"; + $form->error($locale->text($msg)); + } + } + } + } + + &display_form; + +} + + +sub select_name { + + $label = ucfirst $form->{vc}; + + @column_index = qw(ndx name address); + $column_data{ndx} = qq|<th> </th>|; + $column_data{name} = qq|<th class=listheading>|.$locale->text($label).qq|</th>|; + $column_data{address} = qq|<th class=listheading colspan=5>|.$locale->text('Address').qq|</th>|; + + $form->header; + $title = $locale->text('Select from one of the names below'); + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$title</th> + </tr> + <tr space=5></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + @column_index = qw(ndx name address city state zipcode country); + + my $i = 0; + foreach $ref (@{ $form->{name_list} }) { + $checked = ($i++) ? "" : "checked"; + + $ref->{name} = $form->quote($ref->{name}); + + $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|; + $column_data{name} = qq|<td><input name="new_name_$i" type=hidden value="$ref->{name}">$ref->{name}</td>|; + $column_data{address} = qq|<td>$ref->{address1} $ref->{address2}</td>|; + for (qw(city state zipcode country)) { $column_data{$_} = qq|<td>$ref->{$_} </td>| } + + $j++; $j %= 2; + print qq| + <tr class=listrow$j>|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> + +<input name="new_id_$i" type=hidden value=$ref->{id}> + +|; + + } + + print qq| + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input name=lastndx type=hidden value=$i> + +|; + + # delete variables + for (qw(action nextsub name_list)) { delete $form->{$_} } + + $form->hide_form; + + print qq| +<input type=hidden name=nextsub value=name_selected> +<br> +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub name_selected { + + # replace the variable with the one checked + + # index for new item + $i = $form->{ndx}; + + $form->{$form->{vc}} = $form->{"new_name_$i"}; + $form->{"$form->{vc}_id"} = $form->{"new_id_$i"}; + $form->{"old$form->{vc}"} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|; + + # delete all the new_ variables + for $i (1 .. $form->{lastndx}) { + for (qw(id name)) { delete $form->{"new_${_}_$i"} } + } + + for (qw(ndx lastndx nextsub)) { delete $form->{$_} } + + &display_form; + +} + + +sub display_form { + + &{ "$form->{type}_header" }; + &{ "$form->{type}_footer" }; + +} + +sub continue { &{ $form->{nextsub} } }; + +sub add_group { &add } +sub add_project { &add } +sub add_job { &add } +sub add_pricegroup { &add } + + + +sub project_sales_order { + + PE->project_sales_order(\%myconfig, \%$form); + + if (@{ $form->{all_years} }) { + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + $fromto = qq| + <tr> + <th align=right nowrap>|.$locale->text('Transaction Dates').qq|</th> + <td>|.$locale->text('From').qq| <input name=transdatefrom size=11 title="$myconfig{dateformat}"> + |.$locale->text('To').qq| <input name=transdateto size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom +|; + + if (@{ $form->{all_project} }) { + $form->{selectprojectnumber} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + } else { + $form->error($locale->text('No open Projects!')); + } + + if (@{ $form->{all_employee} }) { + $form->{selectemployee} = "<option>\n"; + for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + + $employee = qq| + <tr> + <th align=right nowrap>|.$locale->text('Employee').qq|</th> + <td><select name=employee>$form->{selectemployee}</select></td> + </tr> +|; + } + + $form->{title} = $locale->text('Generate Sales Orders'); + $form->{vc} = "customer"; + $form->{type} = "sales_order"; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr valign=top> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Project').qq|</th> + <td colspan=3><select name=projectnumber>$form->{selectprojectnumber}</select></td> + </tr> + $employee + $fromto + <tr> + <th></th> + <td><input name=summary type=radio class=radio value=1 checked> |.$locale->text('Summary').qq| + <input name=summary type=radio class=radio value=0> |.$locale->text('Detail').qq| + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +|; + + $form->{nextsub} = "project_jcitems_list"; + $form->hide_form(qw(path login sessionid nextsub type vc)); + + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> + +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub project_jcitems_list { + + $form->{projectnumber} = $form->unescape($form->{projectnumber}); + $form->{employee} = $form->unescape($form->{employee}); + $form->{callback} = "$form->{script}?action=project_jcitems_list"; + for (qw(month year interval summary transdatefrom transdateto login path sessionid nextsub type vc)) { $form->{callback} .= "&$_=$form->{$_}" } + for (qw(employe projectnumber)) { $form->{callback} .= "&$_=".$form->escape($form->{$_},1) } + + PE->get_jcitems(\%myconfig, \%$form); + + # flatten array + $i = 1; + foreach $ref (@{ $form->{jcitems} }) { + + if ($form->{summary}) { + + $thisitem = qq|$ref->{project_id}:$ref->{"$form->{vc}_id"}:$ref->{parts_id}|; + + if ($thisitem eq $sameitem) { + + $i--; + for (qw(qty amount)) { $form->{"${_}_$i"} += $ref->{$_} } + $form->{"id_$i"} .= " $ref->{id}:$ref->{qty}"; + if ($form->{"notes_$i"}) { + $form->{"notes_$i"} .= qq|\n\n$ref->{notes}|; + } else { + $form->{"notes_$i"} = $ref->{notes}; + } + + } else { + + for (keys %$ref) { $form->{"${_}_$i"} = $ref->{$_} } + + $form->{"checked_$i"} = 1; + $form->{"$form->{vc}_$i"} = $ref->{$form->{vc}}; + $form->{"id_$i"} = "$ref->{id}:$ref->{qty}"; + + } + + $sameitem = qq|$ref->{project_id}:$ref->{"$form->{vc}_id"}:$ref->{parts_id}|; + } else { + + for (keys %$ref) { $form->{"${_}_$i"} = $ref->{$_} } + $form->{"checked_$i"} = 1; + $form->{"id_$i"} = "$ref->{id}:$ref->{qty}"; + + } + + $i++; + + } + + $form->{rowcount} = $i - 1; + + for $i (1 .. $form->{rowcount}) { + for (qw(qty allocated)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}) } + for (qw(amount sellprice)) { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } + } + + &jcitems; + +} + + +sub jcitems { + +# $locale->text('Customer') +# $locale->text('Vendor') + + $vc = ucfirst $form->{vc}; + + @column_index = qw(id projectnumber name); + if (!$form->{summary}) { + push @column_index, qw(transdate); + } + push @column_index, qw(partnumber description qty amount); + + $column_header{id} = qq|<th> </th>|; + $column_header{transdate} = qq|<th class=listheading>|.$locale->text('Date').qq|</th>|; + $column_header{partnumber} = qq|<th class=listheading>|.$locale->text('Service Code').qq|<br>|.$locale->text('Part Number').qq|</th>|; + $column_header{projectnumber} = qq|<th class=listheading>|.$locale->text('Project Number').qq|</th>|; + $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|; + $column_header{name} = qq|<th class=listheading>$vc</th>|; + $column_header{qty} = qq|<th class=listheading>|.$locale->text('Qty').qq|</th>|; + $column_header{amount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|; + + if ($form->{type} eq 'sales_order') { + $form->{title} = $locale->text('Generate Sales Orders'); + } + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + for $i (1 .. $form->{rowcount}) { + + for (@column_index) { $column_data{$_} = qq|<td>$form->{"${_}_$i"}</td>| } + for (qw(qty amount)) { $column_data{$_} = qq|<td align=right>$form->{"${_}_$i"}</td>| } + + $checked = ($form->{"checked_$i"}) ? "checked" : ""; + $column_data{id} = qq|<td><input name="checked_$i" class=checkbox type=checkbox value="1" $checked></td>|; + + if ($form->{"$form->{vc}_id_$i"}) { + $column_data{name} = qq|<td>$form->{"$form->{vc}_$i"}</td>|; + $form->hide_form("$form->{vc}_id_$i", "$form->{vc}_$i"); + } else { + $column_data{name} = qq|<td><input name="ndx_$i" class=checkbox type=checkbox value="1"></td>|; + } + + for (qw(projectnumber partnumber description notes)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}) } + $form->hide_form(map {"${_}_$i"} qw(id project_id parts_id projectnumber transdate partnumber description notes qty amount taxaccounts sellprice)); + + $j++; $j %= 2; + print " + <tr class=listrow$j>"; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + } + + print qq| + </table> + </td> + </tr> + + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +|; + + $form->hide_form(qw(path login sessionid vc nextsub rowcount type currency defaultcurrency taxaccounts summary callback)); + + for (split / /, $form->{taxaccounts}) { $form->hide_form("${_}_rate") } + + if ($form->{rowcount}) { + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Generate Sales Orders').qq|">|; + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Select Customer').qq|">|; + + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub select_customer { + + for (1 .. $form->{rowcount}) { + last if ($ok = $form->{"ndx_$_"}); + } + + $form->error($locale->text('Nothing selected!')) unless $ok; + + $label = ($form->{vc} eq 'customer') ? $locale->text('Customer') : $locale->text('Vendor'); + + $form->header; + + print qq| +<body onLoad="document.forms[0].$form->{vc}.focus()" /> + +<form method=post action=$form->{script}> + +<b>$label</b> <input name=$form->{vc} size=40> + +|; + + $form->{nextsub} = "$form->{vc}_selected"; + $form->{action} = "$form->{vc}_selected"; + + $form->hide_form; + + print qq| +<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|"> + +</form> +|; + + print qq| + +</body> +</html> +|; + +} + + +sub customer_selected { + + if (($rv = $form->get_name(\%myconfig, $form->{vc}, $form->{startdate})) > 1) { + &select_name($form->{vc}); + exit; + } + + if ($rv == 1) { + $form->{"$form->{vc}"} = $form->{name_list}[0]->{name}; + $form->{"$form->{vc}_id"} = $form->{name_list}[0]->{id}; + } else { + $msg = ($form->{vc} eq 'customer') ? $locale->text('Customer not on file!') : $locale->text('Vendor not on file!'); + $form->error($locale->text($msg)); + } + + &display_form; + +} + + +sub sales_order_header { + + for (1 .. $form->{rowcount}) { + if ($form->{"ndx_$_"}) { + $form->{"$form->{vc}_id_$_"} = $form->{"$form->{vc}_id"}; + $form->{"$form->{vc}_$_"} = $form->{"$form->{vc}"}; + } + } + +} + +sub sales_order_footer { &jcitems } + + +sub generate_sales_orders { + + for $i (1 .. $form->{rowcount}) { + $form->error($locale->text('Customer missing!')) if ($form->{"checked_$i"} && !$form->{"customer_$i"}); + } + + for $i (1 .. $form->{rowcount}) { + if ($form->{"checked_$i"}) { + push @{ $form->{order}{qq|$form->{"customer_id_$i"}|} }, { + partnumber => $form->{"partnumber_$i"}, + id => $form->{"parts_id_$i"}, + description => $form->{"description_$i"}, + qty => $form->{"qty_$i"}, + sellprice => $form->{"sellprice_$i"}, + projectnumber => qq|--$form->{"project_id_$i"}|, + reqdate => $form->{"transdate_$i"}, + taxaccounts => $form->{"taxaccounts_$i"}, + jcitems => $form->{"id_$i"}, + notes => $form->{"notes_$i"}, + } + } + } + + $order = new Form; + for (keys %{ $form->{order} }) { + + for (qw(type vc defaultcurrency login)) { $order->{$_} = $form->{$_} } + for (split / /, $form->{taxaccounts}) { $order->{"${_}_rate"} = $form->{"${_}_rate"} } + + $i = 0; + $order->{"$order->{vc}_id"} = $_; + + AA->get_name(\%myconfig, \%$order); + + foreach $ref (@ {$form->{order}{$_} }) { + $i++; + + for (keys %$ref) { $order->{"${_}_$i"} = $ref->{$_} } + + $taxaccounts = ""; + for (split / /, $order->{taxaccounts}) { $taxaccounts .= qq|$_ | if ($_ =~ /$order->{"taxaccounts_$i"}/) } + $order->{"taxaccounts_$i"} = $taxaccounts; + + } + $order->{rowcount} = $i; + + for (qw(currency)) { $order->{$_} = $form->{$_} } + + $order->{ordnumber} = $order->update_defaults(\%myconfig, 'sonumber'); + $order->{transdate} = $order->current_date(\%myconfig); + $order->{reqdate} = $order->{transdate}; + + for (qw(intnotes employee employee_id)) { delete $order->{$_} } + + if (OE->save(\%myconfig, \%$order)) { + if (! PE->allocate_projectitems(\%myconfig, \%$order)) { + OE->delete(\%myconfig, \%$order, $spool); + } + } else { + $order->error($locale->text('Failed to save order!')); + } + + for (keys %$order) { delete $order->{$_} } + + } + + $form->redirect($locale->text('Orders generated!')); + +} + + diff --git a/bin/lynx/pos.pl b/bin/lynx/pos.pl new file mode 100755 index 00000000..ca6a87b4 --- /dev/null +++ b/bin/lynx/pos.pl @@ -0,0 +1,938 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2003 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: Steve Doerr <sdoerr907@everestkc.net> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#===================================================================== +# +# POS +# +#===================================================================== + + +1; +# end + + +sub add { + + $form->{title} = $locale->text('Add POS Invoice'); + + $form->{callback} = "$form->{script}?action=$form->{nextsub}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &invoice_links; + + $form->{type} = "pos_invoice"; + $form->{format} = "txt"; + $form->{media} = ($myconfig{printer}) ? $myconfig{printer} : "screen"; + $form->{rowcount} = 0; + + $form->{readonly} = ($myconfig{acs} =~ /POS--Sale/) ? 1 : 0; + + $ENV{REMOTE_ADDR} =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/; + $form->{till} = $4; + + $form->{partsgroup} = ""; + for (@{ $form->{all_partsgroup} }) { $form->{partsgroup} .= "$_->{partsgroup}--$_->{translation}\n"; } + + &display_form; + +} + + +sub openinvoices { + + $ENV{REMOTE_ADDR} =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/; + $form->{till} = $4; + + $form->{sort} = 'transdate'; + + for (qw(open l_invnumber l_transdate l_name l_amount l_curr l_till l_subtotal)) { $form->{$_} = 'Y'; } + + if ($myconfig{role} ne 'user') { + $form->{l_employee} = 'Y'; + } + + $form->{title} = $locale->text('Open'); + transactions; + +} + + +sub edit { + + $form->{title} = $locale->text('Edit POS Invoice'); + + $form->{callback} = "$form->{script}?action=$form->{nextsub}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback}; + + &invoice_links; + &prepare_invoice; + + $form->{type} = "pos_invoice"; + $form->{format} = "txt"; + $form->{media} = ($myconfig{printer}) ? $myconfig{printer} : "screen"; + + $form->{readonly} = ($myconfig{acs} =~ /POS--Sale/) ? 1 : 0; + + $form->{partsgroup} = ""; + for (@{ $form->{all_partsgroup} }) { $form->{partsgroup} .= "$_->{partsgroup}--$_->{translation}\n"; } + + &display_form; + +} + + +sub form_header { + + # set option selected + for (qw(AR currency)) { + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/option>\Q$form->{$_}\E/option selected>$form->{$_}/; + } + + for (qw(customer department employee)) { + $form->{"select$_"} = $form->unescape($form->{"select$_"}); + $form->{"select$_"} =~ s/ selected//; + $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/; + } + + $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate}); + + $exchangerate = qq|<tr>|; + $exchangerate .= qq| + <th align=right nowrap>|.$locale->text('Currency').qq|</th> + <td><select name=currency>$form->{selectcurrency}</select></td> | if $form->{defaultcurrency}; + $exchangerate .= qq| + <input type=hidden name=selectcurrency value="$form->{selectcurrency}"> + <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}> +|; + + if ($form->{defaultcurrency} && $form->{currency} ne $form->{defaultcurrency}) { + if ($form->{forex}) { + $exchangerate .= qq|<th align=right>|.$locale->text('Exchange Rate').qq|</th><td>$form->{exchangerate}<input type=hidden name=exchangerate value=$form->{exchangerate}></td>|; + } else { + $exchangerate .= qq|<th align=right>|.$locale->text('Exchange Rate').qq|</th><td><input name=exchangerate size=10 value=$form->{exchangerate}></td>|; + } + } + $exchangerate .= qq| +<input type=hidden name=forex value=$form->{forex}> +</tr> +|; + + if ($form->{selectcustomer}) { + $customer = qq|<select name=customer>$form->{selectcustomer}</select> + <input type=hidden name="selectcustomer" value="|. + $form->escape($form->{selectcustomer},1).qq|">|; + } else { + $customer = qq|<input name=customer value="$form->{customer}" size=35>|; + } + + $department = qq| + <tr> + <th align="right" nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select> + <input type=hidden name=selectdepartment value="|. + $form->escape($form->{selectdepartment},1).qq|"> + </td> + </tr> +| if $form->{selectdepartment}; + + $employee = qq| + <tr> + <th align=right nowrap>|.$locale->text('Salesperson').qq|</th> + <td colspan=3><select name=employee>$form->{selectemployee}</select></td> + <input type=hidden name=selectemployee value="|. + $form->escape($form->{selectemployee},1).qq|"> + </tr> +| if $form->{selectemployee}; + + if ($form->{change} != $form->{oldchange}) { + $form->{creditremaining} -= $form->{oldchange}; + } + $n = ($form->{creditremaining} < 0) ? "0" : "1"; + + if ($form->{business}) { + $business = qq| + <tr> + <th align=right nowrap>|.$locale->text('Business').qq|</th> + <td>$form->{business}</td> + <td width=10></td> + <th align=right nowrap>|.$locale->text('Trade Discount').qq|</th> + <td>|.$form->format_amount(\%myconfig, $form->{tradediscount} * 100).qq| %</td> + </tr> +|; + } + + if ($form->{selectlanguage}) { + if ($form->{language_code} ne $form->{oldlanguage_code}) { + # rebuild partsgroup + $form->get_partsgroup(\%myconfig, { language_code => $form->{language_code}, searchitems => 'nolabor'}); + $form->{partsgroup} = ""; + for (@{ $form->{all_partsgroup} }) { $form->{partsgroup} .= "$_->{partsgroup}--$_->{translation}\n"; } + $form->{oldlanguage_code} = $form->{language_code}; + } + + + $form->{"selectlanguage"} = $form->unescape($form->{"selectlanguage"}); + $form->{"selectlanguage"} =~ s/ selected//; + $form->{"selectlanguage"} =~ s/(<option value="\Q$form->{language_code}\E")/$1 selected/; + $lang = qq| + <tr> + <th align=right>|.$locale->text('Language').qq|</th> + <td colspan=3><select name=language_code>$form->{selectlanguage}</select></td> + </tr> + <input type=hidden name=oldlanguage_code value=$form->{oldlanguage_code}> + <input type=hidden name=selectlanguage value="|. + $form->escape($form->{selectlanguage},1).qq|">|; + } + + $i = $form->{rowcount} + 1; + $focus = "partnumber_$i"; + + $form->header; + + print qq| +<body onLoad="document.forms[0].${focus}.focus()" /> + +<form method=post action="$form->{script}"> +|; + + $form->hide_form(qw(id till type format printed title discount creditlimit creditremaining tradediscount business closedto locked oldtransdate customer_id oldcustomer)); + + print qq| +<input type=hidden name=vc value="customer"> + +<table width=100%> + <tr class=listtop> + <th class=listtop>$form->{title}</font></th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Customer').qq|</th> + <td colspan=3>$customer</td> + </tr> + <tr> + <td></td> + <td colspan=3> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Credit Limit').qq|</th> + <td>$form->{creditlimit}</td> + <td width=10></td> + <th align=right nowrap>|.$locale->text('Remaining').qq|</th> + <td class="plus$n">|.$form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0").qq|</font></td> + </tr> + $business + </table> + </td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Record in').qq|</th> + <td colspan=3><select name=AR>$form->{selectAR}</select></td> + <input type=hidden name=selectAR value="$form->{selectAR}"> + </tr> + $department + </table> + </td> + <td> + <table> + $employee + $exchangerate + $lang + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + </td> + </tr> +|; + + $form->hide_form(qw(taxaccounts duedate invnumber transdate selectcurrency defaultcurrency)); + + for (split / /, $form->{taxaccounts}) { + $form->hide_form("${_}_rate", "${_}_description", "${_}_taxnumber"); + } + +} + + + +sub form_footer { + + $form->{invtotal} = $form->{invsubtotal}; + + $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : ""; + + $taxincluded = ""; + if ($form->{taxaccounts}) { + $taxincluded = qq| + <tr height="5"></tr> + <tr> + <td align=right> + <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td><th align=left>|.$locale->text('Tax Included').qq|</th> + </tr> +|; + } + + if (!$form->{taxincluded}) { + + for (split / /, $form->{taxaccounts}) { + if ($form->{"${_}_base"}) { + $form->{"${_}_total"} = $form->round_amount($form->{"${_}_base"} * $form->{"${_}_rate"}, 2); + $form->{invtotal} += $form->{"${_}_total"}; + $form->{"${_}_total"} = $form->format_amount(\%myconfig, $form->{"${_}_total"}, 2, 0); + + $tax .= qq| + <tr> + <th align=right>$form->{"${_}_description"}</th> + <td align=right>$form->{"${_}_total"}</td> + </tr> +|; + } + } + + $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0); + + $subtotal = qq| + <tr> + <th align=right>|.$locale->text('Subtotal').qq|</th> + <td align=right>$form->{invsubtotal}</td> + </tr> +|; + } + + @column_index = qw(paid source memo AR_paid); + + $column_data{paid} = "<th>".$locale->text('Amount')."</th>"; + $column_data{source} = "<th>".$locale->text('Source')."</th>"; + $column_data{memo} = "<th>".$locale->text('Memo')."</th>"; + $column_data{AR_paid} = "<th> </th>"; + + print qq| + <tr> + <td> + <table width=100%> + <tr valign=top> + <td> + <table> + <tr> +|; + + for (@column_index) { print "$column_data{$_}\n"; } + + print qq| + </tr> +|; + + $totalpaid = 0; + + $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"}); + for $i (1 .. $form->{paidaccounts}) { + + $form->{"selectAR_paid_$i"} = $form->{selectAR_paid}; + $form->{"selectAR_paid_$i"} =~ s/option>\Q$form->{"AR_paid_$i"}\E/option selected>$form->{"AR_paid_$i"}/; + + # format amounts + $totalpaid += $form->{"paid_$i"}; + $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2); + $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"}); + + + $column_data{paid} = qq|<td><input name="paid_$i" size=11 value=$form->{"paid_$i"}></td>|; + $column_data{source} = qq|<td><input name="source_$i" size=10 value="$form->{"source_$i"}"></td>|; + $column_data{memo} = qq|<td><input name="memo_$i" size=10 value="$form->{"memo_$i"}"></td>|; + $column_data{AR_paid} = qq|<td><select name="AR_paid_$i">$form->{"selectAR_paid_$i"}</select></td>|; + + print qq| + <tr> +|; + for (@column_index) { print "$column_data{$_}\n"; } + + print qq| + </tr> +|; + + $form->hide_form("cleared_$i", "exchangerate_$i", "forex_$i"); + + } + + $form->{change} = 0; + if ($totalpaid > $form->{invtotal}) { + $form->{change} = $totalpaid - $form->{invtotal}; + } + $form->{oldchange} = $form->{change}; + $form->{change} = $form->format_amount(\%myconfig, $form->{change}, 2, 0); + $form->{totalpaid} = $form->format_amount(\%myconfig, $totalpaid, 2); + + $form->{oldinvtotal} = $form->{invtotal}; + $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0); + + print qq| + <tr> + <th align=right>|.$locale->text('Change').qq|</th> + <th>$form->{change}</th> + </tr> + </table> + </td> + <td align=right> + <table> + $subtotal + $tax + <tr> + <th align=right>|.$locale->text('Total').qq|</th> + <td align=right>$form->{invtotal}</td> + </tr> + $taxincluded + </table> + </td> + </tr> + </table> + </td> + </tr> + +<input type=hidden name=oldtotalpaid value=$totalpaid> +<input type=hidden name=datepaid value=$form->{transdate}> + +<tr> + <td> +|; + + $form->hide_form(qw(paidaccounts selectAR_paid oldinvtotal change oldchange invtotal)); + + &print_options; + + print qq| + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + $transdate = $form->datetonum(\%myconfig, $form->{transdate}); + $closedto = $form->datetonum(\%myconfig, $form->{closedto}); + +# type=submit $locale->text('Update') +# type=submit $locale->text('Print') +# type=submit $locale->text('Post') +# type=submit $locale->text('Print and Post') +# type=submit $locale->text('Delete') + + if (! $form->{readonly}) { + %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') }, + 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') }, + 'Post' => { ndx => 3, key => 'O', value => $locale->text('Post') }, + 'Print and Post' => { ndx => 4, key => 'R', value => $locale->text('Print and Post') }, + 'Delete' => { ndx => 5, key => 'D', value => $locale->text('Delete') }, + ); + + if ($transdate > $closedto) { + + if (! $form->{id}) { + delete $button{'Delete'}; + } + + delete $button{'Print and Post'} unless $latex; + } else { + for ('Print', 'Post', 'Print and Post', 'Delete') { delete $button{$_} } + } + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + print qq|<p> + <input type=text size=1 value="B" accesskey="B" title="[Alt-B]">\n|; + + if ($form->{partsgroup}) { + $form->{partsgroup} =~ s/\r//g; + $form->{partsgroup} = $form->quote($form->{partsgroup}); + + $spc = ($form->{path} =~ /lynx/) ? "." : " "; + print qq| +<input type=hidden name=nextsub value=lookup_partsgroup> +<input type=hidden name=partsgroup value="$form->{partsgroup}">|; + + foreach $item (split /\n/, $form->{partsgroup}) { + ($partsgroup, $translation) = split /--/, $item; + $item = ($translation) ? $translation : $partsgroup; + print qq| <input class=submit type=submit name=action value="$spc$item">\n| if $item; + } + } + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + $form->hide_form(qw(rowcount callback path login sessionid)); + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub post { + + $form->isblank("customer", $locale->text('Customer missing!')); + + # if oldcustomer ne customer redo form + $customer = $form->{customer}; + $customer =~ s/--.*//g; + $customer .= "--$form->{customer_id}"; + if ($customer ne $form->{oldcustomer}) { + &update; + exit; + } + + &validate_items; + + $form->isblank("exchangerate", $locale->text('Exchange rate missing!')) if ($form->{currency} ne $form->{defaultcurrency}); + + $paid = 0; + for (1 .. $form->{paidaccounts}) { $paid += $form->parse_amount(\%myconfig, $form->{"paid_$_"}); } + delete $form->{datepaid} unless $paid; + + $total = $form->parse_amount(\%myconfig, $form->{invtotal}); + + # deduct change from first payment + $form->{"paid_1"} = $form->format_amount(\%myconfig, $form->parse_amount(\%myconfig, $form->{"paid_1"}) - ($paid - $total), 2) if $paid > $total; + + ($form->{AR}) = split /--/, $form->{AR}; + + if (IS->post_invoice(\%myconfig, \%$form)) { + $form->redirect($locale->text('Posted!')); + } else { + $form->error($locale->text('Cannot post transaction!')); + } + +} + + +sub display_row { + my $numrows = shift; + + @column_index = qw(partnumber description partsgroup qty unit sellprice discount linetotal); + + $form->{invsubtotal} = 0; + + for (split / /, $form->{taxaccounts}) { $form->{"${_}_base"} = 0; } + + $column_data{partnumber} = qq|<th class=listheading nowrap>|.$locale->text('Number').qq|</th>|; + $column_data{description} = qq|<th class=listheading nowrap>|.$locale->text('Description').qq|</th>|; + $column_data{qty} = qq|<th class=listheading nowrap>|.$locale->text('Qty').qq|</th>|; + $column_data{unit} = qq|<th class=listheading nowrap>|.$locale->text('Unit').qq|</th>|; + $column_data{sellprice} = qq|<th class=listheading nowrap>|.$locale->text('Price').qq|</th>|; + $column_data{linetotal} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|; + $column_data{discount} = qq|<th class=listheading nowrap>%</th>|; + + print qq| + <tr> + <td> + <table width=100%> + <tr class=listheading>|; + + for (@column_index) { print "\n$column_data{$_}"; }; + + print qq| + </tr> +|; + + $exchangerate = $form->parse_amount(\%myconfig, $form->{exchangerate}); + $exchangerate = ($exchangerate) ? $exchangerate : 1; + + for $i (1 .. $numrows) { + # undo formatting + for (qw(qty discount sellprice)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}); } + + ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + + if (($form->{"qty_$i"} != $form->{"oldqty_$i"}) || ($form->{currency} ne $form->{oldcurrency})) { + # check for a pricematrix + @a = split / /, $form->{"pricematrix_$i"}; + if (scalar @a) { + foreach $item (@a) { + ($q, $p) = split /:/, $item; + if (($p * 1) && ($form->{"qty_$i"} >= ($q * 1))) { + ($dec) = ($p =~ /\.(\d+)/); + $dec = length $dec; + $decimalplaces = ($dec > 2) ? $dec : 2; + $form->{"sellprice_$i"} = $form->round_amount($p / $exchangerate, $decimalplaces); + } + } + } + } + + if ($i < $numrows) { + $column_data{discount} = qq|<td align=right><input name="discount_$i" size=3 value=|.$form->format_amount(\%myconfig, $form->{"discount_$i"}).qq|></td>|; + } else { + $column_data{discount} = qq|<td></td>|; + } + + $discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}/100, $decimalplaces); + $linetotal = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces); + $linetotal = $form->round_amount($linetotal * $form->{"qty_$i"}, 2); + + for (qw(partnumber sku description partsgroup unit)) { $form->{"${_}_$i"} = $form->quote($form->{"${_}_$i"}); } + + $column_data{partnumber} = qq|<td><input name="partnumber_$i" size=20 value="$form->{"partnumber_$i"}" accesskey="$i" title="[Alt-$i]"></td>|; + + if (($rows = $form->numtextrows($form->{"description_$i"}, 40, 6)) > 1) { + $column_data{description} = qq|<td><textarea name="description_$i" rows=$rows cols=46 wrap=soft>$form->{"description_$i"}</textarea></td>|; + } else { + $column_data{description} = qq|<td><input name="description_$i" size=48 value="$form->{"description_$i"}"></td>|; + } + + $column_data{qty} = qq|<td align=right><input name="qty_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"qty_$i"}).qq|></td>|; + $column_data{unit} = qq|<td>$form->{"unit_$i"}</td>|; + $column_data{sellprice} = qq|<td align=right><input name="sellprice_$i" size=9 value=|.$form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces).qq|></td>|; + $column_data{linetotal} = qq|<td align=right>|.$form->format_amount(\%myconfig, $linetotal, 2).qq|</td>|; + + print qq| + <tr valign=top>|; + + for (@column_index) { print "\n$column_data{$_}"; } + + print qq| + </tr> +|; + + $form->{"oldqty_$i"} = $form->{"qty_$i"}; + + for (qw(id listprice lastcost taxaccounts pricematrix oldqty sku partsgroup unit inventory_accno_id income_accno_id expense_accno_id)) { $form->hide_form("${_}_$i") } + + for (split / /, $form->{"taxaccounts_$i"}) { $form->{"${_}_base"} += $linetotal; } + + $form->{invsubtotal} += $linetotal; + } + + print qq| + </table> + </td> + </tr> + +<input type=hidden name=oldcurrency value=$form->{currency}> + +|; + +} + + +sub print { + + if (!$form->{invnumber}) { + $form->{invnumber} = $form->update_defaults(\%myconfig, "sinumber"); + if ($form->{media} eq 'screen') { + &update; + exit; + } + } + + $old_form = new Form; + for (keys %$form) { $old_form->{$_} = $form->{$_}; } + + for (qw(employee department)) { $form->{$_} =~ s/--.*//g; } + $form->{invdate} = $form->{transdate}; + $form->{dateprinted} = scalar localtime; + + &print_form($old_form); + +} + + +sub print_form { + my $old_form = shift; + + # if oldcustomer ne customer redo form + $customer = $form->{customer}; + $customer =~ s/--.*//g; + $customer .= "--$form->{customer_id}"; + if ($customer ne $form->{oldcustomer}) { + &update; + exit; + } + + &validate_items; + + &{ "$form->{vc}_details" }; + + @a = (); + for (1 .. $form->{rowcount}) { push @a, ("partnumber_$_", "description_$_"); } + for (split / /, $form->{taxaccounts}) { push @a, "${_}_description"; } + $form->format_string(@a); + + # format payment dates + for (1 .. $form->{paidaccounts}) { $form->{"datepaid_$_"} = $locale->date(\%myconfig, $form->{"datepaid_$_"}); } + + IS->invoice_details(\%myconfig, \%$form); + + if ($form->parse_amount(\%myconfig, $form->{total}) <= 0) { + $form->{total} = 0; + } else { + $form->{change} = 0; + } + + for (qw(company address tel fax businessnumber)) { $form->{$_} = $myconfig{$_}; } + $form->{username} = $myconfig{name}; + + $form->{address} =~ s/\\n/\n/g; + push @a, qw(company address tel fax businessnumber username); + $form->format_string(@a); + + $form->{templates} = "$myconfig{templates}"; + $form->{IN} = "$form->{type}.$form->{format}"; + + if ($form->{format} =~ /(postscript|pdf)/) { + $form->{IN} =~ s/$&$/tex/; + } + + if ($form->{media} ne 'screen') { + $form->{OUT} = "| $printer{$form->{media}}"; + } + + $form->{discount} = $form->format_amount(\%myconfig, $form->{discount} * 100); + + $form->{rowcount}--; + $form->{pre} = "<body bgcolor=#ffffff>\n<pre>"; + delete $form->{stylesheet}; + + $form->parse_template(\%myconfig, $userspath); + + if ($form->{printed} !~ /$form->{formname}/) { + $form->{printed} .= " $form->{formname}"; + $form->{printed} =~ s/^ //; + + $form->update_status(\%myconfig); + } + $old_form->{printed} = $form->{printed}; + + # if we got back here restore the previous form + if ($form->{media} ne 'screen') { + # restore and display form + for (keys %$old_form) { $form->{$_} = $old_form->{$_}; } + $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate}); + + for $i (1 .. $form->{paidaccounts}) { + for (qw(paid exchangerate)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}); } + } + + delete $form->{pre}; + + if (! $form->{printandpost}) { + $form->{rowcount}--; + &display_form; + } + } + +} + + +sub print_and_post { + + $form->error($locale->text('Select a Printer!')) if ($form->{media} eq 'screen'); + $form->{printandpost} = 1; + &print; + &post; + +} + +sub lookup_partsgroup { + + $form->{action} =~ s/\r//; + $form->{action} = substr($form->{action}, 1); + + if ($form->{language_code}) { + # get english + foreach $item (split /\n/, $form->{partsgroup}) { + if ($item =~ /$form->{action}/) { + ($partsgroup, $translation) = split /--/, $item; + $form->{action} = $partsgroup; + last; + } + } + } + + $form->{"partsgroup_$form->{rowcount}"} = $form->{action}; + + &update; + +} + + + +sub print_options { + + $form->{PD}{$form->{type}} = "checked"; + + print qq| +<input type=hidden name=format value=$form->{format}> +<input type=hidden name=formname value=$form->{type}> + +<table width=100%> + <tr> +|; + + + $media = qq| + <td><input class=radio type=radio name=media value="screen"></td> + <td>|.$locale->text('Screen').qq|</td>|; + + if (%printer) { + for (keys %printer) { + $media .= qq| + <td><input class=radio type=radio name=media value="$_"></td> + <td nowrap>$_</td> +|; + } + } + + $media =~ s/(value="\Q$form->{media}\E")/$1 checked/; + + print qq| + $media + + <td width=99%> </td>|; + + if ($form->{printed} =~ /$form->{type}/) { + print qq| + <th>\||.$locale->text('Printed').qq|\|</th>|; + } + + print qq| + </tr> +</table> +|; + +} + + +sub receipts { + + $form->{title} = $locale->text('Receipts'); + + $form->{db} = 'ar'; + RP->paymentaccounts(\%myconfig, \%$form); + + $paymentaccounts = ""; + for (@{ $form->{PR} } ) { $paymentaccounts .= "$_->{accno} "; } + + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n|; } + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n|; } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=title value="$form->{title}"> +<input type=hidden name=paymentaccounts value="$paymentaccounts"> + +<input type=hidden name=till value=1> +<input type=hidden name=subtotal value=1> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + + <input type=hidden name=nextsub value=list_payments> + + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + <input type=hidden name=sort value=transdate> + <input type=hidden name=db value=$form->{db}> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</form> + +</body> +</html> +|; + +} + + diff --git a/bin/lynx/ps.pl b/bin/lynx/ps.pl new file mode 100755 index 00000000..1a11743e --- /dev/null +++ b/bin/lynx/ps.pl @@ -0,0 +1,45 @@ +###################################################################### +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 1999 - 2005 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +# +####################################################################### +# +# point of sale script +# +####################################################################### + +use SL::AA; +use SL::IS; +use SL::RP; + +require "$form->{path}/ar.pl"; +require "$form->{path}/is.pl"; +require "$form->{path}/rp.pl"; +require "$form->{path}/pos.pl"; + +# customizations +if (-f "$form->{path}/custom_pos.pl") { + eval { require "$form->{path}/custom_pos.pl"; }; +} +if (-f "$form->{path}/$form->{login}_pos.pl") { + eval { require "$form->{path}/$form->{login}_pos.pl"; }; +} + +1; +# end diff --git a/bin/lynx/pw.pl b/bin/lynx/pw.pl new file mode 100755 index 00000000..a634e74b --- /dev/null +++ b/bin/lynx/pw.pl @@ -0,0 +1,73 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2004 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== + + +1; +# end of main + + +sub getpassword { + my ($s) = @_; + + $form->{endsession} = 1; + $form->header; + + $sessionexpired = qq|<b><font color=red><blink>|.$locale->text('Session expired!').qq|</blink></font></b><p>| if $s; + + print qq| +<script language="JavaScript" type="text/javascript"> +<!-- +function sf(){ + document.pw.password.focus(); +} +// End --> +</script> + +<body onload="sf()"> + + $sessionexpired + +<form method=post action=$form->{script} name=pw> + +<table> + <tr> + <th align=right>|.$locale->text('Password').qq|</th> + <td><input type=password name=password size=30></td> + <td><input type=submit value="|.$locale->text('Continue').qq|"></td> + </tr> +</table> + +|; + + for (qw(script endsession password)) { delete $form->{$_} } + $form->hide_form; + + print qq| +</form> + +</body> +</html> +|; + +} + + diff --git a/bin/lynx/rc.pl b/bin/lynx/rc.pl new file mode 100755 index 00000000..3ba199e4 --- /dev/null +++ b/bin/lynx/rc.pl @@ -0,0 +1,502 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2003 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# Account reconciliation module +# +#====================================================================== + +use SL::RC; + +1; +# end of main + +# this is for our long dates +# $locale->text('January') +# $locale->text('February') +# $locale->text('March') +# $locale->text('April') +# $locale->text('May ') +# $locale->text('June') +# $locale->text('July') +# $locale->text('August') +# $locale->text('September') +# $locale->text('October') +# $locale->text('November') +# $locale->text('December') + +# this is for our short month +# $locale->text('Jan') +# $locale->text('Feb') +# $locale->text('Mar') +# $locale->text('Apr') +# $locale->text('May') +# $locale->text('Jun') +# $locale->text('Jul') +# $locale->text('Aug') +# $locale->text('Sep') +# $locale->text('Oct') +# $locale->text('Nov') +# $locale->text('Dec') + + +sub reconciliation { + + RC->paymentaccounts(\%myconfig, \%$form); + + $selection = ""; + for (@{ $form->{PR} }) { $selection .= "<option>$_->{accno}--$_->{description}\n" } + + $form->{title} = $locale->text('Reconciliation'); + + if ($form->{report}) { + $form->{title} = $locale->text('Reconciliation Report'); + $cleared = qq| + <input type=hidden name=report value=1> + <tr> + <td align=right><input type=checkbox class=checkbox name=outstanding value=1 checked></td> + <td>|.$locale->text('Outstanding').qq|</td> + <td align=right><input type=checkbox class=checkbox name=cleared value=1></td> + <td>|.$locale->text('Cleared').qq|</td> + </tr> +|; + + } + + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Account').qq|</th> + <td colspan=3><select name=accno>$selection</select></td> + </tr> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td colspan=3><input name=fromdate size=11 title="$myconfig{dateformat}"> <b>|.$locale->text('To').qq|</b> <input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + $cleared + <tr> + <td></td> + <td colspan=3><input type=radio style=radio name=summary value=1 checked> |.$locale->text('Summary').qq| + <input type=radio style=radio name=summary value=0> |.$locale->text('Detail').qq|</td> + </tr> + <tr> + <td></td> + <td colspan=3><input type=checkbox class=checkbox name=fx_transaction value=1 checked> |.$locale->text('Include Exchange Rate Difference').qq|</td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<input type=hidden name=nextsub value=get_payments> +|; + + $form->hide_form(qw(path login sessionid)); + + print qq| +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> + +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub continue { &{ $form->{nextsub} } }; + + +sub get_payments { + + ($form->{accno}, $form->{account}) = split /--/, $form->{accno}; + + RC->payment_transactions(\%myconfig, \%$form); + + $ml = ($form->{category} eq 'A') ? -1 : 1; + $form->{statementbalance} = $form->{endingbalance} * $ml; + if (! $form->{fx_transaction}) { + $form->{statementbalance} = ($form->{endingbalance} - $form->{fx_endingbalance}) * $ml; + } + + $form->{statementbalance} = $form->format_amount(\%myconfig, $form->{statementbalance}, 2, 0); + + &display_form; + +} + + +sub display_form { + + if ($form->{report}) { + @column_index = qw(transdate source name cleared debit credit); + } else { + @column_index = qw(transdate source name cleared debit credit balance); + } + + $column_header{cleared} = qq|<th>|.$locale->text('R').qq|</th>|; + $column_header{source} = "<th class=listheading>".$locale->text('Source')."</a></th>"; + $column_header{name} = "<th class=listheading>".$locale->text('Description')."</a></th>"; + $column_header{transdate} = "<th class=listheading>".$locale->text('Date')."</a></th>"; + + $column_header{debit} = "<th class=listheading>".$locale->text('Debit')."</a></th>"; + $column_header{credit} = "<th class=listheading>".$locale->text('Credit')."</a></th>"; + $column_header{balance} = "<th class=listheading>".$locale->text('Balance')."</a></th>"; + + if ($form->{fromdate}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{fromdate}, 1); + } + if ($form->{todate}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{todate}, 1); + } + + $form->{title} = "$form->{accno}--$form->{account}"; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + $ml = ($form->{category} eq 'A') ? -1 : 1; + $form->{beginningbalance} *= $ml; + $form->{fx_balance} *= $ml; + + if (! $form->{fx_transaction}) { + $form->{beginningbalance} -= $form->{fx_balance}; + } + $balance = $form->{beginningbalance}; + + $i = 0; + $j = 0; + + for (qw(cleared transdate source debit credit)) { $column_data{$_} = "<td> </td>" } + + if (! $form->{report}) { + $column_data{name} = qq|<td>|.$locale->text('Beginning Balance').qq|</td>|; + $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $balance, 2, 0)."</td>"; + print qq| + <tr class=listrow$j> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + } + + + foreach $ref (@{ $form->{PR} }) { + + $i++; + + if (! $form->{fx_transaction}) { + next if $ref->{fx_transaction}; + } + + $checked = ($ref->{cleared}) ? "checked" : ""; + + %temp = (); + if (!$ref->{fx_transaction}) { + for (qw(name source transdate)) { $temp{$_} = $ref->{$_} } + } + + $column_data{name} = "<td>"; + for (@{ $temp{name} }) { $column_data{name} .= "$_<br>" } + $column_data{name} .= "</td>"; + $column_data{source} = qq|<td>$temp{source} </td> + <input type=hidden name="id_$i" value=$ref->{id}>|; + + $column_data{debit} = "<td> </td>"; + $column_data{credit} = "<td> </td>"; + + $balance += $ref->{amount} * $ml; + + if ($ref->{amount} < 0) { + + $totaldebits += $ref->{amount} * -1; + + $column_data{debit} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount} * -1, 2, " ")."</td>"; + + } else { + + $totalcredits += $ref->{amount}; + + $column_data{credit} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount}, 2, " ")."</td>"; + + } + + $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $balance, 2, 0)."</td>"; + + if ($ref->{fx_transaction}) { + + $column_data{cleared} = ($clearfx) ? qq|<td align=center>*</td>| : qq|<td> </td>|; + $cleared += $ref->{amount} * $ml if $clearfx; + + } else { + + if ($form->{report}) { + + if ($ref->{cleared}) { + $column_data{cleared} = qq|<td align=center>*</td>|; + $clearfx = 1; + } else { + $column_data{cleared} = qq|<td> </td>|; + $clearfx = 0; + } + + } else { + + if ($ref->{oldcleared}) { + $cleared += $ref->{amount} * $ml; + $clearfx = 1; + $column_data{cleared} = qq|<td align=center>*</td> + <input type=hidden name="cleared_$i" value=$ref->{cleared}> + <input type=hidden name="oldcleared_$i" value=$ref->{oldcleared}> + <input type=hidden name="source_$i" value="$ref->{source}">|; + } else { + $cleared += $ref->{amount} * $ml if $checked; + $clearfx = ($checked) ? 1 : 0; + $column_data{cleared} = qq|<td align=center><input name="cleared_$i" type=checkbox class=checkbox value=1 $checked> + <input type=hidden name="source_$i" value="$ref->{source}"></td>|; + } + + } + } + + $column_data{transdate} = qq|<td>$temp{transdate} </td> + <input type=hidden name="transdate_$i" value=$ref->{transdate}>|; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + } + + $form->{rowcount} = $i; + + # print totals + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{debit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totaldebits, 2, " ")."</th>"; + $column_data{credit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalcredits, 2, " ")."</th>"; + + print qq| + <tr class=listtotal> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + $form->{statementbalance} = $form->parse_amount(\%myconfig, $form->{statementbalance}); + $difference = $form->format_amount(\%myconfig, $form->{beginningbalance} + $cleared - $form->{statementbalance}, 2, 0); + $form->{statementbalance} = $form->format_amount(\%myconfig, $form->{statementbalance}, 2, 0); + + print qq| + </tr> + </table> + </td> + </tr> +|; + + + if ($form->{report}) { + + print qq| + </tr> + </table> +|; + + } else { + + print qq| + + <tr> + <td> + <table width=100%> + <tr> + <td align=right> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Statement Balance').qq|</th> + <td width=10%></td> + <td align=right><input name=statementbalance size=11 value=$form->{statementbalance}></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Difference').qq|</th> + <td width=10%></td> + <td align=right><input name=null size=11 value=$difference></td> + <input type=hidden name=difference value=$difference> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + $form->hide_form(qw(fx_transaction summary rowcount accno account fromdate todate path login sessionid)); + + print qq| +<br> +<input type=submit class=submit name=action value="|.$locale->text('Update').qq|"> +<input type=submit class=submit name=action value="|.$locale->text('Select all').qq|"> +<input type=submit class=submit name=action value="|.$locale->text('Done').qq|">|; + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub update { + + RC->payment_transactions(\%myconfig, \%$form); + + $i = 0; + foreach $ref (@{ $form->{PR} }) { + $i++; + $ref->{cleared} = ($form->{"cleared_$i"}) ? 1 : 0; + } + + &display_form; + +} + + +sub select_all { + + RC->payment_transactions(\%myconfig, \%$form); + + for (@{ $form->{PR} }) { $_->{cleared} = 1 } + + &display_form; + +} + + +sub done { + + $form->{callback} = "$form->{script}?path=$form->{path}&action=reconciliation&login=$form->{login}&sessionid=$form->{sessionid}"; + + $form->error($locale->text('Out of balance!')) if ($form->{difference} *= 1); + + RC->reconcile(\%myconfig, \%$form); + $form->redirect; + +} + + diff --git a/bin/lynx/rp.pl b/bin/lynx/rp.pl new file mode 100755 index 00000000..d9803c93 --- /dev/null +++ b/bin/lynx/rp.pl @@ -0,0 +1,2351 @@ +#===================================================================== +# LedgerSMB Small Medium Business Accounting +# Copyright (c) 2001 +# +# Author: DWS Systems Inc. +# Web: http://sourceforge.net/projects/ledger-smb/ +# +# Contributors: Antonio Gallardo <agssa@ibw.com.ni> +# Benjamin Lee <benjaminlee@consultant.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. +#====================================================================== +# +# module for preparing Income Statement and Balance Sheet +# +#====================================================================== + +require "$form->{path}/arap.pl"; + +use SL::PE; +use SL::RP; + +1; +# end of main + +# this is for our long dates +# $locale->text('January') +# $locale->text('February') +# $locale->text('March') +# $locale->text('April') +# $locale->text('May ') +# $locale->text('June') +# $locale->text('July') +# $locale->text('August') +# $locale->text('September') +# $locale->text('October') +# $locale->text('November') +# $locale->text('December') + +# this is for our short month +# $locale->text('Jan') +# $locale->text('Feb') +# $locale->text('Mar') +# $locale->text('Apr') +# $locale->text('May') +# $locale->text('Jun') +# $locale->text('Jul') +# $locale->text('Aug') +# $locale->text('Sep') +# $locale->text('Oct') +# $locale->text('Nov') +# $locale->text('Dec') + +# $locale->text('Balance Sheet') +# $locale->text('Income Statement') +# $locale->text('Trial Balance') +# $locale->text('AR Aging') +# $locale->text('AP Aging') +# $locale->text('Tax collected') +# $locale->text('Tax paid') +# $locale->text('Receipts') +# $locale->text('Payments') +# $locale->text('Project Transactions') +# $locale->text('Non-taxable Sales') +# $locale->text('Non-taxable Purchases') + + +sub report { + + %report = ( balance_sheet => { title => 'Balance Sheet' }, + income_statement => { title => 'Income Statement' }, + trial_balance => { title => 'Trial Balance' }, + ar_aging => { title => 'AR Aging', vc => 'customer' }, + ap_aging => { title => 'AP Aging', vc => 'vendor' }, + tax_collected => { title => 'Tax collected', vc => 'customer' }, + tax_paid => { title => 'Tax paid' }, + nontaxable_sales => { title => 'Non-taxable Sales', vc => 'customer' }, + nontaxable_purchases => { title => 'Non-taxable Purchases' }, + receipts => { title => 'Receipts', vc => 'customer' }, + payments => { title => 'Payments' }, + projects => { title => 'Project Transactions' }, + ); + + $form->{title} = $locale->text($report{$form->{report}}->{title}); + + $gifi = qq| +<tr> + <th align=right>|.$locale->text('Accounts').qq|</th> + <td><input name=accounttype class=radio type=radio value=standard checked> |.$locale->text('Standard').qq| + + <input name=accounttype class=radio type=radio value=gifi> |.$locale->text('GIFI').qq| + </td> +</tr> +|; + + + # get departments + $form->all_departments(\%myconfig, undef, $report{$form->{report}}->{vc}); + if (@{ $form->{all_department} }) { + $form->{selectdepartment} = "<option>\n"; + + for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| } + } + + $department = qq| + <tr> + <th align=right nowrap>|.$locale->text('Department').qq|</th> + <td colspan=3><select name=department>$form->{selectdepartment}</select></td> + </tr> +| if $form->{selectdepartment}; + + if (@{ $form->{all_years} }) { + # accounting years + $form->{selectaccountingyear} = "<option>\n"; + for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| } + + $form->{selectaccountingmonth} = "<option>\n"; + for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| } + + $selectfrom = qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + + $selectto = qq| + <tr> + <th align=right></th> + <td> + <select name=month>$form->{selectaccountingmonth}</select> + <select name=year>$form->{selectaccountingyear}</select> + </td> + </tr> +|; + } + + + $summary = qq| + <tr> + <th></th> + <td><input name=summary type=radio class=radio value=1 checked> |.$locale->text('Summary').qq| + <input name=summary type=radio class=radio value=0> |.$locale->text('Detail').qq| + </td> + </tr> +|; + + # get projects + $form->all_projects(\%myconfig); + if (@{ $form->{all_project} }) { + $form->{selectproject} = "<option>\n"; + for (@{ $form->{all_project} }) { $form->{selectproject} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| } + + $project = qq| + <tr> + <th align=right nowrap>|.$locale->text('Project').qq|</th> + <td colspan=3><select name=projectnumber>$form->{selectproject}</select></td> + </tr>|; + + } + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<input type=hidden name=title value="$form->{title}"> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table> + $department +|; + + if ($form->{report} eq "projects") { + print qq| + $project + <input type=hidden name=nextsub value=generate_projects> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + </table> + </td> + </tr> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td><input name=l_heading class=checkbox type=checkbox value=Y> |.$locale->text('Heading').qq| + <input name=l_subtotal class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq|</td> + </tr> +|; + } + + if ($form->{report} eq "income_statement") { + print qq| + $project + <input type=hidden name=nextsub value=generate_income_statement> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> +|; + + if ($selectfrom) { + print qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td colspan=3> + <select name=frommonth>$form->{selectaccountingmonth}</select> + <select name=fromyear>$form->{selectaccountingyear}</select> + <input name=interval class=radio type=radio value=0 checked> |.$locale->text('Current').qq| + <input name=interval class=radio type=radio value=1> |.$locale->text('Month').qq| + <input name=interval class=radio type=radio value=3> |.$locale->text('Quarter').qq| + <input name=interval class=radio type=radio value=12> |.$locale->text('Year').qq| + </td> + </tr> +|; + } + + print qq| + + <tr> + <th align=right>|.$locale->text('Compare to').qq|</th> + </tr> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=comparefromdate size=11 title="$myconfig{dateformat}"></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=comparetodate size=11 title="$myconfig{dateformat}"></td> + </tr> +|; + + if ($selectto) { + print qq| + <tr> + <th align=right>|.$locale->text('Period').qq|</th> + <td> + <select name=comparemonth>$form->{selectaccountingmonth}</select> + <select name=compareyear>$form->{selectaccountingyear}</select> + </td> + </tr> +|; + } + + print qq| + <tr> + <th align=right>|.$locale->text('Decimalplaces').qq|</th> + <td><input name=decimalplaces size=3 value=2></td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Method').qq|</th> + <td colspan=3><input name=method class=radio type=radio value=accrual checked>|.$locale->text('Accrual').qq| + <input name=method class=radio type=radio value=cash>|.$locale->text('Cash').qq|</td> + </tr> + + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td colspan=3><input name=l_heading class=checkbox type=checkbox value=Y> |.$locale->text('Heading').qq| + <input name=l_subtotal class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq| + <input name=l_accno class=checkbox type=checkbox value=Y> |.$locale->text('Account Number').qq|</td> + </tr> +|; + } + + + if ($form->{report} eq "balance_sheet") { + print qq| + <input type=hidden name=nextsub value=generate_balance_sheet> + <tr> + <th align=right>|.$locale->text('as at').qq|</th> + <td><input name=asofdate size=11 title="$myconfig{dateformat}" value=$form->{asofdate}></td> +|; + + if ($selectfrom) { + print qq| + <td> + <select name=asofmonth>$form->{selectaccountingmonth}</select> + <select name=asofyear>$form->{selectaccountingyear}</select> + </td> +|; + } + + print qq| + </tr> + + <th align=right nowrap>|.$locale->text('Compare to').qq|</th> + <td><input name=compareasofdate size=11 title="$myconfig{dateformat}"></td> + <td> +|; + + if ($selectto) { + print qq| + <select name=compareasofmonth>$form->{selectaccountingmonth}</select> + <select name=compareasofyear>$form->{selectaccountingyear}</select> + </td> +|; + } + + print qq| + </tr> + <tr> + <th align=right>|.$locale->text('Decimalplaces').qq|</th> + <td><input name=decimalplaces size=3 value=2></td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Method').qq|</th> + <td colspan=3><input name=method class=radio type=radio value=accrual checked>|.$locale->text('Accrual').qq| + <input name=method class=radio type=radio value=cash>|.$locale->text('Cash').qq|</td> + </tr> + + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td><input name=l_heading class=checkbox type=checkbox value=Y> |.$locale->text('Heading').qq| + <input name=l_subtotal class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq| + <input name=l_accno class=checkbox type=checkbox value=Y> |.$locale->text('Account Number').qq|</td> + </tr> +|; + } + + + if ($form->{report} eq "trial_balance") { + print qq| + <input type=hidden name=nextsub value=generate_trial_balance> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + </table> + </td> + </tr> + <tr> + <td> + <table> + <tr> + <th align=right nowrap>|.$locale->text('Include in Report').qq|</th> + <td><input name=l_heading class=checkbox type=checkbox value=Y> |.$locale->text('Heading').qq| + <input name=l_subtotal class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq| + <input name=all_accounts class=checkbox type=checkbox value=Y> |.$locale->text('All Accounts').qq|</td> + </tr> +|; + } + + + if ($form->{report} =~ /^tax_/) { + $gifi = ""; + + $form->{db} = ($form->{report} =~ /_collected/) ? "ar" : "ap"; + + RP->get_taxaccounts(\%myconfig, \%$form); + + print qq| + <input type=hidden name=nextsub value=generate_tax_report> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + $summary + <tr> + <th align=right>|.$locale->text('Report for').qq|</th> + <td colspan=3> +|; + + $checked = "checked"; + foreach $ref (@{ $form->{taxaccounts} }) { + + print qq|<input name=accno class=radio type=radio value=$ref->{accno} $checked> $ref->{description} + + <input name="$ref->{accno}_description" type=hidden value="$ref->{description}"> + <input name="$ref->{accno}_rate" type=hidden value="$ref->{rate}">|; + + $checked = ""; + + } + + print qq| + <input type=hidden name=db value=$form->{db}> + <input type=hidden name=sort value=transdate> + + </td> + </tr> +|; + + + if (@{ $form->{gifi_taxaccounts} }) { + print qq| + <tr> + <th align=right>|.$locale->text('GIFI').qq|</th> + <td colspan=3> +|; + + foreach $ref (@{ $form->{gifi_taxaccounts} }) { + + print qq|<input name=accno class=radio type=radio value="gifi_$ref->{accno}"> $ref->{description} + + <input name="gifi_$ref->{accno}_description" type=hidden value="$ref->{description}"> + <input name="gifi_$ref->{accno}_rate" type=hidden value="$ref->{rate}">|; + + } + + print qq| + </td> + </tr> +|; + } + + +print qq| + <tr> + <th align=right>|.$locale->text('Method').qq|</th> + <td colspan=3><input name=method class=radio type=radio value=accrual checked>|.$locale->text('Accrual').qq| + <input name=method class=radio type=radio value=cash>|.$locale->text('Cash').qq|</td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table> + <tr> + <th align=right>|.$locale->text('Include in Report').qq|</th> + <td> + <table> + <tr> + <td><input name="l_id" class=checkbox type=checkbox value=Y></td> + <td>|.$locale->text('ID').qq|</td> + <td><input name="l_invnumber" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Invoice').qq|</td> + <td><input name="l_transdate" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Date').qq|</td> + </tr> + <tr> + <td><input name="l_name" class=checkbox type=checkbox value=Y checked></td> +|; + + if ($form->{db} eq 'ar') { + print qq|<td>|.$locale->text('Customer').qq|</td>|; + } + if ($form->{db} eq 'ap') { + print qq|<td>|.$locale->text('Vendor').qq|</td>|; + } + + print qq| + <td><input name="l_description" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Description').qq|</td> + <td><input name="l_netamount" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Amount').qq|</td> + + <td><input name="l_tax" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Tax').qq|</td> + + <td><input name="l_total" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Total').qq|</td> + </tr> + <tr> + </tr> + <tr> + <td><input name="l_subtotal" class=checkbox type=checkbox value=Y></td> + <td>|.$locale->text('Subtotal').qq|</td> + </tr> + </table> + </td> + </tr> +|; + + } + + + if ($form->{report} =~ /^nontaxable_/) { + $gifi = ""; + + $form->{db} = ($form->{report} =~ /_sales/) ? "ar" : "ap"; + + print qq| + <input type=hidden name=nextsub value=generate_tax_report> + + <input type=hidden name=db value=$form->{db}> + <input type=hidden name=sort value=transdate> + <input type=hidden name=report value=$form->{report}> + + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + $summary + <tr> + <th align=right>|.$locale->text('Method').qq|</th> + <td colspan=3><input name=method class=radio type=radio value=accrual checked>|.$locale->text('Accrual').qq| + <input name=method class=radio type=radio value=cash>|.$locale->text('Cash').qq|</td> + </tr> + <tr> + <th align=right>|.$locale->text('Include in Report').qq|</th> + <td colspan=3> + <table> + <tr> + <td><input name="l_id" class=checkbox type=checkbox value=Y></td> + <td>|.$locale->text('ID').qq|</td> + <td><input name="l_invnumber" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Invoice').qq|</td> + <td><input name="l_transdate" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Date').qq|</td> + </tr> + <tr> + <td><input name="l_name" class=checkbox type=checkbox value=Y checked></td> +|; + + if ($form->{db} eq 'ar') { + print qq|<td>|.$locale->text('Customer').qq|</td>|; + } + if ($form->{db} eq 'ap') { + print qq|<td>|.$locale->text('Vendor').qq|</td>|; + } + + print qq| + <td><input name="l_description" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Description').qq|</td> + <td><input name="l_netamount" class=checkbox type=checkbox value=Y checked></td> + <td>|.$locale->text('Amount').qq|</td> + </tr> + <tr> + <td><input name="l_subtotal" class=checkbox type=checkbox value=Y></td> + <td>|.$locale->text('Subtotal').qq|</td> + </tr> + </table> + </td> + </tr> +|; + + } + + + if (($form->{report} eq "ar_aging") || ($form->{report} eq "ap_aging")) { + $gifi = ""; + + if ($form->{report} eq 'ar_aging') { + $label = $locale->text('Customer'); + $form->{vc} = 'customer'; + } else { + $label = $locale->text('Vendor'); + $form->{vc} = 'vendor'; + } + + $nextsub = "generate_$form->{report}"; + + # setup vc selection + $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP"); + + for (@{ $form->{"all_$form->{vc}"} }) { $vc .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| } + + $vc = ($vc) ? qq|<select name=$form->{vc}><option>\n$vc</select>| : qq|<input name=$form->{vc} size=35>|; + + $postscript = "postscript" if $myconfig{printer}; + + print qq| + <tr> + <th align=right>|.$locale->text($label).qq|</th> + <td>$vc</td> + </tr> + <tr> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectto + <input type=hidden name=type value=statement> + <input type=hidden name=format value=$postscript> + <input type=hidden name=media value="$myconfig{printer}"> + + <input type=hidden name=nextsub value=$nextsub> + <input type=hidden name=action value=$nextsub> + $summary + <tr> + <table> + <tr> + <th>|.$locale->text('Include in Report').qq|</th> + + <td> + <table> + <tr> + <td nowrap><input name=overdue type=radio class=radio value=0 checked> |.$locale->text('Aged').qq|</td> + <td nowrap><input name=overdue type=radio class=radio value=1> |.$locale->text('Overdue').qq|</td> + </tr> + <tr> + <td nowrap width=70><input name=c0 type=checkbox class=checkbox value=1 checked> |.$locale->text('Current').qq|</td> + <td nowrap width=70><input name=c30 type=checkbox class=checkbox value=1 checked> 30</td> + <td nowrap width=70><input name=c60 type=checkbox class=checkbox value=1 checked> 60</td> + <td nowrap width=70><input name=c90 type=checkbox class=checkbox value=1 checked> 90</td> + </td> + </tr> + </table> + </td> + </tr> + </table> + </tr> + +|; + } + +# above action can be removed if there is more than one input field + + + if ($form->{report} =~ /(receipts|payments)$/) { + $gifi = ""; + + $form->{db} = ($form->{report} =~ /payments$/) ? "ap" : "ar"; + + RP->paymentaccounts(\%myconfig, \%$form); + + $selection = "<option>\n"; + foreach $ref (@{ $form->{PR} }) { + $paymentaccounts .= "$ref->{accno} "; + $selection .= "<option>$ref->{accno}--$ref->{description}\n"; + } + + chop $paymentaccounts; + + print qq| + <input type=hidden name=nextsub value=list_payments> + <tr> + <th align=right nowrap>|.$locale->text('Account').qq|</th> + <td colspan=3><select name=account>$selection</select> + <input type=hidden name=paymentaccounts value="$paymentaccounts"> + </td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Description').qq|</th> + <td colspan=3><input name=description size=35></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Source').qq|</th> + <td colspan=3><input name=source></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Memo').qq|</th> + <td colspan=3><input name=memo size=30></td> + </tr> + <tr> + <th align=right>|.$locale->text('From').qq|</th> + <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td> + <th align=right>|.$locale->text('To').qq|</th> + <td><input name=todate size=11 title="$myconfig{dateformat}"></td> + </tr> + $selectfrom + <tr> + <td align=right><input type=checkbox class=checkbox name=fx_transaction value=1 checked></td> + <td colspan=3>|.$locale->text('Include Exchange Rate Difference').qq|</td> + </tr> + <tr> + <td align=right><input name=l_subtotal class=checkbox type=checkbox value=Y></td> + <td align=left colspan=3>|.$locale->text('Subtotal').qq|</th> + </tr> + + <input type=hidden name=db value=$form->{db}> + <input type=hidden name=sort value=transdate> +|; + + } + + + print qq| + +$gifi + + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<br> +<input type=hidden name=path value=$form->{path}> +<input type=hidden name=login value=$form->{login}> +<input type=hidden name=sessionid value=$form->{sessionid}> + +<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|"> + +</form> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub continue { &{$form->{nextsub}} }; + + +sub generate_income_statement { + + $form->{padding} = " "; + $form->{bold} = "<b>"; + $form->{endbold} = "</b>"; + $form->{br} = "<br>"; + + RP->income_statement(\%myconfig, \%$form); + + ($form->{department}) = split /--/, $form->{department}; + ($form->{projectnumber}) = split /--/, $form->{projectnumber}; + + $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1); + $form->{todate} = $form->current_date(\%myconfig) unless $form->{todate}; + + # if there are any dates construct a where + if ($form->{fromdate} || $form->{todate}) { + + unless ($form->{todate}) { + $form->{todate} = $form->current_date(\%myconfig); + } + + $longtodate = $locale->date(\%myconfig, $form->{todate}, 1); + $shorttodate = $locale->date(\%myconfig, $form->{todate}, 0); + + $longfromdate = $locale->date(\%myconfig, $form->{fromdate}, 1); + $shortfromdate = $locale->date(\%myconfig, $form->{fromdate}, 0); + + $form->{this_period} = "$shortfromdate<br>\n$shorttodate"; + $form->{period} = $locale->text('for Period').qq|<br>\n$longfromdate |.$locale->text('To').qq| $longtodate|; + } + + if ($form->{comparefromdate} || $form->{comparetodate}) { + $longcomparefromdate = $locale->date(\%myconfig, $form->{comparefromdate}, 1); + $shortcomparefromdate = $locale->date(\%myconfig, $form->{comparefromdate}, 0); + + $longcomparetodate = $locale->date(\%myconfig, $form->{comparetodate}, 1); + $shortcomparetodate = $locale->date(\%myconfig, $form->{comparetodate}, 0); + + $form->{last_period} = "$shortcomparefromdate<br>\n$shortcomparetodate"; + $form->{period} .= "<br>\n$longcomparefromdate ".$locale->text('To').qq| $longcomparetodate|; + } + + # setup variables for the form + @a = qw(company address businessnumber); + for (@a) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/<br>/g; + + $form->{templates} = $myconfig{templates}; + + $form->{IN} = "income_statement.html"; + + $form->parse_template; + +} + + +sub generate_balance_sheet { + + $form->{padding} = " "; + $form->{bold} = "<b>"; + $form->{endbold} = "</b>"; + $form->{br} = "<br>"; + + RP->balance_sheet(\%myconfig, \%$form); + + $form->{asofdate} = $form->current_date(\%myconfig) unless $form->{asofdate}; + $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1); + + ($form->{department}) = split /--/, $form->{department}; + + # define Current Earnings account + $padding = ($form->{l_heading}) ? $form->{padding} : ""; + push(@{$form->{equity_account}}, $padding.$locale->text('Current Earnings')); + + $form->{this_period} = $locale->date(\%myconfig, $form->{asofdate}, 0); + $form->{last_period} = $locale->date(\%myconfig, $form->{compareasofdate}, 0); + + $form->{IN} = "balance_sheet.html"; + + # setup company variables for the form + for (qw(company address businessnumber nativecurr)) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/<br>/g; + + $form->{templates} = $myconfig{templates}; + + $form->parse_template; + +} + + +sub generate_projects { + + $form->{nextsub} = "generate_projects"; + $form->{title} = $locale->text('Project Transactions'); + + RP->trial_balance(\%myconfig, \%$form); + + &list_accounts; + +} + + +# Antonio Gallardo +# +# D.S. Feb 16, 2001 +# included links to display transactions for period entered +# added headers and subtotals +# +sub generate_trial_balance { + + # get for each account initial balance, debits and credits + RP->trial_balance(\%myconfig, \%$form); + + $form->{nextsub} = "generate_trial_balance"; + $form->{title} = $locale->text('Trial Balance'); + + $form->{callback} = "$form->{script}?action=generate_trial_balance"; + for (qw(login path sessionid nextsub fromdate todate month year interval l_heading l_subtotal all_accounts accounttype title)) { $form->{callback} .= "&$_=$form->{$_}" } + $form->{callback} = $form->escape($form->{callback}); + + &list_accounts; + +} + + +sub list_accounts { + + $title = $form->escape($form->{title}); + + if ($form->{department}) { + ($department) = split /--/, $form->{department}; + $options = $locale->text('Department')." : $department<br>"; + $department = $form->escape($form->{department}); + } + if ($form->{projectnumber}) { + ($projectnumber) = split /--/, $form->{projectnumber}; + $options .= $locale->text('Project Number')." : $projectnumber<br>"; + $projectnumber = $form->escape($form->{projectnumber}); + } + + # if there are any dates + if ($form->{fromdate} || $form->{todate}) { + + if ($form->{fromdate}) { + $fromdate = $locale->date(\%myconfig, $form->{fromdate}, 1); + } + if ($form->{todate}) { + $todate = $locale->date(\%myconfig, $form->{todate}, 1); + } + + $form->{period} = "$fromdate - $todate"; + } else { + $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1); + + } + $options .= $form->{period}; + + @column_index = qw(accno description begbalance debit credit endbalance); + + $column_header{accno} = qq|<th class=listheading>|.$locale->text('Account').qq|</th>|; + $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|; + $column_header{debit} = qq|<th class=listheading>|.$locale->text('Debit').qq|</th>|; + $column_header{credit} = qq|<th class=listheading>|.$locale->text('Credit').qq|</th>|; + $column_header{begbalance} = qq|<th class=listheading>|.$locale->text('Balance').qq|</th>|; + $column_header{endbalance} = qq|<th class=listheading>|.$locale->text('Balance').qq|</th>|; + + + if ($form->{accounttype} eq 'gifi') { + $column_header{accno} = qq|<th class=listheading>|.$locale->text('GIFI').qq|</th>|; + } + + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$options</td> + </tr> + <tr> + <td> + <table width=100%> + <tr>|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + + + # sort the whole thing by account numbers and display + foreach $ref (sort { $a->{accno} cmp $b->{accno} } @{ $form->{TB} }) { + + $description = $form->escape($ref->{description}); + + $href = qq|ca.pl?path=$form->{path}&action=list_transactions&accounttype=$form->{accounttype}&login=$form->{login}&sessionid=$form->{sessionid}&fromdate=$form->{fromdate}&todate=$form->{todate}&sort=transdate&l_heading=$form->{l_heading}&l_subtotal=$form->{l_subtotal}&department=$department&projectnumber=$projectnumber&project_id=$form->{project_id}&title=$title&nextsub=$form->{nextsub}&prevreport=$form->{callback}|; + + if ($form->{accounttype} eq 'gifi') { + $href .= "&gifi_accno=$ref->{accno}&gifi_description=$description"; + $na = $locale->text('N/A'); + if (!$ref->{accno}) { + for (qw(accno description)) { $ref->{$_} = $na } + } + } else { + $href .= "&accno=$ref->{accno}&description=$description"; + } + + $ml = ($ref->{category} =~ /(A|E)/) ? -1 : 1; + $ml *= -1 if $ref->{contra}; + + $debit = $form->format_amount(\%myconfig, $ref->{debit}, 2, " "); + $credit = $form->format_amount(\%myconfig, $ref->{credit}, 2, " "); + $begbalance = $form->format_amount(\%myconfig, $ref->{balance} * $ml, 2, " "); + $endbalance = $form->format_amount(\%myconfig, ($ref->{balance} + $ref->{amount}) * $ml, 2, " "); + + + if ($ref->{charttype} eq "H" && $subtotal && $form->{l_subtotal}) { + + if ($subtotal) { + + for (qw(accno begbalance endbalance)) { $column_data{$_} = "<th> </th>" } + + $subtotalbegbalance = $form->format_amount(\%myconfig, $subtotalbegbalance, 2, " "); + $subtotalendbalance = $form->format_amount(\%myconfig, $subtotalendbalance, 2, " "); + $subtotaldebit = $form->format_amount(\%myconfig, $subtotaldebit, 2, " "); + $subtotalcredit = $form->format_amount(\%myconfig, $subtotalcredit, 2, " "); + + $column_data{description} = "<th class=listsubtotal>$subtotaldescription</th>"; + $column_data{begbalance} = "<th align=right class=listsubtotal>$subtotalbegbalance</th>"; + $column_data{endbalance} = "<th align=right class=listsubtotal>$subtotalendbalance</th>"; + $column_data{debit} = "<th align=right class=listsubtotal>$subtotaldebit</th>"; + $column_data{credit} = "<th align=right class=listsubtotal>$subtotalcredit</th>"; + + print qq| + <tr class=listsubtotal> +|; + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + } + + if ($ref->{charttype} eq "H") { + $subtotal = 1; + $subtotaldescription = $ref->{description}; + $subtotaldebit = $ref->{debit}; + $subtotalcredit = $ref->{credit}; + $subtotalbegbalance = 0; + $subtotalendbalance = 0; + + if ($form->{l_heading}) { + if (! $form->{all_accounts}) { + if (($subtotaldebit + $subtotalcredit) == 0) { + $subtotal = 0; + next; + } + } + } else { + $subtotal = 0; + if ($form->{all_accounts} || ($form->{l_subtotal} && (($subtotaldebit + $subtotalcredit) != 0))) { + $subtotal = 1; + } + next; + } + + for (qw(accno debit credit begbalance endbalance)) { $column_data{$_} = "<th> </th>" } + $column_data{description} = "<th class=listheading>$ref->{description}</th>"; + } + + if ($ref->{charttype} eq "A") { + $column_data{accno} = "<td><a href=$href>$ref->{accno}</a></td>"; + $column_data{description} = "<td>$ref->{description}</td>"; + $column_data{debit} = "<td align=right>$debit</td>"; + $column_data{credit} = "<td align=right>$credit</td>"; + $column_data{begbalance} = "<td align=right>$begbalance</td>"; + $column_data{endbalance} = "<td align=right>$endbalance</td>"; + + $totaldebit += $ref->{debit}; + $totalcredit += $ref->{credit}; + + $cml = ($ref->{contra}) ? -1 : 1; + + $subtotalbegbalance += $ref->{balance} * $ml * $cml; + $subtotalendbalance += ($ref->{balance} + $ref->{amount}) * $ml * $cml; + + } + + + if ($ref->{charttype} eq "H") { + print qq| + <tr class=listheading> +|; + } + if ($ref->{charttype} eq "A") { + $i++; $i %= 2; + print qq| + <tr class=listrow$i> +|; + } + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + + # print last subtotal + if ($subtotal && $form->{l_subtotal}) { + for (qw(accno begbalance endbalance)) { $column_data{$_} = "<th> </th>" } + $subtotalbegbalance = $form->format_amount(\%myconfig, $subtotalbegbalance, 2, " "); + $subtotalendbalance = $form->format_amount(\%myconfig, $subtotalendbalance, 2, " "); + $subtotaldebit = $form->format_amount(\%myconfig, $subtotaldebit, 2, " "); + $subtotalcredit = $form->format_amount(\%myconfig, $subtotalcredit, 2, " "); + $column_data{description} = "<th class=listsubtotal>$subtotaldescription</th>"; + $column_data{begbalance} = "<th align=right class=listsubtotal>$subtotalbegbalance</th>"; + $column_data{endbalance} = "<th align=right class=listsubtotal>$subtotalendbalance</th>"; + $column_data{debit} = "<th align=right class=listsubtotal>$subtotaldebit</th>"; + $column_data{credit} = "<th align=right class=listsubtotal>$subtotalcredit</th>"; + + print qq| + <tr class=listsubtotal> +|; + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + } + + $totaldebit = $form->format_amount(\%myconfig, $totaldebit, 2, " "); + $totalcredit = $form->format_amount(\%myconfig, $totalcredit, 2, " "); + + for (qw(accno description begbalance endbalance)) { $column_data{$_} = "<th> </th>" } + + $column_data{debit} = qq|<th align=right class=listtotal>$totaldebit</th>|; + $column_data{credit} = qq|<th align=right class=listtotal>$totalcredit</th>|; + + print qq| + <tr class=listtotal> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +</body> +</html> +|; + +} + + +sub generate_ar_aging { + + # split customer + ($form->{customer}) = split(/--/, $form->{customer}); + $customer = $form->escape($form->{customer},1); + $title = $form->escape($form->{title},1); + $media = $form->escape($form->{media},1); + + $form->{ct} = "customer"; + $form->{arap} = "ar"; + + RP->aging(\%myconfig, \%$form); + + $form->{callback} = qq|$form->{script}?path=$form->{path}&action=generate_ar_aging&login=$form->{login}&sessionid=$form->{sessionid}&todate=$form->{todate}&customer=$customer&title=$title&type=$form->{type}&format=$form->{format}&media=$media&summary=$form->{summary}|; + + &aging; + +} + + +sub generate_ap_aging { + + # split vendor + ($form->{vendor}) = split(/--/, $form->{vendor}); + $vendor = $form->escape($form->{vendor},1); + $title = $form->escape($form->{title},1); + $media = $form->escape($form->{media},1); + + $form->{ct} = "vendor"; + $form->{arap} = "ap"; + + RP->aging(\%myconfig, \%$form); + + $form->{callback} = qq|$form->{script}?path=$form->{path}&action=generate_ap_aging&login=$form->{login}&sessionid=$form->{sessionid}&todate=$form->{todate}&vendor=$vendor&title=$title&type=$form->{type}&format=$form->{format}&media=$media&summary=$form->{summary}|; + + &aging; + +} + + +sub aging { + + $form->header; + + $column_header{statement} = qq|<th class=listheading width=1%> </th>|; + $column_header{ct} = qq|<th class=listheading width=60%>|.$locale->text(ucfirst $form->{ct}).qq|</th>|; + $column_header{language} = qq|<th class=listheading>|.$locale->text('Language').qq|</th>|; + $column_header{invnumber} = qq|<th class=listheading>|.$locale->text('Invoice').qq|</th>|; + $column_header{ordnumber} = qq|<th class=listheading>|.$locale->text('Order').qq|</th>|; + $column_header{transdate} = qq|<th class=listheading nowrap>|.$locale->text('Date').qq|</th>|; + $column_header{duedate} = qq|<th class=listheading nowrap>|.$locale->text('Due Date').qq|</th>|; + $column_header{c0} = qq|<th class=listheading width=10% nowrap>|.$locale->text('Current').qq|</th>|; + $column_header{c30} = qq|<th class=listheading width=10% nowrap>30</th>|; + $column_header{c60} = qq|<th class=listheading width=10% nowrap>60</th>|; + $column_header{c90} = qq|<th class=listheading width=10% nowrap>90</th>|; + $column_header{total} = qq|<th class=listheading width=10% nowrap>|.$locale->text('Total').qq|</th>|; + + @column_index = qw(statement ct); + + if (@{ $form->{all_language} } && $form->{arap} eq 'ar') { + push @column_index, "language"; + $form->{selectlanguage} = qq|<option>\n|; + + for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| } + } + + @c = (); + for (qw(c0 c30 c60 c90)) { + if ($form->{$_}) { + push @c, $_; + $form->{callback} .= "&$_=$form->{$_}"; + } + } + + if (!$form->{summary}) { + push @column_index, qw(invnumber ordnumber transdate duedate); + } + push @column_index, @c; + push @column_index, "total"; + + $option = $locale->text('Aged'); + if ($form->{overdue}) { + $option= $locale->text('Aged Overdue'); + $form->{callback} .= "&overdue=$form->{overdue}"; + } + + if ($form->{department}) { + $option .= "\n<br>" if $option; + ($department) = split /--/, $form->{department}; + $option .= $locale->text('Department')." : $department"; + $department = $form->escape($form->{department},1); + $form->{callback} .= "&department=$department"; + } + + if ($form->{arap} eq 'ar') { + if ($form->{customer}) { + $option .= "\n<br>" if $option; + $option .= $form->{customer}; + } + } + if ($form->{arap} eq 'ap') { + shift @column_index; + if ($form->{vendor}) { + $option .= "\n<br>" if $option; + $option .= $form->{vendor}; + } + } + + $todate = $locale->date(\%myconfig, $form->{todate}, 1); + $option .= "\n<br>" if $option; + $option .= $locale->text('for Period')." ".$locale->text('To')." $todate"; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> +|; + + $ctid = 0; + $i = 0; + $k = 0; + $l = $#{ $form->{AG} }; + + foreach $ref (@{ $form->{AG} }) { + + if ($curr ne $ref->{curr}) { + $ctid = 0; + for (@column_index) { $column_data{$_} = qq|<th> </th>| } + if ($curr) { + $c0total = $form->format_amount(\%myconfig, $c0total, 2, " "); + $c30total = $form->format_amount(\%myconfig, $c30total, 2, " "); + $c60total = $form->format_amount(\%myconfig, $c60total, 2, " "); + $c90total = $form->format_amount(\%myconfig, $c90total, 2, " "); + $total = $form->format_amount(\%myconfig, $total, 2, " "); + + for (qw(ct statement language)) { $column_data{$_} = qq|<td> </td>| } + $column_data{c0} = qq|<th align=right>$c0total</th>|; + $column_data{c30} = qq|<th align=right>$c30total</th>|; + $column_data{c60} = qq|<th align=right>$c60total</th>|; + $column_data{c90} = qq|<th align=right>$c90total</th>|; + $column_data{total} = qq|<th align=right>$total</th>|; + + print qq| + <tr class=listtotal> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + $c0subtotal = 0; + $c30subtotal = 0; + $c60subtotal = 0; + $c90subtotal = 0; + $subtotal = 0; + + $c0total = 0; + $c30total = 0; + $c60total = 0; + $c90total = 0; + $total = 0; + + } + + $curr = $ref->{curr}; + print qq| + <tr> + <td></td> + <th>$curr</th> + </tr> + + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + } + + $k++; + + if ($ctid != $ref->{ctid}) { + + $i++; + + $column_data{ct} = qq|<td>$ref->{name}</td>|; + + if ($form->{selectlanguage}) { + $form->{"selectlanguage_$i"} = $form->{selectlanguage}; + $form->{"selectlanguage_$i"} =~ s/(<option value="\Q$ref->{language_code}\E")/$1 selected/; + $column_data{language} = qq|<td><select name="language_code_$i">$form->{"selectlanguage_$i"}</select></td>|; + } + + $column_data{statement} = qq|<td><input name="statement_$i" type=checkbox class=checkbox value=1 $ref->{checked}> + <input type=hidden name="$form->{ct}_id_$i" value=$ref->{ctid}> + <input type=hidden name="curr_$i" value=$ref->{curr}> + </td>|; + + } + + $ctid = $ref->{ctid}; + + for (qw(c0 c30 c60 c90)) { $ref->{$_} = $form->round_amount($ref->{$_} / $ref->{exchangerate}, 2) } + + $c0subtotal += $ref->{c0}; + $c30subtotal += $ref->{c30}; + $c60subtotal += $ref->{c60}; + $c90subtotal += $ref->{c90}; + + $c0total += $ref->{c0}; + $c30total += $ref->{c30}; + $c60total += $ref->{c60}; + $c90total += $ref->{c90}; + + $ref->{total} = ($ref->{c0} + $ref->{c30} + $ref->{c60} + $ref->{c90}); + $subtotal += $ref->{total}; + $total += $ref->{total}; + + $ref->{c0} = $form->format_amount(\%myconfig, $ref->{c0}, 2, " "); + $ref->{c30} = $form->format_amount(\%myconfig, $ref->{c30}, 2, " "); + $ref->{c60} = $form->format_amount(\%myconfig, $ref->{c60}, 2, " "); + $ref->{c90} = $form->format_amount(\%myconfig, $ref->{c90}, 2, " "); + $ref->{total} = $form->format_amount(\%myconfig, $ref->{total}, 2, " "); + + $href = qq|$ref->{module}.pl?path=$form->{path}&action=edit&id=$ref->{id}&login=$form->{login}&sessionid=$form->{sessionid}&callback=|.$form->escape($form->{callback}); + + $column_data{invnumber} = qq|<td><a href=$href>$ref->{invnumber}</a></td>|; + for (qw(ordnumber transdate duedate)) { $column_data{$_} = qq|<td>$ref->{$_}</td>| } + for (qw(c0 c30 c60 c90 total)) { $column_data{$_} = qq|<td align=right>$ref->{$_}</td>| } + + if (!$form->{summary}) { + + $j++; $j %= 2; + print qq| + <tr class=listrow$j> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + for (qw(ct statement language)) { $column_data{$_} = qq|<td> </td>| } + + } + + # print subtotal + $nextid = ($k <= $l) ? $form->{AG}->[$k]->{ctid} : 0; + if ($ctid != $nextid) { + + $c0subtotal = $form->format_amount(\%myconfig, $c0subtotal, 2, " "); + $c30subtotal = $form->format_amount(\%myconfig, $c30subtotal, 2, " "); + $c60subtotal = $form->format_amount(\%myconfig, $c60subtotal, 2, " "); + $c90subtotal = $form->format_amount(\%myconfig, $c90subtotal, 2, " "); + $subtotal = $form->format_amount(\%myconfig, $subtotal, 2, " "); + + if ($form->{summary}) { + $column_data{c0} = qq|<td align=right>$c0subtotal</th>|; + $column_data{c30} = qq|<td align=right>$c30subtotal</th>|; + $column_data{c60} = qq|<td align=right>$c60subtotal</th>|; + $column_data{c90} = qq|<td align=right>$c90subtotal</th>|; + $column_data{total} = qq|<td align=right>$subtotal</th>|; + + $j++; $j %= 2; + print qq| + <tr class=listrow$j> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + } else { + + for (@column_index) { $column_data{$_} = qq|<th> </th>| } + + $column_data{c0} = qq|<th class=listsubtotal align=right>$c0subtotal</th>|; + $column_data{c30} = qq|<th class=listsubtotal align=right>$c30subtotal</th>|; + $column_data{c60} = qq|<th class=listsubtotal align=right>$c60subtotal</th>|; + $column_data{c90} = qq|<th class=listsubtotal align=right>$c90subtotal</th>|; + $column_data{total} = qq|<th class=listsubtotal align=right>$subtotal</th>|; + + # print subtotals + print qq| + <tr class=listsubtotal> +|; + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + } + + $c0subtotal = 0; + $c30subtotal = 0; + $c60subtotal = 0; + $c90subtotal = 0; + $subtotal = 0; + + } + } + + print qq| + </tr> + <tr class=listtotal> +|; + + for (@column_index) { $column_data{$_} = qq|<th> </th>| } + + $c0total = $form->format_amount(\%myconfig, $c0total, 2, " "); + $c30total = $form->format_amount(\%myconfig, $c30total, 2, " "); + $c60total = $form->format_amount(\%myconfig, $c60total, 2, " "); + $c90total = $form->format_amount(\%myconfig, $c90total, 2, " "); + $total = $form->format_amount(\%myconfig, $total, 2, " "); + + $column_data{c0} = qq|<th align=right class=listtotal>$c0total</th>|; + $column_data{c30} = qq|<th align=right class=listtotal>$c30total</th>|; + $column_data{c60} = qq|<th align=right class=listtotal>$c60total</th>|; + $column_data{c90} = qq|<th align=right class=listtotal>$c90total</th>|; + $column_data{total} = qq|<th align=right class=listtotal>$total</th>|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> + <input type=hidden name=rowcount value=$i> + </table> + </td> + </tr> + + <tr> + <td> +|; + + &print_options if ($form->{arap} eq 'ar'); + + print qq| + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + if ($form->{arap} eq 'ar') { + + $form->hide_form(qw(todate title summary overdue c0 c30 c60 c90 callback arap ct department path login sessionid)); + + print qq| +<input type=hidden name=$form->{ct} value="$form->{$form->{ct}}"> +|; + +# type=submit $locale->text('Select all') +# type=submit $locale->text('Print') +# type=submit $locale->text('E-mail') + + %button = ('Select all' => { ndx => 1, key => 'A', value => $locale->text('Select all') }, + 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') }, + 'E-mail' => { ndx => 5, key => 'E', value => $locale->text('E-mail') }, + ); + + for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) } + + } + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| +</form> + +</body> +</html> +|; + +} + + +sub select_all { + + RP->aging(\%myconfig, \%$form); + + for (@{ $form->{AG} }) { $_->{checked} = "checked" } + + &aging; + +} + + +sub print_options { + + $form->{sendmode} = "attachment"; + $form->{copies} = 1 unless $form->{copies}; + + $form->{PD}{$form->{type}} = "selected"; + $form->{DF}{$form->{format}} = "selected"; + $form->{SM}{$form->{sendmode}} = "selected"; + + $format = qq| + <option value=html $form->{PD}{format}>html|; + + $type = qq| + <option value=statement $form->{PD}{statement}>|.$locale->text('Statement'); + + + if ($form->{media} eq 'email') { + $media = qq| + <td><select name=sendmode> + <option value=attachment $form->{SM}{attachment}>|.$locale->text('Attachment').qq| + <option value=inline $form->{SM}{inline}>|.$locale->text('In-line'); + } else { + $media = qq| + <td><select name=media> + <option value=screen>|.$locale->text('Screen'); + if (%printer && $latex) { + for (sort keys %printer) { $media .= qq| + <option value="$_">$_| } + } + } + + $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/; + $media .= qq|</select></td>|; + + if ($latex) { + $format .= qq| + <option value=postscript $form->{DF}{postscript}>|.$locale->text('Postscript').qq| + <option value=pdf $form->{DF}{pdf}>|.$locale->text('PDF'); + } + + print qq| +<table> + <tr> + <td><select name=type>$type</select></td> + <td><select name=format>$format</select></td> + $media +|; + + if (%printer && $latex && $form->{media} ne 'email') { + print qq| + <td>|.$locale->text('Copies').qq| + <input name=copies size=2 value=$form->{copies}></td> +|; + } + + print qq| + </tr> +</table> +|; + +} + + +sub e_mail { + + # get name and email addresses + for $i (1 .. $form->{rowcount}) { + if ($form->{"statement_$i"}) { + $form->{"$form->{ct}_id"} = $form->{"$form->{ct}_id_$i"}; + $form->{"statement_1"} = 1; + $form->{"language_code_1"} = $form->{"language_code_$i"}; + $form->{"curr_1"} = $form->{"curr_$i"}; + RP->get_customer(\%myconfig, \%$form); + $selected = 1; + last; + } + } + + $form->error($locale->text('Nothing selected!')) unless $selected; + + if ($myconfig{role} =~ /(admin|manager)/) { + $bcc = qq| + <th align=right nowrap=true>|.$locale->text('Bcc').qq|</th> + <td><input name=bcc size=30 value="$form->{bcc}"></td> +|; + } + + $title = $locale->text('E-mail Statement to')." $form->{$form->{ct}}"; + + $form->{media} = "email"; + + $form->header; + + print qq| +<body> + +<form method=post action=$form->{script}> + +<table width=100%> + <tr class=listtop> + <th>$title</th> + </tr> + <tr height="5"></tr> + <tr> + <td> + <table width=100%> + <tr> + <th align=right nowrap>|.$locale->text('E-mail').qq|</th> + <td><input name=email size=30 value="$form->{email}"></td> + <th align=right nowrap>|.$locale->text('Cc').qq|</th> + <td><input name=cc size=30 value="$form->{cc}"></td> + </tr> + <tr> + <th align=right nowrap>|.$locale->text('Subject').qq|</th> + <td><input name=subject size=30 value="$form->{subject}"></td> + $bcc + </tr> + </table> + </td> + </tr> + <tr> + <td> + <table width=100%> + <tr> + <th align=left nowrap>|.$locale->text('Message').qq|</th> + </tr> + <tr> + <td><textarea name=message rows=15 cols=60 wrap=soft>$form->{message}</textarea></td> + </tr> + </table> + </td> + </tr> + <tr> + <td> +|; + + &print_options; + + for (qw(email cc bcc subject message type sendmode format action nextsub)) { delete $form->{$_} } + + $form->hide_form; + + print qq| + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +<input type=hidden name=nextsub value=send_email> + +<br> +<input name=action class=submit type=submit value="|.$locale->text('Continue').qq|"> +</form> + +</body> +</html> +|; + +} + + +sub send_email { + + $form->{OUT} = "$sendmail"; + + $form->{subject} = $locale->text('Statement').qq| - $form->{todate}| unless $form->{subject}; + $form->isblank("email", $locale->text('E-mail address missing!')); + + RP->aging(\%myconfig, \%$form); + + &print_form; + + $form->redirect($locale->text('Statement sent to')." $form->{$form->{ct}}"); + +} + + + +sub print { + + if ($form->{media} !~ /(screen|email)/) { + $form->error($locale->text('Select postscript or PDF!')) if ($form->{format} !~ /(postscript|pdf)/); + } + + for $i (1 .. $form->{rowcount}) { + if ($form->{"statement_$i"}) { + $form->{"$form->{ct}_id"} = $form->{"$form->{ct}_id_$i"}; + $language_code = $form->{"language_code_$i"}; + $curr = $form->{"curr_$i"}; + $selected = 1; + last; + } + } + + $form->error($locale->text('Nothing selected!')) unless $selected; + + + if ($form->{media} !~ /(screen|email)/) { + $form->{OUT} = "| $printer{$form->{media}}"; + $form->{"$form->{ct}_id"} = ""; + $SIG{INT} = 'IGNORE'; + } else { + $form->{"statement_1"} = 1; + $form->{"language_code_1"} = $language_code; + $form->{"curr_1"} = $curr; + } + + RP->aging(\%myconfig, \%$form); + + &print_form; + + $form->redirect($locale->text('Statements sent to printer!')) if ($form->{media} !~ /(screen|email)/); + +} + + +sub print_form { + + $form->{statementdate} = $locale->date(\%myconfig, $form->{todate}, 1); + + $form->{templates} = "$myconfig{templates}"; + + # setup variables for the form + @a = qw(company address businessnumber tel fax); + for (@a) { $form->{$_} = $myconfig{$_} } + $form->{address} =~ s/\\n/\n/g; + + $form->format_string(@a); + + $form->{IN} = "$form->{type}.html"; + + if ($form->{format} eq 'postscript') { + $form->{IN} =~ s/html$/tex/; + } + if ($form->{format} eq 'pdf') { + $form->{IN} =~ s/html$/tex/; + } + + @a = qw(name address1 address2 city state zipcode country contact); + push @a, "$form->{ct}phone", "$form->{ct}fax", "$form->{ct}taxnumber"; + push @a, 'email' if ! $form->{media} eq 'email'; + + $i = 0; + while (@{ $form->{AG} }) { + + $ref = shift @{ $form->{AG} }; + + if ($ctid != $ref->{ctid}) { + + $ctid = $ref->{ctid}; + $i++; + + if ($form->{"statement_$i"}) { + + for (@a) { $form->{$_} = $ref->{$_} } + $form->format_string(@a); + + $form->{$form->{ct}} = $form->{name}; + $form->{"$form->{ct}_id"} = $ref->{ctid}; + $form->{language_code} = $form->{"language_code_$i"}; + $form->{currency} = $form->{"curr_$i"}; + + for (qw(invnumber ordnumber ponumber notes invdate duedate)) { $form->{$_} = () } + $form->{total} = 0; + foreach $item (qw(c0 c30 c60 c90)) { + $form->{$item} = (); + $form->{"${item}total"} = 0; + } + + &statement_details($ref) if $ref->{curr} eq $form->{currency}; + + while ($ref) { + + if (scalar (@{ $form->{AG} }) > 0) { + # one or more left to go + if ($ctid == $form->{AG}->[0]->{ctid}) { + $ref = shift @{ $form->{AG} }; + &statement_details($ref) if $ref->{curr} eq $form->{currency}; + # any more? + $ref = scalar (@{ $form->{AG} }); + } else { + $ref = 0; + } + } else { + # set initial ref to 0 + $ref = 0; + } + + } + + for ("c0", "c30", "c60", "c90", "") { $form->{"${_}total"} = $form->format_amount(\%myconfig, $form->{"${_}total"}, 2) } + + $form->parse_template(\%myconfig, $userspath); + + } + } + } + +} + + +sub statement_details { + my ($ref) = @_; + + $ref->{invdate} = $ref->{transdate}; + my @a = qw(invnumber ordnumber ponumber notes invdate duedate); + for (@a) { $form->{"${_}_1"} = $ref->{$_} } + $form->format_string(qw(invnumber_1 ordnumber_1 ponumber_1 notes_1)); + for (@a) { push @{ $form->{$_} }, $form->{"${_}_1"} } + + foreach $item (qw(c0 c30 c60 c90)) { + eval { $ref->{$item} = $form->round_amount($ref->{$item} / $ref->{exchangerate}, 2) }; + $form->{"${item}total"} += $ref->{$item}; + $form->{total} += $ref->{$item}; + push @{ $form->{$item} }, $form->format_amount(\%myconfig, $ref->{$item}, 2); + } + +} + + +sub generate_tax_report { + + RP->tax_report(\%myconfig, \%$form); + + $descvar = "$form->{accno}_description"; + $description = $form->escape($form->{$descvar}); + $ratevar = "$form->{accno}_rate"; + $taxrate = $form->{"$form->{accno}_rate"}; + + if ($form->{accno} =~ /^gifi_/) { + $descvar = "gifi_$form->{accno}_description"; + $description = $form->escape($form->{$descvar}); + $ratevar = "gifi_$form->{accno}_rate"; + $taxrate = $form->{"gifi_$form->{accno}_rate"}; + } + + $department = $form->escape($form->{department}); + + # construct href + $href = "$form->{script}?path=$form->{path}&direction=$form->{direction}&oldsort=$form->{oldsort}&action=generate_tax_report&login=$form->{login}&sessionid=$form->{sessionid}&fromdate=$form->{fromdate}&todate=$form->{todate}&db=$form->{db}&method=$form->{method}&summary=$form->{summary}&accno=$form->{accno}&$descvar=$description&department=$department&$ratevar=$taxrate&report=$form->{report}"; + + # construct callback + $description = $form->escape($form->{$descvar},1); + $department = $form->escape($form->{department},1); + + $form->sort_order(); + + $callback = "$form->{script}?path=$form->{path}&direction=$form->{direction}&oldsort=$form->{oldsort}&action=generate_tax_report&login=$form->{login}&sessionid=$form->{sessionid}&fromdate=$form->{fromdate}&todate=$form->{todate}&db=$form->{db}&method=$form->{method}&summary=$form->{summary}&accno=$form->{accno}&$descvar=$description&department=$department&$ratevar=$taxrate&report=$form->{report}"; + + $form->{title} = $locale->text('GIFI')." - " if ($form->{accno} =~ /^gifi_/); + + $title = $form->escape($form->{title}); + $href .= "&title=$title"; + $title = $form->escape($form->{title},1); + $callback .= "&title=$title"; + + $form->{title} = qq|$form->{title} $form->{"$form->{accno}_description"} |; + + @columns = $form->sort_columns(qw(id transdate invnumber name description netamount tax total)); + + $form->{"l_description"} = "" if $form->{summary}; + + foreach $item (@columns) { + if ($form->{"l_$item"} eq "Y") { + push @column_index, $item; + + # add column to href and callback + $callback .= "&l_$item=Y"; + $href .= "&l_$item=Y"; + } + } + + + if ($form->{l_subtotal} eq 'Y') { + $callback .= "&l_subtotal=Y"; + $href .= "&l_subtotal=Y"; + } + + + if ($form->{department}) { + ($department) = split /--/, $form->{department}; + $option = $locale->text('Department')." : $department"; + } + + # if there are any dates + if ($form->{fromdate} || $form->{todate}) { + if ($form->{fromdate}) { + $fromdate = $locale->date(\%myconfig, $form->{fromdate}, 1); + } + if ($form->{todate}) { + $todate = $locale->date(\%myconfig, $form->{todate}, 1); + } + + $form->{period} = "$fromdate - $todate"; + } else { + $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1); + } + + + if ($form->{db} eq 'ar') { + $name = $locale->text('Customer'); + $invoice = 'is.pl'; + $arap = 'ar.pl'; + } + if ($form->{db} eq 'ap') { + $name = $locale->text('Vendor'); + $invoice = 'ir.pl'; + $arap = 'ap.pl'; + } + + $option .= "<br>" if $option; + $option .= "$form->{period}"; + + + $column_header{id} = qq|<th><a class=listheading href=$href&sort=id>|.$locale->text('ID').qq|</th>|; + $column_header{invnumber} = qq|<th><a class=listheading href=$href&sort=invnumber>|.$locale->text('Invoice').qq|</th>|; + $column_header{transdate} = qq|<th><a class=listheading href=$href&sort=transdate>|.$locale->text('Date').qq|</th>|; + $column_header{netamount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|; + $column_header{tax} = qq|<th class=listheading>|.$locale->text('Tax').qq|</th>|; + $column_header{total} = qq|<th class=listheading>|.$locale->text('Total').qq|</th>|; + + $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>$name</th>|; + + $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</th>|; + + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop colspan=$colspan>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "$column_header{$_}\n" } + + print qq| + </tr> +|; + + # add sort and escape callback + $callback = $form->escape($callback . "&sort=$form->{sort}"); + + if (@{ $form->{TR} }) { + $sameitem = $form->{TR}->[0]->{$form->{sort}}; + } + + foreach $ref (@{ $form->{TR} }) { + + $module = ($ref->{invoice}) ? $invoice : $arap; + $module = 'ps.pl' if $ref->{till}; + + if ($form->{l_subtotal} eq 'Y') { + if ($sameitem ne $ref->{$form->{sort}}) { + &tax_subtotal; + $sameitem = $ref->{$form->{sort}}; + } + } + + $totalnetamount += $ref->{netamount}; + $totaltax += $ref->{tax}; + $ref->{total} = $ref->{netamount} + $ref->{tax}; + + $subtotalnetamount += $ref->{netamount}; + $subtotaltax += $ref->{tax}; + + for (qw(netamount tax total)) { $ref->{$_} = $form->format_amount(\%myconfig, $ref->{$_}, 2, " "); } + + $column_data{id} = qq|<td>$ref->{id}</td>|; + $column_data{invnumber} = qq|<td><a href=$module?path=$form->{path}&action=edit&id=$ref->{id}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{invnumber}</a></td>|; + + for (qw(id transdate name partnumber description)) { $column_data{$_} = qq|<td>$ref->{$_}</td>| } + + for (qw(netamount tax total)) { $column_data{$_} = qq|<td align=right>$ref->{$_}</td>| } + + $i++; $i %= 2; + print qq| + <tr class=listrow$i> +|; + + for (@column_index) { print "$column_data{$_}\n" } + + print qq| + </tr> +|; + + } + + if ($form->{l_subtotal} eq 'Y') { + &tax_subtotal; + } + + + for (@column_index) { $column_data{$_} = qq|<th> </th>| } + + print qq| + </tr> + <tr class=listtotal> +|; + + $total = $form->format_amount(\%myconfig, $totalnetamount + $totaltax, 2, " "); + $totalnetamount = $form->format_amount(\%myconfig, $totalnetamount, 2, " "); + $totaltax = $form->format_amount(\%myconfig, $totaltax, 2, " "); + + $column_data{netamount} = qq|<th class=listtotal align=right>$totalnetamount</th>|; + $column_data{tax} = qq|<th class=listtotal align=right>$totaltax</th>|; + $column_data{total} = qq|<th class=listtotal align=right>$total</th>|; + + for (@column_index) { print "$column_data{$_}\n" } + + + print qq| + </tr> + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> + +</body> +</html> +|; + +} + + +sub tax_subtotal { + + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $subtotal = $form->format_amount(\%myconfig, $subtotalnetamount + $subtotaltax, 2, " "); + $subtotalnetamount = $form->format_amount(\%myconfig, $subtotalnetamount, 2, " "); + $subtotaltax = $form->format_amount(\%myconfig, $subtotaltax, 2, " "); + + $column_data{netamount} = "<th class=listsubtotal align=right>$subtotalnetamount</th>"; + $column_data{tax} = "<th class=listsubtotal align=right>$subtotaltax</th>"; + $column_data{total} = "<th class=listsubtotal align=right>$subtotal</th>"; + + $subtotalnetamount = 0; + $subtotaltax = 0; + + print qq| + <tr class=listsubtotal> +|; + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + +} + + + +sub list_payments { + + + if ($form->{account}) { + ($form->{paymentaccounts}) = split /--/, $form->{account}; + } + if ($form->{department}) { + ($department, $form->{department_id}) = split /--/, $form->{department}; + $option = $locale->text('Department')." : $department"; + } + + RP->payments(\%myconfig, \%$form); + + @columns = $form->sort_columns(qw(transdate name paid source memo)); + + if ($form->{till}) { + @columns = $form->sort_columns(qw(transdate name paid curr source till)); + if ($myconfig{role} ne 'user') { + @columns = $form->sort_columns(qw(transdate name paid curr source till employee)); + } + } + + # construct href + $title = $form->escape($form->{title}); + $form->{paymentaccounts} =~ s/ /%20/g; + + $href = "$form->{script}?path=$form->{path}&direction=$form->{direction}&sort=$form->{sort}&oldsort=$form->{oldsort}&action=list_payments&till=$form->{till}&login=$form->{login}&sessionid=$form->{sessionid}&fromdate=$form->{fromdate}&todate=$form->{todate}&fx_transaction=$form->{fx_transaction}&db=$form->{db}&l_subtotal=$form->{l_subtotal}&prepayment=$form->{prepayment}&paymentaccounts=$form->{paymentaccounts}&title=".$form->escape($form->{title}); + + $form->sort_order(); + + $form->{callback} = "$form->{script}?path=$form->{path}&direction=$form->{direction}&sort=$form->{sort}&oldsort=$form->{oldsort}&action=list_payments&till=$form->{till}&login=$form->{login}&sessionid=$form->{sessionid}&fromdate=$form->{fromdate}&todate=$form->{todate}&fx_transaction=$form->{fx_transaction}&db=$form->{db}&l_subtotal=$form->{l_subtotal}&prepayment=$form->{prepayment}&paymentaccounts=$form->{paymentaccounts}&title=".$form->escape($form->{title},1); + + if ($form->{account}) { + $callback .= "&account=".$form->escape($form->{account},1); + $href .= "&account=".$form->escape($form->{account}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Account')." : $form->{account}"; + } + if ($form->{department}) { + $callback .= "&department=".$form->escape($form->{department},1); + $href .= "&department=".$form->escape($form->{department}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Department')." : $form->{department}"; + } + if ($form->{description}) { + $callback .= "&description=".$form->escape($form->{description},1); + $href .= "&description=".$form->escape($form->{description}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Description')." : $form->{description}"; + } + if ($form->{source}) { + $callback .= "&source=".$form->escape($form->{source},1); + $href .= "&source=".$form->escape($form->{source}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Source')." : $form->{source}"; + } + if ($form->{memo}) { + $callback .= "&memo=".$form->escape($form->{memo},1); + $href .= "&memo=".$form->escape($form->{memo}); + $option .= "\n<br>" if ($option); + $option .= $locale->text('Memo')." : $form->{memo}"; + } + if ($form->{fromdate}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{fromdate}, 1); + } + if ($form->{todate}) { + $option .= "\n<br>" if ($option); + $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{todate}, 1); + } + + $callback = $form->escape($form->{callback}); + + $column_header{name} = "<th><a class=listheading href=$href&sort=name>".$locale->text('Description')."</a></th>"; + $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>"; + $column_header{paid} = "<th class=listheading>".$locale->text('Amount')."</a></th>"; + $column_header{curr} = "<th class=listheading>".$locale->text('Curr')."</a></th>"; + $column_header{source} = "<th><a class=listheading href=$href&sort=source>".$locale->text('Source')."</a></th>"; + $column_header{memo} = "<th><a class=listheading href=$href&sort=memo>".$locale->text('Memo')."</a></th>"; + + $column_header{employee} = "<th><a class=listheading href=$href&sort=employee>".$locale->text('Salesperson')."</a></th>"; + $column_header{till} = "<th><a class=listheading href=$href&sort=till>".$locale->text('Till')."</a></th>"; + + @column_index = @columns; + $colspan = $#column_index + 1; + + $form->header; + + print qq| +<body> + +<table width=100%> + <tr> + <th class=listtop>$form->{title}</th> + </tr> + <tr height="5"></tr> + <tr> + <td>$option</td> + </tr> + <tr> + <td> + <table width=100%> + <tr class=listheading> +|; + + for (@column_index) { print "\n$column_header{$_}" } + + print qq| + </tr> +|; + + + foreach $ref (sort { $a->{accno} cmp $b->{accno} } @{ $form->{PR} }) { + + next unless @{ $form->{$ref->{id}} }; + + print qq| + <tr> + <th colspan=$colspan align=left>$ref->{accno}--$ref->{description}</th> + </tr> +|; + + if (@{ $form->{$ref->{id}} }) { + $sameitem = $form->{$ref->{id}}[0]->{$form->{sort}}; + } + + foreach $payment (@{ $form->{$ref->{id}} }) { + + if ($form->{l_subtotal}) { + if ($payment->{$form->{sort}} ne $sameitem) { + # print subtotal + &payment_subtotal; + } + } + + next if ($form->{till} && ! $payment->{till}); + + $column_data{name} = "<td>$payment->{name} </td>"; + $column_data{transdate} = "<td>$payment->{transdate} </td>"; + $column_data{paid} = "<td align=right>".$form->format_amount(\%myconfig, $payment->{paid}, 2, " ")."</td>"; + $column_data{curr} = "<td>$payment->{curr}</td>"; + $column_data{source} = "<td>$payment->{source} </td>"; + $column_data{memo} = "<td>$payment->{memo} </td>"; + $column_data{employee} = "<td>$payment->{employee} </td>"; + $column_data{till} = "<td>$payment->{till} </td>"; + + $subtotalpaid += $payment->{paid}; + $accounttotalpaid += $payment->{paid}; + $totalpaid += $payment->{paid}; + + $i++; $i %= 2; + print qq| + <tr class=listrow$i> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + $sameitem = $payment->{$form->{sort}}; + + } + + &payment_subtotal if $form->{l_subtotal}; + + # print account totals + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{paid} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $accounttotalpaid, 2, " ")."</th>"; + + print qq| + <tr class=listtotal> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + + $accounttotalpaid = 0; + + } + + + # print total + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{paid} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalpaid, 2, " ")."</th>"; + + print qq| + <tr class=listtotal> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> + + </table> + </td> + </tr> + <tr> + <td><hr size=3 noshade></td> + </tr> +</table> +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +</body> +</html> +|; + +} + + +sub payment_subtotal { + + if ($subtotalpaid != 0) { + for (@column_index) { $column_data{$_} = "<td> </td>" } + + $column_data{paid} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalpaid, 2, " ")."</th>"; + + print qq| + <tr class=listsubtotal> +|; + + for (@column_index) { print "\n$column_data{$_}" } + + print qq| + </tr> +|; + } + + $subtotalpaid = 0; + +} + + |