Revision 429
- Date:
- 2014/03/14 20:03:40
- Files:
Legend:
- Added
- Removed
- Modified
-
utf8/plugins/webshop/lib/webshop/Discount.pm
32 32 rem => 'Список разделов, на содержимое которых распространяется скидка по купону', 33 33 }, 34 34 { 'attr' => 'min_sum', 'type' => 'string', 'rusname' => 'Порог суммы, с которого действует скидка', 35 default => 0, column => 2, shortname => 'Сумма заказа' }, 35 default => 0, column => 6, shortname => 'Сумма заказа' }, 36 { 'attr' => 'field', 'type' => 'string', 'rusname' => 'Название ценовой колонки', shortname => 'Колонка', 37 column => 7, 38 rem => 'Используется название, отмеченное серым цветом в "name=priceNN"' }, 36 39 { 'attr' => 'discount', 'type' => 'string', 'rusname' => 'Размер скидки (число или процент)', shortname => 'Скидка', 37 default => 0, column => 3 }, 40 default => 0, column => 8, 41 rem => 'Данное поле будет задействовано, если не указана ценовая колонка', }, 38 42 ) 39 43 } 40 44 … … 78 82 my $self = shift; 79 83 80 84 my (%opts) = @_; 81 my $basket = delete $opts{basket}; 82 return 0 unless exists $opts{uid} && $opts{uid} || exists $opts{session} && $opts{session}; 85 return 0 unless exists $opts{basket} || exists $opts{uid} && $opts{uid} || exists $opts{session} && $opts{session}; 83 86 return 0 unless $self->discount; 84 87 85 $basket ||= $keeper->{webshop}->get_basket ( %opts ); 88 my $basket = delete $opts{basket}; 89 $basket = $keeper->{webshop}->get_basket ( %opts ) unless $basket; 86 90 return 0 unless ref $basket eq 'ARRAY' && @$basket; 87 91 92 my @basket = grep { exists $_->{item} && $_->{item} } @$basket; 93 return 0 unless @basket; 94 88 95 my ($number, $sum_total) = (0, 0); 89 map { $number += $_->number; $sum_total += $_->number * $_->price } @$basket; 96 map { $number += $_->number; $sum_total += $_->number * $_->{item}->price } @basket; 90 97 warn "BASKET: $number Items of $sum_total Value\n"; 91 98 99 my %item_props = map { $_->{attr} => $_ } $basket[0]->{item}->structure; 100 if ( exists $item_props{special_price} ) { 101 @basket = grep { !$_->{item}->special_price } @basket; 102 return 0 unless @basket; 103 } 104 92 105 my $discount_counted = 0; 93 106 my $items; 94 107 if ( $self->groups ) { 95 108 $items = $self->keeper->get_documents ( 96 109 s => [$self->groups], 97 110 class => $state->{webshop}->{item_document_class}, 98 light => 1, 111 ids => 1, 99 112 return_mode => 'array_ref', 100 113 ); 114 return 0 unless ref $items eq 'ARRAY' && @$items; 101 115 } else { 102 116 $items = $self->keeper->get_documents ( 103 117 class => $state->{webshop}->{item_document_class}, 104 118 lclass => 'webshop::DiscountItemLink', 105 119 lsource => $self->id, 106 light => 1, 120 ids => 1, 107 121 return_mode => 'array_ref', 108 122 ); 109 123 } 110 124 111 125 if ( ref $items eq 'ARRAY' && @$items ) { 112 my $found_sum = 0; 113 foreach my $bi ( @$basket ) { 114 warn "BASKET: Item id [".$bi->item_id."]\n" if $DEBUG; 115 next if $bi->special_price; 116 foreach my $item ( @$items) { 117 if ( $bi->item_id == $item->id ) { 118 warn "BASKET: Item [".$item->name."] id [".$item->id."]\n" if $DEBUG; 119 $found_sum += $bi->number * $bi->price; 120 last; 121 } 122 } 126 my %items = map { $_ => 1 } @$items; 127 @basket = grep { exists $items{$_->item_id} } @basket; 128 return 0 unless @basket; 129 } 130 if ( $self->field ) { 131 foreach my $bi ( @basket ) { 132 next if exists $bi->{item}{special_price} && $bi->{item}->special_price; 133 $discount_counted += $self->count_item_discount( $bi->{item} ) * $bi->number; 123 134 } 124 warn "Sum found: [$found_sum]\n" if $DEBUG; 125 return $self->can_discount( $found_sum ); 126 } elsif ( $self->groups ) { 127 return 0; 128 135 } else { 129 136 my $found_sum = 0; 130 137 foreach my $bi ( @$basket ) { 131 warn "BASKET: Item id [".$bi->item_id."]\n" if $DEBUG; 132 next if $bi->special_price; 133 $found_sum += $bi->number * $bi->price; 138 $found_sum += $bi->number * $bi->{item}->price; 134 139 } 135 140 warn "Sum found: [$found_sum]\n" if $DEBUG; 136 return $self->can_discount( $found_sum ); 141 $discount_counted = $self->count_sum_discount( $found_sum ); 137 142 } 138 return 0; 143 return $discount_counted; 139 144 } 140 145 141 146 142 sub can_discount 147 sub count_item_discount { 148 my $self = shift; 149 my $item = shift; 150 return 0 unless $item; 151 return 0 if exists $item->{special_price} && $item->special_price; 152 153 my $count = 0; 154 my $item_field = $self->field; 155 $item_field =~ s/\s//sg; 156 if ( $item_field && $item->$item_field && $item->price > $item->$item_field ) { 157 $count = $item->price - $item->$item_field; 158 } elsif ( $self->discount ) { 159 my $value = $self->discount; 160 $value =~ s/\s//sg; 161 if ( $value =~ /([\d\.]+)%/ ) { 162 my $proc = $1; 163 $count = $item->price / 100 * $proc; 164 } 165 } 166 return $count; 167 } 168 169 sub count_sum_discount 143 170 { 144 171 my $self = shift; 145 172 my $sum = shift; 146 173 return 0 unless $sum; 147 174 148 175 my $discount = $self->discount; 149 my $min_sum = $self->min_sum || 0; 150 176 my $count = 0; 151 177 if ( $discount =~ /([\d\.]+)%/ ) { 152 178 my $proc = $1; … … 155 181 } else { 156 182 $count = $discount; 157 183 } 158 my $rest = $sum - $count; 159 $count = 0 if $rest < $min_sum || $rest == 0; 184 $count = 0 if $sum <= $count; 160 185 return $count; 161 186 } 162 187 -
utf8/plugins/webshop/lib/webshop/Keeper.pm
153 153 154 154 return unless $opts{uid} || $opts{session} || $opts{order_id}; 155 155 156 my $with_products = delete $opts{with_products} || 0; 156 157 my $uid = delete $opts{uid}; 157 158 my $session_id = delete $opts{session}; 158 159 unless ( exists $opts{order_id} && $opts{order_id} ) { … … 164 165 } 165 166 } 166 167 $opts{status} = 1 unless exists $opts{status} && defined $opts{status}; 167 my @items = $keeper->get_documents ( 168 my @basket = $keeper->get_documents ( 168 169 class => 'webshop::Basket', 169 170 %opts, 170 171 ); 171 172 my $total = 0; 172 173 my $sum = 0; 173 foreach my $item ( @items ) { 174 if ( $item->status == 1 ) { 175 $total += $item->number; 176 $sum += $item->number * $item->price; 174 my $items; 175 if ( $with_products ) { 176 my %ids = map { $_->item_id => 1 } @basket; 177 my @ids = keys %ids; 178 $items = @ids ? $keeper->get_documents ( 179 id => \@ids, 180 class => $state->{webshop}->{item_document_class}, 181 return_mode => 'hash_ref', 182 ) : {}; 183 } 184 foreach my $bi ( @basket ) { 185 if ( $bi->status == 1 ) { 186 $total += $bi->number; 187 $sum += $bi->number * ($bi->price || 0); 177 188 } 189 if ( ref $items eq 'HASH' && exists $items->{$bi->item_id} ) { 190 $bi->{item} = $items->{$bi->item_id}; 191 } 178 192 } 179 return \@items; 193 return \@basket; 180 194 } 181 195 182 196 … … 418 432 } else { 419 433 $dopts{uid} = 0; 420 434 } 421 my $basket = exists $opts{basket} ? $opts{basket} : $self->get_basket( %opts ); 435 my $basket = exists $opts{basket} ? $opts{basket} : $self->get_basket( %opts, with_products => 1 ); 436 return 0 unless ref $basket eq 'ARRAY' && @$basket; 437 my @basket = grep { exists $_->{item} && $_->{item} } @$basket; 438 return 0 unless @basket; 422 439 423 440 my $now = Contenido::DateTime->new; 424 441 my @discounts = $keeper->get_documents( … … 429 446 ); 430 447 return 0 unless @discounts; 431 448 my @summoned = sort { $b->min_sum <=> $a->min_sum } grep { $_->min_sum && $_->discount && $_->min_sum =~ /^\d+$/ } @discounts; 432 my ($total, $sum) = $self->basket_count( $basket ); 449 my ($total, $sum) = $self->basket_count( \@basket ); 433 450 return 0 unless $sum; 434 451 my $result = 0; 435 452 foreach my $discount ( @summoned ) { 436 453 if ( $sum > $discount->min_sum ) { 437 my $res = 0; 438 my $value = $discount->discount; 439 $value =~ s/\s//sg; 440 if ( $value =~ /([\d\.]+)%/ ) { 441 my $proc = $1; 442 $res = $sum / 100 * $proc; 443 } elsif ( $value =~ /([\d\.]+)/ ) { 444 my $res = $1; 445 } 454 my $res = $discount->get_discount( basket => \@basket ); 446 455 $result = $res if $res > $result; 447 456 } 448 457 }