Line # Revision Author
1 270 ahitrov package webshop::Coupon;
2
3 use strict;
4 use warnings 'all';
5
6 use Contenido::Globals;
7 use base "Contenido::Document";
8 use Data::Dumper;
9
10 sub extra_properties
11 {
12 return (
13 { 'attr' => 'class', 'column' => undef },
14 { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус',
15 'cases' => [
16 [0, 'Купон не активен'],
17 [1, 'Купон активен и разослан'],
18 [2, 'Прототип ждет обработки'],
19 [3, 'Купон использован'],
20 [4, 'Прототип обработан роботом'],
21 ],
22 },
23 { 'attr' => 'uid_proto','type' => 'status', 'rusname' => 'Прототип пользовательского доступа',
24 'cases' => [
25 [0, 'Купон доступен всем пользователям'],
26 [1, 'Персональный купон, создается для всех зарегистрированных пользователей'],
27 [2, 'Персональный купон, пользователи по выбору'],
28 [3, 'Персональный купон для одного пользователя'],
29 ],
30 'rem' => 'Заполняется при создании прототипа купона',
31 },
32 { 'attr' => 'uid_condition', 'type' => 'string', 'rusname' => 'Условие для прототипа' },
33 { 'attr' => 'uid', 'type' => 'pickup', 'rusname' => 'Пользователь',
34 lookup_opts => { class => $state->{users}->profile_document_class, order_by => 'email', search_by => 'email' },
35 allow_null => 1, default => 0,
36 rem => '0 - действует для всех пользователей, многократно. id - для одного пользователя, однократно.'
37 },
38 { 'attr' => 'groups', 'rusname' => 'Группы товаров',
39 lookup_opts => { class => $state->{webshop}->{item_section_class}, },
40 allow_null => 1,
41 rem => 'Список разделов, на содержимое которых распространяется скидка по купону',
42 },
43 { 'attr' => 'discount', 'type' => 'string', 'rusname' => 'Скидка на сумму заказа (число или процент)', shortname => 'Скидка',
44 default => 0, column => 2 },
45 { 'attr' => 'min_sum', 'type' => 'string', 'rusname' => 'Минимальная сумма, на которую действует скидка', default => 0 },
46 684 ahitrov { 'attr' => 'summon', 'type' => 'checkbox', 'rusname' => 'Может суммироваться с другими купонами', default => 0 },
47 270 ahitrov )
48 }
49
50 sub class_name
51 {
52 return 'Webshop: купон';
53 }
54
55 sub class_description
56 {
57 return 'Webshop: купон';
58 }
59
60 sub class_table
61 {
62 return 'webshop::SQL::CouponsTable';
63 }
64
65 sub contenido_status_style
66 {
67 my $self = shift;
68 if ( $self->status == 3 ) {
69 return 'color:black;';
70 } elsif ( $self->status == 2 ) {
71 return 'color:red;';
72 } elsif ( $self->status == 4 ) {
73 return 'color:olive;';
74 }
75 }
76
77 274 ahitrov sub table_links
78 {
79 return [
80 { name => 'Купоны', class => 'webshop::Coupon', filter => 'pid', field => 'pid' },
81 ];
82 }
83 270 ahitrov
84
85 sub get_discount
86 {
87 my $self = shift;
88
89 my (%opts) = @_;
90 432 ahitrov return 0 unless exists $opts{basket} || exists $opts{uid} && $opts{uid} || exists $opts{session} && $opts{session};
91 270 ahitrov return 0 unless $self->discount;
92
93 589 ahitrov my $basket = exists $opts{basket} ? delete $opts{basket} : $keeper->{webshop}->get_basket ( %opts, with_products => 1 );
94 270 ahitrov return 0 unless ref $basket eq 'ARRAY' && @$basket;
95
96 my ($number, $sum_total) = (0, 0);
97 589 ahitrov my @basket = grep { exists $_->{item} && $_->{item} } @$basket;
98 return 0 unless @basket;
99 map { my $price = $_->{item}->price; $number += $_->number; $sum_total += $_->number * $price } @basket;
100 270 ahitrov warn "BASKET: $number Items of $sum_total Value\n";
101
102 my $discount_counted = 0;
103 589 ahitrov my $items = $self->keeper->get_documents (
104 270 ahitrov class => $state->{webshop}->{item_document_class},
105 lclass => 'webshop::CouponItemLink',
106 lsource => $self->id,
107 light => 1,
108 589 ahitrov return_mode => 'hash_ref',
109 270 ahitrov );
110 589 ahitrov
111 if ( $self->groups ) {
112 my %groups = map { $_ => 1 } $self->groups;
113 590 ahitrov @basket = grep { scalar (grep { exists $groups{$_} } $_->{item}->sections) > 0 || exists $items->{$_->{item}->id} } @basket;
114 589 ahitrov } elsif ( keys %$items ) {
115 @basket = grep { exists $items->{$_->{item}->id} } @basket;
116 270 ahitrov }
117 589 ahitrov return 0 unless @basket;
118 270 ahitrov
119 589 ahitrov my $found_sum = 0;
120 foreach my $bi ( @basket ) {
121 warn "BASKET: Basket item id [".$bi->item_id."]\n" if $DEBUG;
122 next if $bi->{item}->special_price;
123 next unless $bi->{item}->price > 0 && $bi->{item}->storage;
124 $found_sum += $bi->number * $bi->{item}->price;
125 270 ahitrov }
126 591 ahitrov return $found_sum > 0 ? $self->can_discount( $found_sum, $sum_total ) : 0;
127 270 ahitrov }
128
129
130 sub can_discount
131 {
132 my $self = shift;
133 my $sum = shift;
134 591 ahitrov my $total = shift || $sum;
135 270 ahitrov return 0 unless $sum;
136
137 my $discount = $self->discount;
138 my $min_sum = $self->min_sum || 0;
139 my $count = 0;
140 if ( $discount =~ /([\d\.]+)%/ ) {
141 my $proc = $1;
142 return 0 unless $proc;
143 $count = $sum / 100 * $proc;
144 } else {
145 $count = $discount;
146 }
147 my $rest = $sum - $count;
148 432 ahitrov warn "Min Sum: $min_sum. Rest: $rest\n" if $DEBUG;
149 591 ahitrov $count = 0 if ($min_sum && $total < $min_sum) || $rest <= 0;
150 432 ahitrov warn "Count: $count\n" if $DEBUG;
151 270 ahitrov return $count;
152 }
153
154
155
156
157 #sub table_links
158 #{
159 # return [
160 # { name => 'Города', class => 'webshop::Town', filter => 'pid', field => 'pid' },
161 # ];
162 #}
163
164 sub pre_store
165 {
166 my $self = shift;
167
168 my $default_section = $project->s_alias->{webshop_coupons} if ref $project->s_alias eq 'HASH';
169 if ( $default_section && !$self->sections ) {
170 $self->sections($default_section);
171 }
172
173 return 1;
174 }
175
176 274 ahitrov
177 sub post_delete
178 {
179 my $self = shift;
180
181 my $sql = $self->keeper->SQL->prepare('DELETE FROM webshop_coupons where pid = ?');
182 $sql->execute( $self->id );
183 276 ahitrov $sql = $self->keeper->SQL->prepare('DELETE FROM webshop_coupon_links where source_id = ?');
184 274 ahitrov $sql->execute( $self->id );
185 276 ahitrov $sql = $self->keeper->SQL->prepare('DELETE FROM webshop_order_coupons where dest_id = ?');
186 274 ahitrov $sql->execute( $self->id );
187
188 1;
189 }
190
191 270 ahitrov 1;