per-agent disable_previous_balance, #15863
[freeside.git] / FS / FS / ClientAPI_XMLRPC.pm
1 package FS::ClientAPI_XMLRPC;
2
3 =head1 NAME
4
5 FS::ClientAPI_XMLRPC - Freeside XMLRPC accessible self-service API, on the backend
6
7 =head1 SYNOPSIS
8
9 This module implements the self-service API offered by xmlrpc.cgi and friends,
10 but on a backend machine.
11
12 =head1 DESCRIPTION
13
14 Use this API to implement your own client "self-service" module vi XMLRPC.
15
16 Each routine described in L<FS::SelfService> is available vi XMLRPC as the
17 method FS.SelfService.XMLRPC.B<method>.  All values are passed to the
18 selfservice-server in a struct of strings.  The return values are in a
19 struct as strings, arrays, or structs as appropriate for the values
20 described in L<FS::SelfService>.
21
22 =head1 BUGS
23
24 =head1 SEE ALSO
25
26 L<FS::SelfService::XMLRPC>, L<FS::SelfService>
27
28 =cut
29
30 use strict;
31
32 use vars qw($DEBUG $AUTOLOAD);
33 use XMLRPC::Lite; # for XMLRPC::Data
34 use FS::ClientAPI;
35
36 $DEBUG = 0;
37 $FS::ClientAPI::DEBUG = $DEBUG;
38
39 #false laziness w/FS::SelfService/XMLRPC.pm, same problem as below but worse
40 our %typefix = (
41   'invoice_pdf'        => { 'invoice_pdf' => 'base64', },
42   'legacy_invoice_pdf' => { 'invoice_pdf' => 'base64', },
43   'skin_info'          => { 'logo'              => 'base64',
44                             'title_left_image'  => 'base64',
45                             'title_right_image' => 'base64',
46                             'menu_top_image'    => 'base64',
47                             'menu_body_image'   => 'base64',
48                             'menu_bottom_image' => 'base64',
49                           },
50   'invoice_logo'       => { 'logo' => 'base64', },
51 );
52
53 sub AUTOLOAD {
54   my $call = $AUTOLOAD;
55   $call =~ s/^FS::(SelfService::|ClientAPI_)XMLRPC:://;
56
57   warn "FS::ClientAPI_XMLRPC::AUTOLOAD $call\n" if $DEBUG;
58
59   my $autoload = &ss2clientapi;
60
61   if (exists($autoload->{$call})) {
62
63     shift; #discard package name;
64
65     #$call = "FS::SelfService::$call";
66     #no strict 'refs';
67     #&{$call}(@_);
68     #FS::ClientAPI->dispatch($autoload->{$call}, @_);
69
70     my $return = FS::ClientAPI->dispatch($autoload->{$call}, { @_ } );
71
72     if ( exists($typefix{$call}) ) {
73       my $typefix = $typefix{$call};
74       foreach my $field ( grep exists($return->{$_}), keys %$typefix ) {
75         my $type = $typefix->{$field};
76         $return->{$field} = XMLRPC::Data->value($return->{$field})
77                                         ->type($type);
78       }
79     }
80
81     $return;
82
83   }else{
84     die "No such procedure: $call";
85   }
86 }
87
88 #terrible false laziness w/SelfService.pm
89 # - fix at build time, by including some file in both selfserv and backend libs?
90 # - or fix at runtime, by having selfservice client ask server for the list?
91 sub ss2clientapi {
92   {
93   'passwd'                    => 'passwd/passwd',
94   'chfn'                      => 'passwd/passwd',
95   'chsh'                      => 'passwd/passwd',
96   'login_info'                => 'MyAccount/login_info',
97   'login'                     => 'MyAccount/login',
98   'logout'                    => 'MyAccount/logout',
99   'switch_acct'               => 'MyAccount/switch_acct',
100   'customer_info'             => 'MyAccount/customer_info',
101   'customer_info_short'       => 'MyAccount/customer_info_short',
102   'edit_info'                 => 'MyAccount/edit_info',     #add to ss cgi!
103   'invoice'                   => 'MyAccount/invoice',
104   'invoice_pdf'               => 'MyAccount/invoice_pdf',
105   'legacy_invoice'            => 'MyAccount/legacy_invoice',
106   'legacy_invoice_pdf'        => 'MyAccount/legacy_invoice_pdf',
107   'invoice_logo'              => 'MyAccount/invoice_logo',
108   'list_invoices'             => 'MyAccount/list_invoices', #?
109   'cancel'                    => 'MyAccount/cancel',        #add to ss cgi!
110   'payment_info'              => 'MyAccount/payment_info',
111   'payment_info_renew_info'   => 'MyAccount/payment_info_renew_info',
112   'process_payment'           => 'MyAccount/process_payment',
113   'store_payment'             => 'MyAccount/store_payment',
114   'process_stored_payment'    => 'MyAccount/process_stored_payment',
115   'process_payment_order_pkg' => 'MyAccount/process_payment_order_pkg',
116   'process_payment_change_pkg' => 'MyAccount/process_payment_change_pkg',
117   'process_payment_order_renew' => 'MyAccount/process_payment_order_renew',
118   'process_prepay'            => 'MyAccount/process_prepay',
119   'realtime_collect'          => 'MyAccount/realtime_collect',
120   'list_pkgs'                 => 'MyAccount/list_pkgs',     #add to ss (added?)
121   'list_svcs'                 => 'MyAccount/list_svcs',     #add to ss (added?)
122   'list_svc_usage'            => 'MyAccount/list_svc_usage',   
123   'svc_status_html'           => 'MyAccount/svc_status_html',
124   'acct_forward_info'         => 'MyAccount/acct_forward_info',
125   'process_acct_forward'      => 'MyAccount/process_acct_forward',
126   'list_dsl_devices'          => 'MyAccount/list_dsl_devices',   
127   'add_dsl_device'            => 'MyAccount/add_dsl_device',   
128   'delete_dsl_device'         => 'MyAccount/delete_dsl_device',   
129   'port_graph'                => 'MyAccount/port_graph',   
130   'list_cdr_usage'            => 'MyAccount/list_cdr_usage',   
131   'list_support_usage'        => 'MyAccount/list_support_usage',   
132   'order_pkg'                 => 'MyAccount/order_pkg',     #add to ss cgi!
133   'change_pkg'                => 'MyAccount/change_pkg', 
134   'order_recharge'            => 'MyAccount/order_recharge',
135   'renew_info'                => 'MyAccount/renew_info',
136   'order_renew'               => 'MyAccount/order_renew',
137   'cancel_pkg'                => 'MyAccount/cancel_pkg',    #add to ss cgi!
138   'suspend_pkg'               => 'MyAccount/suspend_pkg',   #add to ss cgi!
139   'charge'                    => 'MyAccount/charge',        #?
140   'part_svc_info'             => 'MyAccount/part_svc_info',
141   'provision_acct'            => 'MyAccount/provision_acct',
142   'provision_phone'           => 'MyAccount/provision_phone',
143   'provision_external'        => 'MyAccount/provision_external',
144   'unprovision_svc'           => 'MyAccount/unprovision_svc',
145   'myaccount_passwd'          => 'MyAccount/myaccount_passwd',
146   'reset_passwd'              => 'MyAccount/reset_passwd',
147   'check_reset_passwd'        => 'MyAccount/check_reset_passwd',
148   'process_reset_passwd'      => 'MyAccount/process_reset_passwd',
149   'create_ticket'             => 'MyAccount/create_ticket',
150   'get_ticket'                => 'MyAccount/get_ticket',
151   'adjust_ticket_priority'    => 'MyAccount/adjust_ticket_priority',
152   'did_report'                => 'MyAccount/did_report',
153   'signup_info'               => 'Signup/signup_info',
154   'skin_info'                 => 'MyAccount/skin_info',
155   'access_info'               => 'MyAccount/access_info',
156   'domain_select_hash'        => 'Signup/domain_select_hash',  # expose?
157   'new_customer'              => 'Signup/new_customer',
158   'capture_payment'           => 'Signup/capture_payment',
159   'clear_signup_cache'        => 'Signup/clear_cache',
160   'new_agent'                 => 'Agent/new_agent',
161   'agent_login'               => 'Agent/agent_login',
162   'agent_logout'              => 'Agent/agent_logout',
163   'agent_info'                => 'Agent/agent_info',
164   'agent_list_customers'      => 'Agent/agent_list_customers',
165   'check_username'            => 'Agent/check_username',
166   'suspend_username'          => 'Agent/suspend_username',
167   'unsuspend_username'        => 'Agent/unsuspend_username',
168   'mason_comp'                => 'MasonComponent/mason_comp',
169   'call_time'                 => 'PrepaidPhone/call_time',
170   'call_time_nanpa'           => 'PrepaidPhone/call_time_nanpa',
171   'phonenum_balance'          => 'PrepaidPhone/phonenum_balance',
172   #izoom
173   #'bulk_processrow'           => 'Bulk/processrow',
174   #conflicts w/Agentone# 'check_username'            => 'Bulk/check_username',
175   #sg
176   'ping'                      => 'SGNG/ping',
177   'decompify_pkgs'            => 'SGNG/decompify_pkgs',
178   'previous_payment_info'     => 'SGNG/previous_payment_info',
179   'previous_payment_info_renew_info'
180                               => 'SGNG/previous_payment_info_renew_info',
181   'previous_process_payment'  => 'SGNG/previous_process_payment',
182   'previous_process_payment_order_pkg'
183                               => 'SGNG/previous_process_payment_order_pkg',
184   'previous_process_payment_change_pkg'
185                               => 'SGNG/previous_process_payment_change_pkg',
186   'previous_process_payment_order_renew'
187                               => 'SGNG/previous_process_payment_order_renew',
188   };
189 }
190
191
192 #XXX submit patch to SOAP::Lite
193
194 use XMLRPC::Transport::HTTP;
195
196 package XMLRPC::Transport::HTTP::Server;
197
198 @XMLRPC::Transport::HTTP::Server::ISA = qw(SOAP::Transport::HTTP::Server);
199
200 sub initialize; *initialize = \&XMLRPC::Server::initialize;
201 sub make_fault; *make_fault = \&XMLRPC::Transport::HTTP::CGI::make_fault;
202 sub make_response; *make_response = \&XMLRPC::Transport::HTTP::CGI::make_response;
203
204 1;