Interchange6-Schema
view release on metacpan or search on metacpan
lib/Interchange6/Schema/Result/Product.pm view on Meta::CPAN
Defaults to true.
=cut
column combine => {
data_type => "boolean",
default_value => 1,
};
=head2 created
Date and time when this record was created returned as L<DateTime> object.
Value is auto-set on insert.
=cut
column created => {
data_type => "datetime",
set_on_create => 1
};
=head2 last_modified
Date and time when this record was last modified returned as L<DateTime> object.
Value is auto-set on insert and update.
=cut
column last_modified => {
data_type => "datetime",
set_on_create => 1,
set_on_update => 1
};
=head1 RELATIONS
=head2 canonical
Type: belongs_to
Related object: L<Interchange6::Schema::Result::Product>
=cut
belongs_to
canonical => "Interchange6::Schema::Result::Product",
{ 'foreign.sku' => 'self.canonical_sku' },
{ join_type => 'left' };
=head2 variants
Type: has_many
Related object: L<Interchange6::Schema::Result::Product>
=cut
has_many
variants => "Interchange6::Schema::Result::Product",
{ "foreign.canonical_sku" => "self.sku" },
{ cascade_copy => 0, cascade_delete => 0 };
=head2 cart_products
Type: has_many
Related object: L<Interchange6::Schema::Result::CartProduct>
=cut
has_many
cart_products => "Interchange6::Schema::Result::CartProduct",
"sku",
{ cascade_copy => 0, cascade_delete => 0 };
=head2 price_modifiers
Type: has_many
Related object: L<Interchange6::Schema::Result::PriceModifier>
=cut
has_many
price_modifiers => "Interchange6::Schema::Result::PriceModifier",
"sku";
=head2 inventory
Type: might_have
Related object: L<Interchange6::Schema::Result::Inventory>
=cut
might_have
inventory => "Interchange6::Schema::Result::Inventory",
"sku",
{ cascade_copy => 0, cascade_delete => 0 };
=head2 media_products
Type: has_many
Related object: L<Interchange6::Schema::Result::MediaProduct>
=cut
has_many
media_products => "Interchange6::Schema::Result::MediaProduct",
"sku",
{ cascade_copy => 0, cascade_delete => 0 };
=head2 merchandising_products
Type: has_many
Related object: L<Interchange6::Schema::Result::MerchandisingProduct>
=cut
has_many
merchandising_products =>
"Interchange6::Schema::Result::MerchandisingProduct",
"sku",
{ cascade_copy => 0, cascade_delete => 0 };
=head2 merchandising_product_related
Type: has_many
Related object: L<Interchange6::Schema::Result::MerchandisingProduct>
=cut
has_many
merchandising_product_related =>
"Interchange6::Schema::Result::MerchandisingProduct",
{ "foreign.sku_related" => "self.sku" },
{ cascade_copy => 0, cascade_delete => 0 };
=head2 navigation_products
Type: has_many
Related object: L<Interchange6::Schema::Result::NavigationProduct>
=cut
has_many
navigation_products => "Interchange6::Schema::Result::NavigationProduct",
"sku",
{ cascade_copy => 0, cascade_delete => 0 };
=head2 navigation
Type: many_to_many with navigation
=cut
many_to_many navigations => "navigation_products", "navigation";
=head2 orderlines
Type: has_many
Related object: L<Interchange6::Schema::Result::Orderline>
=cut
has_many
orderlines => "Interchange6::Schema::Result::Orderline",
"sku",
{ cascade_copy => 0, cascade_delete => 0 };
=head2 product_attributes
Type: has_many
Related object: L<Interchange6::Schema::Result::ProductAttribute>
=cut
has_many
product_attributes => "Interchange6::Schema::Result::ProductAttribute",
"sku",
{ cascade_copy => 0, cascade_delete => 0 };
=head2 media
Type: many_to_many with media
=cut
many_to_many media => "media_products", "media";
=head2 product_messages
Type: has_many
Related object: L<Interchange6::Schema::Result::ProductMessage>
=cut
has_many
product_messages => "Interchange6::Schema::Result::ProductMessage",
"sku", { cascade_copy => 0 };
=head2 messages
Type: many_to_many
Accessor to related Message results.
=cut
many_to_many messages => "product_messages", "message";
=head1 METHODS
Attribute methods are provided by the L<Interchange6::Schema::Base::Attribute> class.
=head2 insert
Override inherited method to call L</generate_uri> method in case L</name>
and L</sku> have been supplied as arguments but L</uri> has not.
=cut
sub insert {
my ( $self, @args ) = @_;
$self->generate_uri unless $self->uri;
$self->next::method(@args);
return $self;
}
=head2 update_price_modifiers
Called when L</price> is updated.
=cut
sub update_price_modifiers {
my ( $self, $old_value, $new_value ) = @_;
my $price_modifiers =
$self->price_modifiers->search( { discount => { '!=' => undef } } );
while ( my $result = $price_modifiers->next ) {
$result->update(
{
price => sprintf( "%.2f",
$new_value - ( $new_value * $result->discount / 100 ) )
}
);
}
}
=head2 generate_uri($attrs)
Called by L</new> if no uri is given as an argument.
The following steps are taken:
=over
1. Join C<< $self->name >> and C<< $self->uri >> with C<-> and stash
lib/Interchange6/Schema/Result/Product.pm view on Meta::CPAN
=item Return Value: not defined
=back
Similar to L<DBIx::Class::Relationship::Base/set_$rel> except that this method DOES delete objects in the table on the right side of the relation.
=cut
sub set_reviews {
my $self = shift;
@_ > 0
or $self->throw_exception(
"set_reviews needs a list of objects or hashrefs" );
my @to_set = ( ref( $_[0] ) eq 'ARRAY' ? @{ $_[0] } : @_ );
$self->product_reviews->delete_all;
$self->add_to_reviews( $_ ) for (@to_set);
}
=head2 quantity_in_stock
Returns undef if L<inventory_exempt> is true and otherwise returns the
quantity of the product in the inventory. For a product variant the
quantity returned is for the variant itself whereas for a canonical
(parent) product the quantity returned is the total for all variants.
If the query was constructed using
L<Interchange6::Schema::ResultSet::Product/with_quantity_in_stock> then
the cached value will be used rather than running a new query.
=cut
sub quantity_in_stock {
my $self = shift;
# if already loaded by resultset query then return that value
return $self->get_column('quantity_in_stock')
if $self->has_column_loaded('quantity_in_stock');
my $quantity;
my $variants = $self->variants;
if ( $variants->has_rows ) {
my $not_exempt = $variants->search( { inventory_exempt => 0 } );
if ( $not_exempt->has_rows ) {
$quantity = $not_exempt->search_related( 'inventory',
{ quantity => { '>' => 0 } } )->get_column('quantity')->sum;
}
}
elsif ( ! $self->inventory_exempt ) {
my $inventory = $self->inventory;
$quantity = defined $inventory ? $self->inventory->quantity : 0;
}
return $quantity;
}
=head2 delete
Overload delete to force removal of any product reviews. Only parent products should have reviews so in the case of child products no attempt is made to delete reviews.
=cut
# FIXME: (SysPete) There ought to be a way to force this with cascade delete.
sub delete {
my ( $self, @args ) = @_;
my $guard = $self->result_source->schema->txn_scope_guard;
$self->product_reviews->delete_all unless defined $self->canonical_sku;
$self->next::method(@args);
$guard->commit;
}
1;
( run in 0.568 second using v1.01-cache-2.11-cpan-39bf76dae61 )