Projekt

Allgemein

Profil

Herunterladen (17,9 KB) Statistiken
| Zweig: | Markierung: | Revision:
package SL::DB::Reclamation;

use utf8;
use strict;

use Carp;
use DateTime;
use List::Util qw(max sum0);
use List::MoreUtils qw(any);

use SL::DB::MetaSetup::Reclamation;
use SL::DB::Manager::Reclamation;
use SL::DB::Helper::Attr;
use SL::DB::Helper::AttrHTML;
use SL::DB::Helper::AttrSorted;
use SL::DB::Helper::FlattenToForm;
use SL::DB::Helper::LinkedRecords;
use SL::DB::Helper::PriceTaxCalculator;
use SL::DB::Helper::PriceUpdater;
use SL::DB::Helper::TransNumberGenerator;
use SL::Locale::String qw(t8);
use SL::RecordLinks;
use Rose::DB::Object::Helpers qw(as_tree);

__PACKAGE__->meta->add_relationship(

reclamation_items => {
type => 'one to many',
class => 'SL::DB::ReclamationItem',
column_map => { id => 'reclamation_id' },
manager_args => {
with_objects => [ 'part', 'reason' ]
}
},
custom_shipto => {
type => 'one to one',
class => 'SL::DB::Shipto',
column_map => { id => 'trans_id' },
query_args => [ module => 'Reclamation' ],
},
exchangerate_obj => {
type => 'one to one',
class => 'SL::DB::Exchangerate',
column_map => { currency_id => 'currency_id', transdate => 'transdate' },
},
);

SL::DB::Helper::Attr::make(__PACKAGE__, daily_exchangerate => 'numeric');

__PACKAGE__->meta->initialize;

__PACKAGE__->attr_html('notes');
__PACKAGE__->attr_sorted('items');

__PACKAGE__->before_save('_before_save_set_record_number');
__PACKAGE__->before_save('_before_save_remove_empty_custom_shipto');
__PACKAGE__->before_save('_before_save_set_custom_shipto_module');

# hooks

sub _before_save_set_record_number {
my ($self) = @_;

$self->create_trans_number if !$self->record_number;

return 1;
}

sub _before_save_remove_empty_custom_shipto {
my ($self) = @_;

$self->custom_shipto(undef) if $self->custom_shipto && $self->custom_shipto->is_empty;

return 1;
}

sub _before_save_set_custom_shipto_module {
my ($self) = @_;

$self->custom_shipto->module('Reclamation') if $self->custom_shipto;

return 1;
}

# methods

sub items { goto &reclamation_items; }
sub add_items { goto &add_reclamation_items; }
sub record_items { goto &reclamation_items; }

sub type {
my ($self) = @_;

return 'sales_reclamation' if $self->customer_id;
return 'purchase_reclamation' if $self->vendor_id;

return;
}

sub is_type {
my ($self, $type) = @_;
return $self->type eq $type;
}

sub effective_tax_point {
my ($self) = @_;

return $self->tax_point || $self->reqdate || $self->transdate;
}

sub displayable_type {
my $type = shift->type;

return $::locale->text('Sales Reclamation') if $type eq 'sales_reclamation';
return $::locale->text('Purchase Reclamation') if $type eq 'purchase_reclamation';

die 'invalid type';
}

sub displayable_name {
join ' ', grep $_, map $_[0]->$_, qw(displayable_type record_number);
};

sub is_sales {
croak 'not an accessor' if @_ > 1;
return !!shift->customer_id;
}

sub daily_exchangerate {
my ($self, $val) = @_;

return 1 if $self->currency_id == $::instance_conf->get_currency_id;

my $rate = (any { $self->is_type($_) } qw(sales_reclamation)) ? 'buy'
: (any { $self->is_type($_) } qw(purchase_reclamation)) ? 'sell'
: undef;
return if !$rate;

if (defined $val) {
croak t8('exchange rate has to be positive') if $val <= 0;
if (!$self->exchangerate_obj) {
$self->exchangerate_obj(SL::DB::Exchangerate->new(
currency_id => $self->currency_id,
transdate => $self->transdate,
$rate => $val,
));
} elsif (!defined $self->exchangerate_obj->$rate) {
$self->exchangerate_obj->$rate($val);
} else {
croak t8('exchange rate already exists, no update allowed');
}
}
return $self->exchangerate_obj->$rate if $self->exchangerate_obj;
}

sub taxes {
my ($self) = @_;
# add taxes to recalmation
my %pat = $self->calculate_prices_and_taxes();
my @taxes;
foreach my $tax_id (keys %{ $pat{taxes_by_tax_id} }) {
my $netamount = sum0 map { $pat{amounts}->{$_}->{amount} } grep { $pat{amounts}->{$_}->{tax_id} == $tax_id } keys %{ $pat{amounts} };
push(@taxes, { amount => $pat{taxes_by_tax_id}->{$tax_id},
netamount => $netamount,
tax => SL::DB::Tax->new(id => $tax_id)->load });
}
return \@taxes;
}

sub displayable_state {
my ($self) = @_;

return $self->closed ? $::locale->text('closed') : $::locale->text('open');
}

sub valid_reclamation_reasons {
my ($self) = @_;

my $valid_for_type = ($self->type =~ m{sales} ? 'valid_for_sales' : 'valid_for_purchase');
return SL::DB::Manager::ReclamationReason->get_all_sorted(
where => [ $valid_for_type => 1 ]);
}

sub convert_to_order {
my ($self, %params) = @_;

my $order;
$params{destination_type} = $self->is_sales ? 'sales_order'
: 'purchase_order';
if (!$self->db->with_transaction(sub {
require SL::DB::Order;
$order = SL::DB::Order->new_from($self, %params);
$order->save;
$self->link_to_record($order);
foreach my $item (@{ $order->items }) {
foreach (qw(reclamation_item)) {
if ($item->{"converted_from_${_}_id"}) {
die unless $item->{id};
RecordLinks->create_links('dbh' => $self->db->dbh,
'mode' => 'ids',
'from_table' => 'reclamation_items',
'from_ids' => $item->{"converted_from_${_}_id"},
'to_table' => 'orderitems',
'to_id' => $item->{id},
) || die;
delete $item->{"converted_from_${_}_id"};
}
}
}

1;
})) {
return undef;
}

return $order;
}

sub convert_to_delivery_order {
my ($self, %params) = @_;

my $delivery_order;
if (!$self->db->with_transaction(sub {
require SL::DB::DeliveryOrder;
$delivery_order = SL::DB::DeliveryOrder->new_from($self, %params);
$delivery_order->save;
$self->link_to_record($delivery_order);