Revision 5b5dbec0
Von Moritz Bunkus vor etwa 12 Jahren hinzugefügt
SL/Presenter/CustomerVendor.pm | ||
---|---|---|
package SL::Presenter::CustomerVendor;
|
||
|
||
use strict;
|
||
|
||
use parent qw(Exporter);
|
||
|
||
use Exporter qw(import);
|
||
our @EXPORT = qw(customer vendor);
|
||
|
||
use Carp;
|
||
|
||
sub customer {
|
||
my ($self, $customer, $type, %params) = @_;
|
||
return _customer_vendor($self, $customer, 'customer', %params);
|
||
}
|
||
|
||
sub vendor {
|
||
my ($self, $vendor, $type, %params) = @_;
|
||
return _customer_vendor($self, $vendor, 'vendor', %params);
|
||
}
|
||
|
||
sub _customer_vendor {
|
||
my ($self, $cv, $type, %params) = @_;
|
||
|
||
$params{display} ||= 'inline';
|
||
|
||
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
|
||
|
||
my $text = join '', (
|
||
$params{no_link} ? '' : '<a href="ct.pl?action=edit&db=' . $type . '&id=' . $self->escape($cv->id) . '">',
|
||
$self->escape($cv->name),
|
||
$params{no_link} ? '' : '</a>',
|
||
);
|
||
return $self->escaped_text($text);
|
||
}
|
||
|
||
1;
|
||
|
||
__END__
|
||
|
||
=pod
|
||
|
||
=encoding utf8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Presenter::CustomerVendor - Presenter module for customer and
|
||
vendor Rose::DB objects
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
# Customers:
|
||
my $customer = SL::DB::Manager::Customer->get_first;
|
||
my $html = SL::Presenter->get->customer($customer, display => 'inline');
|
||
|
||
# Vendors:
|
||
my $vendor = SL::DB::Manager::Vendor->get_first;
|
||
my $html = SL::Presenter->get->vendor($customer, display => 'inline');
|
||
|
||
=head1 FUNCTIONS
|
||
|
||
=over 4
|
||
|
||
=item C<customer $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the customer object C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the customer's name linked
|
||
to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the customer's name will be linked to
|
||
the "edit customer" dialog from the master data menu.
|
||
|
||
=back
|
||
|
||
=item C<vendor $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the vendor object C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the vendor's name linked
|
||
to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the vendor's name will be linked to
|
||
the "edit vendor" dialog from the master data menu.
|
||
|
||
=back
|
||
|
||
=back
|
||
|
||
=head1 BUGS
|
||
|
||
Nothing here yet.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
|
||
|
||
=cut
|
SL/Presenter/DeliveryOrder.pm | ||
---|---|---|
package SL::Presenter::DeliveryOrder;
|
||
|
||
use strict;
|
||
|
||
use parent qw(Exporter);
|
||
|
||
use Exporter qw(import);
|
||
our @EXPORT = qw(sales_delivery_order purchase_delivery_order);
|
||
|
||
use Carp;
|
||
|
||
sub sales_delivery_order {
|
||
my ($self, $delivery_order, %params) = @_;
|
||
|
||
return _do_record($self, $delivery_order, 'sales_delivery_order', %params);
|
||
}
|
||
|
||
sub purchase_delivery_order {
|
||
my ($self, $delivery_order, %params) = @_;
|
||
|
||
return _do_record($self, $delivery_order, 'purchase_delivery_order', %params);
|
||
}
|
||
|
||
sub _do_record {
|
||
my ($self, $delivery_order, $type, %params) = @_;
|
||
|
||
$params{display} ||= 'inline';
|
||
|
||
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
|
||
|
||
my $text = join '', (
|
||
$params{no_link} ? '' : '<a href="do.pl?action=edit&type=' . $type . '&id=' . $self->escape($delivery_order->id) . '">',
|
||
$self->escape($delivery_order->donumber),
|
||
$params{no_link} ? '' : '</a>',
|
||
);
|
||
return $self->escaped_text($text);
|
||
}
|
||
|
||
1;
|
||
|
||
__END__
|
||
|
||
=pod
|
||
|
||
=encoding utf8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Presenter::DeliveryOrder - Presenter module for Rose::DB objects
|
||
for sales and purchase delivery orders
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
# Sales delivery orders:
|
||
my $object = SL::DB::Manager::DeliveryOrder->get_first(where => [ is_sales => 1 ]);
|
||
my $html = SL::Presenter->get->sales_delivery_order($object, display => 'inline');
|
||
|
||
# Purchase delivery orders:
|
||
my $object = SL::DB::Manager::DeliveryOrder->get_first(where => [ or => [ is_sales => undef, is_sales => 0 ]]);
|
||
my $html = SL::Presenter->get->purchase_delivery_order($object, display => 'inline');
|
||
|
||
=head1 FUNCTIONS
|
||
|
||
=over 4
|
||
|
||
=item C<sales_delivery_order $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the sales delivery order object
|
||
C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the objects's delivery
|
||
order number linked to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the delivery order number will be linked
|
||
to the "edit delivery order" dialog from the sales menu.
|
||
|
||
=back
|
||
|
||
=item C<purchase_delivery_order $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the purchase delivery order object
|
||
C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the objects's delivery
|
||
order number linked to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the delivery order number will be linked
|
||
to the "edit delivery order" dialog from the purchase menu.
|
||
|
||
=back
|
||
|
||
=back
|
||
|
||
=head1 BUGS
|
||
|
||
Nothing here yet.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
|
||
|
||
=cut
|
SL/Presenter/Invoice.pm | ||
---|---|---|
package SL::Presenter::Invoice;
|
||
|
||
use strict;
|
||
|
||
use parent qw(Exporter);
|
||
|
||
use Exporter qw(import);
|
||
our @EXPORT = qw(sales_invoice ar_transaction purchase_invoice ap_transaction);
|
||
|
||
use Carp;
|
||
|
||
sub sales_invoice {
|
||
my ($self, $invoice, %params) = @_;
|
||
|
||
return _is_ir_record($self, $invoice, 'is', %params);
|
||
}
|
||
|
||
sub ar_transaction {
|
||
my ($self, $invoice, %params) = @_;
|
||
|
||
return _is_ir_record($self, $invoice, 'ar', %params);
|
||
}
|
||
|
||
sub purchase_invoice {
|
||
my ($self, $invoice, %params) = @_;
|
||
|
||
return _is_ir_record($self, $invoice, 'is', %params);
|
||
}
|
||
|
||
sub ap_transaction {
|
||
my ($self, $invoice, %params) = @_;
|
||
|
||
return _is_ir_record($self, $invoice, 'ap', %params);
|
||
}
|
||
|
||
sub _is_ir_record {
|
||
my ($self, $invoice, $controller, %params) = @_;
|
||
|
||
$params{display} ||= 'inline';
|
||
|
||
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
|
||
|
||
my $text = join '', (
|
||
$params{no_link} ? '' : '<a href="' . $controller . '.pl?action=edit&type=invoice&id=' . $self->escape($invoice->id) . '">',
|
||
$self->escape($invoice->invnumber),
|
||
$params{no_link} ? '' : '</a>',
|
||
);
|
||
return $self->escaped_text($text);
|
||
}
|
||
|
||
1;
|
||
|
||
__END__
|
||
|
||
=pod
|
||
|
||
=encoding utf8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Presenter::Invoice - Presenter module for sales invoice, AR
|
||
transaction, purchase invoice and AP transaction Rose::DB objects
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
# Sales invoices:
|
||
my $object = SL::DB::Manager::Invoice->get_first(where => [ invoice => 1 ]);
|
||
my $html = SL::Presenter->get->sales_invoice($object, display => 'inline');
|
||
|
||
# AR transactions:
|
||
my $object = SL::DB::Manager::Invoice->get_first(where => [ or => [ invoice => undef, invoice => 0 ]]);
|
||
my $html = SL::Presenter->get->ar_transaction($object, display => 'inline');
|
||
|
||
# Purchase invoices:
|
||
my $object = SL::DB::Manager::PurchaseInvoice->get_first(where => [ invoice => 1 ]);
|
||
my $html = SL::Presenter->get->purchase_invoice($object, display => 'inline');
|
||
|
||
# AP transactions:
|
||
my $object = SL::DB::Manager::PurchaseInvoice->get_first(where => [ or => [ invoice => undef, invoice => 0 ]]);
|
||
my $html = SL::Presenter->get->ar_transaction($object, display => 'inline');
|
||
|
||
=head1 FUNCTIONS
|
||
|
||
=over 4
|
||
|
||
=item C<sales_invoice $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the sales invoice object C<$object>
|
||
.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the invoice number linked
|
||
to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the invoice number will be linked to the
|
||
"edit invoice" dialog from the sales menu.
|
||
|
||
=back
|
||
|
||
=item C<ar_transaction $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the AR transaction object C<$object>
|
||
.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the invoice number linked
|
||
to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the invoice number will be linked to the
|
||
"edit invoice" dialog from the general ledger menu.
|
||
|
||
=back
|
||
|
||
=item C<purchase_invoice $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the purchase invoice object
|
||
C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the invoice number name
|
||
linked to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the invoice number will be linked to
|
||
the "edit invoice" dialog from the purchase menu.
|
||
|
||
=back
|
||
|
||
=item C<ap_transaction $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the AP transaction object C<$object>
|
||
.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the invoice number linked
|
||
to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the invoice number will be linked to the
|
||
"edit invoice" dialog from the general ledger menu.
|
||
|
||
=back
|
||
|
||
=back
|
||
|
||
=head1 BUGS
|
||
|
||
Nothing here yet.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
|
||
|
||
=cut
|
SL/Presenter/Order.pm | ||
---|---|---|
package SL::Presenter::Order;
|
||
|
||
use strict;
|
||
|
||
use parent qw(Exporter);
|
||
|
||
use Exporter qw(import);
|
||
our @EXPORT = qw(sales_quotation sales_order request_quotation purchase_order);
|
||
|
||
use Carp;
|
||
|
||
sub sales_quotation {
|
||
my ($self, $order, %params) = @_;
|
||
|
||
return _oe_record($self, $order, 'sales_quotation', %params);
|
||
}
|
||
|
||
sub sales_order {
|
||
my ($self, $order, %params) = @_;
|
||
|
||
return _oe_record($self, $order, 'sales_order', %params);
|
||
}
|
||
|
||
sub request_quotation {
|
||
my ($self, $order, %params) = @_;
|
||
|
||
return _oe_record($self, $order, 'request_quotation', %params);
|
||
}
|
||
|
||
sub purchase_order {
|
||
my ($self, $order, %params) = @_;
|
||
|
||
return _oe_record($self, $order, 'purchase_order', %params);
|
||
}
|
||
|
||
sub _oe_record {
|
||
my ($self, $order, $type, %params) = @_;
|
||
|
||
$params{display} ||= 'inline';
|
||
|
||
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
|
||
|
||
my $number_method = $order->quotation ? 'quonumber' : 'ordnumber';
|
||
|
||
my $text = join '', (
|
||
$params{no_link} ? '' : '<a href="oe.pl?action=edit&type=' . $type . '&id=' . $self->escape($order->id) . '">',
|
||
$self->escape($order->$number_method),
|
||
$params{no_link} ? '' : '</a>',
|
||
);
|
||
return $self->escaped_text($text);
|
||
}
|
||
|
||
1;
|
||
|
||
|
||
__END__
|
||
|
||
=pod
|
||
|
||
=encoding utf8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Presenter::Order - Presenter module for Rose::DB objects for sales
|
||
quotations, sales orders, requests for quotations and purchase orders
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
# Sales quotations:
|
||
my $object = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('sales_quotation') ]);
|
||
my $html = SL::Presenter->get->sales_quotation($object, display => 'inline');
|
||
|
||
# Sales orders:
|
||
my $object = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('sales_order') ]);
|
||
my $html = SL::Presenter->get->sales_order($object, display => 'inline');
|
||
|
||
# Requests for quotations:
|
||
my $object = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('request_quotation') ]);
|
||
my $html = SL::Presenter->get->request_quotation($object, display => 'inline');
|
||
|
||
# Purchase orders:
|
||
my $object = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('purchase_order') ]);
|
||
my $html = SL::Presenter->get->purchase_order($object, display => 'inline');
|
||
|
||
=head1 FUNCTIONS
|
||
|
||
=over 4
|
||
|
||
=item C<sales_quotation $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the sales quotation object
|
||
C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the objects's
|
||
quotation number linked to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the order number will be linked to the
|
||
"edit quotation" dialog from the sales menu.
|
||
|
||
=back
|
||
|
||
=item C<sales_order $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the sales order object C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the objects's
|
||
order number linked to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the order number will be linked
|
||
to the "edit order" dialog from the sales menu.
|
||
|
||
=back
|
||
|
||
=item C<request_quotation $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the request for quotation object
|
||
C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the objects's
|
||
quotation number linked to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the order number will be linked to the
|
||
"edit request for quotation" dialog from the purchase menu.
|
||
|
||
=back
|
||
|
||
=item C<purchase_order $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the purchase order object
|
||
C<$object>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the objects's
|
||
order number linked to the corresponding 'edit' action.
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the order number will be linked
|
||
to the "edit order" dialog from the purchase menu.
|
||
|
||
=back
|
||
|
||
=back
|
||
|
||
=head1 BUGS
|
||
|
||
Nothing here yet.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
|
||
|
||
=cut
|
SL/Presenter/Project.pm | ||
---|---|---|
package SL::Presenter::Project;
|
||
|
||
use strict;
|
||
|
||
use parent qw(Exporter);
|
||
|
||
use Exporter qw(import);
|
||
our @EXPORT = qw(project);
|
||
|
||
use Carp;
|
||
|
||
sub project {
|
||
my ($self, $project, %params) = @_;
|
||
|
||
return '' unless $project;
|
||
|
||
$params{display} ||= 'inline';
|
||
|
||
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
|
||
|
||
$params{style} ||= 'both';
|
||
my $description;
|
||
|
||
if ($params{style} =~ m/number/) {
|
||
$description = $project->projectnumber;
|
||
|
||
} elsif ($params{style} =~ m/description/) {
|
||
$description = $project->description;
|
||
|
||
} else {
|
||
$description = $project->projectnumber;
|
||
if ($project->description && do { my $desc = quotemeta $project->description; $project->projectnumber !~ m/$desc/ }) {
|
||
$description .= ' (' . $project->description . ')';
|
||
}
|
||
}
|
||
|
||
my $text = join '', (
|
||
$params{no_link} ? '' : '<a href="controller.pl?action=Project/edit&id=' . $self->escape($project->id) . '">',
|
||
$self->escape($description),
|
||
$params{no_link} ? '' : '</a>',
|
||
);
|
||
return $self->escaped_text($text);
|
||
}
|
||
|
||
1;
|
||
|
||
__END__
|
||
|
||
=pod
|
||
|
||
=encoding utf8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Presenter::Project - Presenter module for project Rose::DB objects
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
my $project = SL::DB::Manager::Project->get_first;
|
||
my $html = SL::Presenter->get->project($project, display => 'inline');
|
||
|
||
=head1 FUNCTIONS
|
||
|
||
=over 4
|
||
|
||
=item C<project $object, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of the project object C<$customer>.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
=item * display
|
||
|
||
Either C<inline> (the default) or C<table-cell>. At the moment both
|
||
representations are identical and produce the project's description
|
||
(controlled by the C<style> parameter) linked to the corresponding
|
||
'edit' action.
|
||
|
||
=item * style
|
||
|
||
Determines what exactly will be output. Can be one of the values with
|
||
C<both> being the default if it is missing:
|
||
|
||
=over 2
|
||
|
||
=item C<projectnumber> (or simply C<number>)
|
||
|
||
Outputs only the project's number.
|
||
|
||
=item C<projectdescription> (or simply C<description>)
|
||
|
||
Outputs only the project's description.
|
||
|
||
=item C<both>
|
||
|
||
Outputs the project's number followed by its description in
|
||
parenthesis (e.g. "12345 (Secret Combinations)"). If the project's
|
||
description is already part of the project's number then it will not
|
||
be appended.
|
||
|
||
=back
|
||
|
||
=item * no_link
|
||
|
||
If falsish (the default) then the project's description will be linked to
|
||
the "edit project" dialog from the master data menu.
|
||
|
||
=back
|
||
|
||
=back
|
||
|
||
=head1 BUGS
|
||
|
||
Nothing here yet.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
|
||
|
||
=cut
|
SL/Presenter/Record.pm | ||
---|---|---|
package SL::Presenter::Record;
|
||
|
||
use strict;
|
||
|
||
use parent qw(Exporter);
|
||
|
||
use Exporter qw(import);
|
||
our @EXPORT = qw(grouped_record_list empty_record_list record_list);
|
||
|
||
use Carp;
|
||
use List::Util qw(first);
|
||
|
||
sub grouped_record_list {
|
||
my ($self, $list, %params) = @_;
|
||
|
||
my %groups = _group_records($list);
|
||
my $output = '';
|
||
|
||
$output .= _sales_quotation_list( $self, $groups{sales_quotations}) if $groups{sales_quotations};
|
||
$output .= _sales_order_list( $self, $groups{sales_orders}) if $groups{sales_orders};
|
||
$output .= _sales_delivery_order_list( $self, $groups{sales_delivery_orders}) if $groups{sales_delivery_orders};
|
||
$output .= _sales_invoice_list( $self, $groups{sales_invoices}) if $groups{sales_invoices};
|
||
$output .= _ar_transaction_list( $self, $groups{ar_transactions}) if $groups{ar_transactions};
|
||
|
||
$output .= _request_quotation_list( $self, $groups{purchase_quotations}) if $groups{purchase_quotations};
|
||
$output .= _purchase_order_list( $self, $groups{purchase_orders}) if $groups{purchase_orders};
|
||
$output .= _purchase_delivery_order_list($self, $groups{purchase_delivery_orders}) if $groups{purchase_delivery_orders};
|
||
$output .= _purchase_invoice_list( $self, $groups{purchase_invoices}) if $groups{purchase_invoices};
|
||
$output .= _ar_transaction_list( $self, $groups{ar_transactions}) if $groups{ar_transactions};
|
||
|
||
return $output || $self->empty_record_list;
|
||
}
|
||
|
||
sub empty_record_list {
|
||
my ($self) = @_;
|
||
return $self->render('presenter/record/empty_record_list');
|
||
}
|
||
|
||
sub record_list {
|
||
my ($self, $list, %params) = @_;
|
||
|
||
my @columns;
|
||
|
||
if (ref($params{columns}) eq 'ARRAY') {
|
||
@columns = map {
|
||
if (ref($_) eq 'ARRAY') {
|
||
{ title => $_->[0], data => $_->[1], link => $_->[2] }
|
||
} else {
|
||
$_;
|
||
}
|
||
} @{ delete $params{columns} };
|
||
|
||
} else {
|
||
croak "Wrong type for 'columns' argument: not an array reference";
|
||
}
|
||
|
||
my %column_meta = map { $_->name => $_ } @{ $list->[0]->meta->columns };
|
||
my %relationships = map { $_->name => $_ } @{ $list->[0]->meta->relationships };
|
||
|
||
my $call = sub {
|
||
my ($obj, $method, @args) = @_;
|
||
$obj->$method(@args);
|
||
};
|
||
|
||
my @data;
|
||
foreach my $obj (@{ $list }) {
|
||
my @row;
|
||
|
||
foreach my $spec (@columns) {
|
||
my %cell;
|
||
|
||
my $method = $spec->{column} || $spec->{data};
|
||
my $meta = $column_meta{ $spec->{data} };
|
||
my $type = lc ref $meta;
|
||
$type =~ s/.*:://;
|
||
my $relationship = $relationships{ $spec->{data} };
|
||
my $rel_type = !$relationship ? '' : lc $relationship->class;
|
||
$rel_type =~ s/.*:://;
|
||
|
||
if (ref($spec->{data}) eq 'CODE') {
|
||
$cell{value} = $spec->{data}->($obj);
|
||
|
||
} else {
|
||
$cell{value} = $rel_type eq 'customer' ? $self->customer($obj->$method, display => 'table-cell')
|
||
: $rel_type eq 'vendor' ? $self->vendor( $obj->$method, display => 'table-cell')
|
||
: $rel_type eq 'project' ? $self->project( $obj->$method, display => 'table-cell')
|
||
: $type eq 'date' ? $call->($obj, $method . '_as_date')
|
||
: $type =~ m/float|numeric|real/ ? $::form->format_amount(\%::myconfig, $call->($obj, $method), 2)
|
||
: $type eq 'boolean' ? $call->($obj, $method . '_as_bool_yn')
|
||
: $type =~ m/int|serial/ ? $spec->{data} * 1
|
||
: $call->($obj, $method);
|
||
}
|
||
|
||
$cell{alignment} = 'right' if $type =~ m/int|serial|float|real|numeric/;
|
||
|
||
push @row, \%cell;
|
||
}
|
||
|
||
push @data, \@row;
|
||
}
|
||
|
||
my @header =
|
||
map +{ value => $columns[$_]->{title},
|
||
alignment => $data[0]->[$_]->{alignment},
|
||
}, (0..scalar(@columns) - 1);
|
||
|
||
return $self->render(
|
||
'presenter/record/record_list',
|
||
%params,
|
||
TABLE_HEADER => \@header,
|
||
TABLE_ROWS => \@data,
|
||
);
|
||
}
|
||
|
||
#
|
||
# private methods
|
||
#
|
||
|
||
sub _group_records {
|
||
my ($list) = @_;
|
||
|
||
my %matchers = (
|
||
sales_quotations => sub { (ref($_[0]) eq 'SL::DB::Order') && $_[0]->is_type('sales_quotation') },
|
||
sales_orders => sub { (ref($_[0]) eq 'SL::DB::Order') && $_[0]->is_type('sales_order') },
|
||
sales_delivery_orders => sub { (ref($_[0]) eq 'SL::DB::DeliveryOrder') && $_[0]->is_sales },
|
||
sales_invoices => sub { (ref($_[0]) eq 'SL::DB::Invoice') && $_[0]->invoice },
|
||
ar_transactions => sub { (ref($_[0]) eq 'SL::DB::Invoice') && !$_[0]->invoice },
|
||
purchase_quotations => sub { (ref($_[0]) eq 'SL::DB::Order') && $_[0]->is_type('request_quotation') },
|
||
purchase_orders => sub { (ref($_[0]) eq 'SL::DB::Order') && $_[0]->is_type('purchase_order') },
|
||
purchase_delivery_orders => sub { (ref($_[0]) eq 'SL::DB::DeliveryOrder') && !$_[0]->is_sales },
|
||
purchase_invoices => sub { (ref($_[0]) eq 'SL::DB::PurchaseInvoice') && $_[0]->invoice },
|
||
ap_transactions => sub { (ref($_[0]) eq 'SL::DB::PurchaseInvoice') && !$_[0]->invoice },
|
||
);
|
||
|
||
my %groups;
|
||
|
||
foreach my $record (@{ $list || [] }) {
|
||
my $type = (first { $matchers{$_}->($record) } keys %matchers) || 'other';
|
||
$groups{$type} ||= [];
|
||
push @{ $groups{$type} }, $record;
|
||
}
|
||
|
||
return %groups;
|
||
}
|
||
|
||
sub _sales_quotation_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('Sales Quotations'),
|
||
columns => [
|
||
[ $::locale->text('Quotation Date'), 'transdate' ],
|
||
[ $::locale->text('Quotation Number'), sub { $self->sales_quotation($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Customer'), 'customer' ],
|
||
[ $::locale->text('Net amount'), 'netamount' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
[ $::locale->text('Project'), 'globalproject', ],
|
||
[ $::locale->text('Closed'), 'closed' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _request_quotation_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('Request Quotations'),
|
||
columns => [
|
||
[ $::locale->text('Quotation Date'), 'transdate' ],
|
||
[ $::locale->text('Quotation Number'), sub { $self->sales_quotation($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Vendor'), 'vendor' ],
|
||
[ $::locale->text('Net amount'), 'netamount' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
[ $::locale->text('Project'), 'globalproject', ],
|
||
[ $::locale->text('Closed'), 'closed' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _sales_order_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('Sales Orders'),
|
||
columns => [
|
||
[ $::locale->text('Order Date'), 'transdate' ],
|
||
[ $::locale->text('Order Number'), sub { $self->sales_order($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Quotation'), 'quonumber' ],
|
||
[ $::locale->text('Customer'), 'customer' ],
|
||
[ $::locale->text('Net amount'), 'netamount' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
[ $::locale->text('Project'), 'globalproject', ],
|
||
[ $::locale->text('Closed'), 'closed' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _purchase_order_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('Purchase Orders'),
|
||
columns => [
|
||
[ $::locale->text('Order Date'), 'transdate' ],
|
||
[ $::locale->text('Order Number'), sub { $self->sales_order($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Request for Quotation'), 'quonumber' ],
|
||
[ $::locale->text('Vendor'), 'vendor' ],
|
||
[ $::locale->text('Net amount'), 'netamount' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
[ $::locale->text('Project'), 'globalproject', ],
|
||
[ $::locale->text('Closed'), 'closed' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _sales_delivery_order_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('Sales Delivery Orders'),
|
||
columns => [
|
||
[ $::locale->text('Delivery Order Date'), 'transdate' ],
|
||
[ $::locale->text('Delivery Order Number'), sub { $self->sales_delivery_order($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Order Number'), 'ordnumber' ],
|
||
[ $::locale->text('Customer'), 'customer' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
[ $::locale->text('Project'), 'globalproject', ],
|
||
[ $::locale->text('Delivered'), 'delivered' ],
|
||
[ $::locale->text('Closed'), 'closed' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _purchase_delivery_order_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('Purchase Delivery Orders'),
|
||
columns => [
|
||
[ $::locale->text('Delivery Order Date'), 'transdate' ],
|
||
[ $::locale->text('Delivery Order Number'), sub { $self->sales_delivery_order($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Order Number'), 'ordnumber' ],
|
||
[ $::locale->text('Vendor'), 'vendor' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
[ $::locale->text('Project'), 'globalproject', ],
|
||
[ $::locale->text('Delivered'), 'delivered' ],
|
||
[ $::locale->text('Closed'), 'closed' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _sales_invoice_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('Sales Invoices'),
|
||
columns => [
|
||
[ $::locale->text('Invoice Date'), 'transdate' ],
|
||
[ $::locale->text('Invoice Number'), sub { $self->sales_invoice($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Quotation Number'), 'quonumber' ],
|
||
[ $::locale->text('Order Number'), 'ordnumber' ],
|
||
[ $::locale->text('Customer'), 'customer' ],
|
||
[ $::locale->text('Net amount'), 'netamount' ],
|
||
[ $::locale->text('Paid'), 'paid' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _purchase_invoice_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('Purchase Invoices'),
|
||
columns => [
|
||
[ $::locale->text('Invoice Date'), 'transdate' ],
|
||
[ $::locale->text('Invoice Number'), sub { $self->sales_invoice($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Request for Quotation Number'), 'quonumber' ],
|
||
[ $::locale->text('Order Number'), 'ordnumber' ],
|
||
[ $::locale->text('Vendor'), 'vendor' ],
|
||
[ $::locale->text('Net amount'), 'netamount' ],
|
||
[ $::locale->text('Paid'), 'paid' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _ar_transaction_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('AR Transactions'),
|
||
columns => [
|
||
[ $::locale->text('Invoice Date'), 'transdate' ],
|
||
[ $::locale->text('Invoice Number'), sub { $self->ar_transaction($_[0], display => 'table-cell') } ],
|
||
[ $::locale->text('Customer'), 'customer' ],
|
||
[ $::locale->text('Net amount'), 'netamount' ],
|
||
[ $::locale->text('Paid'), 'paid' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
sub _ap_transaction_list {
|
||
my ($self, $list) = @_;
|
||
|
||
return $self->record_list(
|
||
$list,
|
||
title => $::locale->text('AP Transactions'),
|
||
columns => [
|
||
[ $::locale->text('Invoice Date'), 'transdate' ],
|
||
[ $::locale->text('Invoice Number'), sub { $self->ar_transaction($_[0 ], display => 'table-cell') } ],
|
||
[ $::locale->text('Vendor'), 'vendor' ],
|
||
[ $::locale->text('Net amount'), 'netamount' ],
|
||
[ $::locale->text('Paid'), 'paid' ],
|
||
[ $::locale->text('Transaction description'), 'transaction_description' ],
|
||
],
|
||
);
|
||
}
|
||
|
||
1;
|
||
|
||
__END__
|
||
|
||
=pod
|
||
|
||
=encoding utf8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Presenter::Record - Presenter module for lists of
|
||
sales/purchase/general ledger record Rose::DB objects
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
# Retrieve a number of documents from somewhere, e.g.
|
||
my $order = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('sales_order') ]);
|
||
my $records = $order->linked_records(destination => 'to');
|
||
|
||
# Give HTML representation:
|
||
my $html = SL::Presenter->get->grouped_record_list($records);
|
||
|
||
=head1 OVERVIEW
|
||
|
||
TODO
|
||
|
||
=head1 FUNCTIONS
|
||
|
||
=over 4
|
||
|
||
=item C<empty_record_list>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of an empty list of records. Is usually
|
||
only called by L<grouped_record_list> if its list is empty.
|
||
|
||
=item C<grouped_record_list $list, %params>
|
||
|
||
Given a number of Rose::DB objects in the array reference C<$list>
|
||
this function first groups them by type. Then it calls L<record_list>
|
||
with each non-empty type-specific sub-list and the appropriate
|
||
parameters for outputting a list of those records.
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of all the lists.
|
||
|
||
The order in which the records are grouped is:
|
||
|
||
=over 2
|
||
|
||
=item * sales quotations
|
||
|
||
=item * sales orders
|
||
|
||
=item * sales delivery orders
|
||
|
||
=item * sales invoices
|
||
|
||
=item * AR transactions
|
||
|
||
=item * requests for quotations
|
||
|
||
=item * purchase orders
|
||
|
||
=item * purchase delivery orders
|
||
|
||
=item * purchase invoices
|
||
|
||
=item * AP transactions
|
||
|
||
=back
|
||
|
||
Objects of unknown types are skipped.
|
||
|
||
=item C<record_list $list, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of a list of records. This list
|
||
consists of a heading and a tabular representation of the list.
|
||
|
||
The parameters include:
|
||
|
||
=over 2
|
||
|
||
=item C<title>
|
||
|
||
Mandatory. The title to use in the heading. Must already be
|
||
translated.
|
||
|
||
=item C<columns>
|
||
|
||
Mandatory. An array reference of column specs to output. Each column
|
||
spec can be either an array reference or a hash reference.
|
||
|
||
If a column spec is an array reference then the first element is the
|
||
column's name shown in the table header. It must already be translated.
|
||
|
||
The second element can be either a string or a code reference. A
|
||
string is taken as the name of a function to call on the Rose::DB
|
||
object for the current row. Its return value is formatted depending on
|
||
the column's type (e.g. dates are output as the user expects them,
|
||
floating point numbers are rounded to two decimal places and
|
||
right-aligned etc). If it is a code reference then that code is called
|
||
with the object as the first argument. Its return value should be an
|
||
instance of L<SL::Presenter::EscapedText> and contain the rendered
|
||
representation of the content to output.
|
||
|
||
The third element, if present, can be a link to which the column will
|
||
be linked.
|
||
|
||
If the column spec is a hash reference then the same arguments are
|
||
expected. The corresponding hash keys are C<title>, C<data> and
|
||
C<link>.
|
||
|
||
=back
|
||
|
||
=back
|
||
|
||
=head1 BUGS
|
||
|
||
Nothing here yet.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
|
||
|
||
=cut
|
locale/de/all | ||
---|---|---|
'Line Total' => 'Zeilensumme',
|
||
'Line and column' => 'Zeile und Spalte',
|
||
'Line endings' => 'Zeilenumbrüche',
|
||
'Linked Records' => 'Verknüpfte Belege',
|
||
'List Accounts' => 'Konten anzeigen',
|
||
'List Languages' => 'Sprachen anzeigen',
|
||
'List Price' => 'Listenpreis',
|
||
... | ... | |
'Projects' => 'Projekte',
|
||
'Projecttransactions' => 'Projektbuchungen',
|
||
'Prozentual/Absolut' => 'Prozentual/Absolut',
|
||
'Purchase Delivery Orders' => 'Einkaufslieferscheine',
|
||
'Purchase Delivery Orders deleteable' => 'Einkaufslieferscheine löschbar',
|
||
'Purchase Invoice' => 'Einkaufsrechnung',
|
||
'Purchase Invoices' => 'Einkaufsrechnungen',
|
||
'Purchase Order' => 'Lieferantenauftrag',
|
||
'Purchase Orders' => 'Lieferantenaufträge',
|
||
'Purchase Orders deleteable' => 'Lieferantenaufträge löschbar',
|
||
... | ... | |
'Reports' => 'Berichte',
|
||
'Representative' => 'Vertreter',
|
||
'Reqdate' => 'Liefertermin',
|
||
'Request Quotations' => 'Preisanfragen',
|
||
'Request for Quotation' => 'Anfrage',
|
||
'Request for Quotation Number' => 'Anfragenummer',
|
||
'Request for Quotations' => 'Anfragen',
|
||
'Request quotation' => 'Preisanfrage',
|
||
'Requested execution date' => 'Gewünschtes Ausführungsdatum',
|
||
... | ... | |
'Saldo neu' => 'Saldo neu',
|
||
'Saldo per' => 'Saldo per',
|
||
'Sale Prices' => 'Verkaufspreise',
|
||
'Sales Delivery Orders' => 'Verkaufslieferscheine',
|
||
'Sales Delivery Orders deleteable' => 'Verkaufslieferscheine löschbar',
|
||
'Sales Invoice' => 'Rechnung',
|
||
'Sales Invoices' => 'Kundenrechnung',
|
||
'Sales Invoices' => 'Kundenrechnungen',
|
||
'Sales Order' => 'Kundenauftrag',
|
||
'Sales Orders' => 'Aufträge',
|
||
'Sales Orders deleteable' => 'Kundenaufträge löschbar',
|
||
'Sales Price information' => 'Verkaufspreisinformation',
|
||
'Sales Quotations' => 'Angebote',
|
||
'Sales Report' => 'Verkaufsbericht',
|
||
'Sales and purchase invoices with inventory transactions with taxkeys' => 'Einkaufs- und Verkaufsrechnungen mit Warenbestandsbuchungen mit Steuerschlüsseln',
|
||
'Sales delivery order' => 'Lieferschein (Verkauf)',
|
templates/webpages/presenter/record/empty_record_list.html | ||
---|---|---|
[% USE LxERP %]
|
||
<p class="message_hint">[% LxERP.t8('No data was found.') %]</p>
|
templates/webpages/presenter/record/record_list.html | ||
---|---|---|
[% USE L %][% USE LxERP %]
|
||
<div class="listtop">[%- P.escape(title) %]</div>
|
||
|
||
<div style="padding-bottom: 15px">
|
||
<table style="width: 100%">
|
||
<thead>
|
||
<tr>
|
||
[%- FOREACH column = TABLE_HEADER %]
|
||
<th class="listheading"[% IF column.alignment %] align="[% column.alignment %]"[% END %]>[%- P.escape(column.value) %]</th>
|
||
[%- END %]
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
[%- FOREACH row = TABLE_ROWS %]
|
||
<tr class="listrow[% loop.count % 2 %]">
|
||
[%- FOREACH column = row %]
|
||
<td[% IF column.alignment %] align="[% column.alignment %]"[% END %]>
|
||
[%- IF column.link %]<a href="[% column.link %]">[%- END %]
|
||
[%- P.escape(column.value) %]
|
||
[%- IF column.link %]</a>[%- END %]
|
||
</td>
|
||
[%- END %]
|
||
</tr>
|
||
[%- END %]
|
||
</tbody>
|
||
</table>
|
||
</div>
|
Auch abrufbar als: Unified diff
Presenter-Module für Listen von Verkaufs-/Einkaufsobjekte