MyRedland/lib/MyRedland/SubscriptionOrders.pm

147 lines
4.1 KiB
Perl

package MyRedland::SubscriptionOrders;
use v5.34.1;
use strict;
use warnings;
use Moo;
use Types::Standard qw/Str Bool InstanceOf ArrayRef Int/;
use Params::ValidationCompiler qw/validation_for/;
use DateTime::Format::Pg;
use Data::Dumper;
use List::AllUtils qw/any/;
use MyRedland::DB;
use MyRedland::Lusers;
use MyRedland::Products;
use MyRedland::SubscriptionOrder;
has app => (
is => 'ro',
isa => InstanceOf['Mojolicious'],
);
my $fpg = DateTime::Format::Pg->new;
my @FIELDS = qw/uuid product_id user_uuid payment_intent_id client_secret renew_auto paid create_date to_pay save_card/;
has dbh => ( is => 'lazy', );
sub _build_dbh {
my $self = shift;
return MyRedland::DB->connect( $self->app );
}
{
my $validator = validation_for(
params => {
product => { type => InstanceOf['MyRedland::Product'] },
user => { type => InstanceOf['MyRedland::Luser'] },
payment_intent_id => { type => Str },
client_secret => { type => Str },
renew_auto => { type => Bool },
save_card => { type => Bool },
paid => { type => Bool },
to_pay => { type => Int },
}
);
sub create {
my $self = shift;
my %params = $validator->(@_);
my $dbh = $self->dbh;
my ($product, $user, $payment_intent_id, $client_secret, $renew_auto, $paid, $to_pay, $save_card) = @params{qw/product user payment_intent_id client_secret
renew_auto paid to_pay save_card/};
my $returning_hash = $dbh->selectrow_hashref(
<<"EOF", undef, $product->id, $user->uuid, $client_secret, $renew_auto, $paid, $to_pay, $payment_intent_id, $save_card);
INSERT INTO subscription_orders
(product_id, user_uuid, client_secret, renew_auto,
paid, to_pay, payment_intent_id, save_card)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?)
RETURNING @{[join ', ', @FIELDS]};
EOF
return $self->_convert_hash_to_object($returning_hash);
}
}
sub _convert_hash_to_object {
my $self = shift;
my $hash = shift;
my $users_dao = MyRedland::Lusers->new( app => $self->app );
my $products_dao = MyRedland::Products->new;
my $product_id = delete $hash->{product_id};
my $user_uuid = delete $hash->{user_uuid};
my $create_date = delete $hash->{create_date};
$hash->{create_date} = $fpg->parse_datetime($create_date);
if (!defined $product_id) {
# This should not happen.
die 'No product.';
}
if (!defined $user_uuid) {
# This should not happen.
die 'No user';
}
$hash->{user} = $users_dao->find_by_uuid(uuid => $user_uuid);
$hash->{product} = $products_dao->find_by_id(id => $product_id);
return MyRedland::SubscriptionOrder->new(%$hash);
}
{
my $validator = validation_for(
params => {
subscription_order => { type => InstanceOf ['MyRedland::SubscriptionOrder'] },
fields => { type => ArrayRef [Str] },
}
);
sub update {
my $self = shift;
my %params = $validator->(@_);
my $subscription_order = $params{subscription_order};
my $fields = $params{fields};
my %updates;
for my $field (@$fields) {
if ( any { $field eq $_ } qw/renew_auto paid save_card/ ) {
$updates{$field} = $subscription_order->$field;
next;
}
die "No such field $field.";
}
my $query = <<"EOF";
UPDATE subscription_orders
SET @{[
join ', ', map { "$_ = ?" } @$fields
]} WHERE uuid = ?
RETURNING @{[join ', ', @FIELDS]};
EOF
my $dbh = $self->dbh;
my $hash = $dbh->selectrow_hashref($query, undef, @updates{@$fields}, $subscription_order->uuid);
return $self->_convert_hash_to_object($hash);
}
}
{
my $validator = validation_for(
params => {
uuid => { type => Str },
}
);
sub find_by_uuid {
my $self = shift;
my %params = $validator->(@_);
my $uuid = $params{uuid};
my $dbh = $self->dbh;
my $hash = $dbh->selectrow_hashref( <<"EOF", undef, $uuid );
SELECT @{[join ', ', @FIELDS]} FROM subscription_orders where uuid = ?;
EOF
if ( !defined $hash ) {
return;
}
return $self->_convert_hash_to_object($hash);
}
}
1;