Revision 424
Date:
2014/03/05 11:42:50
Author:
ahitrov
Revision Log:
Discounts workaround
Files:
Legend:
Added
Removed
Modified
utf8/plugins/webshop/lib/webshop/Discount.pm
1
package webshop::Discount;
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
],
19
},
20
{ 'attr' => 'uid', 'type' => 'status', 'rusname' => 'Доступность для пользователей',
21
'cases' => [
22
[0, 'Скидка доступна всем пользователям'],
23
[1, 'Скидка доступна только зарегистрированным пользователям'],
24
],
25
},
26
{ 'attr' => 'groups', 'rusname' => 'Группы товаров',
27
lookup_opts => { class => $state->{webshop}->{item_section_class}, },
28
allow_null => 1,
29
rem => 'Список разделов, на содержимое которых распространяется скидка по купону',
30
},
31
{ 'attr' => 'discount', 'type' => 'string', 'rusname' => 'Скидка на сумму заказа (число или процент)', shortname => 'Скидка',
32
default => 0, column => 2 },
33
{ 'attr' => 'min_sum', 'type' => 'string', 'rusname' => 'Минимальная сумма, на которую действует скидка', default => 0 },
34
)
35
}
36
37
sub class_name
38
{
39
return 'Webshop: скидка';
40
}
41
42
sub class_description
43
{
44
return 'Webshop: скидка';
45
}
46
47
sub class_table
48
{
49
return 'webshop::SQL::CouponsTable';
50
}
51
52
sub contenido_status_style
53
{
54
my $self = shift;
55
if ( $self->status == 3 ) {
56
return 'color:black;';
57
} elsif ( $self->status == 2 ) {
58
return 'color:red;';
59
} elsif ( $self->status == 4 ) {
60
return 'color:olive;';
61
}
62
}
63
64
sub table_links
65
{
66
return [
67
# { name => 'Купоны', class => 'webshop::Coupon', filter => 'pid', field => 'pid' },
68
];
69
}
70
71
72
sub get_discount
73
{
74
my $self = shift;
75
76
my (%opts) = @_;
77
my $basket = delete $opts{basket};
78
return 0 unless exists $opts{uid} && $opts{uid} || exists $opts{session} && $opts{session};
79
return 0 unless $self->discount;
80
81
$basket ||= $keeper->{webshop}->get_basket ( %opts );
82
return 0 unless ref $basket eq 'ARRAY' && @$basket;
83
84
my ($number, $sum_total) = (0, 0);
85
map { $number += $_->number; $sum_total += $_->number * $_->price } @$basket;
86
warn "BASKET: $number Items of $sum_total Value\n";
87
88
my $discount_counted = 0;
89
my $items;
90
if ( $self->groups ) {
91
$items = $self->keeper->get_documents (
92
s => [$self->groups],
93
class => $state->{webshop}->{item_document_class},
94
light => 1,
95
return_mode => 'array_ref',
96
);
97
} else {
98
$items = $self->keeper->get_documents (
99
class => $state->{webshop}->{item_document_class},
100
lclass => 'webshop::DiscountItemLink',
101
lsource => $self->id,
102
light => 1,
103
return_mode => 'array_ref',
104
);
105
}
106
107
if ( ref $items eq 'ARRAY' && @$items ) {
108
my $found_sum = 0;
109
foreach my $bi ( @$basket ) {
110
warn "BASKET: Item id [".$bi->item_id."]\n" if $DEBUG;
111
next if $bi->special_price;
112
foreach my $item ( @$items) {
113
if ( $bi->item_id == $item->id ) {
114
warn "BASKET: Item [".$item->name."] id [".$item->id."]\n" if $DEBUG;
115
$found_sum += $bi->number * $bi->price;
116
last;
117
}
118
}
119
}
120
warn "Sum found: [$found_sum]\n" if $DEBUG;
121
return $self->can_discount( $found_sum );
122
} elsif ( $self->groups ) {
123
return 0;
124
} else {
125
my $found_sum = 0;
126
foreach my $bi ( @$basket ) {
127
warn "BASKET: Item id [".$bi->item_id."]\n" if $DEBUG;
128
next if $bi->special_price;
129
$found_sum += $bi->number * $bi->price;
130
}
131
warn "Sum found: [$found_sum]\n" if $DEBUG;
132
return $self->can_discount( $found_sum );
133
}
134
return 0;
135
}
136
137
138
sub can_discount
139
{
140
my $self = shift;
141
my $sum = shift;
142
return 0 unless $sum;
143
144
my $discount = $self->discount;
145
my $min_sum = $self->min_sum || 0;
146
my $count = 0;
147
if ( $discount =~ /([\d\.]+)%/ ) {
148
my $proc = $1;
149
return 0 unless $proc;
150
$count = $sum / 100 * $proc;
151
} else {
152
$count = $discount;
153
}
154
my $rest = $sum - $count;
155
$count = 0 if $rest < $min_sum || $rest == 0;
156
return $count;
157
}
158
159
160
161
sub pre_store
162
{
163
my $self = shift;
164
165
my $default_section = $project->s_alias->{webshop_discounts} if ref $project->s_alias eq 'HASH';
166
if ( $default_section && !$self->sections ) {
167
$self->sections($default_section);
168
}
169
170
return 1;
171
}
172
173
174
sub post_delete
175
{
176
my $self = shift;
177
178
$sql = $self->keeper->SQL->prepare('DELETE FROM webshop_coupon_links where source_id = ?');
179
$sql->execute( $self->id );
180
$sql = $self->keeper->SQL->prepare('DELETE FROM webshop_order_coupons where dest_id = ?');
181
$sql->execute( $self->id );
182
183
1;
184
}
185
186
1;
utf8/plugins/webshop/lib/webshop/DiscountItemLink.pm
1
package webshop::DiscountItemLink;
2
3
use base 'Contenido::Link';
4
use Contenido::Globals;
5
6
sub class_name
7
{
8
return 'Скидка на товар';
9
}
10
11
sub class_description
12
{
13
return 'Скидка на товар';
14
}
15
16
sub extra_properties
17
{
18
return ();
19
}
20
21
sub class_table
22
{
23
return 'webshop::SQL::CouponLinkTable';
24
}
25
26
27
sub available_sources
28
{
29
return [ qw(webshop::Discount) ];
30
}
31
32
sub available_destinations
33
{
34
my $self = shift;
35
return $state->{webshop}->{item_document_class};
36
}
37
38
1;
utf8/plugins/webshop/lib/webshop/Init.pm
23
23
webshop::Delivery
24
24
webshop::Payment
25
25
webshop::Coupon
26
webshop::Discount
26
27
27
28
webshop::Country
28
29
webshop::Area
…
…
33
34
webshop::RegionSection
34
35
35
36
webshop::CouponItemLink
37
webshop::DiscountItemLink
36
38
webshop::OrderCouponLink
37
39
));
38
40
utf8/plugins/webshop/lib/webshop/Keeper.pm
407
407
}
408
408
409
409
410
sub check_discount {
411
my $self = shift;
412
my (%opts) = @_;
410
413
414
warn "Check discount begin: ".Dumper(\%opts)."\n" if $DEBUG;
415
my %dopts;
416
if ( exists $opts{uid} && $opts{uid} ) {
417
$dopts{uid} = [0,1];
418
} else {
419
$dopts{uid} = 0;
420
}
421
my $basket = exists $opts{basket} ? $opts{basket} : $self->get_basket( %opts );
422
423
my @discounts = $keeper->get_documents(
424
class => 'webshop::Discount',
425
status => 1,
426
%dopts
427
);
428
}
429
430
411
431
sub price_format {
412
432
my $self = shift;
413
433
my $price = shift;
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.