Revision 693 
  Date: 
  2018/08/13 11:24:32 
  Author: 
  ahitrov 
  Revision Log: 
  Initial import 
  Files: 
  
    
   
 
  
    Legend: 
    
        Added 
        Removed 
        Modified 
     
       
     
      utf8/plugins/money/comps/contenido/money/autohandler 
      
        
           
        
          
              
           
         
                              
      
             1 
            <%init>  
         
      
             2 
             
         
      
             3 
             $r->content_type('text/html');  
         
      
             4 
             $m->call_next();  
         
      
             5 
             
         
      
             6 
            </%init>  
          
   
      utf8/plugins/money/comps/contenido/money/dhandler 
      
        
           
        
          
              
           
         
                              
      
             1 
            <& $call, %ARGS &>  
         
      
             2 
            <%init>  
         
      
             3 
             
         
      
             4 
              my $call;  
         
      
             5 
              if ( $r->uri eq '/contenido/money/' ) {  
         
      
             6 
                    $call = 'index.html';  
         
      
             7 
              } else {  
         
      
             8 
                    &abort404;  
         
      
             9 
              }  
         
      
             10 
             
         
      
             11 
            </%init>  
          
   
      utf8/plugins/money/comps/contenido/money/index.html 
      
        
           
        
          
              
           
         
                              
      
             1 
            <& "/contenido/components/header.msn" &>  
         
      
             2 
            <& "/contenido/components/naviline.msn" &>  
         
      
             3 
             
         
      
             4 
            <p>PLugin [money]</p>  
         
      
             5 
             
         
      
             6 
            </body>  
         
      
             7 
            </html>  
          
   
      utf8/plugins/money/comps/www/money.backend/dreamkas.check.html 
      
        
           
        
          
              
           
         
                              
      
             1 
            <%args>  
         
      
             2 
            </%args>  
         
      
             3 
            <%init>  
         
      
             4 
             
         
      
             5 
                &abort404;  
         
      
             6 
             
         
      
             7 
            </%init>  
          
   
      utf8/plugins/money/config.proto 
      
        
           
        
          
              
           
         
                              
      
             1 
            #############################################################################  
         
      
             2 
            #  
         
      
             3 
            #  Параметры данного шаблона необходимо ВРУЧНУЮ добавить в config.mk проекта  
         
      
             4 
            #  и привести в соответствие с требованиями проекта  
         
      
             5 
            #  
         
      
             6 
            #############################################################################  
         
      
             7 
            PLUGINS +=			money  
         
      
             8 
             
         
      
             9 
            #  dreamkas.ru  
         
      
             10 
            ############################################################  
         
      
             11 
            DREAMKAS_ID =  
         
      
             12 
            DREAMKAS_SECRET =		123  
         
      
             13 
            DREAMKAS_CURRENCY_CODE =	RUB  
         
      
             14 
            DREAMKAS_TAX_MODE =		DEFAULT		# DEFAULT or SIMPLE or SIMPLE_WO or ENVD or AGRICULT or PATENT  
         
      
             15 
            DREAMKAS_TAX_NDS =		NDS_NO_TAX	# NDS_NO_TAX or NDS_0 or NDS_10 or NDS_18 or NDS_20 or NDS_10_CALCULATED or NDS_18_CALCULATED  
         
      
             16 
            DREAMKAS_TEST_MODE =		1		# 0 - для боевого режима  
         
      
             17 
             
         
      
             18 
            REWRITE +=			DREAMKAS_ID DREAMKAS_SECRET DREAMKAS_CURRENCY_CODE DREAMKAS_TAX_MODE DREAMKAS_TAX_NDS DREAMKAS_TEST_MODE  
         
      
             19 
            ############################################################  
         
      
             20 
            #  /dreamkas.ru  
          
   
      utf8/plugins/money/lib/money/Apache.pm 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::Apache;  
         
      
             2 
             
         
      
             3 
            use strict;  
         
      
             4 
            use warnings 'all';  
         
      
             5 
             
         
      
             6 
            use money::State;  
         
      
             7 
            use Contenido::Globals;  
         
      
             8 
             
         
      
             9 
             
         
      
             10 
            sub child_init {  
         
      
             11 
            	# встраиваем keeper плагина в keeper проекта  
         
      
             12 
            	$keeper->{money} = money::Keeper->new($state->money);  
         
      
             13 
            }  
         
      
             14 
             
         
      
             15 
            sub request_init {  
         
      
             16 
            }  
         
      
             17 
             
         
      
             18 
            sub child_exit {  
         
      
             19 
            }  
         
      
             20 
             
         
      
             21 
            1;  
          
   
      utf8/plugins/money/lib/money/Init.pm 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::Init;  
         
      
             2 
             
         
      
             3 
            use strict;  
         
      
             4 
            use warnings 'all';  
         
      
             5 
             
         
      
             6 
            use Contenido::Globals;  
         
      
             7 
            use money::Apache;  
         
      
             8 
            use money::Keeper;  
         
      
             9 
             
         
      
             10 
             
         
      
             11 
            # загрузка всех необходимых плагину классов  
         
      
             12 
            # money::SQL::SomeTable  
         
      
             13 
            # money::SomeClass  
         
      
             14 
            Contenido::Init::load_classes(qw(  
         
      
             15 
            		money::SQL::MovementsTable  
         
      
             16 
            		money::Movement  
         
      
             17 
             
         
      
             18 
            		money::MovementSection  
         
      
             19 
             
         
      
             20 
            		money::Provider::Base  
         
      
             21 
            	));  
         
      
             22 
             
         
      
             23 
            sub init {  
         
      
             24 
            	0;  
         
      
             25 
            }  
         
      
             26 
             
         
      
             27 
            1;  
          
   
      utf8/plugins/money/lib/money/Keeper.pm 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::Keeper;  
         
      
             2 
             
         
      
             3 
            use strict;  
         
      
             4 
            use warnings 'all';  
         
      
             5 
            use base qw(Contenido::Keeper);  
         
      
             6 
             
         
      
             7 
             
         
      
             8 
            use Contenido::Globals;  
         
      
             9 
             
         
      
             10 
             
         
      
             11 
            1;  
          
   
      utf8/plugins/money/lib/money/Movement.pm 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::Movement;  
         
      
             2 
             
         
      
             3 
            use base "Contenido::Document";  
         
      
             4 
            sub extra_properties  
         
      
             5 
            {  
         
      
             6 
            	return (  
         
      
             7 
            		{ 'attr' => 'status',   'type' => 'status',     'rusname' => 'Статус тестирования',  
         
      
             8 
            			'cases' => [  
         
      
             9 
            					[0, 'Реальный чек'],  
         
      
             10 
            					[1, 'Тестовый чек'],  
         
      
             11 
            				],  
         
      
             12 
            		},  
         
      
             13 
            	)  
         
      
             14 
            }  
         
      
             15 
             
         
      
             16 
            sub class_name  
         
      
             17 
            {  
         
      
             18 
            	return 'Money: онлайн-чек';  
         
      
             19 
            }  
         
      
             20 
             
         
      
             21 
            sub class_description  
         
      
             22 
            {  
         
      
             23 
            	return 'Money: онлайн-чек';  
         
      
             24 
            }  
         
      
             25 
             
         
      
             26 
            sub class_table  
         
      
             27 
            {  
         
      
             28 
            	return 'money::SQL::MovementsTable';  
         
      
             29 
            }  
         
      
             30 
             
         
      
             31 
            1;  
          
   
      utf8/plugins/money/lib/money/MovementSection.pm 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::MovementSection;  
         
      
             2 
             
         
      
             3 
            use base 'Contenido::Section';  
         
      
             4 
             
         
      
             5 
            sub extra_properties  
         
      
             6 
            {  
         
      
             7 
            	return (  
         
      
             8 
            		{ 'attr' => 'brief',    'type' => 'text',       'rusname' => 'Описание секции' },  
         
      
             9 
            		{ 'attr' => 'default_document_class',		'default' => 'money::Movement' },  
         
      
             10 
            		{ 'attr' => '_sorted',				'hidden' => 1 },  
         
      
             11 
            		{ 'attr' => 'order_by',				'hidden' => 1 },  
         
      
             12 
            	)  
         
      
             13 
            }  
         
      
             14 
             
         
      
             15 
            sub class_name  
         
      
             16 
            {  
         
      
             17 
            	return 'Money: Секция чеков';  
         
      
             18 
            }  
         
      
             19 
             
         
      
             20 
            sub class_description  
         
      
             21 
            {  
         
      
             22 
            	return 'Money: Секция транзакций';чеков  
         
      
             23 
            }  
         
      
             24 
             
         
      
             25 
            1;  
          
   
      utf8/plugins/money/lib/money/Provider/Base.pm 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::Provider::Base;  
         
      
             2 
             
         
      
             3 
            use strict;  
         
      
             4 
            use warnings 'all';  
         
      
             5 
            use Contenido::Globals;  
         
      
             6 
            use payments::Keeper;  
         
      
             7 
             
         
      
             8 
             
         
      
             9 
            sub new {  
         
      
             10 
                my ($proto, %params) = @_;  
         
      
             11 
                my $class = ref($proto) || $proto;  
         
      
             12 
                my $self = {};  
         
      
             13 
                my $prefix = $class =~ /\:\:(\w+)$/ ? lc($1) : undef;  
         
      
             14 
                return	unless $prefix;  
         
      
             15 
             
         
      
             16 
                $self->{provider} =		$prefix;  
         
      
             17 
                $self->{app_id} =		$state->{money}->{$prefix."_app_id"};  
         
      
             18 
                $self->{secret} =		$state->{money}->{$prefix."_app_secret"};  
         
      
             19 
                $self->{currency} =		$state->{money}->{$prefix."_currency_code"};  
         
      
             20 
                $self->{test_mode} =	$state->{money}->{$prefix."_test_mode"};  
         
      
             21 
             
         
      
             22 
                bless $self, $class;  
         
      
             23 
             
         
      
             24 
                return $self;  
         
      
             25 
            }  
         
      
             26 
             
         
      
             27 
             
         
      
             28 
            sub id {  
         
      
             29 
                my $self = shift;  
         
      
             30 
                return $self->{app_id};  
         
      
             31 
            }  
         
      
             32 
             
         
      
             33 
            sub app_id {  
         
      
             34 
                my $self = shift;  
         
      
             35 
                return $self->{app_id};  
         
      
             36 
            }  
         
      
             37 
             
         
      
             38 
            sub secret {  
         
      
             39 
                my $self = shift;  
         
      
             40 
                return $self->{secret};  
         
      
             41 
            }  
         
      
             42 
             
         
      
             43 
            sub test_mode {  
         
      
             44 
                my $self = shift;  
         
      
             45 
                return $self->{test_mode};  
         
      
             46 
            }  
         
      
             47 
             
         
      
             48 
            sub currency {  
         
      
             49 
                my $self = shift;  
         
      
             50 
                return $self->{currency};  
         
      
             51 
            }  
         
      
             52 
             
         
      
             53 
            sub currency_code {  
         
      
             54 
                my $self = shift;  
         
      
             55 
                return $self->{currency};  
         
      
             56 
            }  
         
      
             57 
             
         
      
             58 
            sub provider {  
         
      
             59 
                my $self = shift;  
         
      
             60 
                return $self->{provider};  
         
      
             61 
            }  
         
      
             62 
             
         
      
             63 
            #################################  
         
      
             64 
            # Пытается зарегистрировать движение средств по order_id.  
         
      
             65 
            # В случае успеха возвращает объект money::Movement  
         
      
             66 
            # В случае неуспеха выставляет ошибку и возвращает undef.  
         
      
             67 
            # Сумма чека в копейках  
         
      
             68 
            ##########################################################  
         
      
             69 
            sub money_movement_register {  
         
      
             70 
                my $self = shift;  
         
      
             71 
                my $opts = shift // {};  
         
      
             72 
                unless ( $opts->{order_id} && $opts->{uid} && $opts->{sum} && $opts->{name} ) {  
         
      
             73 
            	$self->{result}{error} = 'Переданы не все обязательные параметры';  
         
      
             74 
            	return undef;  
         
      
             75 
                }  
         
      
             76 
                  
         
      
             77 
                my $mm = $keeper->get_documents(  
         
      
             78 
            		class		=> 'money::Movement',  
         
      
             79 
            		status		=> $self->{test_mode},  
         
      
             80 
            		order_id	=> $opts->{order_id},  
         
      
             81 
            		order_by	=> 'ctime',  
         
      
             82 
            		return_mode	=> 'array_ref',  
         
      
             83 
            	);  
         
      
             84 
                my $new = 0;  
         
      
             85 
                if ( ref $mm eq 'ARRAY' && @$mm ) {  
         
      
             86 
            	my $last = $mm->[-1];  
         
      
             87 
            	if ( $opts->{name} eq 'payment' && $last->name eq 'payment' ) {  
         
      
             88 
            		return $last;  
         
      
             89 
            	} elsif ( $opts->{name} eq 'refund' && (grep { $_->name eq 'payment' } @$mm) ) {  
         
      
             90 
            		$new = 1;  
         
      
             91 
            	}  
         
      
             92 
                } elsif ( $opts->{name} eq 'payment' ) {  
         
      
             93 
            	$new = 1;  
         
      
             94 
                }  
         
      
             95 
                if ( $new ) {  
         
      
             96 
            	$mm = money::Movement->new( $keeper );  
         
      
             97 
            	$mm->status( $self->{test_mode} );  
         
      
             98 
            	$mm->name( $opts->{name} );  
         
      
             99 
            	$mm->order_id( $opts->{order_id} );  
         
      
             100 
            	$mm->uid( $opts->{uid} );  
         
      
             101 
            	$mm->sum( sprintf("%.2f", $opts->{sum} / 100) );  
         
      
             102 
            	$mm->store;  
         
      
             103 
                }  
         
      
             104 
                return $mm;  
         
      
             105 
            }  
         
      
             106 
             
         
      
             107 
            sub get_mm_by_order_id {  
         
      
             108 
                my $self = shift;  
         
      
             109 
                my $order_id = shift;  
         
      
             110 
             
         
      
             111 
                my ($mm) = $keeper->get_documents(  
         
      
             112 
            			class   => 'money::Movement',  
         
      
             113 
            			status  => $self->{test_mode},  
         
      
             114 
            			limit   => 1,  
         
      
             115 
            			order_id        => $order_id,  
         
      
             116 
            			order_by	=> 'ctime desc',  
         
      
             117 
            			provider        => $self->{provider},  
         
      
             118 
            		);  
         
      
             119 
             
         
      
             120 
                return $mm;  
         
      
             121 
            }  
         
      
             122 
             
         
      
             123 
            1;  
          
   
      utf8/plugins/money/lib/money/Provider/Dreamkas.pm 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::Provider::Dreamkas;  
         
      
             2 
             
         
      
             3 
            use strict;  
         
      
             4 
            use warnings 'all';  
         
      
             5 
             
         
      
             6 
            use base 'money::Provider::Base';  
         
      
             7 
            use Contenido::Globals;  
         
      
             8 
            use money::Keeper;  
         
      
             9 
            use MIME::Base64;  
         
      
             10 
            use URI;  
         
      
             11 
            use URI::QueryParam;  
         
      
             12 
            use JSON::XS;  
         
      
             13 
            use Data::Dumper;  
         
      
             14 
             
         
      
             15 
            use constant (  
         
      
             16 
            	TAXMODE_DEFAULT	=> 'DEFAULT',  
         
      
             17 
            );  
         
      
             18 
             
         
      
             19 
            our %TAX_MODES = (  
         
      
             20 
            	'DEFAULT'	=> 1, # Общая  
         
      
             21 
            	'SIMPLE'	=> 1, # Упрощенная доход  
         
      
             22 
            	'SIMPLE_WO'	=> 1, # Упрощенная доход минус расход  
         
      
             23 
            	'ENVD'		=> 1, # Единый налог на вмененный доход  
         
      
             24 
            	'AGRICULT'	=> 1, # Единый сельскохозяйственный  
         
      
             25 
            	'PATENT'	=> 1, # Патентная система налогообложения  
         
      
             26 
            );  
         
      
             27 
             
         
      
             28 
            our %TAX_NDS = (  
         
      
             29 
            	'NDS_NO_TAX'	=> 0,  
         
      
             30 
            	'NDS_0'		=> 0,  
         
      
             31 
            	'NDS_10'	=> 0.10,  
         
      
             32 
            	'NDS_18'	=> 0.18,  
         
      
             33 
            	'NDS_20'	=> 0.20,  
         
      
             34 
            	'NDS_10_CALCULATED'	=> 0.10/110,  
         
      
             35 
            	'NDS_18_CALCULATED'	=> 0.10/110,  
         
      
             36 
            );  
         
      
             37 
             
         
      
             38 
            our %OP_STATUS = (  
         
      
             39 
            	'PENDING'	=> 0,  
         
      
             40 
            	'IN_PROGRESS'	=> 1,  
         
      
             41 
            	'SUCCESS'	=> 2,  
         
      
             42 
            	'ERROR'		=> -1,  
         
      
             43 
            );  
         
      
             44 
             
         
      
             45 
            sub new {  
         
      
             46 
                my ($proto, %params) = @_;  
         
      
             47 
                my $class = ref($proto) || $proto;  
         
      
             48 
                my $self = {};  
         
      
             49 
                my $prefix = $class =~ /\:\:(\w+)$/ ? lc($1) : undef;  
         
      
             50 
                return      unless $prefix;  
         
      
             51 
             
         
      
             52 
                $self->{prefix} =		$prefix;  
         
      
             53 
                $self->{app_id} =		$state->{money}{$prefix."_app_id"};  
         
      
             54 
                $self->{secret} =		$state->{money}{$prefix."_app_secret"};  
         
      
             55 
                $self->{token} =		$state->{money}{$prefix."_app_token"};  
         
      
             56 
                $self->{tax_mode} =		$state->{money}{$prefix."_tax_mode"};  
         
      
             57 
                unless ( exists $TAX_MODES{$self->{tax_mode}} ) {  
         
      
             58 
            	warn "Неверная мнемоника типа налоговой системы\n";  
         
      
             59 
            	return undef;  
         
      
             60 
                }  
         
      
             61 
                $self->{tax_nds} =		$state->{money}{$prefix."_tax_nds"};  
         
      
             62 
                unless ( exists $TAX_NDS{$self->{tax_nds}} ) {  
         
      
             63 
            	warn "Неверная мнемоника типа НДС\n";  
         
      
             64 
            	return undef;  
         
      
             65 
                }  
         
      
             66 
                $self->{device_id} =	$state->{money}{$prefix."_device_id"};  
         
      
             67 
                unless ( $self->{device_id} ) {  
         
      
             68 
            	warn "Не указан или неверно указан ID кассового аппарата\n";  
         
      
             69 
            	return undef;  
         
      
             70 
                }  
         
      
             71 
                $self->{test_mode} =	exists $params{test_mode} ? $params{test_mode} : $state->{money}->{$prefix."_test_mode"};  
         
      
             72 
                $self->{return_url} =	$params{return_url} || $state->{money}{$prefix."_return_url"};  
         
      
             73 
                $self->{fail_url} =		$params{fail_url} || $state->{money}{$prefix."_fail_url"};  
         
      
             74 
             
         
      
             75 
                $self->{currency} =		$state->{money}{$prefix."_currency_code"};  
         
      
             76 
             
         
      
             77 
                $self->{$base_url} = 'https://'. ($self->{test_mode} ? 'private-anon-f6c2f7b545-kabinet.apiary-mock.com' : 'kabinet.dreamkas.ru').'/api';  
         
      
             78 
                $self->{result} = {};  
         
      
             79 
             
         
      
             80 
                bless $self, $class;  
         
      
             81 
                return $self;  
         
      
             82 
            }  
         
      
             83 
             
         
      
             84 
             
         
      
             85 
            =for rem RECEIPT  
         
      
             86 
            # Фискализация чека (только для Дримкас-Ф)  
         
      
             87 
             
         
      
             88 
            $mm->receipt({  
         
      
             89 
            	# обязательные:  
         
      
             90 
                    order		=> webshop::Order  
         
      
             91 
            	# или  
         
      
             92 
            	order_id	=> ID от webshop::Order  
         
      
             93 
            	total		=> общая сумма заказа, если не передан order  
         
      
             94 
             
         
      
             95 
            	profile		=> Профиль пользователя, объект  
         
      
             96 
            	# или  
         
      
             97 
            	attributes	=> Атрибуты, пример внизу  
         
      
             98 
            	# или  
         
      
             99 
            	email		=> E-mail  
         
      
             100 
            	phone		=> Phone в формате +79163332222  
         
      
             101 
            	  
         
      
             102 
                    # необязательные:  
         
      
             103 
            	basket		=> Если есть order или order_id, можно не передавать  
         
      
             104 
            	# или  
         
      
             105 
            	positions	=> ARRAY_REF, если не передан order или basket  
         
      
             106 
             
         
      
             107 
            	type		=> SALE || REFUND || OUTFLOW || OUTFLOW_REFUND || SALE  
         
      
             108 
            	timeout		=> Таймаут фискализации в секундах (по умолчанию - 300 секунд).  
         
      
             109 
            			Если в течение этого времени не удастся произвести фискализацию,   
         
      
             110 
            			то операция будет отменена с ошибкой.  
         
      
             111 
            	payment_type	=> CASH || CASHLESS  
         
      
             112 
            });  
         
      
             113 
             
         
      
             114 
            JSON тела вызова:  
         
      
             115 
             
         
      
             116 
            {  
         
      
             117 
              "deviceId": 1385,  
         
      
             118 
              "type": "SALE",  
         
      
             119 
              "timeout": 180,  
         
      
             120 
              "taxMode": "DEFAULT",  
         
      
             121 
              "positions": [  
         
      
             122 
                {  
         
      
             123 
                  "name": "Шоколад Сникерс",  
         
      
             124 
                  "type": "COUNTABLE",  
         
      
             125 
                  "quantity": 2,  
         
      
             126 
                  "price": 4500,  
         
      
             127 
                  "priceSum": 9000,  
         
      
             128 
                  "tax": "NDS_18",  
         
      
             129 
                  "taxSum": 1620  
         
      
             130 
                }  
         
      
             131 
              ],  
         
      
             132 
              "payments": [  
         
      
             133 
                {  
         
      
             134 
                  "sum": 9000,  
         
      
             135 
                  "type": "CASHLESS"  
         
      
             136 
                }  
         
      
             137 
              ],  
         
      
             138 
              "attributes": {  
         
      
             139 
                "email": "john.smith@example.com",  
         
      
             140 
                "phone": "+71239994499"  
         
      
             141 
              },  
         
      
             142 
              "total": {  
         
      
             143 
                "priceSum": 9000  
         
      
             144 
              }  
         
      
             145 
            }  
         
      
             146 
             
         
      
             147 
             
         
      
             148 
            Результат:  
         
      
             149 
             
         
      
             150 
            {  
         
      
             151 
                "id": "5956889136fdd7733f19cfe6",  
         
      
             152 
                "createdAt": "2017-06-20 12:01:47.990Z",  
         
      
             153 
                "status": "PENDING"  
         
      
             154 
            }  
         
      
             155 
             
         
      
             156 
            status:  
         
      
             157 
             
         
      
             158 
            PENDING		- В обработке  
         
      
             159 
            IN_PROGRESS	- Задача принята в обработку (например, устройство приняло чек на фискализацию)  
         
      
             160 
            SUCCESS		- Завершено успешно  
         
      
             161 
            ERROR		- Завершено с ошибкой  
         
      
             162 
             
         
      
             163 
            =cut  
         
      
             164 
            ##########################################################  
         
      
             165 
            sub receipt {  
         
      
             166 
                my $self = shift;  
         
      
             167 
                my $opts = shift // {};  
         
      
             168 
             
         
      
             169 
                my $type = delete $opts->{type};  
         
      
             170 
                if ( $type && $type =~ /^(SALE|REFUND|OUTFLOW|OUTFLOW_REFUND)$/ ) {  
         
      
             171 
            	$self->{result}{error} = 'Неверно указан тип операции';  
         
      
             172 
            	return $self;  
         
      
             173 
                }  
         
      
             174 
                $opts->{type} ||= 'SALE';  
         
      
             175 
             
         
      
             176 
                my $data = {  
         
      
             177 
            	type	=> $type,  
         
      
             178 
            	deviceId=> $self->{device_id},  
         
      
             179 
            	taxMode	=> $self->{tax_mode},  
         
      
             180 
                };  
         
      
             181 
             
         
      
             182 
                if ( exists $opts->{order_id} ) {  
         
      
             183 
            	$opts->{order} = $keeper->{webshop}->get_orders( id => $opts->{order_id} );  
         
      
             184 
            	unless ( ref $opts->{order} eq 'webshop::Order' ) {  
         
      
             185 
            		$self->{result}{error} = 'Заказ не найден. Передан неверный order_id';  
         
      
             186 
            		return $self;  
         
      
             187 
            	}  
         
      
             188 
                }  
         
      
             189 
             
         
      
             190 
                my $MM;  
         
      
             191 
                if ( exists $opts->{order} ) {  
         
      
             192 
            	$MM = $self->_GetLastMoneyMovement( $opts->{order}->id );  
         
      
             193 
                }  
         
      
             194 
                if ( ref $MM && $MM->session_id && $MM->name eq $opts->{type} ) {  
         
      
             195 
            	$self->{result}{money_movement} = $MM;  
         
      
             196 
            	return $self;  
         
      
             197 
                }  
         
      
             198 
                unless ( $MM ) {  
         
      
             199 
            	$MM = money::Movement->new( $keeper );  
         
      
             200 
            	$MM->name( $opts->{type} );  
         
      
             201 
            	$MM->provider( $self->{prefix} );  
         
      
             202 
            	$MM->status( $self->{test_mode} );  
         
      
             203 
            	$MM->success( 0 );  
         
      
             204 
            	if ( ref $opts->{order} ) {  
         
      
             205 
            		$MM->order_id( $opts->{order}->id );  
         
      
             206 
            	}  
         
      
             207 
            	$MM->currency_code( $self->{currency} );  
         
      
             208 
                }  
         
      
             209 
             
         
      
             210 
                if ( exists $opts->{order} && !exists $opts->{basket} ) {  
         
      
             211 
            	$opts->{basket} = $keeper->{webshop}->get_basket( order_id => $opts->{order}->id, with_products => 1 );  
         
      
             212 
            	unless ( ref $opts->{basket} eq 'ARRAY' && @{$opts->{basket}} ) {  
         
      
             213 
            		$self->{result}{error} = 'Невозможно получить список товарных позиций в заказе';  
         
      
             214 
            		return $self;  
         
      
             215 
            	}  
         
      
             216 
                }  
         
      
             217 
             
         
      
             218 
                if ( exists $opts->{basket} && ref $opts->{basket} eq 'ARRAY' ) {  
         
      
             219 
            	my $positions = [];  
         
      
             220 
            	foreach my $bi ( @{$opts->{basket}} ) {  
         
      
             221 
            		my $item = $bi->{item};  
         
      
             222 
            		next	unless ref $item;  
         
      
             223 
            		my $price = int($bi->{item}->price * 100)  
         
      
             224 
            		my $pos = {  
         
      
             225 
            			name	=> $bi->name,  
         
      
             226 
            			type	=> 'COUNTABLE',  
         
      
             227 
            			quantity	=> $bi->number,  
         
      
             228 
            			price		=> $price,  
         
      
             229 
            			priceSum	=> $price * $bi->number,  
         
      
             230 
            			tax	=> $self->{tax_nds},  
         
      
             231 
            			taxSum	=> ($price * $bi->number) * $TAX_NDS{$self->{tax_nds}},  
         
      
             232 
            		};  
         
      
             233 
            		push @$positions, $pos;  
         
      
             234 
            	}  
         
      
             235 
            	unless ( @$positions ) {  
         
      
             236 
            		$self->{result}{error} = 'Cписок товарных позиций в заказе неверный. Возможно, в состав корзины не включенны товары';  
         
      
             237 
            		return $self;  
         
      
             238 
            	}  
         
      
             239 
            	$data->{positions} = $positions;  
         
      
             240 
                } elsif ( exists $opts->{positions} && ref $opts->{positions} eq 'ARRAY' && @{$opts->{positions}} ) {  
         
      
             241 
            	$data->{positions} = $opts->{positions};  
         
      
             242 
                }  
         
      
             243 
             
         
      
             244 
                # Заполняем атрибуты плательщика  
         
      
             245 
                if ( exists $opts->{profile} && ref $opts->{profile} eq $state->{users}->profile_document_class ) {  
         
      
             246 
            	my $profile = $opts->{profile};  
         
      
             247 
            	my $email = $profile->email;  
         
      
             248 
            	my $attributes = { email => "$email" };  
         
      
             249 
            	$data->{attributes} = $attributes;  
         
      
             250 
                } elsif ( exists $opts->{attributes} ) {  
         
      
             251 
            	$data->{attributes} = $data->{attributes};  
         
      
             252 
                } elsif ( exists $opts->{email} || $opts->{phone} ) {  
         
      
             253 
            	my $attributes = {};  
         
      
             254 
            	if ( exists $opts->{email} && $opts->{email} ) {  
         
      
             255 
            		if ( ref $opts->{email} ) {  
         
      
             256 
            			$arrtibutes->{email} = $opts->{email}->name;  
         
      
             257 
            		} else {  
         
      
             258 
            			$arrtibutes->{email} = $opts->{email};  
         
      
             259 
            		}  
         
      
             260 
            	}  
         
      
             261 
            	if ( exists $opts->{phone} && $opts->{phone} ) {  
         
      
             262 
            		if ( ref $opts->{phone} ) {  
         
      
             263 
            			$arrtibutes->{phone} = $opts->{phone}->name;  
         
      
             264 
            		} else {  
         
      
             265 
            			$arrtibutes->{phone} = $opts->{phone};  
         
      
             266 
            		}  
         
      
             267 
            	}  
         
      
             268 
            	$data->{attributes} = $attributes;  
         
      
             269 
                }  
         
      
             270 
             
         
      
             271 
                # Заполняем параметры оплаты: total и payments  
         
      
             272 
                if ( exists $opts->{order} && ref $opts->{order} eq 'webshop::Order' ) {  
         
      
             273 
            	$data->{total}{priceSum} = int($opts->{order}->sum_total * 10);  
         
      
             274 
                } else {  
         
      
             275 
            	if ( $opts->{total} ) {  
         
      
             276 
            		$data->{total}{priceSum} = $opts->{total};  
         
      
             277 
            	}  
         
      
             278 
                }  
         
      
             279 
                unless ( $data->{total}{priceSum} ) {  
         
      
             280 
            	$self->{result}{error} = 'Не указана итоговая сумма. Необходимо передать параметр total или order';  
         
      
             281 
            	return $self;  
         
      
             282 
                }  
         
      
             283 
                $data->{payments}{sum} = $data->{total}{priceSum};  
         
      
             284 
                $MM->sum( $data->{total}{priceSum} );  
         
      
             285 
                if ( exists $opts->{payment_type} && $opts->{payment_type} eq 'CASH' ) {  
         
      
             286 
            	$data->{payments}{type} = 'CASH';  
         
      
             287 
                }  
         
      
             288 
             
         
      
             289 
                my $api_url = '/api/receipts';  
         
      
             290 
             
         
      
             291 
                $self->_MakeRequest( $api_url, 'post', $data );  
         
      
             292 
                if ( $self->{result}{code} == 202 ) {  
         
      
             293 
            	$MM->success( $OP_STATUS{$self->{result}{content}{status}} );  
         
      
             294 
            	$MM->session_id( $self->{result}{content}{id} );  
         
      
             295 
            	$MM->store;  
         
      
             296 
            	$self->{result}{money_movement} = $MM;  
         
      
             297 
                } else {  
         
      
             298 
            	$self->{result}{error} = $self->{result}{status};  
         
      
             299 
                }  
         
      
             300 
             
         
      
             301 
                return $self;  
         
      
             302 
            }  
         
      
             303 
             
         
      
             304 
             
         
      
             305 
            =for rem RECEIPT  
         
      
             306 
            # Информация о статусе операции  
         
      
             307 
             
         
      
             308 
            $mm->check( $operation_id );  
         
      
             309 
             
         
      
             310 
            Передается ID, полученное на этапе запроса на фискализацию чека  
         
      
             311 
             
         
      
             312 
            Результат:  
         
      
             313 
             
         
      
             314 
            {  
         
      
             315 
              "id": "5956889136fdd7733f19cfe6",  
         
      
             316 
              "createdAt": "2017-06-20 12:01:47.990Z",  
         
      
             317 
              "status": "ERROR",  
         
      
             318 
              "completedAt": "2017-06-20 12:03:12.440Z",  
         
      
             319 
              "data": {  
         
      
             320 
                "error": {  
         
      
             321 
                  "code": "NeedUpdateCash",  
         
      
             322 
                  "message": "Требуется обновление кассы"  
         
      
             323 
                }  
         
      
             324 
              }  
         
      
             325 
            }  
         
      
             326 
             
         
      
             327 
            status:  
         
      
             328 
             
         
      
             329 
            PENDING		- В обработке  
         
      
             330 
            IN_PROGRESS	- Задача принята в обработку (например, устройство приняло чек на фискализацию)  
         
      
             331 
            SUCCESS		- Завершено успешно  
         
      
             332 
            ERROR		- Завершено с ошибкой  
         
      
             333 
             
         
      
             334 
            =cut  
         
      
             335 
            ##########################################################  
         
      
             336 
            sub check {  
         
      
             337 
                my $self = shift;  
         
      
             338 
                my $opts = shift // {};  
         
      
             339 
                if ( exists $self->{result} && exists $self->{result}{error} ) {  
         
      
             340 
            	return $self;  
         
      
             341 
                }  
         
      
             342 
             
         
      
             343 
                my $MM;  
         
      
             344 
                if ( exists $self->{result}{money_movement} ) {  
         
      
             345 
            	$MM = $self->{result}{money_movement};  
         
      
             346 
                } elsif ( exists $opts->{money_movement} ) {  
         
      
             347 
            	$MM = $opts->{money_movement};  
         
      
             348 
                } elsif ( $opts->{operation_id} ) {  
         
      
             349 
            	($MM) = $self->_GetMMByOperationId( $opts->{operation_id} );  
         
      
             350 
                }  
         
      
             351 
                unless ( ref $MM ) {  
         
      
             352 
            	$self->{result}{error} = 'Не найден объект "движение денежных средств". Проверьте входные параметры';  
         
      
             353 
            	return $self;  
         
      
             354 
                }  
         
      
             355 
             
         
      
             356 
                my $api_url = '/api/operations/'.$MM->session_id;  
         
      
             357 
             
         
      
             358 
                $self->_MakeRequest( $api_url, 'get' );  
         
      
             359 
                if ( $self->{result}{code} == 200 ) {  
         
      
             360 
            	$MM->success( $OP_STATUS{$self->{result}{content}{status}} );  
         
      
             361 
            	$MM->store;  
         
      
             362 
            	$self->{result}{money_movement} = $MM;  
         
      
             363 
            	if ( $self->{result}{content}{status} eq 'ERROR' ) {  
         
      
             364 
            		$self->{result}{error} = $self->{result}{content}{data}{error}{message};  
         
      
             365 
            		$self->{result}{code} = $self->{result}{content}{data}{error}{code};  
         
      
             366 
            	}  
         
      
             367 
                } else {  
         
      
             368 
            	$self->{result}{error} = $self->{result}{status};  
         
      
             369 
                }  
         
      
             370 
             
         
      
             371 
                return $self;  
         
      
             372 
            }  
         
      
             373 
             
         
      
             374 
             
         
      
             375 
            sub _MakeRequest {  
         
      
             376 
                my ($self, $url, $type, $body) = @_;  
         
      
             377 
                $type ||= 'post';  
         
      
             378 
             
         
      
             379 
                my $ua = LWP::UserAgent->new;  
         
      
             380 
                $ua->timeout( 10 );  
         
      
             381 
                $ua->agent('Mozilla/5.0');  
         
      
             382 
             
         
      
             383 
                my $auth = encode_base64($self->{app_id}.':'.$self->{secret});  
         
      
             384 
                $ua->default_header( 'Authorization' => "Application: {$auth}" );  
         
      
             385 
                $ua->default_header( 'Content-Type' => 'application/json' );  
         
      
             386 
             
         
      
             387 
                if ( ref $body ) {  
         
      
             388 
            	$body = encode_json( $body );  
         
      
             389 
                }  
         
      
             390 
             
         
      
             391 
                my $req = URI->new( $self->{host}.($url =~ /^\// ? '' : '/').$url );  
         
      
             392 
                my $res;  
         
      
             393 
                if ( $type eq 'post' ) {  
         
      
             394 
            	$res = $ua->post( $req, Content => $body );  
         
      
             395 
                } elsif ( $type eq 'delete' ) {  
         
      
             396 
            	$res = $ua->delete( $req );  
         
      
             397 
                } else {  
         
      
             398 
            	$res = $ua->get( $req );  
         
      
             399 
                }  
         
      
             400 
                $self->{result} = {  
         
      
             401 
            	code	=> $res->code,  
         
      
             402 
            	status	=> $res->status_line,  
         
      
             403 
            	content	=> JSON::XS->new->decode( $res->decoded_content ),  
         
      
             404 
                }  
         
      
             405 
                return $self;  
         
      
             406 
            }  
         
      
             407 
             
         
      
             408 
            sub _GetLastMoneyMovement {  
         
      
             409 
                my $self = shift;  
         
      
             410 
                my $order_id = shift;  
         
      
             411 
                my ($mm) = $keeper->get_documents(  
         
      
             412 
            		class	=> 'money::Movement',  
         
      
             413 
            		limit	=> 1,  
         
      
             414 
            		order_id	=> $order_id  
         
      
             415 
            		order_by	=> 'id desc',  
         
      
             416 
            	);  
         
      
             417 
                return $mm;  
         
      
             418 
            }  
         
      
             419 
             
         
      
             420 
            sub _GetMMByOperationId {  
         
      
             421 
                my $self = shift;  
         
      
             422 
                my $op_id = shift;  
         
      
             423 
                my ($mm) = $keeper->get_documents(  
         
      
             424 
            		class	=> 'money::Movement',  
         
      
             425 
            		limit	=> 1,  
         
      
             426 
            		session_id	=> $op_id,  
         
      
             427 
            	);  
         
      
             428 
                return $mm;  
         
      
             429 
            }  
         
      
             430 
             
         
      
             431 
            1;  
          
   
      utf8/plugins/money/lib/money/SQL/MovementsTable.pm 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::SQL::MovementsTable;  
         
      
             2 
             
         
      
             3 
            use base 'SQL::DocumentTable';  
         
      
             4 
             
         
      
             5 
            sub db_table  
         
      
             6 
            {  
         
      
             7 
            	return 'money_movements';  
         
      
             8 
            }  
         
      
             9 
             
         
      
             10 
            sub db_id_sequence {  
         
      
             11 
            	return 'money_movements_id_seq';  
         
      
             12 
            }  
         
      
             13 
             
         
      
             14 
            sub available_filters {  
         
      
             15 
            	my @available_filters = qw(  
         
      
             16 
             
         
      
             17 
            					_class_filter  
         
      
             18 
            					_status_filter  
         
      
             19 
            					_in_id_filter  
         
      
             20 
            					_id_filter  
         
      
             21 
            					_name_filter  
         
      
             22 
            				        _class_excludes_filter  
         
      
             23 
            					_sfilter_filter  
         
      
             24 
            					_excludes_filter  
         
      
             25 
            					_datetime_filter  
         
      
             26 
            					_date_equal_filter  
         
      
             27 
            					_date_filter  
         
      
             28 
            					_previous_days_filter  
         
      
             29 
             
         
      
             30 
            					_provider_filter  
         
      
             31 
            					_session_id_filter  
         
      
             32 
            					_order_id_filter  
         
      
             33 
            					_success_filter  
         
      
             34 
            					_name_exact_filter  
         
      
             35 
            			);  
         
      
             36 
             
         
      
             37 
            	return \@available_filters;  
         
      
             38 
            }  
         
      
             39 
             
         
      
             40 
            # ----------------------------------------------------------------------------  
         
      
             41 
            # Свойства храним в массивах, потому что порядок важен!  
         
      
             42 
            # Это общие свойства - одинаковые для всех документов.  
         
      
             43 
            #  
         
      
             44 
            #   attr - обязательный параметр, название атрибута;  
         
      
             45 
            #   type - тип аттрибута, требуется для отображдения;  
         
      
             46 
            #   rusname - русское название, опять же требуется для отображения;  
         
      
             47 
            #   hidden - равен 1, когда  
         
      
             48 
            #   readonly - инициализации при записи только без изменения в дальнейшем  
         
      
             49 
            #   db_field - поле в таблице  
         
      
             50 
            #   default  - значение по умолчанию (поле всегда имеет это значение)  
         
      
             51 
            # ----------------------------------------------------------------------------  
         
      
             52 
            sub required_properties  
         
      
             53 
            {  
         
      
             54 
            	my $self = shift;  
         
      
             55 
             
         
      
             56 
            	my @parent_properties = grep { $_->{attr} ne 'sections' } $self->SUPER::required_properties;  
         
      
             57 
            	return (  
         
      
             58 
            		@parent_properties,  
         
      
             59 
            		{  
         
      
             60 
            			'attr'		=> 'provider',  
         
      
             61 
            			'type'		=> 'string',  
         
      
             62 
            			'rusname'	=> 'Провайдер',  
         
      
             63 
            			'db_field'      => 'provider',  
         
      
             64 
            			'db_type'       => 'text',  
         
      
             65 
            		},  
         
      
             66 
            		{  
         
      
             67 
            			'attr'		=> 'session_id',  
         
      
             68 
            			'type'		=> 'string',  
         
      
             69 
            			'rusname'	=> 'Ключ сессии',  
         
      
             70 
            			'db_field'      => 'session_id',  
         
      
             71 
            			'db_type'       => 'text',  
         
      
             72 
            		},  
         
      
             73 
            		{						       # ID заказа  
         
      
             74 
            			'attr'		=> 'order_id',  
         
      
             75 
            			'type'		=> 'integer',  
         
      
             76 
            			'rusname'	=> 'ID заказа',  
         
      
             77 
            			'db_field'	=> 'order_id',  
         
      
             78 
            			'db_type'	=> 'integer',  
         
      
             79 
            			'db_opts'	=> "not null",  
         
      
             80 
            		},  
         
      
             81 
            		{  
         
      
             82 
            			'attr'		=> 'currency_code',  
         
      
             83 
            			'type'		=> 'string',  
         
      
             84 
            			'rusname'	=> 'ID валюты',  
         
      
             85 
            			'db_field'	=> 'currency_code',  
         
      
             86 
            			'db_type'	=> 'varchar(4)',  
         
      
             87 
            		},  
         
      
             88 
            		{  
         
      
             89 
            			'attr'		=> 'sum',  
         
      
             90 
            			'type'		=> 'string',  
         
      
             91 
            			'rusname'	=> 'Сумма чека',  
         
      
             92 
            			'db_field'	=> 'sum',  
         
      
             93 
            			'db_type'	=> 'float',  
         
      
             94 
            		},  
         
      
             95 
            		{						       # Результат транзакции  
         
      
             96 
            			'attr'		=> 'success',  
         
      
             97 
            			'type'		=> 'checkbox',  
         
      
             98 
            			'rusname'	=> 'Транзакция прошла успешно',  
         
      
             99 
            			'db_field'	=> 'success',  
         
      
             100 
            			'db_type'	=> 'smallint',  
         
      
             101 
            			'db_opts'	=> "default 0",  
         
      
             102 
            		},  
         
      
             103 
            	);  
         
      
             104 
            }  
         
      
             105 
             
         
      
             106 
             
         
      
             107 
            ########### FILTERS DESCRIPTION ###############################################################################  
         
      
             108 
            sub _order_id_filter {  
         
      
             109 
            	my ($self,%opts)=@_;  
         
      
             110 
            	return undef unless ( exists $opts{order_id} );  
         
      
             111 
            	return &SQL::Common::_generic_int_filter('d.order_id', $opts{order_id});  
         
      
             112 
            }  
         
      
             113 
             
         
      
             114 
            sub _success_filter {  
         
      
             115 
            	my ($self,%opts)=@_;  
         
      
             116 
            	return undef unless ( exists $opts{success} );  
         
      
             117 
            	return &SQL::Common::_generic_int_filter('d.success', $opts{success});  
         
      
             118 
            }  
         
      
             119 
             
         
      
             120 
            sub _provider_filter {  
         
      
             121 
            	my ($self,%opts)=@_;  
         
      
             122 
            	return undef unless ( exists $opts{provider} );  
         
      
             123 
            	return &SQL::Common::_generic_text_filter('d.provider', $opts{provider});  
         
      
             124 
            }  
         
      
             125 
             
         
      
             126 
            sub _session_id_filter {  
         
      
             127 
            	my ($self,%opts)=@_;  
         
      
             128 
            	return undef unless ( exists $opts{session_id} );  
         
      
             129 
            	return &SQL::Common::_generic_int_filter('d.session_id', $opts{session_id});  
         
      
             130 
            }  
         
      
             131 
             
         
      
             132 
            sub _name_exact_filter {  
         
      
             133 
            	my ($self,%opts)=@_;  
         
      
             134 
            	return undef unless ( exists $opts{name_exact} );  
         
      
             135 
            	return &SQL::Common::_generic_text_filter('d.name', $opts{name_exact});  
         
      
             136 
            }  
         
      
             137 
             
         
      
             138 
            1;  
          
   
      utf8/plugins/money/lib/money/State.pm.proto 
      
        
           
        
          
              
           
         
                              
      
             1 
            package money::State;  
         
      
             2 
             
         
      
             3 
            use strict;  
         
      
             4 
            use warnings 'all';  
         
      
             5 
            use vars qw($AUTOLOAD);  
         
      
             6 
             
         
      
             7 
             
         
      
             8 
            sub new {  
         
      
             9 
            	my ($proto) = @_;  
         
      
             10 
            	my $class = ref($proto) || $proto;  
         
      
             11 
            	my $self = {};  
         
      
             12 
            	bless $self, $class;  
         
      
             13 
             
         
      
             14 
            	# configured  
         
      
             15 
                    $self->{project} =		'@PROJECT@';  
         
      
             16 
                    $self->{debug} =		(lc('@DEBUG@') eq 'yes');  
         
      
             17 
            	$self->{contenido_notab} =	1;  
         
      
             18 
            	$self->{tab_name} =		'money';  
         
      
             19 
            	$self->{project_name}		= '@PROJECT_NAME@';  
         
      
             20 
            	$self->{default_expire}		= '@DEFAULT_EXPIRE@' || 300;  
         
      
             21 
            	$self->{default_object_expire}	= '@DEFAULT_OBJECT_EXPIRE@' || 600;  
         
      
             22 
             
         
      
             23 
            	# зашитая конфигурация плагина  
         
      
             24 
            	$self->{db_type} =		'none';		### For REAL database use 'remote'  
         
      
             25 
            	$self->{db_keepalive} =	0;  
         
      
             26 
            	$self->{db_host} =		'';  
         
      
             27 
            	$self->{db_name} =		'';  
         
      
             28 
            	$self->{db_user} =		'';  
         
      
             29 
            	$self->{db_password} =	'';  
         
      
             30 
            	$self->{db_port} =		'';  
         
      
             31 
            	$self->{store_method} =		'toast';  
         
      
             32 
            	$self->{cascade} =		1;  
         
      
             33 
            	$self->{db_prepare} =		0;  
         
      
             34 
             
         
      
             35 
            	$self->{memcached_enable} =		lc( '@MEMCACHED_ENABLE@' ) eq 'yes' ? 1 : 0;  
         
      
             36 
            	$self->{memcached_backend} =		'@MEMCACHED_BACKEND@';  
         
      
             37 
            	$self->{memcached_select_timeout} =	'@MEMCACHED_SELECT_TIMEOUT@' || 0.2;  
         
      
             38 
            	$self->{memcached_servers} =		[qw(@MEMCACHED_SERVERS@)];  
         
      
             39 
            	$self->{memcached_enable_compress} =	lc( '@MEMCACHED_ENABLE_COMPRESS@' ) eq 'yes' ? 1 : 0;  
         
      
             40 
            	$self->{memcached_delayed} =		lc('@MEMCACHED_DELAYED@') eq 'yes' ? 1 : 0;  
         
      
             41 
            	$self->{memcached_set_mode} =		lc('@MEMCACHED_SET_MODE@') eq 'add' ? 'add' : 'set';  
         
      
             42 
            	$self->{memcached_busy_lock} =		60;  
         
      
             43 
            	$self->{memcached_namespace} =		lc( $self->{'project'} ).'|plugin_payments|';  
         
      
             44 
             
         
      
             45 
            	$self->{serialize_with} =	'json';		### or 'dumper'  
         
      
             46 
             
         
      
             47 
            	# not implemented really (core compatibility)  
         
      
             48 
            	$self->{binary_directory} =	'/nonexistent';  
         
      
             49 
            	$self->{data_directory} =	'/nonexistent';  
         
      
             50 
            	$self->{images_directory} =	'/nonexistent';  
         
      
             51 
            	$self->{preview} =		'0';  
         
      
             52 
             
         
      
             53 
            	$self->{dreamkas_app_id} =		'@DREAMKAS_ID@';  
         
      
             54 
            	$self->{dreamkas_app_secret} =		'@DREAMKAS_SECRET@';  
         
      
             55 
            	$self->{dreamkas_currency_code} =	'@DREAMKAS_CURRENCY_CODE@';  
         
      
             56 
            	$self->{dreamkas_tax_mode} =		'@DREAMKAS_TAX_MODE@' || 'DEFAULT';  
         
      
             57 
            	$self->{dreamkas_tax_nds} =		'@DREAMKAS_TAX_NDS@' || 'NDS_NO_TAX';  
         
      
             58 
            	$self->{dreamkas_device_id} =		int('@DREAMKAS_DEVICE_ID@' || 0);  
         
      
             59 
            	$self->{dreamkas_test_mode} =		int('@DREAMKAS_TEST_MODE@' || 0);  
         
      
             60 
             
         
      
             61 
            	$self->_init_();  
         
      
             62 
            	$self;	  
         
      
             63 
            }  
         
      
             64 
             
         
      
             65 
            sub info {  
         
      
             66 
            	my $self = shift;  
         
      
             67 
            	return unless ref $self;  
         
      
             68 
             
         
      
             69 
            	for (sort keys %{$self->{attributes}}) {  
         
      
             70 
            		my $la = length $_;  
         
      
             71 
            		warn "\t$_".("\t" x (2-int($la/8))).": $self->{$_}\n";  
         
      
             72 
            	}  
         
      
             73 
            }  
         
      
             74 
             
         
      
             75 
            sub _init_ {  
         
      
             76 
            	my $self = shift;  
         
      
             77 
             
         
      
             78 
            	# зашитая конфигурация плагина  
         
      
             79 
            	$self->{attributes}->{$_} = 'SCALAR' for qw(  
         
      
             80 
                            debug  
         
      
             81 
                            project  
         
      
             82 
            		tab_name  
         
      
             83 
             
         
      
             84 
            		db_type  
         
      
             85 
            		db_keepalive  
         
      
             86 
            		db_host  
         
      
             87 
            		db_port  
         
      
             88 
            		db_name  
         
      
             89 
            		db_user  
         
      
             90 
            		db_password  
         
      
             91 
            		store_method  
         
      
             92 
            		cascade  
         
      
             93 
            		db_prepare  
         
      
             94 
            		db_client_encoding  
         
      
             95 
             
         
      
             96 
            		memcached_enable  
         
      
             97 
            		memcached_enable_compress  
         
      
             98 
            		memcached_backend  
         
      
             99 
            		memcached_servers  
         
      
             100 
            		memcached_busy_lock  
         
      
             101 
            		memcached_delayed  
         
      
             102 
             
         
      
             103 
            		binary_directory  
         
      
             104 
            		data_directory  
         
      
             105 
            		images_directory  
         
      
             106 
            		preview  
         
      
             107 
            	);  
         
      
             108 
            }  
         
      
             109 
             
         
      
             110 
            sub AUTOLOAD {  
         
      
             111 
            	my $self = shift;  
         
      
             112 
            	my $attribute = $AUTOLOAD;  
         
      
             113 
             
         
      
             114 
            	$attribute =~ s/.*:://;  
         
      
             115 
            	return unless $attribute =~ /[^A-Z]/;  # Отключаем методы типа DESTROY  
         
      
             116 
             
         
      
             117 
            	if (!exists $self->{attributes}->{$attribute}) {  
         
      
             118 
            		warn "Contenido Error (money::State): Вызов метода, для которого не существует обрабатываемого свойства: ->$attribute()\n";  
         
      
             119 
            		return;  
         
      
             120 
            	}  
         
      
             121 
             
         
      
             122 
            	$self->{$attribute} = shift @_ if $#_>=0;  
         
      
             123 
            	$self->{$attribute};  
         
      
             124 
            }  
         
      
             125 
             
         
      
             126 
            1;  
          
   
      utf8/plugins/money/sql/TOAST/money_movement.sql 
      
        
           
        
          
              
           
         
                              
      
             1 
            create sequence money_movements_id_seq;  
         
      
             2 
            select setval('money_movements_id_seq', 1, true);  
         
      
             3 
             
         
      
             4 
            create table money_movements  
         
      
             5 
            (  
         
      
             6 
            	id integer not null primary key default nextval('public.documents_id_seq'::text),  
         
      
             7 
            	class text not null,  
         
      
             8 
            	ctime timestamp not null default now(),  
         
      
             9 
            	mtime timestamp not null default now(),  
         
      
             10 
            	dtime timestamp not null default now(),  
         
      
             11 
            	status smallint not null default 0,  
         
      
             12 
            	provider text,  
         
      
             13 
            	session_id text,  
         
      
             14 
            	name text,  
         
      
             15 
            	order_id integer not null,  
         
      
             16 
            	currency_code varchar(4),  
         
      
             17 
            	sum float,  
         
      
             18 
            	success smallint default 0,  
         
      
             19 
            	data text  
         
      
             20 
            );  
         
      
             21 
            CREATE INDEX money_movements_sessions ON money_movements USING btree (provider, session_id) WHERE session_id is not null;  
         
      
             22 
            CREATE INDEX money_movements_orders ON money_movements USING btree (order_id);  
          
     
 
 
      
    
Небольшая справка по веткам 
cnddist  – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8  – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8  – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core  – исходники ядра; install  – скрипт установки инсталляции; plugins  – плагины; samples  – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.