diff options
author | Mark Wells <mark@freeside.biz> | 2015-04-25 15:02:15 -0700 |
---|---|---|
committer | Mark Wells <mark@freeside.biz> | 2015-04-25 15:02:23 -0700 |
commit | c110da0da864245e47cae019b8a347367cc6430c (patch) | |
tree | e406be890446095b8cd59a5b5c827c62dd063fff /FS/FS/ClientAPI/MyAccount | |
parent | 4fda726fa9f8e709c68ec823edc5ae702723281c (diff) |
selfservice quotations, #33852
Diffstat (limited to 'FS/FS/ClientAPI/MyAccount')
-rw-r--r-- | FS/FS/ClientAPI/MyAccount/quotation.pm | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/FS/FS/ClientAPI/MyAccount/quotation.pm b/FS/FS/ClientAPI/MyAccount/quotation.pm new file mode 100644 index 0000000..ce2debd --- /dev/null +++ b/FS/FS/ClientAPI/MyAccount/quotation.pm @@ -0,0 +1,218 @@ +package FS::ClientAPI::MyAccount::quotation; + +use strict; +use FS::Record qw(qsearch qsearchs); +use FS::quotation; +use FS::quotation_pkg; + +our $DEBUG = 1; + +sub _custoragent_session_custnum { + FS::ClientAPI::MyAccount::_custoragent_session_custnum(@_); +} + +sub _quotation { + # the currently active quotation + my $session = shift; + my $quotation; + if ( my $quotationnum = $session->{'quotationnum'} ) { + $quotation = FS::quotation->by_key($quotationnum); + } + if ( !$quotation ) { + # find the last quotation created through selfservice + $quotation = qsearchs( 'quotation', { + 'custnum' => $session->{'custnum'}, + 'usernum' => $FS::CurrentUser::CurrentUser->usernum, + 'disabled' => '', + }); + warn "found selfservice quotation #". $quotation->quotationnum."\n" + if $quotation and $DEBUG; + } + if ( !$quotation ) { + $quotation = FS::quotation->new({ + 'custnum' => $session->{'custnum'}, + 'usernum' => $FS::CurrentUser::CurrentUser->usernum, + '_date' => time, + }); + $quotation->insert; # what to do on error? call the police? + warn "started new selfservice quotation #". $quotation->quotationnum."\n" + if $quotation and $DEBUG; + } + $session->{'quotationnum'} = $quotation->quotationnum; + return $quotation; +} + +=item quotation_info { session } + +Returns a hashref describing the current quotation, containing: + +- "sections", an arrayref containing one section for each billing frequency. + Each one will have: + - "description" + - "subtotal" + - "detail_items", an arrayref of detail items, each with: + - "pkgnum", the reference number (actually the quotationpkgnum field) + - "description", the package name (or tax name) + - "quantity" + - "amount" + +=cut + +sub quotation_info { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $quotation = _quotation($session); + return { 'error' => "No current quotation for this customer" } if !$quotation; + warn "quotation_info #".$quotation->quotationnum + if $DEBUG; + + # code reuse ftw + my $null_escape = sub { @_ }; + my ($sections) = $quotation->_items_sections(escape => $null_escape); + foreach my $section (@$sections) { + $section->{'detail_items'} = + [ $quotation->_items_pkg('section' => $section, escape_function => $null_escape) ]; + } + return { 'error' => '', 'sections' => $sections } +} + +=item quotation_print { session, 'format' } + +Renders the quotation. 'format' can be either 'html' or 'pdf'; the resulting +hashref will contain 'document' => the HTML or PDF contents. + +=cut + +sub quotation_print { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $quotation = _quotation($session); + return { 'error' => "No current quotation for this customer" } if !$quotation; + warn "quotation_print #".$quotation->quotationnum + if $DEBUG; + + my $format = $p->{'format'} + or return { 'error' => "No rendering format specified" }; + + my $document; + if ($format eq 'html') { + $document = $quotation->print_html; + } elsif ($format eq 'pdf') { + $document = $quotation->print_pdf; + } + warn "$format, ".length($document)." bytes\n" + if $DEBUG; + return { 'error' => '', 'document' => $document }; +} + +=item quotation_add_pkg { session, 'pkgpart', 'quantity', [ location opts ] } + +Adds a package to the user's current quotation. Session info and 'pkgpart' are +required. 'quantity' defaults to 1. + +Location can be specified as 'locationnum' to use an existing location, or +'address1', 'address2', 'city', 'state', 'zip', 'country' to create a new one, +or it will default to the customer's service location. + +=cut + +sub quotation_add_pkg { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $quotation = _quotation($session); + my $cust_main = $quotation->cust_main; + + my $pkgpart = $p->{'pkgpart'}; + my $allowed_pkgpart = $cust_main->agent->pkgpart_hashref; + + my $part_pkg = FS::part_pkg->by_key($pkgpart); + + if (!$part_pkg or !$allowed_pkgpart->{$pkgpart}) { + warn "disallowed quotation_pkg pkgpart $pkgpart\n" + if $DEBUG; + return { 'error' => "unknown package $pkgpart" }; + } + + warn "creating quotation_pkg with pkgpart $pkgpart\n" + if $DEBUG; + my $quotation_pkg = FS::quotation_pkg->new({ + 'quotationnum' => $quotation->quotationnum, + 'pkgpart' => $p->{'pkgpart'}, + 'quantity' => $p->{'quantity'} || 1, + }); + if ( $p->{locationnum} > 0 ) { + $quotation_pkg->set('locationnum', $p->{locationnum}); + } elsif ( $p->{address1} ) { + my $location = FS::cust_location->find_or_insert( + 'custnum' => $cust_main->custnum, + map { $_ => $p->{$_} } + qw( address1 address2 city county state zip country ) + ); + $quotation_pkg->set('locationnum', $location->locationnum); + } + + my $error = $quotation_pkg->insert + || $quotation->estimate; + + { 'error' => $error, + 'quotationnum' => $quotation->quotationnum }; +} + +=item quotation_remove_pkg { session, 'pkgnum' } + +Removes the package from the user's current quotation. 'pkgnum' is required. + +=cut + +sub quotation_remove_pkg { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $quotation = _quotation($session); + my $quotationpkgnum = $p->{pkgnum}; + my $quotation_pkg = FS::quotation_pkg->by_key($quotationpkgnum); + if (!$quotation_pkg + or $quotation_pkg->quotationnum != $quotation->quotationnum) { + return { 'error' => "unknown quotation item $quotationpkgnum" }; + } + warn "removing quotation_pkg with pkgpart ".$quotation_pkg->pkgpart."\n" + if $DEBUG; + + my $error = $quotation_pkg->delete + || $quotation->estimate; + + { 'error' => $error, + 'quotationnum' => $quotation->quotationnum }; +} + +=item quotation_order + +Convert the current quotation to a package order. + +=cut + +sub quotation_order { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $quotation = _quotation($session); + + my $error = $quotation->order; + + return { 'error' => $error }; +} + +1; |