#?
default_csv => $opt->{default_csv},
postinsert_callback => $opt->{postinsert_callback},
+ insert_args_callback => $opt->{insert_args_callback},
);
if ( $opt->{'batch_namecol'} ) {
my $preinsert_callback = '';
$preinsert_callback = $param->{'preinsert_callback'}
if $param->{'preinsert_callback'};
+ my $insert_args_callback = '';
+ $insert_args_callback = $param->{'insert_args_callback'}
+ if $param->{'insert_args_callback'};
if ( $param->{'format'} ) {
next if exists $param->{skiprow} && $param->{skiprow};
}
- my $error = $record->insert;
+ my @insert_args = ();
+ if ( $insert_args_callback ) {
+ @insert_args = &{$insert_args_callback}($record, $param);
+ }
+
+ my $error = $record->insert(@insert_args);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
'part_pkg' => {
'columns' => [
'pkgpart', 'serial', '', '', '', '',
+ 'pkgpartbatch', 'varchar', 'NULL', $char_d, '', '',
'pkg', 'varchar', '', $char_d, '', '',
'comment', 'varchar', 'NULL', 2*$char_d, '', '',
'promo_code', 'varchar', 'NULL', $char_d, '', '',
--- /dev/null
+package FS::part_pkg::Import;
+
+use strict;
+use FS::Record;
+use FS::part_pkg;
+
+=head1 NAME
+
+FS::part_pkg::Import - Batch customer importing
+
+=head1 SYNOPSIS
+
+ use FS::part_pkg::Import;
+
+ #ajax helper
+ use FS::UI::Web::JSRPC;
+ my $server =
+ new FS::UI::Web::JSRPC 'FS::part_pkg::Import::process_batch_import', $cgi;
+ print $server->process;
+
+=head1 DESCRIPTION
+
+Batch package definition importing.
+
+=head1 SUBROUTINES
+
+=item process_batch_import
+
+Load a batch import as a queued JSRPC job
+
+=cut
+
+sub process_batch_import {
+ my $job = shift;
+
+ my $opt = { 'table' => 'part_pkg',
+ 'params' => [qw( agentnum pkgpartbatch )],
+ 'formats' => { 'default' => [
+ 'agent_pkgpartid',
+ 'pkg',
+ 'comment',
+ 'freq',
+ 'plan',
+ 'setup_fee',
+ 'recur_fee',
+ 'setup_cost',
+ 'recur_cost',
+ 'classnum',
+ 'taxclass',
+ ],
+ },
+ 'insert_args_callback' => sub {
+ my $part_pkg = shift;
+ ( 'options' => { 'setup_fee' => $part_pkg->get('setup_fee'),
+ 'recur_fee' => $part_pkg->get('recur_fee'),
+ },
+ );
+ },
+ #'default_csv' => 1,
+ };
+
+ FS::Record::process_batch_import( $job, $opt, @_ );
+
+}
+
+=head1 BUGS
+
+Not enough documentation.
+
+=head1 SEE ALSO
+
+L<FS::cust_main>, L<FS::part_pkg>
+
+=cut
+
+1;
dbh->{'private_profile'} = {} if UNIVERSAL::can(dbh, 'sprintProfile');
#auto-use classes...
- if ( $ljob->job =~ /(FS::(part_export|cust_main|cust_pkg|Cron)::\w+)::/
+ if ( $ljob->job =~ /(FS::(part_export|cust_main|cust_pkg|part_pkg|Cron)::\w+)::/
|| $ljob->job =~ /(FS::\w+)::/
)
{
}
$cgi->delete('classnum');
+if ( $cgi->param('pkgpartbatch') =~ /^([\w\/\-\:\. ]+)$/ ) {
+ push @where, "pkgpartbatch = '$1' ";
+}
+
if ( $cgi->param('missing_recur_fee') ) {
push @where, "NOT EXISTS ( SELECT 1 FROM part_pkg_option
WHERE optionname = 'recur_fee'
if $curuser->access_right('Raw SQL');
tie my %tools_importing, 'Tie::IxHash',
- 'Customers' => [ $fsurl.'misc/cust_main-import.cgi', '' ],
- 'Customer packages' => [ $fsurl.'misc/cust_pkg-import.html', '' ],
- 'Customer comments' => [ $fsurl.'misc/cust_main_note-import.html', '' ],
- 'One-time charges' => [ $fsurl.'misc/cust_main-import_charges.cgi', '' ],
- 'Payments' => [ $fsurl.'misc/cust_pay-import.cgi', '' ],
- 'Credits' => [ $fsurl.'misc/cust_credit-import.html', '' ],
+ 'Customers' => [ $fsurl.'misc/cust_main-import.cgi', '' ],
+ 'Package definitions' => [ $fsurl.'misc/part_pkg-import.html', '' ],
+ 'Customer packages' => [ $fsurl.'misc/cust_pkg-import.html', '' ],
+ 'Customer comments' => [ $fsurl.'misc/cust_main_note-import.html', '' ],
+ 'One-time charges' => [ $fsurl.'misc/cust_main-import_charges.cgi', '' ],
+ 'Payments' => [ $fsurl.'misc/cust_pay-import.cgi', '' ],
+ 'Credits' => [ $fsurl.'misc/cust_credit-import.html', '' ],
'Phone numbers (DIDs)' => [ $fsurl.'misc/phone_avail-import.html', '' ],
'Call Detail Records (CDRs)' => [ $fsurl.'misc/cdr-import.html', '' ],
;
-<% include("/elements/header.html",'Batch Package Import') %>
+<& /elements/header.html, 'Customer package import' &>
-Import a file containing package records.
+Import a file containing customer packages.
<BR><BR>
<& /elements/form-file_upload.html,
'action' => 'process/cust_pkg-import.html',
'num_files' => 1,
'fields' => [ 'agentnum', 'pkgbatch', 'format' ],
- 'message' => 'Package import successful',
+ 'message' => 'Customer package import successful',
'url' => $p."search/cust_pkg.cgi?pkgbatch=$pkgbatch",
'onsubmit' => "document.PackageImportForm.submitButton.disabled=true;"
&>
<% &ntable("#cccccc", 2) %>
- <% include( '/elements/tr-select-agent.html',
- #'curr_value' => '', #$agentnum,
- 'label' => "<B>Agent</B>",
- 'empty_label' => 'Select agent',
- )
- %>
+ <& /elements/tr-select-agent.html,
+ #'curr_value' => '', #$agentnum,
+ 'label' => "<B>Agent</B>",
+ 'empty_label' => 'Select agent',
+ &>
<INPUT TYPE="hidden" NAME="pkgbatch" VALUE="<% $pkgbatch %>"%>
</TD>
</TR>
- <% include( '/elements/file-upload.html',
- 'field' => 'file',
- 'label' => 'Filename',
- )
- %>
+ <& /elements/file-upload.html,
+ 'field' => 'file',
+ 'label' => 'Filename',
+ &>
<TR>
<TD COLSPAN=2 ALIGN="center" STYLE="padding-top:6px">
<BR>
-<% include('/elements/footer.html') %>
+<& /elements/footer.html &>
<%once>
--- /dev/null
+<& /elements/header.html, 'Import package definitions' &>
+
+Import a file containing package definitions.
+<BR><BR>
+
+<& /elements/form-file_upload.html,
+ 'name' => 'PackageDefImportForm',
+ 'action' => 'process/part_pkg-import.html',
+ 'num_files' => 1,
+ 'fields' => [ 'agentnum', 'pkgpartbatch', 'format' ],
+ 'message' => 'Package definition import successful',
+ 'url' => $p."browse/part_pkg.cgi?pkgpartbatch=$pkgpartbatch",
+ 'onsubmit' => "document.PackageDefImportForm.submitButton.disabled=true;"
+&>
+
+<% &ntable("#cccccc", 2) %>
+
+ <& /elements/tr-select-agent.html,
+ #'curr_value' => '', #$agentnum,
+ 'label' => "<B>Agent</B>",
+
+ 'disable_empty' => 1,
+ #this doesn't work yet, no type_pkgs records are inserted
+ #'empty_label' => '(global)',
+
+ #disable_empty => ! $acl_edit_global,
+ &>
+
+
+ <INPUT TYPE="hidden" NAME="pkgpartbatch" VALUE="<% $pkgpartbatch %>"%>
+
+ <TR>
+ <TH ALIGN="right">Format</TH>
+ <TD>
+ <SELECT NAME="format">
+ <OPTION VALUE="default" SELECTED>Default
+ </SELECT>
+ </TD>
+ </TR>
+
+ <& /elements/file-upload.html,
+ 'field' => 'file',
+ 'label' => 'Filename',
+ &>
+
+ <TR>
+ <TD COLSPAN=2 ALIGN="center" STYLE="padding-top:6px">
+ <INPUT TYPE = "submit"
+ NAME = "submitButton"
+ ID = "submitButton"
+ VALUE = "Import file"
+ >
+ </TD>
+ </TR>
+
+</TABLE>
+
+</FORM>
+
+<BR>
+Uploaded files can be CSV (comma-separated value) files or Excel spreadsheets. The file should have a .CSV or .XLS extension.
+<BR><BR>
+
+<b>Default</b> format has the following field order: <i>agent_pkgpartid, pkg<%$req%>, comment<%$req%>, freq<%$req%>, plan<%$req%>, setup_fee<%$req%>, recur_fee<%$req%>, setup_cost, recur_cost, classnum, taxclass
+</i>
+<BR><BR>
+
+<%$req%> Required fields
+<BR><BR>
+
+Field information:
+
+<ul>
+
+ <li><i>agent_pkgpartid</i>: Current product ID or code
+
+ <li><i>pkg</i>: Package name (customer-visible)
+
+ <li><i>comment</i>: Package comment (customer-hidden)
+
+ <li><i>freq</i>: Recurring fee frequency - 0 for one-time charges, a number of months (i.e. 1 for months, 12 for yearly), or a number followed by h, d or w for hours, days or weeks.
+
+ <li><i>plan</i>: Price plan, i.e. flat, prorate, voip_cdr, etc.
+
+ <li><i>setup_fee</i>: Setup price
+
+ <li><i>recur_fee</i>: Recurring price
+
+ <li><i>setup_cost</i>: Setup cost
+
+ <li><i>recur_cost</i>: Recurring cost
+
+ <li><i>classnum</i>: Package class (integer)
+
+ <li><i>taxclass</i>: Tax class (string)
+
+</ul>
+
+<BR>
+
+<& /elements/footer.html &>
+
+<%once>
+
+my $req = qq!<font color="#ff0000">*</font>!;
+
+</%once>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Import');
+
+my $pkgpartbatch =
+ time2str('webimport-%Y/%m/%d-%T'. "-$$-". rand() * 2**32, time);
+
+</%init>
--- /dev/null
+<% $server->process %>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Import');
+
+my $server =
+ new FS::UI::Web::JSRPC 'FS::part_pkg::Import::process_batch_import', $cgi;
+
+</%init>