Skip to content

Instantly share code, notes, and snippets.

@renatocron
Created December 10, 2019 00:48
Show Gist options
  • Save renatocron/b2303649bd4d5f6a6440c3ccfe563806 to your computer and use it in GitHub Desktop.
Save renatocron/b2303649bd4d5f6a6440c3ccfe563806 to your computer and use it in GitHub Desktop.
package TouchBase::Schema::ResultSet::Voucher;
use common::sense;
use Moose;
use namespace::autoclean;
extends 'DBIx::Class::ResultSet';
with 'TouchBase::Role::Verification';
with 'TouchBase::Role::Verification::TransactionalActions::DBIC';
with 'TouchBase::Schema::Role::ResultsetFind';
use TouchBase::Types qw/DateStr/;
use Data::Verifier;
sub verifiers_specs {
my $self = shift;
return {
create => Data::Verifier->new(
filters => [qw( trim )],
profile => {
code => {required => 1, type => 'Str'},
description => {required => 1, type => 'Str'},
percentage => {required => 0, type => 'Num'},
amount => {required => 0, type => 'Int'},
is_percentage => {required => 1, type => 'Bool'},
is_recurring => {required => 1, type => 'Bool'},
max_usage => {required => 0, type => 'Int'},
max_cycle_usage => {required => 0, type => 'Int'},
visible_from => {required => 0, type => DateStr},
visible_until => {required => 0, type => DateStr},
limited_to_plan_ids => {
required => 0,
type => 'Str',
post_check => sub {
my $r = shift;
my @plan_ids = split /,/, $r->get_value('limited_to_plan_ids');
foreach my $plan_id (@plan_ids) {
return 0 unless $plan_id =~ /^\d+$/a;
$self->resultset('Plan')->find($plan_id) or return 0;
}
return 1;
}
}
},
),
info => Data::Verifier->new(filters => [qw( trim )], profile => {code => {required => 1, type => 'Str',}}),
apply => Data::Verifier->new(
filters => [qw( trim )],
profile => {
code => {required => 1, type => 'Str',},
team_id => {required => 1, type => 'Int',},
plan_id => {required => 1, type => 'Int',},
user_id => {required => 1, type => 'Int',},
remove => {required => 0, type => 'Bool',},
}
),
};
}
sub action_specs {
my $self = shift;
return {
create => sub {
my %values = shift->valid_values;
delete @values{grep { not defined $values{$_} } keys %values};
# Tratando valores e erros dos mesmos.
# O voucher deve ser de porcentagem OU de amount
if ($values{is_percentage} == 1) {
die \['amount', 'not-allowed'] if defined $values{amount};
die \['percentage', 'missing'] unless defined $values{percentage};
}
else {
die \['percentage', 'not-allowed'] if defined $values{percentage};
die \['amount', 'missing'] unless defined $values{amount};
}
my $voucher = $self->create(\%values);
return $voucher;
},
info => sub {
my %values = shift->valid_values;
delete @values{grep { not defined $values{$_} } keys %values};
my $voucher = $self->search_by_code(code => $values{code}, attr => {});
return $voucher->build_result_public();
},
apply => sub {
my %values = shift->valid_values;
delete @values{grep { not defined $values{$_} } keys %values};
# TODO verificar se o user_id eh dono ou financeiro do time
my $user = $self->resultset('User')->find_valid($values{user_id}) or die \['user_id', 'invalid'];
my $team = $self->resultset('Team')->find_valid($values{team_id}) or die \['team_id', 'invalid'];
my $plan = $self->resultset('Plan')->find_valid($values{plan_id}) or die \['plan_id', 'invalid'];
my $voucher = $self->search_by_code(code => $values{code}, attr => {for => 'update'});
return $voucher->apply(team => $team, user => $user, plan => $plan, remove => $values{remove});
}
};
}
sub build_list {
my ($self) = @_;
return {
vouchers => [
map {
my $v = $_;
+{
id => $v->id,
limited_to_plan_ids => $v->limited_to_plan_ids,
code => $v->code,
description => $v->description,
is_recurring => $v->is_recurring,
max_usage => $v->max_usage,
current_usage => $v->current_usage,
is_percentage => $v->is_percentage,
percentage => $v->percentage,
amount => $v->amount,
visible_until => $v->visible_until,
visible_from => $v->visible_from,
created_at => $v->created_at,
enabled => $v->enabled,
}
} $self->all()
]
};
}
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
sub search_by_code {
my ($self, %opts) = @_;
my $voucher = $self->search(
{
code => $opts{code},
'-and' => [
{'visible_from' => {'<=' => \'replaceable_now()'},},
{'visible_until' => {'>=' => \'replaceable_now()'},}
]
},
$opts{attr}
)->next
or die {error => 'voucher_expired', status => 404};
die {error => 'voucher_disabled'} unless $voucher->enabled;
if ($voucher->max_usage) {
die {error => 'voucher_reached_limit'} if $voucher->current_usage >= $voucher->max_usage;
}
return $voucher;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment