Revision 422
Date:
2014/02/28 20:20:43
Author:
ahitrov
Revision Log:
Order accounting reports
Files:
Legend:
Added
Removed
Modified
utf8/plugins/webshop/comps/contenido/webshop/components/block_order_finder.msn
1
<fieldset>
2
<legend>Отчет по заказам</legend>
3
<form name="searchdoc" action="orders.html" method="GET" target="_blank">
4
<table width="100%" border="0" cellpadding="0" cellspacing="6" class="tform">
5
<tr><td><b>Выберите статус:</b></td></tr>
6
<tr><td><& "/contenido/components/select.msn", name=>'status', values => \@status_values, check => 4, style=>'width:100%;font-size:8pt;' &></td>
7
<tr><td><b>Сортировать:</b></td></tr>
8
<tr><td><& "/contenido/components/select.msn", name=>'sort', values => \@sorts, style=>'width:100%;font-size:8pt;' &></td>
9
<tr><td height="5"></td></tr>
10
<tr><td><b>Диапазон дат:</b></td></tr>
11
<tr><td><& "/contenido/components/inputs/date.msn", name => 'from' &></td></tr>
12
<tr><td><& "/contenido/components/inputs/date.msn", name => 'to' &></td></tr>
13
<tr><td><b>Отобразить:</b></td></tr>
14
<tr><td><& "/contenido/components/select.msn", name=>'show', values => \@shows, style=>'width:100%;font-size:8pt;' &></td>
15
<tr><td><input type="submit" value="Отобрать" class="btn"></td></tr>
16
</table>
17
</form>
18
</fieldset>
19
20
<%once>
21
22
my @sorts = (
23
'id' => 'по номеру заказа',
24
'uid' => 'по пользователю',
25
);
26
27
my @shows = (
28
'html' => 'В виде HTML',
29
'tsv' => 'Tab-separated текст',
30
);
31
32
</%once>
33
<%args>
34
35
36
</%args>
37
<%init>
38
39
my @props = webshop::Order->new($keeper)->structure;
40
my ($prop_status) = grep { $_->{attr} eq 'status' } @props;
41
my @status_values = map { $_->[0] => $_->[1] } @{$prop_status->{cases}};
42
43
</%init>
utf8/plugins/webshop/comps/contenido/webshop/index.html
16
16
<& /contenido/webshop/components/block_order_status_changer.msn, status => $ost &>
17
17
18
18
<& /contenido/webshop/components/block_coupons.msn &>
19
<& /contenido/webshop/components/block_order_finder.msn &>
19
20
20
21
</td>
21
22
<td width="1%"> </td>
utf8/plugins/webshop/comps/contenido/webshop/orders.html
1
% if ( $show eq 'html' ) {
2
<& "/contenido/components/title.msn", %ARGS &>
3
% }
4
5
% if ( $errstr ) {
6
% if ( $show eq 'html' ) {
7
<p style="color:red;"><% $errstr %></p>
8
% } else {
9
% $m->out($errstr);
10
% }
11
% } else {
12
% if ( $show eq 'html' ) {
13
<fieldset>
14
<legend>Отобраны заказы</legend>
15
<table width="100%" cellspacing="5" cellpadding="0" class="tform">
16
<tr><td>
17
С даты: <b><% $from->dmy('.') %></b><br>
18
По дату: <b><% $to->dmy('.') %></b><br>
19
% if ( $status ) {
20
Со статусом: <b><% $status_opts{$status} %></b><br>
21
% }
22
% if ( $sort && exists $sorts{$sort} ) {
23
Сортировка <b><% $sorts{$sort}{name} %></b>
24
% }
25
</td></tr>
26
</table>
27
</fieldset>
28
% } else {
29
С даты <% $from->dmy('.') %>
30
По дату <% $to->dmy('.') %>
31
% if ( $status ) {
32
Со статусом <% $status_opts{$status} %>
33
% }
34
% if ( $sort && exists $sorts{$sort} ) {
35
Сортировка <% $sorts{$sort}{name} %>
36
% }
37
% }
38
% if ( @orders ) {
39
% if ( $show eq 'html' ) {
40
<div style="padding:10px;">
41
<table border="0" cellpadding="4" cellspacing="0" class="tlistdocs">
42
<tr>
43
<th>#</th>
44
<th>Имя заказчика</th>
45
<th>E-mail</th>
46
<th>Тел.</th>
47
<th>Сумма заказа</th>
48
<th>Скидка</th>
49
<th>Доставка</th>
50
<th>Сумма общая</th>
51
<th>Купоны</th>
52
</tr>
53
% } else {
54
# Имя заказчика E-mail Тел. Сумма заказа Скидка Доставка Сумма общая Купоны
55
% }
56
% foreach my $order ( @orders ) {
57
% my $profile = $order->{profile};
58
% my $coupons = $order->{coupons};
59
% if ( $show eq 'html' ) {
60
<tr>
61
<td><% $order->id %></td>
62
<td><% $order->name %></td>
63
<td><% $order->email %></td>
64
<td><% $order->phone %></td>
65
<td><% $order->sum %></td>
66
<td><% $order->sum_discount %></td>
67
<td><% $order->sum_delivery %></td>
68
<td><% $order->sum_total %></td>
69
<td>
70
% if ( ref $coupons eq 'ARRAY'&& @$coupons ) {
71
% foreach my $coupon ( @$coupons ) {
72
<% $coupon->name %><br>
73
% }
74
% }
75
</td>
76
</tr>
77
% } else {
78
% $m->out( join ("\t", ($order->id, $order->name, $order->email, $order->phone, $order->sum, $order->sum_discount, $order->sum_delivery, $order->sum_total))."\t" );
79
% if ( ref $coupons eq 'ARRAY'&& @$coupons ) {
80
% my $str = join ', ', map { my $name = $_->name; $name =~ s/\t/\ /g; $name } @$coupons;
81
% $m->out( $str );
82
% }
83
% $m->out("\n");
84
% }
85
% }
86
% if ( $show eq 'html' ) {
87
</table>
88
</div>
89
% }
90
% } else {
91
% if ( $show eq 'html' ) {
92
<p>В данном диапазоне дат с учетом выбранных условий заказы не найдены</p>
93
% } else {
94
В данном диапазоне дат с учетом выбранных условий заказы не найдены
95
% }
96
% }
97
% }
98
% if ( $show eq 'html' ) {
99
</body>
100
</html>
101
% }
102
<%once>
103
104
my %sorts = (
105
'id' => { name => 'по номеру заказа', order_by => 'id' },
106
'uid' => { name => 'по пользователю', order_by => 'name, uid' },
107
);
108
109
</%once>
110
<%args>
111
112
$status => undef
113
$sort => undef
114
$show => 'html'
115
116
$from_day => undef
117
$from_month => undef
118
$from_year => undef
119
120
$to_day => undef
121
$to_month => undef
122
$to_year => undef
123
124
</%args>
125
<%init>
126
127
if ( $show eq 'html' ) {
128
$r->content_type ("text/html; charset=utf-8");
129
} else {
130
$r->content_type ("text/plain; charset=utf-8");
131
}
132
my ($from, $to);
133
134
my $errstr;
135
my @props = webshop::Order->new( $keeper )->structure;
136
my ($status_prop) = grep { $_->{attr} eq 'status' } @props;
137
my %status_opts = map { $_->[0] => $_->[1] } @{$status_prop->{cases}};
138
my $now = Contenido::DateTime->new;
139
if ( $from_day && $from_month && $from_year ) {
140
eval { $from = Contenido::DateTime->new( datetime => { day => $from_day, month => $from_month, year => $from_year } ) };
141
}
142
if ( $to_day && $to_month && $to_year ) {
143
eval { $to = Contenido::DateTime->new( datetime => { day => $to_day, month => $to_month, year => $to_year } ) };
144
}
145
$from = $now unless ref $from;
146
$to = $now unless ref $to;
147
if ( $from > $to ) {
148
$errstr = 'Неверно указан диапазон дат';
149
}
150
my %opts = ( date => [$from->ymd, $to->ymd] );
151
if ( $status ) {
152
$opts{status} = $status;
153
}
154
if ( $sort && exists $sorts{$sort} ) {
155
$opts{order_by} = $sorts{$sort}{order_by};
156
}
157
my @orders;
158
unless ( $errstr ) {
159
@orders = $keeper->get_documents(
160
class => 'webshop::Order',
161
%opts
162
);
163
if ( @orders ) {
164
my %uids = map { $_->uid => 1 } @orders;
165
my @uids = keys %uids;
166
my $profiles = @uids ? $keeper->get_documents(
167
id => \@uids,
168
class => $state->{users}->profile_document_class,
169
return_mode => 'hash_ref',
170
) : {};
171
foreach my $order ( @orders ) {
172
$order->{profile} = exists $profiles->{$order->uid} ? $profiles->{$order->uid} : undef;
173
if ( $order->sum_discount ) {
174
my @coupons = $keeper->get_documents(
175
class => 'webshop::Coupon',
176
lclass => 'webshop::OrderCouponLink',
177
lsource => $order->id,
178
);
179
$order->{coupons} = \@coupons;
180
}
181
}
182
}
183
}
184
185
</%init>
utf8/plugins/webshop/lib/webshop/Order.pm
34
34
manager_hidden => 1, postedit => 1, facilshow => 1 },
35
35
{ 'attr' => 'num', 'type' => 'integer', 'rusname' => 'Количество позиций',
36
36
manager_hidden => 1, manshow => 1, postshow => 1, facilshow => 1 },
37
{ 'attr' => 'sum', 'type' => 'string', 'rusname' => 'Сумма (total)', shortname => 'Сумма',
37
{ 'attr' => 'sum', 'type' => 'string', 'rusname' => 'Сумма (gross)', shortname => 'Сумма',
38
38
manager_hidden => 1, column => 5, postshow => 1, facilshow => 1 },
39
39
{ 'attr' => 'sum_discount', 'type' => 'string', 'rusname' => 'Сумма скидки', shortname => 'Скидка',
40
40
manager_hidden => 1, column => 6, postshow => 1, facilshow => 1 },
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.