Revision 637

Date:
2017/01/01 20:51:20
Author:
ahitrov
Revision Log:
Coupon usage report

Files:

Legend:

 
Added
 
Removed
 
Modified
  • utf8/plugins/webshop/comps/contenido/webshop/components/block_coupon_finder.msn

     
    1 <fieldset>
    2 <legend>Отчет по купонам</legend>
    3 <form name="searchdoc" action="coupons_report.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 => $status, style=>'width:100%;font-size:8pt;' &></td>
    7 <%doc>
    8 <tr><td><b>Сортировать:</b></td></tr>
    9 <tr><td><& "/contenido/components/select.msn", name=>'sort', values => \@sorts, style=>'width:100%;font-size:8pt;' &></td>
    10 <tr><td height="5"></td></tr>
    11 </%doc>
    12 <tr><td><b>Диапазон дат:</b></td></tr>
    13 <tr><td><& "/contenido/components/inputs/date.msn", name => 'from' &></td></tr>
    14 <tr><td><& "/contenido/components/inputs/date.msn", name => 'to' &></td></tr>
    15 <tr><td><b>Отобразить:</b></td></tr>
    16 <tr><td><& "/contenido/components/select.msn", name=>'show', values => \@shows, style=>'width:100%;font-size:8pt;' &></td>
    17 <tr><td><input type="submit" value="Отобрать" class="btn"></td></tr>
    18 </table>
    19 </form>
    20 </fieldset>
    21
    22 <%once>
    23
    24 my @sorts = (
    25 'id' => 'по номеру заказа',
    26 'uid' => 'по пользователю',
    27 );
    28
    29 my @shows = (
    30 'html' => 'В виде HTML',
    31 'tsv' => 'Tab-separated текст',
    32 );
    33
    34 my @status_values = (
    35 '', 'Без учета статуса',
    36 '1', 'Активные',
    37 '0', 'Неактивные',
    38 '3', 'Использованные',
    39 '2', 'Прототипы',
    40 '4', 'Обработанные',
    41 );
    42
    43 </%once>
    44 <%args>
    45
    46 $status => ''
    47
    48 </%args>
    49 <%init>
    50
    51 my @props = webshop::Coupon->new($keeper)->structure;
    52 my ($prop_status) = grep { $_->{attr} eq 'status' } @props;
    53
    54 my @coupons = ('' => 'без учета купонов');
    55 my $sql = "select id, name from webshop_coupons where class = 'webshop::Coupon' and ( status in (0, 4) or (status in (1,3) and pid = 0) ) order by status = 1 desc, status, dtime desc";
    56 my $que = $keeper->SQL->prepare($sql);
    57 $que->execute();
    58 while ( my $ln = $que->fetchrow_hashref ) {
    59 push @coupons, ($ln->{id}, $ln->{name});
    60 }
    61
    62 </%init>
  • utf8/plugins/webshop/comps/contenido/webshop/coupons.html

     
    13 13 <tr valign="top">
    14 14 <td width="35%">
    15 15
    16 <& /contenido/webshop/components/block_coupons.msn, status => $cst &>
    17 <& /contenido/webshop/components/block_coupon_finder.msn, status => $cst &>
    18 <& /contenido/webshop/components/block_order_id_finder.msn &>
    16 19 <& /contenido/webshop/components/block_order_status_changer.msn &>
    17 20
    18 <& /contenido/webshop/components/block_coupons.msn, status => $cst &>
    19
    20 21 </td>
    21 22 <td width="1%">&nbsp;</td>
    22 23 <td width="65%">
  • utf8/plugins/webshop/comps/contenido/webshop/coupons_report.html

     
    1 % if ( $show eq 'html' ) {
    2 <& "/contenido/components/title.msn", %ARGS &>
    3 % }
    4 % if ( $errstr ) {
    5 % if ( $show eq 'html' ) {
    6 <p style="color:red;"><% $errstr %></p>
    7 % } else {
    8 % $m->out($errstr);
    9 % }
    10 % } else {
    11 % if ( $show eq 'html' ) {
    12 <fieldset>
    13 <legend>Отобраны купоны</legend>
    14 <table width="100%" cellspacing="5" cellpadding="0" class="tform">
    15 <tr><td>
    16 С даты: <b><% $from->dmy('.') %></b><br>
    17 По дату: <b><% $to->dmy('.') %></b><br>
    18 % if ( $status ) {
    19 Со статусом: <b><% $status_opts{$status} %></b><br>
    20 % }
    21 </td></tr>
    22 </table>
    23 </fieldset>
    24 % } else {
    25 С даты <% $from->dmy('.') %>
    26 По дату <% $to->dmy('.') %>
    27 % if ( $status ) {
    28 Со статусом <% $status_opts{$status} %>
    29 % }
    30 % }
    31 % if ( @coupons ) {
    32 % if ( $show eq 'html' ) {
    33 <div style="padding:10px;">
    34 <table border="0" cellpadding="4" cellspacing="0" class="tlistdocs">
    35 <tr valign="top">
    36 <th rowspan="2">#</th>
    37 <th rowspan="2">Название</th>
    38 <th rowspan="2">Статус</th>
    39 <th colspan="2">Активен</th>
    40 <th rowspan="2">К-во заказов</th>
    41 <th rowspan="2">Сумма заказов</th>
    42 <th rowspan="2">Сумма скидки</th>
    43 </tr>
    44 <tr>
    45 <th>&nbsp; с &nbsp;</th>
    46 <th>&nbsp; по &nbsp;</th>
    47 </tr>
    48 % } else {
    49 # Имя заказчика E-mail Тел. Сумма заказа Скидка Доставка Сумма общая Купоны
    50 % }
    51 % foreach my $coupon ( @coupons ) {
    52 % my $begin = Contenido::DateTime->new( postgres => $coupon->dtime );
    53 % my $end = Contenido::DateTime->new( postgres => $coupon->etime );
    54 % my $status = exists $status_opts{$coupon->status} ? $status_opts{$coupon->status} : 'неизвестный ('.$coupon->status.')';
    55 % if ( $show eq 'html' ) {
    56 <tr>
    57 <td><a<% $coupon->contenido_status_style ? ' style="' . $coupon->contenido_status_style . '"' : '' %> class="<% $coupon->status ? '':'hiddensect' %>"
    58 href="/contenido/webshop/coupon.html?id=<% $coupon->id %>"><% $coupon->id %></a></td>
    59 <td><a<% $coupon->contenido_status_style ? ' style="' . $coupon->contenido_status_style . '"' : '' %> class="<% $coupon->status ? '':'hiddensect' %>"
    60 href="/contenido/webshop/coupon.html?id=<% $coupon->id %>"><% $coupon->name %></a></td>
    61 <td><% $status %></td>
    62 <td><% $begin->dmy('.') %></td>
    63 <td><% $end->dmy('.') %></td>
    64 <td align="right"><% $coupon->{order_amount} %></td>
    65 <td align="right"><% $coupon->{sum_total} %></td>
    66 <td align="right"><% $coupon->{discount_total} %></td>
    67 </tr>
    68 % } else {
    69 % $m->out( join ("\t", ($coupon->id, $coupon->name, $status, $begin->dmy('.'), $end->dmy('.'), $coupon->{order_amount}, $coupon->{sum_total}, $coupon->{discount_total}))."\t" );
    70 % $m->out("\n");
    71 % }
    72 % }
    73 % if ( $show eq 'html' ) {
    74 </table>
    75 </div>
    76 % }
    77 % } else {
    78 % if ( $show eq 'html' ) {
    79 <p>В данном диапазоне дат с учетом выбранных условий купоны не найдены</p>
    80 % } else {
    81 В данном диапазоне дат с учетом выбранных условий купоны не найдены
    82 % }
    83 % }
    84 % }
    85
    86 % if ( $show eq 'html' ) {
    87 </body>
    88 </html>
    89 % }
    90 <%args>
    91
    92 $show => 'html'
    93 $status => undef
    94
    95 $from_day => undef
    96 $from_month => undef
    97 $from_year => undef
    98
    99 $to_day => undef
    100 $to_month => undef
    101 $to_year => undef
    102
    103 </%args>
    104 <%init>
    105
    106 if ( $show eq 'html' ) {
    107 $r->content_type ("text/html; charset=utf-8");
    108 } else {
    109 $r->content_type ("text/plain; charset=utf-8");
    110 }
    111 my ($from, $to);
    112
    113 my $errstr;
    114 my @props = webshop::Coupon->new( $keeper )->structure;
    115 my ($status_prop) = grep { $_->{attr} eq 'status' } @props;
    116 my %status_opts = map { $_->[0] => $_->[1] } @{$status_prop->{cases}};
    117 my $now = Contenido::DateTime->new;
    118 if ( $from_day && $from_month && $from_year ) {
    119 eval { $from = Contenido::DateTime->new( datetime => { day => $from_day, month => $from_month, year => $from_year } ) };
    120 }
    121 if ( $to_day && $to_month && $to_year ) {
    122 eval { $to = Contenido::DateTime->new( datetime => { day => $to_day, month => $to_month, year => $to_year } ) };
    123 }
    124 $from = $now unless ref $from;
    125 $to = $now unless ref $to;
    126 if ( $from > $to ) {
    127 $errstr = 'Неверно указан диапазон дат';
    128 }
    129 my %opts = ( interval => [$from->ymd, $to->ymd] );
    130 if ( $status ) {
    131 $opts{status} = $status;
    132 }
    133
    134 my @coupons;
    135 unless ( $errstr ) {
    136 @coupons = $keeper->get_documents(
    137 class => 'webshop::Coupon',
    138 %opts,
    139 order_by => 'etime desc',
    140 );
    141 foreach my $coupon ( @coupons ) {
    142 my $orders = $keeper->get_documents(
    143 class => 'webshop::Order',
    144 lclass => 'webshop::OrderCouponLink',
    145 lsource => 'positive',
    146 ldest => $coupon->id,
    147 no_limit => 1,
    148 order_by => 'ctime desc',
    149 return_mode => 'array_ref',
    150 );
    151 my ($sum, $discount) = (0,0);
    152 foreach my $order( @$orders ) {
    153 $sum += $order->sum;
    154 $discount += $order->sum_discount;
    155
    156 }
    157 $coupon->{order_amount} = scalar @$orders;
    158 $coupon->{sum_total} = $sum;
    159 $coupon->{discount_total} = $discount;
    160 }
    161 }
    162
    163 </%init>

Небольшая справка по веткам

cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.

koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.

utf8 – актуальная ветка, заточенная под UTF-8.

Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.