diff --git a/UI/Reports/filters/gl.html b/UI/Reports/filters/gl.html index 828dad0be1..838f5fb3c7 100644 --- a/UI/Reports/filters/gl.html +++ b/UI/Reports/filters/gl.html @@ -111,10 +111,47 @@ } %] - [% text('Include in Report') %] + [% text('Transaction status') %] + + + + + + + + - - - - - - - - + +
+ [% PROCESS input element_data = { + name = 'is_approved' + type = 'radio' + value = 'All' + checked = 'CHECKED' + }; %] [% text('All'); %][% PROCESS input element_data = { + name = 'is_approved' + type = 'radio' + value = 'Y' + }; %] [% text('Approved'); %] + [% PROCESS input element_data = { + name = 'is_approved' + type = 'radio' + value = 'N' + }; %] [% text('Unapproved'); %]
[% PROCESS input element_data = { + name = 'is_voided' + type = 'radio' + value = 'All' + checked = 'CHECKED' + }; %] [% text('All'); %][% PROCESS input element_data = { + name = 'is_voided' + type = 'radio' + value = 'Y' + }; %] [% text('Reversed'); %] + [% PROCESS input element_data = { + name = 'is_voided' + type = 'radio' + value = 'N' + }; %] [% text('Non-reversed'); %]
[% PROCESS input element_data = { @@ -125,7 +162,7 @@ value="X" checked = "checked" } %] [% text('All') %] + [% PROCESS input element_data = { name="category" id="category-asset" @@ -133,7 +170,7 @@ type="radio" value="A" } %] [% text('Asset') %] + [% PROCESS input element_data = { name="category" id="category-liability" @@ -141,7 +178,7 @@ type="radio" value="L" } %] [% text('Liability') %] + [% PROCESS input element_data = { name="category" id="category-equity" @@ -149,7 +186,7 @@ type="radio" value="Q" } %] [% text('Equity') %] + [% PROCESS input element_data = { name="category" id="category-income" @@ -157,7 +194,7 @@ type="radio" value="I" } %] [% text('Income') %] + [% PROCESS input element_data = { name="category" id="category-expense" @@ -165,29 +202,16 @@ type="radio" value="E" } %] [% text('Expense') %] -
[% PROCESS input element_data = { - name = 'is_approved' - type = 'radio' - value = 'Y' - checked = 'CHECKED' - }; %] [% text('Approved'); %] - [% PROCESS input element_data = { - name = 'is_approved' - type = 'radio' - value = 'N' - }; %] [% text('Unapproved'); %] - [% PROCESS input element_data = { - name = 'is_approved' - type = 'radio' - value = 'All' - }; %] [% text('All'); %]
+ + + + [% text('Include in Report') %] + + -
- - - + + - - + + - - + + - -
[% PROCESS input element_data = { name="col_id" class="checkbox" @@ -222,8 +246,8 @@ value="1" checked="checked" } %] [% text('Description') %]
[% PROCESS input element_data = { name="col_debits" class="checkbox" @@ -256,8 +280,8 @@ type="checkbox" value="1" } %] [% text('FX Credit') %]
[% PROCESS input element_data = { name="col_source" class="checkbox" @@ -283,8 +307,8 @@ type="checkbox" value="1" } %] [% text('Till') %]
[% PROCESS input element_data = { name="col_accno" class="checkbox" @@ -316,13 +340,10 @@ type="checkbox" value="1" } %] [% text('Subtotal') %]
- diff --git a/UI/Reports/filters/invoice_search.html b/UI/Reports/filters/invoice_search.html index a9743cc3b5..399d260a1e 100644 --- a/UI/Reports/filters/invoice_search.html +++ b/UI/Reports/filters/invoice_search.html @@ -167,44 +167,39 @@ } %] [% PROCESS date_row %] - - [% text('Invoice Status') %] - [% label_pos = 1; PROCESS input element_data = { - label = text('All') - type = 'radio' - name = 'on_hold' - id = 'on_hold-all' - value = '' - checked = 'CHECKED' - }; - PROCESS input element_data = { - label = text('Active') - type = 'radio' - name = 'on_hold' - id = 'on_hold-active' - value = '0' - }; - PROCESS input element_data = { - label = text('On Hold') #' - type = 'radio' - name = 'on_hold' - id = 'on_hold-hold' - value = '1' - }; %] - - -[% text('Include in Report') %] - -   - + [% text('Invoice Status') %] + + + + + + @@ -226,7 +222,6 @@ type = 'radio' value = 'Y' label = text('Approved') - checked = 'CHECKED' }; %] + + + + + +
[% label_pos = 1; PROCESS input element_data = { + label = text('Active') + type = 'radio' + name = 'on_hold' + id = 'on_hold-active' + value = '0' + }; %][% PROCESS input element_data = { + label = text('On Hold') + type = 'radio' + name = 'on_hold' + id = 'on_hold-hold' + value = '1' + }; %][% PROCESS input element_data = { + label = text('All') + type = 'radio' + name = 'on_hold' + id = 'on_hold-all' + value = '' + checked = 'CHECKED' + }; %]
[% PROCESS input element_data = { name = 'oc_state' type = 'radio' value = 'open' - checked = 'CHECKED' label = text('Open') } %] [% PROCESS input element_data = { @@ -218,6 +213,7 @@ type = 'radio' value = 'all' label = text('All') + checked = 'CHECKED' } %]
[% PROCESS input element_data = { name = 'is_approved' @@ -239,8 +234,37 @@ type = 'radio' value = 'All' label = text('All') + checked = 'CHECKED' }; %]
[% PROCESS input element_data = { + name = 'is_voided' + type = 'radio' + value = 'Y' + label = text('Voided') + }; %][% PROCESS input element_data = { + name = 'is_voided' + type = 'radio' + value = 'N' + label = text('Unvoided') + }; %][% PROCESS input element_data = { + name = 'is_voided' + type = 'radio' + value = 'All' + label = text('All') + checked = 'CHECKED' + }; %]
+ + + + [% text('Include in Report') %] + + @@ -280,14 +304,14 @@ name = 'col_transdate' type = 'checkbox' value = '1' - label = text('Invoice Date') #' + label = text('Invoice Date') checked = 'CHECKED' } %] @@ -354,13 +378,13 @@ name = 'col_due_date' type = 'checkbox' value = '1' - label = text('Due Date') #' + label = text('Due Date') } %] diff --git a/UI/journal/journal_entry.html b/UI/journal/journal_entry.html index 8d3f4f6fb8..bd2ef75519 100644 --- a/UI/journal/journal_entry.html +++ b/UI/journal/journal_entry.html @@ -12,7 +12,7 @@ action="[% form.script %]">
[% PROCESS input element_data = { name = 'col_running_number' @@ -259,20 +283,20 @@ name = 'col_invnumber' type = 'checkbox' value = '1' - label = text('Invoice Number') #' + label = text('Invoice Number') checked = 'CHECKED' } %] [% PROCESS input element_data = { name = 'col_ordnumber' type = 'checkbox' value = '1' - label = text('Order Number') #' + label = text('Order Number') } %] [% PROCESS input element_data = { name = 'col_ponumber' type = 'checkbox' value = '1' - label = text('PO Number') #' + label = text('PO Number') } %]
[% PROCESS input element_data = { name = 'col_business_units' type = 'checkbox' value = '1' - label = text('Business Units') #' + label = text('Business Units') } %] [% PROCESS input element_data = { name = 'col_entity_name' @@ -339,7 +363,7 @@ name = 'col_last_payment' type = 'checkbox' value = '1' - label = text('Date Paid') #' + label = text('Date Paid') } %]
[% PROCESS input element_data = { name = 'col_due' type = 'checkbox' value = '1' - label = text('Amount Due') #' + label = text('Amount Due') checked = 'CHECKED' } %] [% PROCESS input element_data = { @@ -381,13 +405,13 @@ name = 'col_shipping_point' type = 'checkbox' value = '1' - label = text('Shipping Point') #' + label = text('Shipping Point') } %] [% PROCESS input element_data = { name = 'col_ship_via' type = 'checkbox' value = '1' - label = text('Ship Via') #' + label = text('Ship Via') } %]
- + @@ -119,10 +119,25 @@
[% form.title %][% form.title %]
+ + [% IF form.reversed_by ; + text('This transaction has been reversed by transaction [_1] with ID [_2]', form.reversed_by_reference, form.reversed_by); + END %] +
+ + [% IF form.reversing ; + IF form.approved ; + text('This transaction reverses transaction [_1] with ID [_2]', form.reversing_reference, form.reversing); + ELSE ; + text('This transaction will reverse transaction [_1] with ID [_2]', form.reversing_reference, form.reversing); + END ; + END %] + + - + - +
@@ -271,7 +287,7 @@ value = displayrow.debit_fx name = "debit_fx_$INDEX" type = "text" - readonly = form.approved + readonly = (form.approved || form.reversing) size = 12 id = "deb_fx_$INDEX" } %] @@ -282,7 +298,7 @@ value = displayrow.credit_fx name = "credit_fx_$INDEX" type = "text" - readonly = form.approved + readonly = (form.approved || form.reversing) size = 12 id = "cre_fx_$INDEX" } %] @@ -313,7 +329,7 @@


[% FOREACH hidden IN hiddens.keys; diff --git a/lib/LedgerSMB/Report/GL.pm b/lib/LedgerSMB/Report/GL.pm index d247a67320..cfa32f8764 100644 --- a/lib/LedgerSMB/Report/GL.pm +++ b/lib/LedgerSMB/Report/GL.pm @@ -31,7 +31,9 @@ use LedgerSMB::Report; use Moose; use namespace::autoclean; extends 'LedgerSMB::Report'; -with 'LedgerSMB::Report::Dates', 'LedgerSMB::Report::Approval_Option'; +with 'LedgerSMB::Report::Dates', + 'LedgerSMB::Report::Approval_Option', + 'LedgerSMB::Report::Voided_Option'; =head1 PROPERTIES diff --git a/lib/LedgerSMB/Report/Invoices/Transactions.pm b/lib/LedgerSMB/Report/Invoices/Transactions.pm index e0f108713e..191ae0298d 100644 --- a/lib/LedgerSMB/Report/Invoices/Transactions.pm +++ b/lib/LedgerSMB/Report/Invoices/Transactions.pm @@ -19,7 +19,8 @@ extends 'LedgerSMB::Report'; with 'LedgerSMB::Report::Dates', 'LedgerSMB::Report::Approval_Option', - 'LedgerSMB::Report::OpenClosed_Option'; + 'LedgerSMB::Report::OpenClosed_Option', + 'LedgerSMB::Report::Voided_Option'; =head1 DESCRIPTION @@ -187,7 +188,7 @@ has '+order_by' => (default => 'transdate'); =back -=head1 INTERNLS +=head1 INTERNALS =head2 columns diff --git a/lib/LedgerSMB/Report/Voided_Option.pm b/lib/LedgerSMB/Report/Voided_Option.pm new file mode 100644 index 0000000000..29dcc85a56 --- /dev/null +++ b/lib/LedgerSMB/Report/Voided_Option.pm @@ -0,0 +1,62 @@ +package LedgerSMB::Report::Voided_Option; + +=head1 NAME + +LedgerSMB::Report::Voided_Option - Report interface for voided selection + +=head1 DESCRIPTION + +This moose role adds an Cd user-settable flag (Y/N/All) +which is mapped to a boolean (True/False/Null). Null is used to request all. + +=head1 ADDED PROPERTIES + +=head2 is_voided string + +Y, N, All + +=head2 voided bool + +mapped from is_voided + +=cut + +use Moose::Role; +use namespace::autoclean; + +has is_voided => (is => 'ro', isa => 'Str', + default => 'Y'); +has voided => (is => 'ro', lazy => 1, + builder => '_voided'); + +my $_voided_map = { + Y => 1, + N => 0, + All => undef +}; + +=head1 METHODS + +This module does not declare any (public) methods. + +=cut + + +sub _voided { + my $self = shift; + die 'Bad approval code: ' . $self->is_voided + unless exists $_voided_map->{$self->is_voided}; + return $_voided_map->{$self->is_voided} +} + +=head1 LICENSE AND COPYRIGHT + +Copyright (C) 2016-2023 The LedgerSMB Core Team + +This file is licensed under the GNU General Public License version 2, or at your +option any later version. A copy of the license should have been included with +your software. + +=cut + +1; diff --git a/old/bin/aa.pl b/old/bin/aa.pl index 0addb0da12..bfeadd610f 100644 --- a/old/bin/aa.pl +++ b/old/bin/aa.pl @@ -167,26 +167,94 @@ sub edit { } else { $form->error("Unknown AR/AP selection value: $form->{ARAP}"); } + } + + &display_form; +} +sub reverse { + $form->{title} = $locale->text('Add'); + $form->{invnumber} .= '-VOID'; + + &create_links; + + delete $form->{workflow_id}; + $form->{reversing} = delete $form->{id}; + delete $form->{approved}; + $form->{reverse} = $form->{reverse} ? 0 : 1; + $form->{paidaccounts} = 0; + if ($form->{reverse}){ + if ($form->{ARAP} eq 'AR'){ + $form->{subtype} = 'credit_note'; + $form->{type} = 'transaction'; + } elsif ($form->{ARAP} eq 'AP'){ + $form->{subtype} = 'debit_note'; + $form->{type} = 'transaction'; + } else { + $form->error("Unknown AR/AP selection value: $form->{ARAP}"); + } } &display_form; } +sub post_reversing { + # we should save only the reference, sequence, transdate, description and notes; + # get the rest from the transaction being reversed. + + $form->error( + $locale->text('Cannot post transaction for a closed period!') ) + if ( $transdate and $form->is_closed( $transdate ) ); + if (not $form->{id}) { + do { + local $form->{id} = $form->{reversing}; + + # save data we want to use from the posted form, + # not from the reversed transaction. + local $form->{reversing}; + local $form->{reverse}; + local $form->{notes}; + local $form->{description}; + local $form->{reference}; + local $form->{approved}; + + &create_links; # create_links overwrites 'reversing' + }; + + AA->post_transaction( \%myconfig, \%$form ); + my $query = q{UPDATE transactions SET reversing = ? WHERE id = ?}; + $form->{dbh}->do( + $query, + {}, + $form->{reversing}, + $form->{id}) + or $form->dberror($query); + } + else { + my $query = <<~'QUERY'; + UPDATE gl + SET reference = ?, + description = ?, + transdate = ?, + notes = ? + WHERE id = ? + QUERY + } +} + sub display_form { my $invnumber = "sinumber"; if ( $form->{vc} eq 'vendor' ) { $invnumber = "vinumber"; } - $form->{sequence_select} = $form->sequence_dropdown($invnumber) - unless $form->{id} and ($form->{vc} eq 'vendor'); $form->{format} = $form->get_setting('format') unless $form->{format}; $form->close_form; $form->generate_selects(\%myconfig); $form->open_form; AA->get_files($form, $locale); - &form_header; - &form_footer; + my $readonly = $form->{reversing} or $form->{approved}; + &form_header( readonly => $readonly ); + &form_footer( readonly => $readonly ); } @@ -376,8 +444,10 @@ sub create_links { } sub form_header { + my %args = @_; my $min_lines = $form->get_setting('min_empty') // 0; - my $readonly = $form->{approved} ? 'readonly="readonly"' : ''; + my $readonly = ($args{readonly} or $form->{approved}) ? 'readonly="readonly"' : ''; + my $readonly_headers = $form->{approved} ? 'readonly="readonly"' : ''; # not read only unless approved $form->generate_selects(\%myconfig) unless $form->{"select$form->{ARAP}"}; @@ -392,6 +462,7 @@ sub form_header { ->create_workflow( 'AR/AP', Workflow::Context->new( 'batch-id' => $form->{batch_id}, + 'table_name' => lc($form->{ARAP}), is_transaction => 1 ) ); $form->{workflow_id} = $wf->id; @@ -481,7 +552,7 @@ sub form_header { } $form->{notes} //= ''; $notes = -qq||; +qq||; $form->{intnotes} //= ''; $intnotes = qq||; @@ -520,7 +591,7 @@ sub form_header { $employee = qq| - + @@ -546,7 +617,7 @@ sub form_header { qw(batch_id approved id printed emailed sort oldtransdate audittrail recurring checktax reverse subtype entity_control_code tax_id meta_number default_reportable - address city zipcode state country workflow_id) + address city zipcode state country workflow_id reversing) ); if ( $form->{vc} eq 'customer' ) { @@ -652,6 +723,8 @@ sub form_header { ponumber)); $myconfig{dateformat} //= ''; $employee //= ''; + $form->{sequence_select} = $form->sequence_dropdown($invnumber, $readonly_headers) + unless $form->{id} and ($form->{vc} eq 'vendor'); $form->{sequence_select} //= ''; print qq| $exchangerate @@ -660,16 +733,20 @@ sub form_header { + value="| . ($form->{description} // '') . qq|" $readonly_headers /> + | . + ($form->{reversing} ? qq|| . ($form->{approved} ? $locale->text('This transaction reverses transaction [_1] with ID [_2]', $form->{reversing_reference}, $form->{reversing}) : $locale->text('This transaction will reverse transaction [_1]', $form->{reversing})) .q|
| : '') . + ($form->{reversed_by} ? qq| | . $locale->text('This transaction is reversed by transaction [_1] with ID [_2]', $form->{reversed_by_reference}, $form->{reversed_by}) . q|| : '') . + qq| $employee - @@ -678,15 +755,15 @@ sub form_header { - + - + - + @@ -757,7 +834,7 @@ sub form_header { if($form->{"taxformcheck_$i"} or ($form->{default_reportable} and ($i == $form->{rowcount}))) { $taxchecked=qq|CHECKED="CHECKED"|; - + $taxchecked.=q| disabled="disabled"| if $readonly; } $taxformcheck=qq||; @@ -799,7 +876,7 @@ sub form_header { } my $tax_base = $form->{invtotal}; - foreach my $item ( split / /, $form->{taxaccounts} ) { + foreach my $item ( split / /, $form->{taxaccounts} ) { $form->{"calctax_$item"} = ( $form->{"calctax_$item"} ) ? "checked" : ""; $form->{"tax_$item"} = @@ -1005,8 +1082,6 @@ sub form_footer { {text=> $locale->text('Transaction'), value => 'transaction'}, ] }; - %button; - $wf->context->param( _is_closed => $form->is_closed( $transdate ) ); %button_types = ( print => 'lsmb/PrintButton' @@ -1024,6 +1099,13 @@ sub form_footer { tooltip => ($action->short_help ? $locale->maketext($action->short_help) : '') }; } + ###TODO: Move "reversing" state to the workflow! + if ($form->{reversing}) { + delete $button{$_} for (qw(schedule update save_temp edit_and_save)); + } + if (not $form->{approved}) { + delete $button{reverse}; + } for ( sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } diff --git a/old/bin/arap.pl b/old/bin/arap.pl index 4213b34efb..63e57f96d6 100644 --- a/old/bin/arap.pl +++ b/old/bin/arap.pl @@ -318,9 +318,11 @@ sub add_transaction { } sub post_as_new { + my %args = @_; $form->{old_workflow_id} = $form->{workflow_id}; for (qw(id printed emailed workflow_id invnumber)) { delete $form->{$_} } + $form->{invnumber} = $args{invnumber} // ''; my $wf = $form->{_wire}->get('workflows') ->create_workflow( 'AR/AP' ); diff --git a/old/bin/gl.pl b/old/bin/gl.pl index e1c851a8d8..ac78da7dc7 100644 --- a/old/bin/gl.pl +++ b/old/bin/gl.pl @@ -52,7 +52,7 @@ package lsmb_legacy; use LedgerSMB::Legacy_Util; use LedgerSMB::Num2text; -require "old/bin/arap.pl"; +require "old/bin/arap.pl"; # for: Schedule action # end of main @@ -107,7 +107,6 @@ sub approve { } } - sub new { for my $row (0 .. $form->{rowcount}){ for my $fld(qw(accno projectnumber acc debit credit source memo)){ @@ -148,6 +147,90 @@ sub add { } +sub _reverse_amounts { + # swap debits and credits + for my $rownum (0 .. $form->{rowcount}) { + my $credit = $form->{"credit_$rownum"}; + my $credit_fx = $form->{"credit_fx_$rownum"}; + $form->{"credit_$rownum"} = $form->{"debit_$rownum"}; + $form->{"credit_fx_$rownum"} = $form->{"debit_fx_$rownum"}; + $form->{"debit_$rownum"} = $credit; + $form->{"debit_fx_$rownum"} = $credit_fx; + } +} + +sub reverse { + $form->{title} = "Reverse"; + + &create_links; # runs GL->transaction() + _reverse_amounts(); + + $form->{reversing} = delete $form->{id}; + $form->{reversing_reference} = $form->{reference}; + delete $form->{approved}; + + display_form(); +} + + +sub post_reversing { + # we should save only the reference, sequence, transdate, description and notes. + + $form->error( + $locale->text('Cannot post transaction for a closed period!') ) + if ( $transdate and $form->is_closed( $transdate ) ); + if (not $form->{id}) { + do { + local $form->{id} = $form->{reversing}; + + # save data we want to use from the posted form, + # not from the reversed transaction. + local $form->{reversing}; + local $form->{notes}; + local $form->{description}; + local $form->{reference}; + local $form->{approved}; + + &create_links; # create_links overwrites 'reversing' + }; + + # Why do I not need _reverse_amounts here??? + # _reverse_amounts(); + GL->post_transaction( \%myconfig, \%$form, $locale); + + my $query = q{UPDATE transactions SET reversing = ? WHERE id = ?}; + $form->{dbh}->do( + $query, + {}, + $form->{reversing}, + $form->{id}) + or $form->dberror($query); + } + else { + my $query = <<~'QUERY'; + UPDATE gl + SET reference = ?, + description = ?, + transdate = ?, + notes = ? + WHERE id = ? + QUERY + + $form->{dbh}->do( + $query, + {}, + $form->{reference}, + $form->{description}, + $form->{transdate}, + $form->{notes}, + + $form->{id}) + or $form->dberror($query); + } + + display_form(); +} + sub display_form { $form->{separate_duties} = $form->get_setting('separate_duties'); @@ -203,6 +286,7 @@ sub display_form 'callback' => $form->{callback}, 'form_id' => $form->{form_id}, 'separate_duties' => $form->{separate_duties}, + 'reversing' => $form->{reversing} ); @@ -237,6 +321,9 @@ sub display_form class => 'post' }, { action => 'edit_and_save', value => $locale->text('Save Draft') }, + { action => 'post_reversing', + value => ($form->{separate_duties} + ? $locale->text('Save') : $locale->text('Post')), }, { action => 'save_temp', value => $locale->text('Save Template') }, { action => 'save_as_new', @@ -250,26 +337,33 @@ sub display_form ); %a = (); - $a{'save_temp'} = 1; + $a{'save_temp'} = not $form->{reversing}; if ( $form->{id}) { - for ( 'new', 'save_as_new', 'schedule', 'copy_to_new' ) { + for ( 'new', 'save_as_new', 'copy_to_new' ) { $a{$_} = 1; } + for ( 'schedule' ) { + $a{$_} = not $form->{reversing}; + } if (!$form->{approved} && !$form->{batch_id}) { # Need to check for draft_modify and draft_post if ($form->is_allowed_role(['draft_post'])) { $a{approve} = 1; } if ($form->is_allowed_role(['draft_modify'])) { - $a{edit_and_save} = 1; + $a{edit_and_save} = not $form->{reversing}; + $a{post_reversing} = $form->{reversing}; } - $a{update} = 1; + $a{update} = not $form->{reversing}; } } else { - $a{'update'} = 1; if ( not $form->is_closed( $transdate ) ) { - for ( 'post', 'schedule' ) { $a{$_} = 1 } + for ( 'post' ) { $a{$_} = not $form->{reversing} } + for ( 'post_reversing' ) { $a{$_} = $form->{reversing} } + } + for ( 'update', 'schedule' ) { + $a{$_} = not $form->{reversing}; } } @@ -287,6 +381,18 @@ sub display_form grep { $a{$_->{action}} } @buttons; } + unless ($form->{reversed_by}) { + if ($form->{approved}) { + push @buttons, { + name => 'action', + value => 'reverse', + text => $locale->text('Reverse'), + type => 'submit', + class => 'submit', + }; + } + } + $form->{recurringset}=0; if ( $form->{recurring} ) { $form->{recurringset}=1; diff --git a/old/bin/io.pl b/old/bin/io.pl index 5a49610210..1752c63228 100644 --- a/old/bin/io.pl +++ b/old/bin/io.pl @@ -142,7 +142,7 @@ sub approve { } sub display_row { - my $readonly = $form->{approved} ? 'readonly="readonly"' : ''; + my $readonly = ($form->{reversing} or $form->{approved}) ? 'readonly="readonly"' : ''; my $numrows = shift; my $min_lines = $form->get_setting('min_empty') // 0; my $lsmb_module; @@ -167,7 +167,8 @@ sub display_row { $column_data{ship} = qq||; + . qq||; + $readonly = ''; } if ( $form->{type} eq "purchase_order" ) { push @column_index, "ship"; @@ -175,6 +176,7 @@ sub display_row { qq||; + $readonly = ''; } for (qw(projectnumber partsgroup)) { @@ -419,7 +421,7 @@ sub display_row { if ($form->{"partnumber_$i"}){ $column_data{deleteline} = qq|
+ $form->{sequence_select}
{duedate} $readonly>{duedate} $readonly_headers>
| . $locale->text('Ship') - . qq|| . $locale->text('Recd') . qq||; - if (not $form->{approved}) { + if (not $form->{approved} and not $readonly) { $column_data{deleteline} .= qq|