File Coverage

blib/lib/Net/KashFlow.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Net::KashFlow;
2 1     1   23743 use Carp qw/croak/;
  1         2  
  1         58  
3 1     1   6 use warnings;
  1         1  
  1         25  
4 1     1   5 use strict;
  1         5  
  1         29  
5 1     1   6884 use Net::KashFlowAPI; # Autogenerated SOAP::Lite stubs
  0            
  0            
6              
7             =head1 NAME
8              
9             Net::KashFlow - Interact with KashFlow accounting web service
10              
11             =head1 SYNOPSIS
12              
13             my $kf = Net::KashFlow->new(username => $u, password => $p);
14              
15             my $c = $kf->get_customer($cust_email);
16             my $i = $kf->create_invoice({
17             InvoiceNumber => time, CustomerID => $c->CustomerID
18             });
19              
20             $i->add_line({ Quantity => 1, Description => "Widgets", Rate => 100 })
21              
22             $i->pay({ PayAmount => 100 });
23              
24             =head1 WARNING
25              
26             This module is incomplete. It does not implement all of the KashFlow
27             API. Please find the github repository at
28             http://github.com/simoncozens/Net-KashFlow and send me pull requests for
29             your newly-implemented features. Thank you.
30              
31             =head1 METHODS
32              
33             =head2 new
34              
35             Simple constructor - requires "username" and "password" named
36             parameters.
37              
38             =cut
39              
40             our $VERSION = '0.01';
41              
42             sub new {
43             my ($self, %args) = @_;
44             for (qw/username password/) {
45             croak("You need to pass a '$_'") unless $args{$_};
46             }
47             bless { %args }, $self;
48             }
49              
50             sub _c {
51             my ($self, $method, @args) = @_;
52             my ($result, $status, $explanation) =
53             KashFlowAPI->$method($self->{username}, $self->{password}, @args);
54             if ($explanation) { croak($explanation) }
55             return $result;
56             }
57              
58             =head2 get_customer($id | $email)
59              
60             Returns a Net::KashFlow::Customer object for the given customer. If the
61             parameter passed has an C<@> sign then this is treated as an email
62             address and the customer looked up email address; otherwise the
63             customer is looked up by customer code. If no customer is found in the
64             database, nothing is returned.
65              
66             =cut
67              
68             sub get_customer {
69             my ($self, $thing, $by_id) = @_;
70             my $method = "GetCustomer"; if ($thing =~ /@/) { $method.="ByEmail" }
71             if ($by_id) { $method.="ByID" }
72             my $customer;
73             eval { $customer = $self->_c($method, $thing) };
74             if ($@ =~ /no customer/) { return } die $@."\n" if $@;
75             $customer = bless $customer, "Net::KashFlow::Customer";
76             $customer->{kf} = $self;
77             return $customer;
78             }
79              
80             =head2 get_customer_by_id($internal_id)
81              
82             Like C, but works on the internal ID of the customer.
83              
84             =cut
85              
86             sub get_customer_by_id { $_[0]->get_customer($_[1], 1) }
87              
88             =head2 get_customers
89              
90             Returns all customers
91              
92             =cut
93              
94             sub get_customers {
95             my $self = shift;
96             return map { $_->{kf} = $self; bless $_, "Net::KashFlow::Customer" }
97             @{$self->_c("GetCustomers")->{Customer}};
98             }
99              
100             =head2 create_customer({ Name => "...", Address => "...", ... });
101              
102             Inserts a new customer into the database, returning a
103             Net::KashFlow::Customer object.
104              
105             =cut
106              
107             sub create_customer {
108             my ($self, $data) = @_;
109             my $id = $self->_c("InsertCustomer", $data);
110             return $self->get_customer_by_id($id);
111             }
112              
113             =head2 get_invoice($your_id)
114              
115             =head2 get_invoice_by_id($internal_id)
116              
117             Returns a Net::KashFlow::Invoice object representing the invoice.
118              
119             =cut
120              
121             sub get_invoice {
122             my ($self, $thing, $by_id) = @_;
123             my $method = "GetInvoice"; if ($by_id) { $method.="ByID" }
124             my $invoice;
125             eval { $invoice = $self->_c($method, $thing) };
126             if ($@ =~ /no invoice/) { return } die $@."\n" if $@;
127             $invoice = bless $invoice, "Net::KashFlow::Invoice";
128             $invoice->{kf} = $self;
129             $invoice->{Lines} = bless $invoice->{Lines}, "InvoiceLineSet"; # Urgh
130             return $invoice;
131             }
132             sub get_invoice_by_id { $_[0]->get_invoice($_[1], 1) }
133              
134             =head2 create_invoice({ ... })
135              
136             =cut
137              
138             sub create_invoice {
139             my ($self, $data) = @_;
140             my $id = $self->_c("InsertInvoice", $data);
141             return $self->get_invoice($id);
142             }
143              
144             package Net::KashFlow::Base;
145             use base 'Class::Accessor';
146              
147             sub update {
148             my $self = shift;
149             my $copy = { %$self }; delete $copy->{kf};
150             $self->{kf}->_c("Update".$self->_this(), $copy);
151             }
152              
153             sub delete {
154             my $self = shift;
155             my $copy = { %$self }; delete $copy->{kf};
156             $self->{kf}->_c("Delete".$self->_this(), $copy);
157             }
158              
159             package Net::KashFlow::Customer;
160              
161             =head1 Net::KashFlow::Customer
162              
163             my $c = $kf->get_customer($email);
164              
165             $c->Telephone("+44.500123456");
166             $c->update;
167              
168             print $c->Address1(), $c->Address2();
169              
170             Customer objects have accessors as specified by
171             C - these accessors
172             are not "live" in that changes to them are only sent to KashFlow on call
173             to the C method.
174              
175             This package also has a C method to remove the customer from the
176             database, and an C method which returns all the
177             C objects assigned to this customer.
178              
179             =cut
180              
181             use base 'Net::KashFlow::Base';
182             __PACKAGE__->mk_accessors(qw(
183             Contact Address2 ShowDiscount CheckBox1 EC OutsideEC PaymentTerms Discount
184             Postcode CheckBox2 Website ExtraText1 Source Email Notes ExtraText2 Mobile
185             Updated Telephone Code CustomerID Address1 Address4 Created Name Address3 Fax
186             ));
187             sub _this { "Customer" }
188              
189             sub invoices {
190             my $self = shift;
191             return map { $_->{kf} = $self->{kf};
192             $_->{Lines} = bless $_->{Lines}, "InvoiceLineSet"; # Urgh
193             bless $_, "Net::KashFlow::Invoice"
194             } @{$self->{kf}->_c("GetInvoicesForCustomer", $self->CustomerID)->{Invoice}};
195             }
196              
197             package Net::KashFlow::Invoice;
198             use base 'Net::KashFlow::Base';
199             sub _this { "Invoice" }
200             __PACKAGE__->mk_accessors(qw/
201             DueDate NetAmount ProjectID Lines CustomerReference InvoiceDate InvoiceNumber
202             SuppressTotal CustomerID Customer CurrencyCode ReadableString ExchangeRate
203             VATAmount AmountPaid Paid InvoiceDBID
204             /);
205              
206             =head1 Net::KashFlow::Invoice
207              
208             my @i = $kf->get_customer($email)->invoices;
209             for (@i) { $i->Paid(1); $i->update }
210              
211             Similarly to Customer, fields found at
212             http://accountingapi.com/manual_class_invoice.asp
213              
214             Also:
215              
216             $i->add_line({ Quantity => 1, Description => "Widgets", Rate => 100 });
217             $i->pay({ PayAmount => 100 });
218              
219             =cut
220              
221             sub add_line {
222             my ($self, $data) = @_;
223             $self->{kf}->_c("InsertInvoiceLine", $self->InvoiceDBID, $data );
224             }
225              
226             sub pay {
227             my ($self, $data) = @_;
228             $data->{PayInvoice} = $self->{InvoiceNumber};
229             $self->{kf}->_c("InsertInvoicePayment", $data );
230             }
231              
232             =head1 AUTHOR
233              
234             Simon Cozens, C<< >>
235              
236             =head1 BUGS
237              
238             Please report any bugs or feature requests to C, or through
239             the web interface at L. I will be notified, and then you'll
240             automatically be notified of progress on your bug as I make changes.
241              
242             I am aware that this module is WOEFULLY INCOMPLETE and I'm looking
243             forward to receiving patches to add new functionality to it. Currently
244             it does what I want and I don't have much incentive to finish it. :/
245              
246             =head1 SUPPORT
247              
248             You can find documentation for this module with the perldoc command.
249              
250             perldoc Net::KashFlow
251              
252              
253             You can also look for information at:
254              
255             =over 4
256              
257             =item * RT: CPAN's request tracker
258              
259             L
260              
261             =item * AnnoCPAN: Annotated CPAN documentation
262              
263             L
264              
265             =item * CPAN Ratings
266              
267             L
268              
269             =item * Search CPAN
270              
271             L
272              
273             =back
274              
275              
276             =head1 ACKNOWLEDGEMENTS
277              
278             Thanks to the UK Free Software Network (http://www.ukfsn.org/) for their
279             support of this module's development. For free-software-friendly hosting
280             and other Internet services, try UKFSN.
281              
282             =head1 COPYRIGHT & LICENSE
283              
284             Copyright 2009 Simon Cozens.
285              
286             This program is free software; you can redistribute it and/or modify it
287             under the terms of either: the GNU General Public License as published
288             by the Free Software Foundation; or the Artistic License.
289              
290             See http://dev.perl.org/licenses/ for more information.
291              
292             =cut
293              
294             1; # End of Net::KashFlow