From cb0c47fff7f412d2a8f9ae611f84584fcf8518de Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 11 Oct 2012 15:57:39 -0700 Subject: fix overage billing with multiple exports? RT#19595 --- FS/FS/part_svc.pm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm index 7f22411e0..c47177171 100644 --- a/FS/FS/part_svc.pm +++ b/FS/FS/part_svc.pm @@ -441,9 +441,10 @@ sub part_export { my $self = shift; my %search; $search{'exporttype'} = shift if @_; - sort { $a->weight <=> $b->weight } - map { qsearchs('part_export', { 'exportnum' => $_->exportnum, %search } ) } - qsearch('export_svc', { 'svcpart' => $self->svcpart } ); + map { $_ } #behavior of sort undefined in scalar context + sort { $a->weight <=> $b->weight } + map { qsearchs('part_export', { 'exportnum'=>$_->exportnum, %search } ) } + qsearch('export_svc', { 'svcpart'=>$self->svcpart } ); } =item part_export_usage -- cgit v1.2.1 From 47ab335f71ebed3cc69f8a6604979798f917b91b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 11 Oct 2012 21:14:41 -0700 Subject: better debugging for errors removing credits requiring charging of previously-exempt texas tax, RT#19870 --- FS/FS/cust_credit_bill_pkg.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cust_credit_bill_pkg.pm b/FS/FS/cust_credit_bill_pkg.pm index 418900785..7427d09ab 100644 --- a/FS/FS/cust_credit_bill_pkg.pm +++ b/FS/FS/cust_credit_bill_pkg.pm @@ -277,7 +277,7 @@ sub delete { $sum = sprintf("%.2f", $sum); unless ($sum eq '0.00' || $sum eq '-0.00') { $dbh->rollback if $oldAutoCommit; - return "Can't unapply credit without charging tax"; + return "Can't unapply credit without charging tax of $sum"; } } -- cgit v1.2.1 From 6aacceec826a2d835af0ea8759924a83256d3ebe Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 18 Oct 2012 12:59:42 -0700 Subject: add modification command to broadband_shellcommands export, RT#19897 --- FS/FS/part_export/broadband_shellcommands.pm | 76 +++++++++++++++++++--------- 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/FS/FS/part_export/broadband_shellcommands.pm b/FS/FS/part_export/broadband_shellcommands.pm index cf9c36c8f..b57267ec5 100644 --- a/FS/FS/part_export/broadband_shellcommands.pm +++ b/FS/FS/part_export/broadband_shellcommands.pm @@ -8,21 +8,26 @@ use FS::part_export; @ISA = qw(FS::part_export); tie my %options, 'Tie::IxHash', - 'user' => { label=>'Remote username', default=>'freeside' }, - 'insert' => { label=>'Insert command', - default=>'php provision.php --mac=$mac_addr --plan=$plan_id --account=active', - }, - 'delete' => { label=>'Delete command', - default=>'', - }, - 'suspend' => { label=>'Suspension command', - default=>'php provision.php --mac=$mac_addr --plan=$plan_id --account=suspend', - }, - 'unsuspend'=> { label=>'Unsuspension command', - default=>'', - }, - 'uppercase_mac' => { label => 'Force MACs to uppercase', - type => 'checkbox', } + 'user' => { label => 'Remote username', + default => 'freeside' }, + 'insert' => { label => 'Insert command', + default => 'php provision.php --mac=$mac_addr --plan=$plan_id --account=active', + }, + 'delete' => { label => 'Delete command', + default => '', + }, + 'replace' => { label => 'Modification command', + default => '', + }, + 'suspend' => { label => 'Suspension command', + default => 'php provision.php --mac=$mac_addr --plan=$plan_id --account=suspend', + }, + 'unsuspend' => { label => 'Unsuspension command', + default => '', + }, + 'uppercase_mac' => { label => 'Force MACs to uppercase', + type => 'checkbox', + } ; %info = ( @@ -30,6 +35,10 @@ tie my %options, 'Tie::IxHash', 'desc' => 'Run remote commands via SSH, for svc_broadband services', 'options' => \%options, 'notes' => <<'END' +Run remote commands via SSH, for broadband services. +

+All fields in svc_broadband are available for interpolation (prefixed with +new_ or old_ for replace operations). END ); @@ -61,28 +70,49 @@ sub _export_command { my $command = $self->option($action); return '' if $command =~ /^\s*$/; - #set variable for the command + #set variables for the command no strict 'vars'; { no strict 'refs'; ${$_} = $svc_broadband->getfield($_) foreach $svc_broadband->fields; } - if ( $self->option('uppercase_mac') ) { - $mac_addr = uc $mac_addr; - } + $mac_addr = uc $mac_addr + if $self->option('uppercase_mac'); #done setting variables for the command $self->shellcommands_queue( $svc_broadband->svcnum, - user => $self->option('user')||'root', - host => $self->machine, - command => eval(qq("$command")), + user => $self->option('user')||'root', + host => $self->machine, + command => eval(qq("$command")), ); } sub _export_replace { - ''; + my($self, $new, $old ) = (shift, shift, shift); + my $command = $self->option('replace'); + + #set variable for the command + no strict 'vars'; + { + no strict 'refs'; + ${"old_$_"} = $old->getfield($_) foreach $old->fields; + ${"new_$_"} = $new->getfield($_) foreach $new->fields; + } + + if ( $self->option('uppercase_mac') ) { + $old_mac_addr = uc $old_mac_addr; + $new_mac_addr = uc $new_mac_addr; + } + + #done setting variables for the command + + $self->shellcommands_queue( $new->svcnum, + user => $self->option('user')||'root', + host => $self->machine, + command => eval(qq("$command")), + ); } #a good idea to queue anything that could fail or take any time -- cgit v1.2.1 From 86133956e12ec229b3a80272364d10e5081d3574 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 19 Oct 2012 09:55:49 -0700 Subject: longer lastdata column, for FreeSwitch, RT#19955 --- FS/FS/Schema.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index fb1f1d69b..4832dd2f6 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3249,7 +3249,7 @@ sub tables_hashref { 'channel', 'varchar', '', $char_d, \"''", '', 'dstchannel', 'varchar', '', $char_d, \"''", '', 'lastapp', 'varchar', '', $char_d, \"''", '', - 'lastdata', 'varchar', '', $char_d, \"''", '', + 'lastdata', 'varchar', '', 255, \"''", '', #currently only opensips 'src_ip_addr', 'varchar', 'NULL', 15, '', '', -- cgit v1.2.1 From a056cbfc08fa8491aa3c995d7053ed4574b18c50 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 19 Oct 2012 12:50:55 -0700 Subject: fix typo --- FS/FS/cust_bill_pkg.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index 20c8e5a55..15750b255 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -894,7 +894,7 @@ sub paid_sql { my $paid = "( SELECT COALESCE(SUM(cust_bill_pay_pkg.amount),0) FROM cust_bill_pay_pkg JOIN cust_bill_pay USING (billpaynum) WHERE cust_bill_pay_pkg.billpkgnum = cust_bill_pkg.billpkgnum - $s $e$setuprecur )"; + $s $e $setuprecur )"; if ( $opt{no_usage} ) { # cap the amount paid at the sum of non-usage charges, -- cgit v1.2.1 From 744b17e5c9a5de68ad8a24b7a35449b535f02731 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 19 Oct 2012 12:51:06 -0700 Subject: recurring indicator for Paymentech batches, #19571 --- FS/FS/Conf.pm | 2 +- FS/FS/cust_main/Billing_Realtime.pm | 11 ++--------- FS/FS/pay_batch/paymentech.pm | 12 ++++++++++-- FS/FS/payinfo_Mixin.pm | 25 +++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 5c43b3ac9..d8fd54514 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -3601,7 +3601,7 @@ and customer address. Include units.', { 'key' => 'batchconfig-paymentech', 'section' => 'billing', - 'description' => 'Configuration for Chase Paymentech batching, five lines: 1. BIN, 2. Terminal ID, 3. Merchant ID, 4. Username, 5. Password (for batch uploads)', + 'description' => 'Configuration for Chase Paymentech batching, six lines: 1. BIN, 2. Terminal ID, 3. Merchant ID, 4. Username, 5. Password (for batch uploads), 6. Flag to send recurring indicator.', 'type' => 'textarea', }, diff --git a/FS/FS/cust_main/Billing_Realtime.pm b/FS/FS/cust_main/Billing_Realtime.pm index f9f90a7dc..c2f2ac57f 100644 --- a/FS/FS/cust_main/Billing_Realtime.pm +++ b/FS/FS/cust_main/Billing_Realtime.pm @@ -170,15 +170,8 @@ sub _bop_recurring_billing { } else { - my %hash = ( 'custnum' => $self->custnum, - 'payby' => 'CARD', - ); - - return 1 - if qsearch('cust_pay', { %hash, 'payinfo' => $opt{'payinfo'} } ) - || qsearch('cust_pay', { %hash, 'paymask' => $self->mask_payinfo('CARD', - $opt{'payinfo'} ) - } ); + # return 1 if the payinfo has been used for another payment + return $self->payinfo_used($opt{'payinfo'}); # in payinfo_Mixin } diff --git a/FS/FS/pay_batch/paymentech.pm b/FS/FS/pay_batch/paymentech.pm index 2ac5a6624..133f8f1ce 100644 --- a/FS/FS/pay_batch/paymentech.pm +++ b/FS/FS/pay_batch/paymentech.pm @@ -10,7 +10,7 @@ use Tie::IxHash; use FS::Conf; my $conf; -my ($bin, $merchantID, $terminalID, $username); +my ($bin, $merchantID, $terminalID, $username, $password, $with_recurringInd); $name = 'paymentech'; my $gateway; @@ -80,7 +80,7 @@ my %paytype = ( eval "use XML::Writer"; die $@ if $@; my $conf = shift; - ($bin, $terminalID, $merchantID, $username) = + ($bin, $terminalID, $merchantID, $username, $password, $with_recurringInd) = $conf->config('batchconfig-paymentech'); }, # Here we do all the work in the header function. @@ -99,6 +99,7 @@ my %paytype = ( foreach (@cust_pay_batch) { $xml->startTag('newOrder', BatchRequestNo => $count++); + my $status = $_->cust_main->status; tie my %order, 'Tie::IxHash', ( industryType => 'EC', transType => 'AC', @@ -124,6 +125,13 @@ my %paytype = ( orderID => $_->paybatchnum, amount => $_->amount * 100, ); + # only do this if recurringInd is enabled in config, + # and the customer has at least one non-canceled recurring package + if ( $with_recurringInd and $status =~ /^active|suspended|ordered$/ ) { + # then send RF if this is the first payment on this payinfo, + # RS otherwise. + $order{'recurringInd'} = $_->payinfo_used ? 'RS' : 'RF'; + } foreach my $key (keys %order) { $xml->dataElement($key, $order{$key}) } diff --git a/FS/FS/payinfo_Mixin.pm b/FS/FS/payinfo_Mixin.pm index d03391f68..7b713efd3 100644 --- a/FS/FS/payinfo_Mixin.pm +++ b/FS/FS/payinfo_Mixin.pm @@ -3,6 +3,7 @@ package FS::payinfo_Mixin; use strict; use Business::CreditCard; use FS::payby; +use FS::Record qw(qsearch); =head1 NAME @@ -267,6 +268,30 @@ sub payby_payinfo_pretty { } } +=item payinfo_used [ PAYINFO ] + +Returns 1 if there's an existing payment using this payinfo. This can be +used to set the 'recurring payment' flag required by some processors. + +=cut + +sub payinfo_used { + my $self = shift; + my $payinfo = shift || $self->payinfo; + my %hash = ( + 'custnum' => $self->custnum, + 'payby' => 'CARD', + ); + + return 1 + if qsearch('cust_pay', { %hash, 'payinfo' => $payinfo } ) + || qsearch('cust_pay', + { %hash, 'paymask' => $self->mask_payinfo('CARD', $payinfo) } ) + ; + + return 0; +} + =back =head1 BUGS -- cgit v1.2.1 From 0f3edcfc6b841251c08742a607d4fbaa1769baea Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 19 Oct 2012 14:08:27 -0700 Subject: option to omit $0 CDRs, RT#19917 --- FS/FS/part_pkg/voip_cdr.pm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 8c3d80d49..28d503883 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -229,6 +229,10 @@ tie my %unrateable_opts, 'Tie::IxHash', }, #eofalse + 'usage_nozero' => { 'name' => 'Omit details for included / no-charge calls.', + 'type' => 'checkbox', + }, + 'bill_every_call' => { 'name' => 'Generate an invoice immediately for every call (as well any setup fee, upon first payment). Useful for prepaid.', 'type' => 'checkbox', }, @@ -358,6 +362,8 @@ sub calc_usage { : 'default' ); + my $usage_nozero = $self->option->('usage_nozero', 1); + my $formatter = FS::detail_format->new($output_format, buffer => $details); my $use_duration = $self->option('use_duration'); @@ -441,7 +447,7 @@ sub calc_usage { $error = $cdr->set_status('done'); } die $error if $error; - $formatter->append($cdr); + $formatter->append($cdr) unless $usage_nozero && $cdr->rated_price == 0; $cdr_search->adjust(1) if $cdr->freesidestatus eq 'rated'; } #$cdr -- cgit v1.2.1 From f5c484dc3879f7e2e5eecca5614cf7236594ba1a Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 20 Oct 2012 03:31:00 -0700 Subject: pass currency flag with voids and refunds too, for Canadian Moneris, RT#18684 --- FS/FS/cust_main/Billing_Realtime.pm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FS/FS/cust_main/Billing_Realtime.pm b/FS/FS/cust_main/Billing_Realtime.pm index f9f90a7dc..ad2bdf98f 100644 --- a/FS/FS/cust_main/Billing_Realtime.pm +++ b/FS/FS/cust_main/Billing_Realtime.pm @@ -1444,6 +1444,10 @@ sub realtime_refund_bop { if length($auth); #echeck/ACH transactions have an order # but no auth #(at least with authorize.net) + my $currency = $conf->exists('business-onlinepayment-currency') + && $conf->config('business-onlinepayment-currency'); + $content{currency} = $currency if $currency; + my $disable_void_after; if ($conf->exists('disable_void_after') && $conf->config('disable_void_after') =~ /^(\d+)$/) { -- cgit v1.2.1 From cb51da1d9c3e75e1319705a5a2ed2d881c986ec4 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 20 Oct 2012 03:31:35 -0700 Subject: FS/FS/part_export/freeswitch_multifile.pm --- FS/FS/part_export/freeswitch_multifile.pm | 180 ++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 FS/FS/part_export/freeswitch_multifile.pm diff --git a/FS/FS/part_export/freeswitch_multifile.pm b/FS/FS/part_export/freeswitch_multifile.pm new file mode 100644 index 000000000..105ff02e1 --- /dev/null +++ b/FS/FS/part_export/freeswitch_multifile.pm @@ -0,0 +1,180 @@ +package FS::part_export::freeswitch_multifile; +use base qw( FS::part_export ); + +use vars qw( %info ); # $DEBUG ); +#use Data::Dumper; +use Tie::IxHash; +use Text::Template; +#use FS::Record qw( qsearch qsearchs ); +#use FS::Schema qw( dbdef ); + +#$DEBUG = 1; + +tie my %options, 'Tie::IxHash', + 'user' => { label => 'SSH username', default=>'root', }, + 'directory' => { label => 'Directory to store FreeSWITCH account XML files', + default => '/usr/local/freeswitch/conf/directory/', + }, + 'domain' => { label => 'Optional fixed SIP domain to use, overrides svc_phone domain', }, + 'reload' => { label => 'Reload command', + default => '/usr/local/freeswitch/bin/fs_cli -x reloadxml', + }, + 'user_template' => { label => 'User XML configuration template', + type => 'textarea', + default => <<'END', + + + + + + + +END + }, +; + +%info = ( + 'svc' => 'svc_phone', + 'desc' => 'Provision phone services to FreeSWITCH XML configuration files (one file per user)', + 'options' => \%options, + 'notes' => <<'END', +Export XML account configuration files to FreeSWITCH, one per phone services. +

+You will need to +setup SSH for unattended operation. +END +); + +sub rebless { shift; } + +sub _export_insert { + my( $self, $svc_phone ) = ( shift, shift ); + + eval "use Net::SCP;"; + die $@ if $@; + + #create and copy over file + + my $tempdir = '%%%FREESIDE_CONF%%%/cache.'. $FS::UID::datasrc; + + my $svcnum = $svc_phone->svcnum; + + my $fh = new File::Temp( + TEMPLATE => "$tempdir/freeswitch.$svcnum.XXXXXXXX", + DIR => $tempdir, + #UNLINK => 0, + ); + + print $fh $self->freeswitch_template_fillin( $svc_phone, 'user' ) + or die "print to freeswitch template failed: $!"; + close $fh; + + my $scp = new Net::SCP; + my $user = $self->option('user')||'root'; + my $host = $self->machine; + my $dir = $self->option('directory'); + + $scp->scp( $fh->filename, "$user\@$host:$dir/$svcnum.xml" ) + or return $scp->{errstr}; + + #signal freeswitch to reload config + $self->freeswitch_ssh( command => $self->option('reload') ); + + ''; + +} + +sub _export_replace { + my( $self, $new, $old ) = ( shift, shift, shift ); + + $self->_export_insert($new, @_); +} + +sub _export_delete { + my( $self, $svc_phone ) = ( shift, shift ); + + my $dir = $self->option('directory'); + my $svcnum = $svc_phone->svcnum; + + #delete file + $self->freeswitch_ssh( command => "rm $dir/$svcnum.xml" ); + + #signal freeswitch to reload config + $self->freeswitch_ssh( command => $self->option('reload') ); + + ''; +} + +sub freeswitch_template_fillin { + my( $self, $svc_phone, $template ) = (shift, shift, shift); + + $template ||= 'user'; #? + + #cache a %tt hash? + my $tt = new Text::Template ( + TYPE => 'STRING', + SOURCE => $self->option($template.'_template'), + DELIMITERS => [ '<%', '%>' ], + ); + + my $domain = $self->option('domain') + || $svc_phone->domain + || '$${sip_profile}'; + + #false lazinessish w/phone_shellcommands::_export_command + my %hash = ( + 'domain' => $domain, + map { $_ => $svc_phone->getfield($_) } $svc_phone->fields + ); + + #might as well do em all, they're all going in an XML file as attribs + foreach ( keys %hash ) { + $hash{$_} =~ s/'/'/g; + $hash{$_} =~ s/"/"/g; + } + + $tt->fill_in( + HASH => \%hash, + ); +} + +##a good idea to queue anything that could fail or take any time +#sub shellcommands_queue { +# my( $self, $svcnum ) = (shift, shift); +# my $queue = new FS::queue { +# 'svcnum' => $svcnum, +# 'job' => "FS::part_export::freeswitch::ssh_cmd", +# }; +# $queue->insert( @_ ); +#} + +sub freeswitch_ssh { #method + my $self = shift; + ssh_cmd( user => $self->option('user')||'root', + host => $self->machine, + @_, + ); +} + +sub ssh_cmd { #subroutine, not method + use Net::OpenSSH; + my $opt = { @_ }; + open my $def_in, '<', '/dev/null' or die "unable to open /dev/null"; + my $ssh = Net::OpenSSH->new( $opt->{'user'}.'@'.$opt->{'host'}, + default_stdin_fh => $def_in, + ); + die "Couldn't establish SSH connection: ". $ssh->error if $ssh->error; + my ($output, $errput) = $ssh->capture2( #{stdin_discard => 1}, + $opt->{'command'} + ); + die "Error running SSH command: ". $ssh->error if $ssh->error; + + #who the fuck knows what freeswitch reload outputs, probably a fucking + # ascii advertisement for cluecon + #die $errput if $errput; + #die $output if $output; + + ''; +} + +1; -- cgit v1.2.1 From eccc8de2366e2e004a37761b8da2b447ec861ecb Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sat, 27 Oct 2012 14:24:00 -0700 Subject: ICS invoice spool format and email delivery, #17620 --- FS/FS/Conf.pm | 8 + FS/FS/Cron/upload.pm | 153 ++++++++++---- FS/FS/Mason.pm | 2 +- FS/FS/Misc/Invoicing.pm | 2 +- FS/FS/Schema.pm | 11 +- FS/FS/cust_bill.pm | 144 +++++++++++-- FS/FS/ftp_target.pm | 194 ----------------- FS/FS/part_event/Action/cust_bill_spool_csv.pm | 9 +- FS/FS/upload_target.pm | 282 +++++++++++++++++++++++++ FS/MANIFEST | 4 +- FS/t/ftp_target.t | 5 - FS/t/upload_target.t | 5 + httemplate/browse/ftp_target.html | 56 ----- httemplate/browse/upload_target.html | 49 +++++ httemplate/edit/ftp_target.html | 46 ---- httemplate/edit/process/ftp_target.html | 12 -- httemplate/edit/process/upload_target.html | 25 +++ httemplate/edit/upload_target.html | 82 +++++++ httemplate/elements/menu.html | 2 +- 19 files changed, 714 insertions(+), 377 deletions(-) delete mode 100644 FS/FS/ftp_target.pm create mode 100644 FS/FS/upload_target.pm delete mode 100644 FS/t/ftp_target.t create mode 100644 FS/t/upload_target.t delete mode 100644 httemplate/browse/ftp_target.html create mode 100644 httemplate/browse/upload_target.html delete mode 100755 httemplate/edit/ftp_target.html delete mode 100644 httemplate/edit/process/ftp_target.html create mode 100644 httemplate/edit/process/upload_target.html create mode 100755 httemplate/edit/upload_target.html diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index d8fd54514..c9f30fe6e 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -3219,6 +3219,14 @@ and customer address. Include units.', 'per_agent' => 1, }, + { + 'key' => 'ics-confirm_template', + 'section' => '', + 'description' => 'Confirmation email template for uploading to ICS invoice printing. Text::Template format, with variables "%count" and "%sum".', + 'type' => 'textarea', + 'per_agent' => 1, + }, + { 'key' => 'svc_acct-usage_suspend', 'section' => 'billing', diff --git a/FS/FS/Cron/upload.pm b/FS/FS/Cron/upload.pm index 51e0d6868..a9094c0b0 100644 --- a/FS/FS/Cron/upload.pm +++ b/FS/FS/Cron/upload.pm @@ -10,12 +10,13 @@ use FS::Conf; use FS::queue; use FS::agent; use FS::Misc qw( send_email ); #for bridgestone -use FS::ftp_target; +use FS::upload_target; use LWP::UserAgent; use HTTP::Request; use HTTP::Request::Common; use HTTP::Response; use Net::FTP; +use List::Util qw( sum ); @ISA = qw( Exporter ); @EXPORT_OK = qw ( upload ); @@ -58,7 +59,7 @@ sub upload { my @agentnums = ('', map {$_->agentnum} @agents); - foreach my $target (qsearch('ftp_target', {})) { + foreach my $target (qsearch('upload_target', {})) { # We don't know here if it's spooled on a per-agent basis or not. # (It could even be both, via different events.) So queue up an # upload for each agent, plus one with null agentnum, and we'll @@ -241,7 +242,7 @@ sub spool_upload { else { #not billco my $targetnum = $opt{targetnum}; - my $ftp_target = FS::ftp_target->by_key($targetnum) + my $upload_target = FS::upload_target->by_key($targetnum) or die "FTP target $targetnum not found\n"; $dir .= "/target$targetnum"; @@ -316,49 +317,82 @@ sub spool_upload { warn "compressing to $zipfile\n$command\n" if $DEBUG; system($command) and die "$command failed\n"; - my $connection = $ftp_target->connect; # dies on error - $connection->put($zipfile); - - my $template = join("\n",$conf->config('bridgestone-confirm_template')); - if ( $template ) { - my $tmpl_obj = Text::Template->new( - TYPE => 'STRING', SOURCE => $template - ); - my $content = $tmpl_obj->fill_in( HASH => - { - zipfile => $zipfile, - prefix => $prefix, - seq => $seq, - rows => $rows, - } - ); - my ($head, $body) = split("\n\n", $content, 2); - $head =~ /^subject:\s*(.*)$/im; - my $subject = $1; - - $head =~ /^to:\s*(.*)$/im; - my $to = $1; - - send_email( - to => $to, - from => $conf->config('invoice_from', $agentnum), - subject => $subject, - body => $body, - ); - } else { #!$template - warn "$me agent $agentnum has no bridgestone-confirm_template, no email sent\n"; - } + my $error = $upload_target->put($zipfile); + die $error if $error; + + send_report('bridgestone-confirm_template', + { + agentnum=> $agentnum, + zipfile => $zipfile, + prefix => $prefix, + seq => $seq, + rows => $rows, + } + ); $seq++; warn "setting batch counter to $seq\n" if $DEBUG; $conf->set('bridgestone-batch_counter', $seq, $agentnum); - } else { # not bridgestone + } elsif ( $opt{'handling'} eq 'ics' ) { + + my ($basename, $regfile, $bigfile); + $basename = sprintf('c%sc1', time2str('%m%d', time)); + $regfile = $basename . 'i.txt'; # for "regular" (short) invoices + $bigfile = $basename . 'b.txt'; # for "big" invoices + + warn "copying spool to $regfile, $bigfile\n" if $DEBUG; + + my ($in, $reg, $big); #filehandles + my %count = (B => 0, 1 => 0, 2 => 0); # number of invoices + my %sum = (B => 0, R => 0); # total of charges field + open $in, '<', "$dir/$file-$date.csv" + or die "unable to read $file-$date.csv\n"; + + open $reg, '>', "$dir/$regfile" or die "unable to write $regfile\n"; + open $big, '>', "$dir/$bigfile" or die "unable to write $bigfile\n"; + + while (my $line = <$in>) { + chomp($line); + my $tag = substr($line, -1, 1, ''); + my $charge = substr($line, 252, 10); + if ( $tag eq 'B' ) { + print $big $line, "\n"; + $count{B}++; + $sum{B} += $charge; + } else { + print $reg $line, "\n"; + $count{$tag}++; + $sum{R} += $charge; + } + } + close $in; + close $reg; + close $big; + + my $zipfile = "$basename" . '.zip'; + my $command = "cd $dir; zip $zipfile $regfile $bigfile"; + system($command) and die "'$command' failed\n"; + $upload_target->put("$dir/$zipfile"); + + for (values %sum) { + $_ = sprintf('%.2f', $_); + } + + send_report('ics-confirm_template', + { + agentnum => $agentnum, + count => \%count, + sum => \%sum, + } + ); + + } else { # not bridgestone or ics # this is the usual case - my $connection = $ftp_target->connect; # dies on error - $connection->put("$file-$date.csv"); + my $error = $upload_target->put("$file-$date.csv"); + die $error if $error; } @@ -369,4 +403,47 @@ sub spool_upload { } +=item send_report CONFIG PARAMS + +Retrieves the config value named CONFIG, parses it as a Text::Template, +extracts "to" and "subject" headers, and sends it by email. + +PARAMS is a hashref to be passed to C. It must contain +'agentnum' to look up the per-agent config. + +=cut + +# we used it twice, so it's now a subroutine +sub send_report { + + my ($config, $params) = @_; + my $agentnum = $params->{agentnum}; + my $conf = FS::Conf->new; + + my $template = join("\n", $conf->config($config, $agentnum)); + if (!$template) { + warn "$me agent $agentnum has no $config, no email report sent\n"; + return; + } + + my $tmpl_obj = Text::Template->new( + TYPE => 'STRING', SOURCE => $template + ); + my $content = $tmpl_obj->fill_in( HASH => $params ); + my ($head, $body) = split("\n\n", $content, 2); + $head =~ /^subject:\s*(.*)$/im; + my $subject = $1; + + $head =~ /^to:\s*(.*)$/im; + my $to = $1; + + send_email( + to => $to, + from => $conf->config('invoice_from', $agentnum), + subject => $subject, + body => $body, + ); + +} + 1; diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 11af25efa..f7d98a156 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -312,7 +312,7 @@ if ( -e $addl_handler_use_file ) { use FS::access_groupsales; use FS::contact_class; use FS::part_svc_class; - use FS::ftp_target; + use FS::upload_target; use FS::quotation; use FS::quotation_pkg; use FS::quotation_pkg_discount; diff --git a/FS/FS/Misc/Invoicing.pm b/FS/FS/Misc/Invoicing.pm index 2fc52a99b..92138c2a7 100644 --- a/FS/FS/Misc/Invoicing.pm +++ b/FS/FS/Misc/Invoicing.pm @@ -19,7 +19,7 @@ Returns a list of the invoice spool formats. =cut sub spool_formats { - qw(default oneline billco bridgestone) + qw(default oneline billco bridgestone ics) } 1; diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 4832dd2f6..01250e593 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3948,16 +3948,17 @@ sub tables_hashref { 'index' => [ [ 'upgrade' ] ], }, - 'ftp_target' => { + 'upload_target' => { 'columns' => [ 'targetnum', 'serial', '', '', '', '', 'agentnum', 'int', 'NULL', '', '', '', + 'protocol', 'varchar', '', 10, '', '', 'hostname', 'varchar', '', $char_d, '', '', - 'port', 'int', '', '', '', '', + 'port', 'int', 'NULL', '', '', '', 'username', 'varchar', '', $char_d, '', '', - 'password', 'varchar', '', $char_d, '', '', - 'path', 'varchar', '', $char_d, '', '', - 'secure', 'char', 'NULL', 1, '', '', + 'password', 'varchar', 'NULL', $char_d, '', '', + 'path', 'varchar', 'NULL', $char_d, '', '', + 'subject', 'varchar', 'NULL', '255', '', '', 'handling', 'varchar', 'NULL', $char_d, '', '', ], 'primary_key' => 'targetnum', diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index c48c80627..dad54348e 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -6,7 +6,7 @@ use vars qw( $DEBUG $me $date_format ); # but NOT $conf use Fcntl qw(:flock); #for spool_csv use Cwd; -use List::Util qw(min max); +use List::Util qw(min max sum); use Date::Format; use File::Temp 0.14; use HTML::Entities; @@ -1819,13 +1819,16 @@ L). =item agent_spools - if set to a true value, will spool to per-agent files rather than a single global file -=item ftp_targetnum - if set to an FTP target (see L), will +=item upload_targetnum - if set to a target (see L), will append to that spool. L will then send the spool file to that destination. =item balanceover - if set, only spools the invoice if the total amount owed on this invoice and all older invoices is greater than the specified amount. +=item time - the "current time". Controls the printing of past due messages +in the ICS format. + =back =cut @@ -1833,6 +1836,7 @@ this invoice and all older invoices is greater than the specified amount. sub spool_csv { my($self, %opt) = @_; + my $time = $opt{'time'} || time; my $cust_main = $self->cust_main; if ( $opt{'dest'} ) { @@ -1850,7 +1854,7 @@ sub spool_csv { my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/cust_bill"; mkdir $spooldir, 0700 unless -d $spooldir; - my $tracctnum = $self->invnum. time2str('-%Y%m%d%H%M%S', time); + my $tracctnum = $self->invnum. time2str('-%Y%m%d%H%M%S', $time); my $file; if ( $opt{'agent_spools'} ) { @@ -1859,8 +1863,8 @@ sub spool_csv { $file = 'spool'; } - if ( $opt{'ftp_targetnum'} ) { - $spooldir .= '/target'.$opt{'ftp_targetnum'}; + if ( $opt{'upload_targetnum'} ) { + $spooldir .= '/target'.$opt{'upload_targetnum'}; mkdir $spooldir, 0700 unless -d $spooldir; } # otherwise it just goes into export.xxx/cust_bill @@ -1870,7 +1874,7 @@ sub spool_csv { $file = "$spooldir/$file.csv"; - my ( $header, $detail ) = $self->print_csv(%opt, 'tracctnum' => $tracctnum ); + my ( $header, $detail ) = $self->print_csv(%opt, 'tracctnum' => $tracctnum); open(CSV, ">>$file") or die "can't open $file: $!"; flock(CSV, LOCK_EX); @@ -1890,7 +1894,7 @@ sub spool_csv { seek(CSV, 0, 2); } - print CSV $detail; + print CSV $detail if defined($detail); flock(CSV, LOCK_UN); close CSV; @@ -2051,8 +2055,11 @@ sub print_csv { my $cust_main = $self->cust_main; my $csv = Text::CSV_XS->new({'always_quote'=>1}); + my $format = lc($opt{'format'}); - if ( lc($opt{'format'}) eq 'billco' ) { + my $time = $opt{'time'} || time; + + if ( $format eq 'billco' ) { my $taxtotal = 0; $taxtotal += $_->{'amount'} foreach $self->_items_tax; @@ -2105,7 +2112,7 @@ sub print_csv { '0', # 29 | Other Taxes & Fees*** NUM* 9 ); - } elsif ( lc($opt{'format'}) eq 'oneline' ) { #name? + } elsif ( $format eq 'oneline' ) { #name my ($previous_balance) = $self->previous; my $totaldue = sprintf('%.2f', $self->owed + $previous_balance); @@ -2136,10 +2143,10 @@ sub print_csv { @items, ); - } elsif ( lc($opt{'format'}) eq 'bridgestone' ) { + } elsif ( $format eq 'bridgestone' ) { # bypass the CSV stuff and just return this - my $longdate = time2str('%B %d, %Y', time); #current time, right? + my $longdate = time2str('%B %d, %Y', $time); #current time, right? my $zip = $cust_main->zip; $zip =~ s/\D//; my $prefix = $self->conf->config('bridgestone-prefix', $cust_main->agentnum) @@ -2161,7 +2168,120 @@ sub print_csv { '' #detail ); - } else { + } elsif ( $format eq 'ics' ) { + + my $bill = $cust_main->bill_location; + my $zip = $bill->zip; + my $zip4 = ''; + + $zip =~ s/\D//; + if ( $zip =~ /^(\d{5})(\d{4})$/ ) { + $zip = $1; + $zip4 = $2; + } + + # minor false laziness with print_generic + my ($previous_balance) = $self->previous; + my $balance_due = $self->owed + $previous_balance; + my $payment_total = sum(0, map { $_->{'amount'} } $self->_items_payments); + my $credit_total = sum(0, map { $_->{'amount'} } $self->_items_credits); + + my $past_due = ''; + if ( $self->due_date and $time >= $self->due_date ) { + $past_due = sprintf('Past due:$%0.2f Due Immediately', $balance_due); + } + + # again, bypass CSV + my $header = sprintf( + '%-10s%-30s%-48s%-2s%-50s%-30s%-30s%-25s%-2s%-5s%-4s%-8s%-8s%-10s%-10s%-10s%-10s%-10s%-10s%-480s%-35s', + $cust_main->display_custnum, #BID + uc($cust_main->first), #FNAME + uc($cust_main->last), #LNAME + '00', #BATCH, should this ever be anything else? + uc($cust_main->company), #COMP + uc($bill->address1), #STREET1 + uc($bill->address2), #STREET2 + uc($bill->city), #CITY + uc($bill->state), #STATE + $zip, + $zip4, + time2str('%Y%m%d', $self->_date), #BILL_DATE + $self->due_date2str('%Y%m%d'), #DUE_DATE, + ( map {sprintf('%0.2f', $_)} + $balance_due, #AMNT_DUE + $previous_balance, #PREV_BAL + $payment_total, #PYMT_RCVD + $credit_total, #CREDITS + $previous_balance, #BEG_BAL--is this correct? + $self->charged, #NEW_CHRG + ), + 'img01', #MRKT_MSG? + $past_due, #PAST_MSG + ); + + my @details; + my %svc_class = ('' => ''); # maybe cache this more persistently? + + foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) { + + my $show_pkgnum = $cust_bill_pkg->pkgnum || ''; + my $cust_pkg = $cust_bill_pkg->cust_pkg if $show_pkgnum; + + if ( $cust_pkg ) { + + my @dates = ( $self->_date, undef ); + if ( my $prev = $cust_bill_pkg->previous_cust_bill_pkg ) { + $dates[1] = $prev->sdate; #questionable + } + + # generate an 01 detail for each service + my @svcs = $cust_pkg->h_cust_svc(@dates, 'I'); + foreach my $cust_svc ( @svcs ) { + $show_pkgnum = ''; # hide it if we're showing svcnums + + my $svcpart = $cust_svc->svcpart; + if (!exists($svc_class{$svcpart})) { + my $classnum = $cust_svc->part_svc->classnum; + my $part_svc_class = FS::part_svc_class->by_key($classnum) + if $classnum; + $svc_class{$svcpart} = $part_svc_class ? + $part_svc_class->classname : + ''; + } + + push @details, sprintf('01%-9s%-20s%-47s', + $cust_svc->svcnum, + $svc_class{$svcpart}, + $cust_svc->svc_x->label, + ); + } #foreach $cust_svc + } #if $cust_pkg + + my $desc = $cust_bill_pkg->desc; # itemdesc or part_pkg.pkg + if ($cust_bill_pkg->recur > 0) { + $desc .= ' '.time2str('%d-%b-%Y', $cust_bill_pkg->sdate).' to '. + time2str('%d-%b-%Y', $cust_bill_pkg->edate - 86400); + } + push @details, sprintf('02%-6s%-60s%-10s', + $show_pkgnum, + $desc, + sprintf('%0.2f', $cust_bill_pkg->setup + $cust_bill_pkg->recur), + ); + } #foreach $cust_bill_pkg + + # Tag this row so that we know whether this is one page (1), two pages + # (2), # or "big" (B). The tag will be stripped off before uploading. + if ( scalar(@details) < 12 ) { + push @details, '1'; + } elsif ( scalar(@details) < 58 ) { + push @details, '2'; + } else { + push @details, 'B'; + } + + return join('', $header, @details, "\n"); + + } else { # default $csv->combine( 'cust_bill', diff --git a/FS/FS/ftp_target.pm b/FS/FS/ftp_target.pm deleted file mode 100644 index bf9fc891a..000000000 --- a/FS/FS/ftp_target.pm +++ /dev/null @@ -1,194 +0,0 @@ -package FS::ftp_target; - -use strict; -use base qw( FS::Record ); -use FS::Record qw( qsearch qsearchs ); -use vars qw($me $DEBUG); - -$DEBUG = 0; - -=head1 NAME - -FS::ftp_target - Object methods for ftp_target records - -=head1 SYNOPSIS - - use FS::ftp_target; - - $record = new FS::ftp_target \%hash; - $record = new FS::ftp_target { 'column' => 'value' }; - - $error = $record->insert; - - $error = $new_record->replace($old_record); - - $error = $record->delete; - - $error = $record->check; - -=head1 DESCRIPTION - -An FS::ftp_target object represents an account on a remote FTP or SFTP -server for transferring files. FS::ftp_target inherits from FS::Record. - -=over 4 - -=item targetnum - primary key - -=item agentnum - L foreign key; can be null - -=item hostname - the DNS name of the FTP site - -=item username - username - -=item password - password - -=item path - the working directory to change to upon connecting - -=item secure - a flag ('Y' or null) for whether to use SFTP - -=back - -=head1 METHODS - -=over 4 - -=cut - -sub table { 'ftp_target'; } - -=item new HASHREF - -Creates a new FTP target. To add it to the database, see L<"insert">. - -=item insert - -Adds this record to the database. If there is an error, returns the error, -otherwise returns false. - -=item delete - -Delete this record from the database. - -=item replace OLD_RECORD - -Replaces the OLD_RECORD with this one in the database. If there is an error, -returns the error, otherwise returns false. - -=item check - -Checks all fields to make sure this is a valid example. If there is -an error, returns the error, otherwise returns false. Called by the insert -and replace methods. - -=cut - -sub check { - my $self = shift; - - if ( !$self->get('port') ) { - if ( $self->secure ) { - $self->set('port', 22); - } else { - $self->set('port', 21); - } - } - - my $error = - $self->ut_numbern('targetnum') - || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum') - || $self->ut_text('hostname') - || $self->ut_text('username') - || $self->ut_text('password') - || $self->ut_number('port') - || $self->ut_text('path') - || $self->ut_flag('secure') - || $self->ut_enum('handling', [ $self->handling_types ]) - ; - return $error if $error; - - $self->SUPER::check; -} - -=item connect - -Creates a Net::FTP or Net::SFTP::Foreign object (according to the setting -of the 'secure' flag), connects to 'hostname', attempts to log in with -'username' and 'password', and changes the working directory to 'path'. -On success, returns the object. On failure, dies with an error message. - -=cut - -sub connect { - my $self = shift; - if ( $self->secure ) { - eval "use Net::SFTP::Foreign;"; - die $@ if $@; - my %args = ( - port => $self->port, - user => $self->username, - password => $self->password, - more => ($DEBUG ? '-v' : ''), - timeout => 30, - autodie => 1, #we're doing this anyway - ); - my $sftp = Net::SFTP::Foreign->new($self->hostname, %args); - $sftp->setcwd($self->path); - return $sftp; - } - else { - eval "use Net::FTP;"; - die $@ if $@; - my %args = ( - Debug => $DEBUG, - Port => $self->port, - Passive => 1,# optional? - ); - my $ftp = Net::FTP->new($self->hostname, %args) - or die "connect to ".$self->hostname." failed: $@"; - $ftp->login($self->username, $self->password) - or die "login to ".$self->username.'@'.$self->hostname." failed: $@"; - $ftp->binary; #optional? - $ftp->cwd($self->path) - or ($self->path eq '/') - or die "cwd to ".$self->hostname.'/'.$self->path." failed: $@"; - - return $ftp; - } -} - -=item label - -Returns a descriptive label for this target. - -=cut - -sub label { - my $self = shift; - $self->targetnum . ': ' . $self->username . '@' . $self->hostname; -} - -=item handling_types - -Returns a list of values for the "handling" field, corresponding to the -known ways to preprocess a file before uploading. Currently those are -implemented somewhat crudely in L. - -=cut - -sub handling_types { - '', - #'billco', #not implemented this way yet - 'bridgestone', -} - -=back - -=head1 SEE ALSO - -L, schema.html from the base documentation. - -=cut - -1; - diff --git a/FS/FS/part_event/Action/cust_bill_spool_csv.pm b/FS/FS/part_event/Action/cust_bill_spool_csv.pm index 14349a9dd..250c83042 100644 --- a/FS/FS/part_event/Action/cust_bill_spool_csv.pm +++ b/FS/FS/part_event/Action/cust_bill_spool_csv.pm @@ -26,9 +26,9 @@ sub option_fields { type => 'checkbox', value => '1', }, - 'ftp_targetnum' => { label => 'Upload spool to FTP target', + 'upload_targetnum' => { label => 'Upload spool to target', type => 'select-table', - table => 'ftp_target', + table => 'upload_target', name_col => 'label', empty_label => '(do not upload)', order_by => 'targetnum', @@ -39,16 +39,17 @@ sub option_fields { sub default_weight { 50; } sub do_action { - my( $self, $cust_bill ) = @_; + my( $self, $cust_bill, $cust_event ) = @_; #my $cust_main = $self->cust_main($cust_bill); my $cust_main = $cust_bill->cust_main; $cust_bill->spool_csv( + 'time' => $cust_event->_date, 'format' => $self->option('spoolformat'), 'balanceover' => $self->option('spoolbalanceover'), 'agent_spools' => $self->option('spoolagent_spools'), - 'ftp_targetnum'=> $self->option('ftp_targetnum'), + 'upload_targetnum'=> $self->option('upload_targetnum'), ); } diff --git a/FS/FS/upload_target.pm b/FS/FS/upload_target.pm new file mode 100644 index 000000000..8466a6229 --- /dev/null +++ b/FS/FS/upload_target.pm @@ -0,0 +1,282 @@ +package FS::upload_target; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs ); +use FS::Misc qw(send_email); +use FS::Conf; +use File::Spec; +use vars qw($me $DEBUG); + +$DEBUG = 0; + +=head1 NAME + +FS::upload_target - Object methods for upload_target records + +=head1 SYNOPSIS + + use FS::upload_target; + + $record = new FS::upload_target \%hash; + $record = new FS::upload_target { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::upload_target object represents a destination to deliver files (such +as invoice batches) by FTP, SFTP, or email. FS::upload_target inherits from +FS::Record. + +=over 4 + +=item targetnum - primary key + +=item agentnum - L foreign key; can be null + +=item protocol - 'ftp', 'sftp', or 'email'. + +=item hostname - the DNS name of the FTP site, or the domain name of the +email address. + +=item port - the TCP port number, if it's not standard. + +=item username - username + +=item password - password + +=item path - for FTP/SFTP, the working directory to change to upon connecting. + +=item subject - for email, the Subject: header + +=item handling - a string naming an additional process to apply to +the file before sending it. + +=back + +=head1 METHODS + +=over 4 + +=cut + +sub table { 'upload_target'; } + +=item new HASHREF + +Creates a new FTP target. To add it to the database, see L<"insert">. + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=item check + +Checks all fields to make sure this is a valid example. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $protocol = lc($self->protocol); + if ( $protocol eq 'email' ) { + $self->set(password => ''); + $self->set(port => ''); + $self->set(path => ''); + } elsif ( $protocol eq 'sftp' ) { + $self->set(port => 22) unless $self->get('port'); + $self->set(subject => ''); + } elsif ( $protocol eq 'ftp' ) { + $self->set('port' => 21) unless $self->get('port'); + $self->set(subject => ''); + } else { + return "protocol '$protocol' not supported"; + } + $self->set(protocol => $protocol); # lowercase it + + my $error = + $self->ut_numbern('targetnum') + || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum') + || $self->ut_text('hostname') + || $self->ut_text('username') + || $self->ut_textn('password') + || $self->ut_numbern('port') + || $self->ut_textn('path') + || $self->ut_textn('subject') + || $self->ut_enum('handling', [ $self->handling_types ]) + ; + return $error if $error; + + $self->SUPER::check; +} + +=item put LOCALNAME [ REMOTENAME ] + +Uploads the file named LOCALNAME, optionally changing its name to REMOTENAME +on the target. For FTP/SFTP, this opens a connection, changes to the working +directory (C), and PUTs the file. For email, it composes an empty +message and attaches the file. + +Returns an error message if anything goes wrong. + +=cut + +sub put { + my $self = shift; + my $localname = shift; + my @s = File::Spec->splitpath($localname); + my $remotename = shift || $s[-1]; + + my $conf = FS::Conf->new; + if ( $self->protocol eq 'ftp' or $self->protocol eq 'sftp' ) { + # could cache this if we ever want to reuse it + local $@; + my $connection = eval { $self->connect }; + return $@ if $@; + $connection->put($localname, $remotename) or return $connection->error; + } elsif ( $self->protocol eq 'email' ) { + + my $to = join('@', $self->username, $self->hostname); + # XXX if we were smarter, this could use a message template for the + # message subject, body, and source address + # (maybe use only the raw content, so that we don't have to supply a + # customer for substitutions? ewww.) + my %message = ( + 'from' => $conf->config('invoice_from'), + 'to' => $to, + 'subject' => $self->subject, + 'nobody' => 1, + 'mimeparts' => [ + { Path => $localname, + Type => 'application/octet-stream', + Encoding => 'base64', + Filename => $remotename, + Disposition => 'attachment', + } + ], + ); + return send_email(%message); + + } else { + return "unknown protocol '".$self->protocol."'"; + } +} + + + + + + + + +=item connect + +Creates a Net::FTP or Net::SFTP::Foreign object (according to the setting +of the 'secure' flag), connects to 'hostname', attempts to log in with +'username' and 'password', and changes the working directory to 'path'. +On success, returns the object. On failure, dies with an error message. + +Always returns an error for email targets. + +=cut + +sub connect { + my $self = shift; + if ( $self->protocol eq 'sftp' ) { + eval "use Net::SFTP::Foreign;"; + die $@ if $@; + my %args = ( + port => $self->port, + user => $self->username, + password => $self->password, + more => ($DEBUG ? '-v' : ''), + timeout => 30, + autodie => 1, #we're doing this anyway + ); + my $sftp = Net::SFTP::Foreign->new($self->hostname, %args); + $sftp->setcwd($self->path); + return $sftp; + } + elsif ( $self->protocol eq 'ftp') { + eval "use Net::FTP;"; + die $@ if $@; + my %args = ( + Debug => $DEBUG, + Port => $self->port, + Passive => 1,# optional? + ); + my $ftp = Net::FTP->new($self->hostname, %args) + or die "connect to ".$self->hostname." failed: $@"; + $ftp->login($self->username, $self->password) + or die "login to ".$self->username.'@'.$self->hostname." failed: $@"; + $ftp->binary; #optional? + $ftp->cwd($self->path) + or ($self->path eq '/') + or die "cwd to ".$self->hostname.'/'.$self->path." failed: $@"; + + return $ftp; + } else { + return "can't connect() to a target of type '".$self->protocol."'"; + } +} + +=item label + +Returns a descriptive label for this target. + +=cut + +sub label { + my $self = shift; + $self->targetnum . ': ' . $self->username . '@' . $self->hostname; +} + +=item handling_types + +Returns a list of values for the "handling" field, corresponding to the +known ways to preprocess a file before uploading. Currently those are +implemented somewhat crudely in L. + +=cut + +sub handling_types { + '', + #'billco', #not implemented this way yet + 'bridgestone', + 'ics', +} + +=back + +=head1 BUGS + +Handling methods should be here, but instead are in FS::Cron. + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index b5ee87e93..f530610e7 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -640,8 +640,8 @@ FS/access_groupsales.pm t/access_groupsales.t FS/part_svc_class.pm t/part_svc_class.t -FS/ftp_target.pm -t/ftp_target.t +FS/upload_target.pm +t/upload_target.t FS/quotation.pm t/quotation.t FS/quotation_pkg.pm diff --git a/FS/t/ftp_target.t b/FS/t/ftp_target.t deleted file mode 100644 index 1a5928118..000000000 --- a/FS/t/ftp_target.t +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN { $| = 1; print "1..1\n" } -END {print "not ok 1\n" unless $loaded;} -use FS::ftp_target; -$loaded=1; -print "ok 1\n"; diff --git a/FS/t/upload_target.t b/FS/t/upload_target.t new file mode 100644 index 000000000..6d55de0f2 --- /dev/null +++ b/FS/t/upload_target.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::upload_target; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/browse/ftp_target.html b/httemplate/browse/ftp_target.html deleted file mode 100644 index 4a5782058..000000000 --- a/httemplate/browse/ftp_target.html +++ /dev/null @@ -1,56 +0,0 @@ -<& elements/browse.html, - 'title' => 'FTP targets', - 'menubar' => [ 'Add a target' => $p.'edit/ftp_target.html', ], - 'name' => 'FTP targets', - 'query' => { 'table' => 'ftp_target', - 'hashref' => {}, - }, - 'count_query' => $count_query, - 'header' => [ '#', - 'Server', - 'Username', - 'Password', - 'Path', - 'Protocol', - '', #handling - ], - 'fields' => [ 'targetnum', - 'hostname', - 'username', - 'password', - 'path', - sub { - my $ftp_target = shift; - my $label; - if ($ftp_target->secure) { - $label = 'SFTP'; - $label .= ' (port '.$ftp_target->port.')' - if $ftp_target->port != 22; - } - else { - $label = 'FTP'; - $label .= ' (port '.$ftp_target->port.')' - if $ftp_target->port != 21; - } - $label; - }, - 'handling', - ], - 'links' => [ $link, $link ], -&> - - -<% include('/elements/footer.html') %> - -<%once> - -my $count_query = 'SELECT COUNT(*) FROM ftp_target'; - - -<%init> - -die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); - -my $link = [ $p.'edit/ftp_target.html?', 'targetnum' ]; - diff --git a/httemplate/browse/upload_target.html b/httemplate/browse/upload_target.html new file mode 100644 index 000000000..e166f3520 --- /dev/null +++ b/httemplate/browse/upload_target.html @@ -0,0 +1,49 @@ +<& elements/browse.html, + 'title' => 'Upload targets', + 'menubar' => [ 'Add a target' => $p.'edit/upload_target.html', ], + 'name' => 'targets', + 'query' => { 'table' => 'upload_target', + 'hashref' => {}, + }, + 'count_query' => $count_query, + 'header' => [ '#', + 'Protocol', + 'Username', + 'Server/Domain', + 'Password', + 'Path', + '', #handling + ], + 'fields' => [ 'targetnum', + sub { + my $target = shift; + $label{$target->protocol} + }, + 'username', + 'hostname', + 'password', + 'path', + 'handling', + ], + 'links' => [ $link, $link, $link, $link, ], +&> + + +<% include('/elements/footer.html') %> + +<%once> + +my $count_query = 'SELECT COUNT(*) FROM upload_target'; +my %label = ( + email => 'Email', + ftp => 'FTP', + sftp => 'SFTP', +); + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $link = [ $p.'edit/upload_target.html?', 'targetnum' ]; + diff --git a/httemplate/edit/ftp_target.html b/httemplate/edit/ftp_target.html deleted file mode 100755 index aebf9aaed..000000000 --- a/httemplate/edit/ftp_target.html +++ /dev/null @@ -1,46 +0,0 @@ -<& elements/edit.html, - 'post_url' => popurl(1).'process/ftp_target.html', - 'name' => 'FTP target', - 'table' => 'ftp_target', - 'viewall_url' => "${p}browse/ftp_target.html", - 'labels' => { targetnum => 'Target', - hostname => 'Server', - username => 'Username', - password => 'Password', - path => 'Directory', - port => 'Port', - secure => 'Use SFTP', - handling => 'Special handling', - }, - 'fields' => [ - { field => 'hostname', size => 40 }, - { field => 'port', size => 8 }, - { field => 'secure', type => 'checkbox', value => 'Y' }, - 'username', - 'password', - { field => 'path', size => 40 }, - { field => 'handling', - type => 'select', - options => [ FS::ftp_target->handling_types ], - }, - ], - 'menubar' => \@menubar, - 'edit_callback' => $edit_callback, -&> -<%init> - -my $curuser = $FS::CurrentUser::CurrentUser; - -die "access denied" - unless $curuser->access_right('Configuration'); - -my @menubar = ('View all FTP targets' => $p.'browse/ftp_target.html'); -my $edit_callback = sub { - my ($cgi, $object) = @_; - if ( $object->targetnum ) { - push @menubar, 'Delete this target', - $p.'misc/delete-ftp_target.html?'.$object->targetnum; - } -}; - - diff --git a/httemplate/edit/process/ftp_target.html b/httemplate/edit/process/ftp_target.html deleted file mode 100644 index 35f56c490..000000000 --- a/httemplate/edit/process/ftp_target.html +++ /dev/null @@ -1,12 +0,0 @@ -<& elements/process.html, - 'table' => 'ftp_target', - 'viewall_dir' => 'browse', - 'agent_null' => 1, -&> -<%init> -my $curuser = $FS::CurrentUser::CurrentUser; - -die "access denied" - unless $curuser->access_right('Configuration'); - - diff --git a/httemplate/edit/process/upload_target.html b/httemplate/edit/process/upload_target.html new file mode 100644 index 000000000..8755bed56 --- /dev/null +++ b/httemplate/edit/process/upload_target.html @@ -0,0 +1,25 @@ +<& elements/process.html, + 'table' => 'upload_target', + 'viewall_dir' => 'browse', + 'agent_null' => 1, + 'precheck_callback'=> \&precheck, +&> +<%init> +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Configuration'); + +sub precheck { + my $cgi = shift; + my $protocol = $cgi->param('protocol'); + # promote whatever set of fields was selected to the "real" values + my $params = $cgi->Vars; + foreach ( keys %$params ) { + if ( $_ =~ /^${protocol}_(\w+)/ ) { + $cgi->param($1, $cgi->param($_)); + } + } +} + + diff --git a/httemplate/edit/upload_target.html b/httemplate/edit/upload_target.html new file mode 100755 index 000000000..47fea78a0 --- /dev/null +++ b/httemplate/edit/upload_target.html @@ -0,0 +1,82 @@ +<& elements/edit.html, + 'post_url' => popurl(1).'process/upload_target.html', + 'name' => 'Upload target', + 'table' => 'upload_target', + 'viewall_url' => "${p}browse/upload_target.html", + 'labels' => { targetnum => 'Target', + protocol => 'Protocol', + handling => 'Special handling', + }, + 'fields' => [ + { field => 'protocol', + type => 'selectlayers', + options => [ '', 'sftp', 'ftp', 'email' ], + labels => { '' => '', + 'email' => 'Email', + 'sftp' => 'SFTP', + 'ftp' => 'FTP', + }, + layer_fields => \%protocol_fields, + layer_values_callback => \&values_callback, + }, + { field => 'handling', + type => 'select', + options => [ FS::upload_target->handling_types ], + }, + ], + 'menubar' => \@menubar, + 'edit_callback' => $edit_callback, +&> +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Configuration'); + +my @menubar = ('View all FTP targets' => $p.'browse/upload_target.html'); +my $edit_callback = sub { + my ($cgi, $object) = @_; + if ( $object->targetnum ) { + push @menubar, 'Delete this target', + $p.'misc/delete-upload_target.html?'.$object->targetnum; + } +}; + +my %protocol_fields = ( + '' => [], + 'sftp' => [ + 'hostname' => { label => 'Server' }, + 'username' => { label => 'Username' }, + 'password' => { label => 'Password' }, + 'port' => { label => 'Port', size => 8 }, + 'path' => { label => 'Path', size => 30 }, + ], + 'email' => [ + 'username' => { label => 'To:' }, + 'hostname' => { label => '@' }, + 'subject' => { label => 'Subject:' }, + ], +); +$protocol_fields{'ftp'} = [ @{ $protocol_fields{'sftp'} } ]; +foreach my $k (keys %protocol_fields) { + # disambiguate the field names + foreach (@{ $protocol_fields{$k} }) { + $_ = $k.'_'.$_ unless ref $_; + } +} + +sub values_callback { + my ($cgi, $object) = @_; + my $layer_values; + # really simple, the interpretation of the fields is the same for all + # three layers + foreach my $l (qw(email ftp sftp)) { + $layer_values->{$l} = { map { $l.'_'.$_ => ($cgi->param($l.'_'.$_) || + $object->get($_) ) } + $object->fields }; + } + $layer_values; +} + + diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index b2141e991..bfbc179b9 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -629,7 +629,7 @@ $config_misc{'Inventory classes and inventory'} = [ $fsurl.'browse/inventory_cla || $curuser->access_right('Edit global inventory') || $curuser->access_right('Configuration'); -$config_misc{'FTP targets'} = [ $fsurl.'browse/ftp_target.html', 'FTP servers for billing and payment processing' ] +$config_misc{'Upload targets'} = [ $fsurl.'browse/upload_target.html', 'Billing and payment upload destinations' ] if $curuser->access_right('Configuration'); tie my %config_menu, 'Tie::IxHash'; -- cgit v1.2.1 From dbae615569712c6f392dfd6cc1930f9d93340e31 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sat, 27 Oct 2012 16:09:24 -0700 Subject: pkgpart in invoice templates, #19907 --- FS/FS/Template_Mixin.pm | 36 ++++++++++++++++++++++--------- FS/FS/cust_bill_pkg.pm | 23 ++++++++++++++++++-- FS/FS/cust_bill_pkg_display.pm | 48 ++++++++++++++++++++++-------------------- 3 files changed, 72 insertions(+), 35 deletions(-) diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index 146e95f1c..025e0d140 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -821,6 +821,7 @@ sub print_generic { ext_description => [], }; $detail->{'ref'} = $line_item->{'pkgnum'}; + $detail->{'pkgpart'} = $line_item->{'pkgpart'}; $detail->{'quantity'} = 1; $detail->{'section'} = $multisection ? $previous_section : $default_section; @@ -917,6 +918,7 @@ sub print_generic { ext_description => [], }; $detail->{'ref'} = $line_item->{'pkgnum'}; + $detail->{'pkgpart'} = $line_item->{'pkgpart'}; $detail->{'quantity'} = $line_item->{'quantity'}; $detail->{'section'} = $section; $detail->{'description'} = &$escape_function($line_item->{'description'}); @@ -1224,6 +1226,10 @@ sub print_generic { } } @discounts_avail; } + # debugging hook: call this with 'diag' => 1 to just get a hash of + # the invoice variables + return \%invoice_data if ( $params{'diag'} ); + # All sections and items are built; now fill in templates. my @includelist = (); push @includelist, 'summary' if $summarypage; @@ -1662,6 +1668,13 @@ sub _items_sections { $not_tax{$section} = 1 unless $cust_bill_pkg->pkgnum == 0; + # there's actually a very important piece of logic buried in here: + # incrementing $late_subtotal{$section} CREATES + # $late_subtotal{$section}. keys(%late_subtotal) is later used + # to define the list of late sections, and likewise keys(%subtotal). + # When _items_cust_bill_pkg is called to generate line items for + # real, it will be called with 'section' => $section for each + # of these. if ( $display->post_total && !$summarypage ) { if (! $type || $type eq 'S') { $late_subtotal{$section} += $cust_bill_pkg->setup @@ -2111,7 +2124,7 @@ which does something complicated. Returns a list of hashrefs, each of which may contain: -pkgnum, description, amount, unit_amount, quantity, _is_setup, and +pkgnum, description, amount, unit_amount, quantity, pkgpart, _is_setup, and ext_description, which is an arrayref of detail lines to show below the package line. @@ -2167,14 +2180,13 @@ sub _items_cust_bill_pkg { if $DEBUG > 1; foreach my $display ( grep { defined($section) - ? $_->section eq $section - : 1 - } - #grep { !$_->summary || !$summary_page } # bunk! + ? $_->section eq $section + : 1 + } grep { !$_->summary || $multisection } @cust_bill_pkg_display ) - { + { warn "$me _items_cust_bill_pkg considering cust_bill_pkg_display ". $display->billpkgdisplaynum. "\n" @@ -2222,6 +2234,9 @@ sub _items_cust_bill_pkg { my $cust_pkg = $cust_bill_pkg->cust_pkg; + # which pkgpart to show for display purposes? + my $pkgpart = $cust_bill_pkg->pkgpart_override || $cust_pkg->pkgpart; + # start/end dates for invoice formats that do nonstandard # things with them my %item_dates = map { $_ => $cust_bill_pkg->$_ } ('sdate', 'edate'); @@ -2272,7 +2287,7 @@ sub _items_cust_bill_pkg { $s = { _is_setup => 1, description => $description, - #pkgpart => $part_pkg->pkgpart, + pkgpart => $pkgpart, pkgnum => $cust_bill_pkg->pkgnum, amount => $cust_bill_pkg->setup, setup_show_zero => $cust_bill_pkg->setup_show_zero, @@ -2339,7 +2354,8 @@ sub _items_cust_bill_pkg { unless ( $cust_pkg->part_pkg->hide_svc_detail || $cust_bill_pkg->itemdesc || $cust_bill_pkg->hidden - || $is_summary && $type && $type eq 'U' ) + || $is_summary && $type && $type eq 'U' + ) { warn "$me _items_cust_bill_pkg adding service details\n" @@ -2424,7 +2440,7 @@ sub _items_cust_bill_pkg { } else { $r = { description => $description, - #pkgpart => $part_pkg->pkgpart, + pkgpart => $pkgpart, pkgnum => $cust_bill_pkg->pkgnum, amount => $amount, recur_show_zero => $cust_bill_pkg->recur_show_zero, @@ -2448,7 +2464,7 @@ sub _items_cust_bill_pkg { } else { $u = { description => $description, - #pkgpart => $part_pkg->pkgpart, + pkgpart => $pkgpart, pkgnum => $cust_bill_pkg->pkgnum, amount => $amount, recur_show_zero => $cust_bill_pkg->recur_show_zero, diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index 15750b255..826569b25 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -581,9 +581,10 @@ appropriate FS::cust_bill_pkg_display objects. Options are passed as a list of name/value pairs. Options are: -part_pkg: FS::part_pkg object from the +part_pkg: FS::part_pkg object from this line item's package. -real_pkgpart: if this line item comes from a bundled package, the pkgpart of the owning package. Otherwise the same as the part_pkg's pkgpart above. +real_pkgpart: if this line item comes from a bundled package, the pkgpart +of the owning package. Otherwise the same as the part_pkg's pkgpart above. =cut @@ -594,13 +595,19 @@ sub set_display { my $conf = new FS::Conf; + # whether to break this down into setup/recur/usage my $separate = $conf->exists('separate_usage'); + my $usage_mandate = $part_pkg->option('usage_mandate', 'Hush!') || $cust_pkg->part_pkg->option('usage_mandate', 'Hush!'); # or use the category from $opt{'part_pkg'} if its not bundled? my $categoryname = $cust_pkg->part_pkg->categoryname; + # if we don't have to separate setup/recur/usage, or put this in a + # package-specific section, or display a usage summary, then don't + # even create one of these. The item will just display in the unnamed + # section as a single line plus details. return $self->set('display', []) unless $separate || $categoryname || $usage_mandate; @@ -608,34 +615,46 @@ sub set_display { my %hash = ( 'section' => $categoryname ); + # whether to put usage details in a separate section, and if so, which one my $usage_section = $part_pkg->option('usage_section', 'Hush!') || $cust_pkg->part_pkg->option('usage_section', 'Hush!'); + # whether to show a usage summary line (total usage charges, no details) my $summary = $part_pkg->option('summarize_usage', 'Hush!') || $cust_pkg->part_pkg->option('summarize_usage', 'Hush!'); if ( $separate ) { + # create lines for setup and (non-usage) recur, in the main section push @display, new FS::cust_bill_pkg_display { type => 'S', %hash }; push @display, new FS::cust_bill_pkg_display { type => 'R', %hash }; } else { + # display everything in a single line push @display, new FS::cust_bill_pkg_display { type => '', %hash, + # and if usage_mandate is enabled, hide details + # (this only works on multisection invoices...) ( ( $usage_mandate ) ? ( 'summary' => 'Y' ) : () ), }; } if ($separate && $usage_section && $summary) { + # create a line for the usage summary in the main section push @display, new FS::cust_bill_pkg_display { type => 'U', summary => 'Y', %hash, }; } + if ($usage_mandate || ($usage_section && $summary) ) { $hash{post_total} = 'Y'; } if ($separate || $usage_mandate) { + # show call details for this line item in the usage section. + # if usage_mandate is on, this will display below the section subtotal. + # this also happens if usage is in a separate section and there's a + # summary in the main section, though I'm not sure why. $hash{section} = $usage_section if $usage_section; push @display, new FS::cust_bill_pkg_display { type => 'U', %hash }; } diff --git a/FS/FS/cust_bill_pkg_display.pm b/FS/FS/cust_bill_pkg_display.pm index a864ec114..d7c147281 100644 --- a/FS/FS/cust_bill_pkg_display.pm +++ b/FS/FS/cust_bill_pkg_display.pm @@ -27,26 +27,26 @@ FS::cust_bill_pkg_display - Object methods for cust_bill_pkg_display records =head1 DESCRIPTION -An FS::cust_bill_pkg_display object represents line item display information. -FS::cust_bill_pkg_display inherits from FS::Record. The following fields are -currently supported: +An FS::cust_bill_pkg_display object represents an instruction to display a +line item in a specific invoice section. FS::cust_bill_pkg_display inherits +from FS::Record and is many-to-one with FS::cust_bill_pkg (invoice line +items). -=over 4 - -=item billpkgdisplaynum +The following fields are currently supported: -primary key - -=item billpkgnum +=over 4 -billpkgnum +=item billpkgdisplaynum - primary key -=item section +=item billpkgnum - the line item number (L foreign key) -section +=item section - the section name where this item should be shown. Defaults +to the package category name, if there is one. =cut +# actually it defaults to null, but then calling ->section will return the +# category name. sub section { my ( $self, $value ) = @_; if ( defined($value) ) { @@ -64,17 +64,19 @@ sub section { } } -=item post_total +=item post_total - 'Y' to have this item shown in a "late" section (below +the invoice totals). -post_total +=item type - Which portion of the item's charges to show in the specified +position. 'S' to show setup fees (including tax and one-time charge), +'R' to show the non-usage recurring charge, 'U' to show the usage charge, +null to show all three as a single amount. -=item type - -type - -=item summary - -summary +=item summary - 'Y' to show a usage summary of this line item. This has +the following effects if type = 'U': +- The description will always be "Usage charges" rather than the package name. +- Service labels and usage details (CDRs) are hidden. +- It will only display on multisection invoices. =back @@ -84,7 +86,8 @@ summary =item new HASHREF -Creates a new line item display object. To add the record to the database, see L<"insert">. +Creates a new line item display object. To add the record to the database, +see L<"insert">. Note that this stores the hash reference, not a distinct copy of the hash it points to. You can ask the object for a copy with the I method. @@ -155,7 +158,6 @@ sub cust_bill_pkg { =head1 BUGS - =head1 SEE ALSO L, L, schema.html from the base documentation. -- cgit v1.2.1 From d77fe06b27410a41855e1425114ab8d9cdae4ff0 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 30 Oct 2012 12:16:13 -0700 Subject: fix ticket display, fallout from #17067 --- FS/FS/Misc/DateTime.pm | 5 +++-- httemplate/elements/table-tickets.html | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/FS/FS/Misc/DateTime.pm b/FS/FS/Misc/DateTime.pm index e36f3a95a..9c12e6408 100644 --- a/FS/FS/Misc/DateTime.pm +++ b/FS/FS/Misc/DateTime.pm @@ -32,13 +32,14 @@ the date as an integer UNIX timestamp. sub parse_datetime { my $string = shift; return '' unless $string =~ /\S/; + my $tz = shift || 'local'; my $conf = new FS::Conf; my $format = $conf->config('date_format') || '%m/%d/%Y'; if ( $format eq '%d/%m/%Y' ) { # =~ /\%d.*\%m/ ) { #$format =~ s/\%//g; - my $parser = DateTime::Format::Natural->new( 'time_zone' => 'local', + my $parser = DateTime::Format::Natural->new( 'time_zone' => $tz, #'format'=>'d/m/y',#lc($format) ); $dt = $parser->parse_datetime($string); @@ -51,7 +52,7 @@ sub parse_datetime { $dt->epoch; } } else { - return str2time($string); + return str2time($string, $tz); } } diff --git a/httemplate/elements/table-tickets.html b/httemplate/elements/table-tickets.html index ffcaf0677..f89f98422 100644 --- a/httemplate/elements/table-tickets.html +++ b/httemplate/elements/table-tickets.html @@ -153,7 +153,7 @@ if ( $ss_priority ) { my $format = $conf->config('date_format') || '%Y-%m-%d'; my $date_formatter = sub { - my $time = str2time($_[0], 'GMT'); + my $time = parse_datetime($_[0], 'GMT'); # exclude times within 24 hours of zero ($time > 86400) ? time2str($format, $time) : ''; }; -- cgit v1.2.1 From 87f255507af9f14dfbccd37eefd71a148f9af344 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 30 Oct 2012 12:16:17 -0700 Subject: IP address management for svc_acct, #19567 --- FS/FS/Conf.pm | 7 + FS/FS/IP_Mixin.pm | 305 +++++++++++++++++++++ FS/FS/Schema.pm | 3 + FS/FS/addr_block.pm | 7 +- FS/FS/svc_IP_Mixin.pm | 123 +++++++++ FS/FS/svc_acct.pm | 16 +- FS/FS/svc_broadband.pm | 194 +------------ httemplate/edit/process/svc_acct.cgi | 5 + httemplate/edit/router.cgi | 10 +- httemplate/edit/svc_acct.cgi | 28 +- httemplate/elements/tr-select-router_block_ip.html | 14 +- httemplate/view/svc_acct/basics.html | 26 +- 12 files changed, 530 insertions(+), 208 deletions(-) create mode 100644 FS/FS/IP_Mixin.pm create mode 100644 FS/FS/svc_IP_Mixin.pm diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index c9f30fe6e..e74c19faa 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1135,6 +1135,13 @@ sub reason_type_options { 'type' => 'checkbox', }, + { + 'key' => 'svc_acct-ip_addr', + 'section' => '', + 'description' => 'Enable IP address management on login services like for broadband services.', + 'type' => 'checkbox', + }, + { 'key' => 'exclude_ip_addr', 'section' => '', diff --git a/FS/FS/IP_Mixin.pm b/FS/FS/IP_Mixin.pm new file mode 100644 index 000000000..fdeb51da7 --- /dev/null +++ b/FS/FS/IP_Mixin.pm @@ -0,0 +1,305 @@ +package FS::IP_Mixin; + +use strict; +use NetAddr::IP; +use FS::addr_block; +use FS::router; +use FS::Record qw(qsearch); +use FS::Conf; +# careful about importing anything here--it will end up in a LOT of +# namespaces + +use vars qw(@subclasses $DEBUG $conf); + +$DEBUG = 0; + +# any subclass that can have IP addresses needs to be added here +@subclasses = (qw(FS::svc_broadband FS::svc_acct)); + +sub conf { + $conf ||= FS::Conf->new; +} + +=head1 NAME + +FS::IP_Mixin - Mixin class for objects that have IP addresses assigned. + +=head1 INTERFACE + +The inheritor may provide the following methods: + +=over 4 + +=item ip_addr [ ADDRESS ] + +Get/set the IP address, as a string. If the inheritor is also an +L subclass and has an 'ip_addr' field, that field will be +used. Otherwise an C method must be defined. + +=item addr_block [ BLOCK ] + +Get/set the address block, as an L object. By default, +the 'blocknum' field will be used. + +=item router [ ROUTER ] + +Get/set the router, as an L object. By default, the +'routernum' field will be used. This is strictly optional; if present +the IP address can be assigned from all those available on a router, +rather than in a specific block. + +=item _used_addresses [ BLOCK ] + +Return a list of all addresses in use (within BLOCK, if it's specified). +The inheritor should cache this if possible. + +=item _is_used ADDRESS + +Test a specific address for availability. Should return an empty string +if it's free, or else a description of who or what is using it. + +=back + +=head1 METHODS + +=over 4 + +=item ip_check + +The method that should be called from check() in the subclass. This does +the following: + +- In an C situation, sets the router and block to match the + object's IP address. +- Otherwise, if the router and IP address are both set, validate the + choice of router and set the block correctly. +- Otherwise, if the router is set, assign an address (in the selected + block if there is one). +- Check the IP address for availability. + +Returns an error if this fails for some reason (an address can't be +assigned from the requested router/block, or the requested address is +unavailable, or doesn't seem to be an IP address). + +If router and IP address are both empty, this will do nothing. The +object's check() method should decide whether to allow a null IP address. + +=cut + +sub ip_check { + my $self = shift; + + if ( $self->ip_addr eq '0.0.0.0' ) { #ipv6? + $self->ip_addr(''); + } + + if ( $self->ip_addr + and !$self->router + and $self->conf->exists('auto_router') ) { + # assign a router that matches this IP address + return $self->check_ip_addr || $self->assign_router; + } + if ( my $router = $self->router ) { + if ( $router->manual_addr ) { + # Router is set, and it's set to manual addressing, so + # clear blocknum and don't tamper with ip_addr. + $self->addr_block(undef); + } else { + my $block = $self->addr_block; + if ( !$block or !$block->manual_flag ) { + my $error = $self->assign_ip_addr; + return $error if $error; + } + # otherwise block is set to manual addressing + } + } + return $self->check_ip_addr; +} + +=item assign_ip_addr + +Set the IP address to a free address in the selected block (C) +or router (C) for this object. A block or router MUST be selected. +If the object already has an IP address and it is in that block/router's +address space, it won't be changed. + +=cut + +sub assign_ip_addr { + my $self = shift; + my %opt = @_; + + my @blocks; + my $na = $self->NetAddr; + + if ( $self->addr_block ) { + # choose an address in a specific block. + @blocks = ( $self->addr_block ); + } elsif ( $self->router ) { + # choose an address from any block on a specific router. + @blocks = $self->router->auto_addr_block; + } else { + # what else should we do, search ALL blocks? that's crazy. + die "no block or router specified for assign_ip_addr\n"; + } + + my $new_addr; + my $new_block; + foreach my $block (@blocks) { + if ( $self->ip_addr and $block->NetAddr->contains($na) ) { + return ''; + } + # don't exit early on assigning a free address--check the rest of + # the blocks to see if the current address is in one of them. + if (!$new_addr) { + $new_addr = $block->next_free_addr->addr; + $new_block = $block; + } + } + + return 'No IP address available on this router' unless $new_addr; + + $self->ip_addr($new_addr); + $self->addr_block($new_block); + ''; +} + +=item assign_router + +If the IP address is set, set the router and block accordingly. If there +is no block containing that address, returns an error. + +=cut + +sub assign_router { + my $self = shift; + return '' unless $self->ip_addr; + my $na = $self->NetAddr; + foreach my $router (qsearch('router', {})) { + foreach my $block ($router->addr_block) { + if ( $block->NetAddr->contains($na) ) { + $self->addr_block($block); + $self->router($router); + return ''; + } + } + } + return $self->ip_addr . ' is not in an allowed block.'; +} + +=item check_ip_addr + +Validate the IP address. Returns an empty string if it's correct and +available (or null), otherwise an error message. + +=cut + +sub check_ip_addr { + my $self = shift; + my $addr = $self->ip_addr; + return '' if $addr eq ''; + my $na = $self->NetAddr + or return "Can't parse address '$addr'"; + if ( my $block = $self->addr_block ) { + if ( !$block->NetAddr->contains($na) ) { + return "Address $addr not in block ".$block->cidr; + } + } + # this returns '' if the address is in use by $self. + if ( my $dup = $self->is_used($self->ip_addr) ) { + return "Address $addr in use by $dup"; + } + ''; +} + +# sensible defaults +sub addr_block { + my $self = shift; + if ( @_ ) { + my $new = shift; + if ( defined $new ) { + die "addr_block() must take an address block" + unless $new->isa('FS::addr_block'); + $self->blocknum($new->blocknum); + return $new; + } else { + #$new is undef + $self->blocknum(''); + return undef; + } + } + # could cache this... + FS::addr_block->by_key($self->blocknum); +} + +sub router { + my $self = shift; + if ( @_ ) { + my $new = shift; + if ( defined $new ) { + die "router() must take a router" + unless $new->isa('FS::router'); + $self->routernum($new->routernum); + return $new; + } else { + #$new is undef + $self->routernum(''); + return undef; + } + } + FS::router->by_key($self->routernum); +} + +=item used_addresses [ BLOCK ] + +Returns a list of all addresses (in BLOCK, or in all blocks) +that are in use. If called as an instance method, excludes +that instance from the search. + +=cut + +sub used_addresses { + my $self = shift; + my $block = shift; + return ( map { $_->_used_addresses($block, $self) } @subclasses ); +} + +sub _used_addresses { + my $class = shift; + die "$class->_used_addresses not implemented"; +} + +=item is_used ADDRESS + +Returns a string describing what object is using ADDRESS, or +an empty string if it's not in use. + +=cut + +sub is_used { + my $self = shift; + my $addr = shift; + for (@subclasses) { + my $used = $_->_is_used($addr, $self); + return $used if $used; + } + ''; +} + +sub _is_used { + my $class = shift; + die "$class->_is_used not implemented"; +} + +=back + +=head1 BUGS + +We can't reliably check for duplicate addresses across tables. A +more robust implementation would be to put all assigned IP addresses +in a single table with a unique index. We do a best-effort check +anyway, but it has a race condition. + +=cut + +1; diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 01250e593..912f3e269 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2184,6 +2184,9 @@ sub tables_hashref { 'shell', 'varchar', 'NULL', $char_d, '', '', 'quota', 'varchar', 'NULL', $char_d, '', '', 'slipip', 'varchar', 'NULL', 15, '', '', #four TINYINTs, bah. + # IP address mgmt + 'routernum', 'int', 'NULL', '', '', '', + 'blocknum', 'int', 'NULL', '', '', '', 'seconds', 'int', 'NULL', '', '', '', #uhhhh 'seconds_threshold', 'int', 'NULL', '', '', '', 'upbytes', 'bigint', 'NULL', '', '', '', diff --git a/FS/FS/addr_block.pm b/FS/FS/addr_block.pm index 686bdbd18..6a62777be 100755 --- a/FS/FS/addr_block.pm +++ b/FS/FS/addr_block.pm @@ -6,6 +6,7 @@ use FS::Record qw( qsearchs qsearch dbh ); use FS::router; use FS::svc_broadband; use FS::Conf; +use FS::IP_Mixin; use NetAddr::IP; use Carp qw( carp ); use List::Util qw( first ); @@ -238,7 +239,7 @@ sub next_free_addr { my $self = shift; my $selfaddr = $self->NetAddr; - return if $self->manual_flag; + return () if $self->manual_flag; my $conf = new FS::Conf; my @excludeaddr = $conf->config('exclude_ip_addr'); @@ -249,9 +250,7 @@ sub next_free_addr { $selfaddr->addr, $selfaddr->network->addr, $selfaddr->broadcast->addr, - (map { $_->NetAddr->addr } - qsearch('svc_broadband', { blocknum => $self->blocknum }) - ), @excludeaddr + FS::IP_Mixin->used_addresses($self) ); # just do a linear search of the block diff --git a/FS/FS/svc_IP_Mixin.pm b/FS/FS/svc_IP_Mixin.pm new file mode 100644 index 000000000..7026205a5 --- /dev/null +++ b/FS/FS/svc_IP_Mixin.pm @@ -0,0 +1,123 @@ +package FS::svc_IP_Mixin; + +use strict; +use base 'FS::IP_Mixin'; +use FS::Record qw(qsearchs qsearch); + +=item addr_block + +Returns the address block assigned to this service. + +=item router + +Returns the router assigned to this service, if there is one. + +=cut + +#addr_block and router methods provided by FS::IP_Mixin + +=item NetAddr + +Returns the address as a L object. Use C<$svc->NetAddr->addr> +to put it into canonical string form. + +=cut + +sub NetAddr { + my $self = shift; + NetAddr::IP->new($self->ip_addr); +} + +=item ip_addr + +Wrapper for set/get on the IP address field. + +=cut + +sub ip_addr { + my $self = shift; + my $ip_field = $self->table_info->{'ip_field'} + or return ''; + if ( @_ ) { + $self->set($ip_field, @_); + } else { + $self->get($ip_field); + } +} + +=item allowed_routers + +Returns a list of L objects allowed on this service. + +=cut + +sub allowed_routers { + my $self = shift; + my $svcpart = $self->svcnum ? $self->cust_svc->svcpart : $self->svcpart; + my @r = map { $_->router } + qsearch('part_svc_router', { svcpart => $svcpart }); + + if ( $self->cust_main ) { + my $agentnum = $self->cust_main->agentnum; + return grep { !$_->agentnum or $_->agentnum == $agentnum } @r; + } else { + return @r; + } +} + +=item svc_ip_check + +Wrapper for C which also checks the validity of the router. + +=cut + +sub svc_ip_check { + my $self = shift; + my $error = $self->ip_check; + return $error if $error; + if ( my $router = $self->router ) { + if ( grep { $_->routernum eq $router->routernum } $self->allowed_routers ) { + return ''; + } else { + return 'Router '.$router->routername.' not available for this service'; + } + } + ''; +} + +sub _used_addresses { + my ($class, $block, $exclude) = @_; + my $ip_field = $class->table_info->{'ip_field'} + or return (); + # if the service doesn't have an ip_field, then it has no IP addresses + # in use, yes? + + my %hash = ( $ip_field => { op => '!=', value => '' } ); + $hash{'blocknum'} = $block->blocknum if $block; + $hash{'svcnum'} = { op => '!=', value => $exclude->svcnum } if ref $exclude; + map { $_->NetAddr->addr } qsearch($class->table, \%hash); +} + +sub _is_used { + my ($class, $addr, $exclude) = @_; + my $ip_field = $class->table_info->{'ip_field'} + or return ''; + + my $svc = qsearchs($class->table, { $ip_field => $addr }) + or return ''; + + return '' if ( ref $exclude and $exclude->svcnum == $svc->svcnum ); + + my $cust_svc = $svc->cust_svc; + if ( $cust_svc ) { + my @label = $cust_svc->label; + # "svc_foo 1234 (Service Desc)" + # this should be enough to identify it without leaking customer + # names across agents + "$label[2] $label[3] ($label[0])"; + } else { + join(' ', $class->table, $svc->svcnum, '(unlinked service)'); + } +} + +1; diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 7ce79ae01..8e71d829d 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -6,6 +6,7 @@ use base qw( FS::svc_Domain_Mixin FS::svc_CGPRule_Mixin FS::svc_Radius_Mixin FS::svc_Tower_Mixin + FS::svc_IP_Mixin FS::svc_Common ); use vars qw( $DEBUG $me $conf $skip_fuzzyfiles $dir_prefix @shells $usernamemin @@ -1126,6 +1127,8 @@ sub check { || $self->ut_foreign_key( 'domsvc', 'svc_domain', 'svcnum' ) || $self->ut_foreign_keyn('pbxsvc', 'svc_pbx', 'svcnum' ) || $self->ut_foreign_keyn('sectornum','tower_sector','sectornum') + || $self->ut_foreign_keyn('routernum','router','routernum') + || $self->ut_foreign_keyn('blocknum','addr_block','blocknum') || $self->ut_textn('sec_phrase') || $self->ut_snumbern('seconds') || $self->ut_snumbern('upbytes') @@ -1161,6 +1164,15 @@ sub check { ; return $error if $error; + # assign IP address, etc. + if ( $conf->exists('svc_acct-ip_addr') ) { + my $error = $self->svc_ip_check; + return $error if $error; + } else { # I think this is correct + $self->routernum(''); + $self->blocknum(''); + } + my $cust_pkg; local $username_letter = $username_letter; local $username_uppercase = $username_uppercase; @@ -1314,7 +1326,7 @@ sub check { unless ( $part_svc->part_svc_column('slipip')->columnflag eq 'F' ) { if ( $recref->{slipip} eq '' ) { - $recref->{slipip} = ''; + $recref->{slipip} = ''; # eh? } elsif ( $recref->{slipip} eq '0e0' ) { $recref->{slipip} = '0e0'; } else { @@ -1322,7 +1334,6 @@ sub check { or return "Illegal slipip: ". $self->slipip; $recref->{slipip} = $1; } - } #arbitrary RADIUS stuff; allow ut_textn for now @@ -1384,6 +1395,7 @@ sub check { else { return "invalid password encoding ('".$recref->{_password_encoding}."'"; } + $self->SUPER::check; } diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index 26659d52a..af8135304 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -1,5 +1,10 @@ package FS::svc_broadband; -use base qw(FS::svc_Radius_Mixin FS::svc_Tower_Mixin FS::svc_Common); +use base qw( + FS::svc_Radius_Mixin + FS::svc_Tower_Mixin + FS::svc_IP_Mixin + FS::svc_Common + ); use strict; use vars qw($conf); @@ -412,38 +417,13 @@ sub check { } my $agentnum = $cust_pkg->cust_main->agentnum if $cust_pkg; - if ( $conf->exists('auto_router') and $self->ip_addr and !$self->routernum ) { - # assign_router is guaranteed to provide a router that's legal - # for this agent and svcpart - my $error = $self->_check_ip_addr || $self->assign_router; - return $error if $error; + # assign IP address / router / block + $error = $self->svc_ip_check; + return $error if $error; + if ( !$self->ip_addr + and !$conf->exists('svc_broadband-allow_null_ip_addr') ) { + return 'IP address is required'; } - elsif ($self->routernum) { - return "Router ".$self->routernum." does not provide this service" - unless qsearchs('part_svc_router', { - svcpart => $svcpart, - routernum => $self->routernum - }); - - my $router = $self->router; - return "Router ".$self->routernum." does not serve this customer" - if $router->agentnum and $agentnum and $router->agentnum != $agentnum; - - if ( $router->manual_addr ) { - $self->blocknum(''); - } - else { - my $addr_block = $self->addr_block; - if ( $self->ip_addr eq '' - and not ( $addr_block and $addr_block->manual_flag ) ) { - my $error = $self->assign_ip_addr; - return $error if $error; - } - } - - my $error = $self->_check_ip_addr; - return $error if $error; - } # if $self->routernum if ( $cust_pkg && ! $self->latitude && ! $self->longitude ) { my $l = $cust_pkg->cust_location_or_main; @@ -459,104 +439,12 @@ sub check { $self->SUPER::check; } -=item assign_ip_addr - -Assign an IP address matching the selected router, and the selected block -if there is one. - -=cut - -sub assign_ip_addr { - my $self = shift; - my @blocks; - my $ip_addr; - - if ( $self->addr_block and $self->addr_block->routernum == $self->routernum ) { - # simple case: user chose a block, find an address in that block - # (this overrides an existing IP address if it's not in the block) - @blocks = ($self->addr_block); - } - elsif ( $self->routernum ) { - @blocks = $self->router->auto_addr_block; - } - else { - return ''; - } -#warn "assigning ip address in blocks\n".join("\n",map{$_->cidr} @blocks)."\n"; - - foreach my $block ( @blocks ) { - if ( $self->ip_addr and $block->NetAddr->contains($self->NetAddr) ) { - # don't change anything - return ''; - } - $ip_addr = $block->next_free_addr; - if ( $ip_addr ) { - $self->set(ip_addr => $ip_addr->addr); - $self->set(blocknum => $block->blocknum); - return ''; - } - } - return 'No IP address available on this router'; -} - -=item assign_router - -Assign an address block and router matching the selected IP address. -Does nothing if IP address is null. - -=cut - -sub assign_router { - my $self = shift; - return '' if !$self->ip_addr; - #warn "assigning router/block for ".$self->ip_addr."\n"; - foreach my $router ($self->allowed_routers) { - foreach my $block ($router->addr_block) { - if ( $block->NetAddr->contains($self->NetAddr) ) { - $self->blocknum($block->blocknum); - $self->routernum($block->routernum); - return ''; - } - } - } - return $self->ip_addr.' is not in an allowed block.'; -} - -sub _check_ip_addr { - my $self = shift; - - if (not($self->ip_addr) or $self->ip_addr eq '0.0.0.0') { - return '' if $conf->exists('svc_broadband-allow_null_ip_addr'); - return 'IP address required'; - } - else { - return 'Cannot parse address: '.$self->ip_addr unless $self->NetAddr; - } - - if ( $self->addr_block - and not $self->addr_block->NetAddr->contains($self->NetAddr) ) { - return 'Address '.$self->ip_addr.' not in block '.$self->addr_block->cidr; - } - -# if (my $dup = qsearchs('svc_broadband', { -# ip_addr => $self->ip_addr, -# svcnum => {op=>'!=', value => $self->svcnum} -# }) ) { -# return 'IP address conflicts with svcnum '.$dup->svcnum; -# } - ''; -} - sub _check_duplicate { my $self = shift; # Not a reliable check because the table isn't locked, but # that's why we have a unique index. This is just to give a # friendlier error message. my @dup; - @dup = $self->find_duplicates('global', 'ip_addr'); - if ( @dup ) { - return "IP address in use (svcnum ".$dup[0]->svcnum.")"; - } @dup = $self->find_duplicates('global', 'mac_addr'); if ( @dup ) { return "MAC address in use (svcnum ".$dup[0]->svcnum.")"; @@ -565,64 +453,6 @@ sub _check_duplicate { ''; } - -=item NetAddr - -Returns a NetAddr::IP object containing the IP address of this service. The netmask -is /32. - -=cut - -sub NetAddr { - my $self = shift; - new NetAddr::IP ($self->ip_addr); -} - -=item addr_block - -Returns the FS::addr_block record (i.e. the address block) for this broadband service. - -=cut - -sub addr_block { - my $self = shift; - qsearchs('addr_block', { blocknum => $self->blocknum }); -} - -=item router - -Returns the FS::router record for this service. - -=cut - -sub router { - my $self = shift; - qsearchs('router', { routernum => $self->routernum }); -} - -=item allowed_routers - -Returns a list of allowed FS::router objects. - -=cut - -sub allowed_routers { - my $self = shift; - my $svcpart = $self->svcnum ? $self->cust_svc->svcpart : $self->svcpart; - my @r = map { $_->router } qsearch('part_svc_router', - { svcpart => $svcpart }); - if ( $self->cust_main ) { - my $agentnum = $self->cust_main->agentnum; - return grep { !$_->agentnum or $_->agentnum == $agentnum } @r; - } - else { - return @r; - } -} - -=back - - =item mac_addr_formatted CASE DELIMITER Format the MAC address (for use by exports). If CASE starts with "l" diff --git a/httemplate/edit/process/svc_acct.cgi b/httemplate/edit/process/svc_acct.cgi index 41aca65ee..d4bcd35ed 100755 --- a/httemplate/edit/process/svc_acct.cgi +++ b/httemplate/edit/process/svc_acct.cgi @@ -31,6 +31,11 @@ foreach (map { $_,$_."_threshold" } qw( upbytes downbytes totalbytes )) { $cgi->param($_, FS::UI::bytecount::parse_bytecount($cgi->param($_)) ); } +#for slipip, convert '(automatic)' to null +my $ip_addr = $cgi->param('slipip'); +$ip_addr =~ s/[^\d\.]//g; +$cgi->param('slipip', $ip_addr); + #unmunge cgp_accessmodes (falze laziness-ish w/part_svc.pm::process &svc_domain) unless ( $cgi->param('cgp_accessmodes') ) { $cgi->param('cgp_accessmodes', diff --git a/httemplate/edit/router.cgi b/httemplate/edit/router.cgi index fdcd7b3b3..0df9b457e 100755 --- a/httemplate/edit/router.cgi +++ b/httemplate/edit/router.cgi @@ -29,8 +29,15 @@ die "access denied" unless $curuser->access_right('Broadband configuration') || $curuser->access_right('Broadband global configuration'); +my @svc_x = 'svc_broadband'; +if ( FS::Conf->new->exists('svc_acct-ip_addr') ) { + push @svc_x, 'svc_acct'; +} + my $callback = sub { my ($cgi, $object, $fields) = (shift, shift, shift); + + my $extra_sql = ' AND svcdb IN(' . join(',', map { "'$_'" } @svc_x) . ')'; unless ($object->svcnum) { push @{$fields}, { 'type' => 'tablebreak-tr-title', @@ -41,7 +48,8 @@ my $callback = sub { 'target_table' => 'part_svc', 'link_table' => 'part_svc_router', 'name_col' => 'svc', - 'hashref' => { 'svcdb' => 'svc_broadband', 'disabled' => '' }, + 'hashref' => { 'disabled' => '' }, + 'extra_sql' => $extra_sql, }; } }; diff --git a/httemplate/edit/svc_acct.cgi b/httemplate/edit/svc_acct.cgi index 142c11150..c1f74551d 100755 --- a/httemplate/edit/svc_acct.cgi +++ b/httemplate/edit/svc_acct.cgi @@ -276,14 +276,26 @@ function randomPass() { 'communigate' => $communigate, &> -% if ( $part_svc->part_svc_column('slipip')->columnflag =~ /^[FA]$/ ) { - -% } else { - - <% mt('IP') |h %> - - -% } +% if ( $conf->exists('svc_acct-ip_addr') ) { +% # router/block selection UI +% # (should we show this if slipip is fixed?) +<& /elements/tr-select-router_block_ip.html, + 'object' => $svc_acct, + 'ip_field' => 'slipip' +&> +% } else { +% # don't expose these to the user--they're only useful in the other case + + +% if ( $part_svc->part_svc_column('slipip')->columnflag =~ /^[FA]$/ ) { + +% } else { + + <% mt('IP') |h %> + + +% } +% } % my %label = ( seconds => 'Time', % upbytes => 'Upload bytes', diff --git a/httemplate/elements/tr-select-router_block_ip.html b/httemplate/elements/tr-select-router_block_ip.html index 95d1787b8..11f7c4831 100644 --- a/httemplate/elements/tr-select-router_block_ip.html +++ b/httemplate/elements/tr-select-router_block_ip.html @@ -58,12 +58,13 @@ function clearhint_ip_addr (what) { <& /elements/tr-td-label.html, label => 'IP address' &> -% if ( $fixed{'ip_addr'} ) { - <% $opt{'ip_addr'} || '' %> % } % else { - % } @@ -78,6 +79,7 @@ my $conf = FS::Conf->new; my $svc_x = $opt{'object'}; if ( $svc_x ) { + # $svc_x->ip_addr does work, even for non-svc_broadband. $opt{$_} = $svc_x->$_ foreach qw(routernum blocknum ip_addr svcpart); if ( $svc_x->svcnum ) { @@ -86,6 +88,8 @@ if ( $svc_x ) { } my $svcpart = $opt{'svcpart'} || ''; +my $ip_field = $opt{'ip_field'} || 'ip_addr'; + my %fixed; # which fields are fixed $svcpart =~ /^\d*$/ or die "invalid svcpart '$svcpart'"; if ( $svcpart ) { @@ -93,13 +97,13 @@ if ( $svcpart ) { # Traditionally, columnflag 'F' on IP address means that it MUST # be auto-assigned (or, if null IP addresses are allowed, that # it must be null). - foreach (qw(routernum blocknum ip_addr)) { + foreach (qw(routernum blocknum), $ip_field) { my $psc = $part_svc->part_svc_column($_); if ( $psc and $psc->columnflag eq 'F' ) { $fixed{$_} = $psc->columnvalue; } } - if ( $fixed{'routernum'} ) { + if ( exists $fixed{'routernum'} ) { @routers = (FS::router->by_key($fixed{'routernum'})) } else { diff --git a/httemplate/view/svc_acct/basics.html b/httemplate/view/svc_acct/basics.html index 1cdf77615..2d9953fcc 100644 --- a/httemplate/view/svc_acct/basics.html +++ b/httemplate/view/svc_acct/basics.html @@ -91,15 +91,29 @@ % } +<%perl> +# minor false laziness w/ view/svc_broadband.cgi +sub slipip { + my $svc_acct = shift; + my $out = $svc_acct->slipip or return ''; + if ( $out eq '0.0.0.0' or $out eq '0e0' ) { + return '('.mt('Dynamic').''; + } + $out .= ' ('. + include('/elements/popup_link-ping.html', ip => $svc_acct->slipip). + ')'; + if ( my $addr_block = $svc_acct->addr_block ) { + $out .= '
Netmask: ' . $addr_block->NetAddr->mask . + '
Gateway: ' . $addr_block->ip_gateway; + } + $out; +} + + % if ($svc_acct->slipip) { <& /view/elements/tr.html, label=>mt('IP address'), - value=> ( $svc_acct->slipip eq "0.0.0.0" || $svc_acct->slipip eq '0e0' ) - ? "(".mt('Dynamic').")" - : $svc_acct->slipip. ' '. - include('/elements/popup_link-ping.html', - 'ip'=>$svc_acct->slipip, - ) + value=> slipip($svc_acct) &> % } -- cgit v1.2.1 From 3182a68ebdfaa52debc2700fac56b1aa76750150 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 30 Oct 2012 14:11:37 -0700 Subject: Windstream CDR format, #17063 --- FS/FS/cdr/windstream.pm | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 FS/FS/cdr/windstream.pm diff --git a/FS/FS/cdr/windstream.pm b/FS/FS/cdr/windstream.pm new file mode 100644 index 000000000..7aa3294e1 --- /dev/null +++ b/FS/FS/cdr/windstream.pm @@ -0,0 +1,77 @@ +package FS::cdr::simple; + +use strict; +use vars qw( @ISA %info %calltypes ); +use FS::cdr qw(_cdr_date_parser_maker); + +@ISA = qw(FS::cdr); + +%calltypes = ( + # numbers are arbitrary + 'IntraLata Calling' => 1 , + 'Intrastate Calling' => 2 , + 'Interstate Calling' => 3 , + 'International Calling' => 4 , + 'Intrastate Toll Free' => 5 , + 'Interstate Toll Free' => 6 , + 'Toll Free Canada' => 7 , + 'Toll Free NANP' => 8 , + 'IntraLata Directory Assistance' => 9 , + 'LD Directory Assistance' => 10 , + 'Message Local Usage' => 11 , + 'Operator Assistance' => 12 , + 'Operator Services' => 13 , + 'O- Assistance (Minus)' => 14 , + 'O+ Assistance (Plus)' => 15 , + 'IntraLata Toll 3rd Party' => 16 , + 'IntraLata Toll Collect' => 17 , + 'Third Number Billing' => 18 , + 'Third Number Billing - Assisted' => 19 , + 'Three Way Calling (per use)' => 20 , + 'Busy Connect (per use)' => 21 , + 'Busy Line Interrupt (per use)' => 22 , + 'Busy Line Verification (per use)' => 23 , + 'Call Forwarding Variable per access' => 24 , + 'Call Return (*69 per use)' => 25 , + 'Call Trace (*per use)' => 26 , + 'Conference Calling Feature' => 27 , + 'Directory Assistance Call Completion (per use)' => 28 , +); + +$_ = lc($_) for keys(%calltypes); + +%info = ( + 'name' => 'Windstream', + 'weight' => 520, + 'header' => 0, + 'sep_char' => "\t", + 'import_fields' => [ + + 'accountcode', # Account Number + 'uniqueid', # Reference Number + '', # Call Type (see Service Type below) + _cdr_date_parser_maker('answerdate'), # Answer Date + '', # Account Code--unused? + '', # CPN_DID + 'src', # From Number + 'upstream_src_regionname', # From Location + '', # From Country + 'dst', # To Number + 'upstream_dst_regionname', # To Location + '', # To Country Code + '', # Units + 'upstream_price', # Amount + sub { # Service Type + my ($cdr, $field) = @_; + $cdr->calltypenum($calltypes{$field} || '') + }, + '', # Payphone Indicator + sub { # TF Service Number + # replace the To Number with this, if there is one + my ($cdr, $field) = @_; + $cdr->dst($field) if ( $field ); + }, + ], +); + +1; -- cgit v1.2.1 From f1615450ec49948f95612b5311c628e261132645 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 30 Oct 2012 15:53:51 -0700 Subject: change name of return files for EFT Canada batches, #16252 --- FS/bin/freeside-eftca-download | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/bin/freeside-eftca-download b/FS/bin/freeside-eftca-download index 702a80ca1..d54a724ab 100755 --- a/FS/bin/freeside-eftca-download +++ b/FS/bin/freeside-eftca-download @@ -82,7 +82,7 @@ foreach my $agent (@agents) { $sftp->setcwd('/Returns'); - my $files = $sftp->ls('.', wanted => qr/^ReturnFile/, names_only => 1); + my $files = $sftp->ls('.', wanted => qr/\.txt$/, names_only => 1); die "no response files found\n" if !@$files; FILE: foreach my $filename (@$files) { -- cgit v1.2.1 From 4aae795edacb818fcab38d86b645a9fa5eb1ec58 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 30 Oct 2012 16:04:21 -0700 Subject: fix spelling --- FS/FS/cdr/windstream.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cdr/windstream.pm b/FS/FS/cdr/windstream.pm index 7aa3294e1..a6200b2cd 100644 --- a/FS/FS/cdr/windstream.pm +++ b/FS/FS/cdr/windstream.pm @@ -1,4 +1,4 @@ -package FS::cdr::simple; +package FS::cdr::windstream; use strict; use vars qw( @ISA %info %calltypes ); -- cgit v1.2.1 From 7d2e3190dd3b3de0c8adbfb742b24f5f686d785f Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 1 Nov 2012 21:33:14 -0700 Subject: per-day radius usage, RT#19771 --- FS/FS/part_pkg/sqlradacct_daily.pm | 196 +++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 FS/FS/part_pkg/sqlradacct_daily.pm diff --git a/FS/FS/part_pkg/sqlradacct_daily.pm b/FS/FS/part_pkg/sqlradacct_daily.pm new file mode 100644 index 000000000..edfa96138 --- /dev/null +++ b/FS/FS/part_pkg/sqlradacct_daily.pm @@ -0,0 +1,196 @@ +package FS::part_pkg::sqlradacct_hour; +use base qw( FS::part_pkg::flat ); + +use strict; +use vars qw(%info); +use Time::Local qw( timelocal timelocal_nocheck ); +#use FS::Record qw(qsearch qsearchs); + +%info = ( + 'name' => 'Time and data charges from an SQL RADIUS radacct table, with per-day limits', + 'shortname' => 'Daily usage charges from RADIUS', + 'inherit_fields' => [ 'global_Mixin' ], + 'fields' => { + 'recur_included_hours' => { 'name' => 'Hours included per day', + 'default' => 0, + }, + 'recur_hourly_charge' => { 'name' => 'Additional charge per hour', + 'default' => 0, + }, + 'recur_hourly_cap' => { 'name' => 'Maximum daily charge for hours'. + ' (0 means no cap)', + + 'default' => 0, + }, + + 'recur_included_input' => { 'name' => 'Upload megabytes included per day', + 'default' => 0, + }, + 'recur_input_charge' => { 'name' => + 'Additional charge per megabyte upload', + 'default' => 0, + }, + 'recur_input_cap' => { 'name' => 'Maximum daily charge for upload'. + ' (0 means no cap)', + 'default' => 0, + }, + + 'recur_included_output' => { 'name' => 'Download megabytes included per day', + 'default' => 0, + }, + 'recur_output_charge' => { 'name' => + 'Additional charge per megabyte download', + 'default' => 0, + }, + 'recur_output_cap' => { 'name' => 'Maximum daily charge for download'. + ' (0 means no cap)', + 'default' => 0, + }, + + 'recur_included_total' => { 'name' => + 'Total megabytes included per day', + 'default' => 0, + }, + 'recur_total_charge' => { 'name' => + 'Additional charge per megabyte total', + 'default' => 0, + }, + 'recur_total_cap' => { 'name' => 'Maximum daily charge for total'. + ' megabytes (0 means no cap)', + 'default' => 0, + }, + + 'global_cap' => { 'name' => 'Daily cap on all overage charges'. + ' (0 means no cap)', + 'default' => 0, + }, + + }, + 'fieldorder' => [qw( recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap )], #global_cap )], + 'weight' => 41, +); + +sub price_info { + my $self = shift; + my $str = $self->SUPER::price_info; + $str .= " plus usage" if $str; + $str; +} + +#hacked-up false laziness w/sqlradacct_hour, +# but keeping it separate to start with is safer for existing folks +sub calc_recur { + my($self, $cust_pkg, $sdate, $details ) = @_; + + my $last_bill = $cust_pkg->last_bill; + + my $charges = 0; + + #loop over each day starting with last_bill inclusive (since we generated a + # bill that day, we didn't have a full picture of the day's usage) + # and ending with sdate exclusive (same reason) + + my($l_day, $l_mon, $l_year) = (localtime($last_bill))[3,5]; + my $day_start = timelocal(0,0,0, $l_day, $l_mon, $l_year); + + my($s_day, $s_mon, $s_year) = (localtime($$sdate))[3,5]; + my $billday_start = timelocal(0,0,0, $s_day, $s_mon, $s_year); + + while ( $day_start < $billday_start ) { + + my($day, $mon, $year) = (localtime($day_start))[3,5]; + my $tomorrow = timelocal_nocheck(0,0,0, $day+1, $mon, $year); + + #afact the usage methods already use the lower bound inclusive and the upper + # exclusive, so no need for $tomorrow-1 + my @range = ( $day_start, $tomorrow ); + + my $hours = $cust_pkg->seconds_since_sqlradacct(@range) / 3600; + $hours -= $self->option('recur_included_hours'); + $hours = 0 if $hours < 0; + + my $input = $cust_pkg->attribute_since_sqlradacct( @range, + 'AcctInputOctets') + / 1048576; + + my $output = $cust_pkg->attribute_since_sqlradacct( @range, + 'AcctOutputOctets' ) + / 1048576; + + my $total = $input + $output - $self->option('recur_included_total'); + $total = 0 if $total < 0; + $input = $input - $self->option('recur_included_input'); + $input = 0 if $input < 0; + $output = $output - $self->option('recur_included_output'); + $output = 0 if $output < 0; + + my $totalcharge = + sprintf('%.2f', $total * $self->option('recur_total_charge')); + $totalcharge = $self->option('recur_total_cap') + if $self->option('recur_total_cap') + && $totalcharge > $self->option('recur_total_cap'); + + my $inputcharge = + sprintf('%.2f', $input * $self->option('recur_input_charge')); + $inputcharge = $self->option('recur_input_cap') + if $self->option('recur_input_cap') + && $inputcharge > $self->option('recur_input_cap'); + + my $outputcharge = + sprintf('%.2f', $output * $self->option('recur_output_charge')); + $outputcharge = $self->option('recur_output_cap') + if $self->option('recur_output_cap') + && $outputcharge > $self->option('recur_output_cap'); + + my $hourscharge = + sprintf('%.2f', $hours * $self->option('recur_hourly_charge')); + $hourscharge = $self->option('recur_hourly_cap') + if $self->option('recur_hourly_cap') + && $hourscharge > $self->option('recur_hourly_cap'); + + my $fordate = time2str('for %a %b %o, %Y', $day_start); + + if ( $self->option('recur_total_charge') > 0 ) { + push @$details, "Data $fordate ". + sprintf('%.1f', $total). " megs: $totalcharge"; + } + if ( $self->option('recur_input_charge') > 0 ) { + push @$details, "Download $fordate ". + sprintf('%.1f', $input). " megs: $inputcharge"; + } + if ( $self->option('recur_output_charge') > 0 ) { + push @$details, "Upload $fordate". + sprintf('%.1f', $output). " megs: $outputcharge"; + } + if ( $self->option('recur_hourly_charge') > 0 ) { + push @$details, "Time $fordate ". + sprintf('%.1f', $hours). " hours: $hourscharge"; + } + + my $daily_charges = $hourscharge + $inputcharge + $outputcharge + $totalcharge; + if ( $self->option('global_cap') && $charges > $self->option('global_cap') ) { + $charges = $self->option('global_cap'); + push @$details, "Usage charges $fordate capped at: $charges"; + } + + $charges += $daily_charges; + + $day_start = $tomorrow; + } + + $self->option('recur_fee') + $charges; +} + +sub can_discount { 0; } + +sub is_free_options { + qw( setup_fee recur_fee recur_hourly_charge + recur_input_charge recur_output_charge recur_total_charge ); +} + +sub base_recur { + my($self, $cust_pkg) = @_; + $self->option('recur_fee'); +} + +1; -- cgit v1.2.1 From bf4ca4ff3981225a2b80e3951284df60de078c68 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 1 Nov 2012 21:33:52 -0700 Subject: better name for RADIUS usage price plan --- FS/FS/part_pkg/sqlradacct_hour.pm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/FS/FS/part_pkg/sqlradacct_hour.pm b/FS/FS/part_pkg/sqlradacct_hour.pm index a2b64c740..c9fdb36f4 100644 --- a/FS/FS/part_pkg/sqlradacct_hour.pm +++ b/FS/FS/part_pkg/sqlradacct_hour.pm @@ -8,7 +8,7 @@ use FS::part_pkg::flat; @ISA = qw(FS::part_pkg::flat); %info = ( - 'name' => 'Base charge plus per-hour (and for data) from an SQL RADIUS radacct table', + 'name' => 'Time and data charges from an SQL RADIUS radacct table', 'shortname' => 'Usage charges from RADIUS', 'inherit_fields' => [ 'global_Mixin' ], 'fields' => { @@ -68,8 +68,6 @@ use FS::part_pkg::flat; }, 'fieldorder' => [qw( recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap global_cap )], - #'setup' => 'what.setup_fee.value', - #'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $inputcharge = sprintf(\"%.2f\", \' + what.recur_input_charge.value + \' * $input); my $outputcharge = sprintf(\"%.2f\", \' + what.recur_output_charge.value + \' * $output); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + what.recur_input_charge.value + \' > 0 ) { push @details, \"Last month\\\'s download \". sprintf(\"%.1f\", $input). \" megs: \\\$$inputcharge\" } if ( \' + what.recur_output_charge.value + \' > 0 ) { push @details, \"Last month\\\'s upload \". sprintf(\"%.1f\", $output). \" megs: \\\$$outputcharge\" } if ( \' + what.recur_hourly_charge.value + \' > 0 ) { push @details, \"Last month\\\'s time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; } \' + what.recur_fee.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'', 'weight' => 40, ); -- cgit v1.2.1 From 5569583bbd74d5f497e2b2923815ff1f66a28be7 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 1 Nov 2012 21:34:56 -0700 Subject: per-day radius usage, RT#19771 --- FS/FS/part_pkg/sqlradacct_daily.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_pkg/sqlradacct_daily.pm b/FS/FS/part_pkg/sqlradacct_daily.pm index edfa96138..7bfdd525f 100644 --- a/FS/FS/part_pkg/sqlradacct_daily.pm +++ b/FS/FS/part_pkg/sqlradacct_daily.pm @@ -66,7 +66,7 @@ use Time::Local qw( timelocal timelocal_nocheck ); }, }, - 'fieldorder' => [qw( recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap )], #global_cap )], + 'fieldorder' => [qw( recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap global_cap )], 'weight' => 41, ); -- cgit v1.2.1 From 650f043339fcf90d84a863763c4a4cbfbbda65bc Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 1 Nov 2012 22:38:01 -0700 Subject: per-day radius usage, RT#19771 --- FS/FS/part_pkg/sqlradacct_daily.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FS/FS/part_pkg/sqlradacct_daily.pm b/FS/FS/part_pkg/sqlradacct_daily.pm index 7bfdd525f..d99def21b 100644 --- a/FS/FS/part_pkg/sqlradacct_daily.pm +++ b/FS/FS/part_pkg/sqlradacct_daily.pm @@ -1,9 +1,10 @@ -package FS::part_pkg::sqlradacct_hour; +package FS::part_pkg::sqlradacct_daily; use base qw( FS::part_pkg::flat ); use strict; use vars qw(%info); use Time::Local qw( timelocal timelocal_nocheck ); +use Date::Format; #use FS::Record qw(qsearch qsearchs); %info = ( -- cgit v1.2.1 From c9e1692c66627ff8cb06be4c556c5b77b30d2b59 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 2 Nov 2012 13:49:39 -0700 Subject: fix new troop dates, RT#20081 --- FS/FS/cdr/troop2.pm | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/FS/FS/cdr/troop2.pm b/FS/FS/cdr/troop2.pm index ee6474061..17a8b2a4a 100644 --- a/FS/FS/cdr/troop2.pm +++ b/FS/FS/cdr/troop2.pm @@ -2,11 +2,12 @@ package FS::cdr::troop2; use strict; use base qw( FS::cdr ); -use vars qw( %info $tmp_date $tmp_src_city $tmp_dst_city ); -use Date::Parse; -#use Time::Local; +use vars qw( %info $tmp_mon $tmp_mday $tmp_year $tmp_src_city $tmp_dst_city ); +use Time::Local; ##use FS::cdr qw( _cdr_date_parser_maker _cdr_min_parser_maker ); +use Data::Dumper; + %info = ( 'name' => 'Troop', 'weight' => 219, @@ -17,16 +18,27 @@ use Date::Parse; 'userfield', #account_num (userfield?) + # XXX false laziness w/bell_west.pm #call_date sub { my($cdr, $date) = @_; - #is this an excel date? or just text? - $tmp_date = $date; + + my $datetime = DateTime::Format::Excel->parse_datetime( $date ); + $tmp_mon = $datetime->mon_0; + $tmp_mday = $datetime->mday; + $tmp_year = $datetime->year; }, #call_time sub { my($cdr, $time) = @_; - #is this an excel time? or just text? - $cdr->startdate( str2time("$tmp_date $time") ); + #my($sec, $min, $hour, $mday, $mon, $year)= localtime($cdr->startdate); + + #$sec = $time * 86400; + my $sec = int( $time * 86400 + .5); + + #$cdr->startdate( timelocal($3, $2, $1 ,$mday, $mon, $year) ); + $cdr->startdate( + timelocal(0, 0, 0, $tmp_mday, $tmp_mon, $tmp_year) + $sec + ); }, 'src', #orig_tn -- cgit v1.2.1 From 7313b39b6d60bea8c5bd9712527a08093bb337af Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 3 Nov 2012 12:23:23 -0700 Subject: adding pkg_unsuspend and unsuspend actions, RT#20084 --- FS/FS/part_event/Action/pkg_unsuspend.pm | 25 +++++++++++++++++++++++++ FS/FS/part_event/Action/unsuspend.pm | 23 +++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 FS/FS/part_event/Action/pkg_unsuspend.pm create mode 100644 FS/FS/part_event/Action/unsuspend.pm diff --git a/FS/FS/part_event/Action/pkg_unsuspend.pm b/FS/FS/part_event/Action/pkg_unsuspend.pm new file mode 100644 index 000000000..894103896 --- /dev/null +++ b/FS/FS/part_event/Action/pkg_unsuspend.pm @@ -0,0 +1,25 @@ +package FS::part_event::Action::pkg_unsuspend; + +use strict; +use base qw( FS::part_event::Action ); + +sub description { 'Unsuspend this package'; } + +sub eventtable_hashref { + { 'cust_pkg' => 1, + 'svc_acct' => 1, }; +} + +sub default_weight { 20; } + +sub do_action { + my( $self, $object, $cust_event ) = @_; + my $cust_pkg = $self->cust_pkg($object); + + my $error = $cust_pkg->unsuspend(); + die $error if $error; + + ''; +} + +1; diff --git a/FS/FS/part_event/Action/unsuspend.pm b/FS/FS/part_event/Action/unsuspend.pm new file mode 100644 index 000000000..b8cfbb12c --- /dev/null +++ b/FS/FS/part_event/Action/unsuspend.pm @@ -0,0 +1,23 @@ +package FS::part_event::Action::unsuspend; + +use strict; +use base qw( FS::part_event::Action ); + +sub description { 'Unsuspend all of this customer\'s suspended packages'; } + +sub default_weight { 11; } + +sub do_action { + my( $self, $cust_object ) = @_; + + my $cust_main = $self->cust_main($cust_object); + + my @err = $cust_main->unsuspend(); + + die join(' / ', @err) if scalar(@err); + + ''; + +} + +1; -- cgit v1.2.1 From d7f622dc83e9050f83dd12abbaf1cd405a15aa22 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 3 Nov 2012 12:25:22 -0700 Subject: adding pkg_reason_type and pkg_not_reason_type conditions, RT#20084 --- FS/FS/part_event/Condition/pkg_not_reason_type.pm | 58 +++++++++++++++++++++++ FS/FS/part_event/Condition/pkg_reason_type.pm | 58 +++++++++++++++++++++++ httemplate/elements/select-reason_type.html | 21 ++++++++ httemplate/elements/tr-select-reason_type.html | 29 ++++++++++++ 4 files changed, 166 insertions(+) create mode 100644 FS/FS/part_event/Condition/pkg_not_reason_type.pm create mode 100644 FS/FS/part_event/Condition/pkg_reason_type.pm create mode 100644 httemplate/elements/select-reason_type.html create mode 100644 httemplate/elements/tr-select-reason_type.html diff --git a/FS/FS/part_event/Condition/pkg_not_reason_type.pm b/FS/FS/part_event/Condition/pkg_not_reason_type.pm new file mode 100644 index 000000000..3fa08b762 --- /dev/null +++ b/FS/FS/part_event/Condition/pkg_not_reason_type.pm @@ -0,0 +1,58 @@ +package FS::part_event::Condition::pkg_not_reason_type; +use base qw( FS::part_event::Condition ); + +use strict; +use Tie::IxHash; +#use FS::Record qw( qsearch ); + +sub description { + 'Package Not Reason Type'; +} + +sub eventtable_hashref { + { 'cust_main' => 0, + 'cust_bill' => 0, + 'cust_pkg' => 1, + 'svc_acct' => 1, + }; +} + +tie my %actions, 'Tie::IxHash', + #'adjourn' => + 'susp' => 'Suspension', + #'expire' => + 'cancel' => 'Cancellation' +; + +sub option_fields { + ( + 'action' => { 'label' => 'Package Action', + 'type' => 'select', + 'options' => [ keys %actions ], + 'labels' => \%actions, + }, + 'typenum' => { 'label' => 'Not Reason Type', + 'type' => 'select-reason_type', + 'multiple' => 1, + }, + ); +} + +sub condition { + my( $self, $object ) = @_; + + my $cust_pkg = $self->cust_pkg($object); + + my $reason = $cust_pkg->last_reason( $self->option('action') ) + or return 0; + + my $hashref = $self->option('typenum') || {}; + ! $hashref->{ $reason->reason_type }; +} + +#sub condition_sql { +# my( $self, $table ) = @_; +# +#} + +1; diff --git a/FS/FS/part_event/Condition/pkg_reason_type.pm b/FS/FS/part_event/Condition/pkg_reason_type.pm new file mode 100644 index 000000000..f110e1b04 --- /dev/null +++ b/FS/FS/part_event/Condition/pkg_reason_type.pm @@ -0,0 +1,58 @@ +package FS::part_event::Condition::pkg_reason_type; +use base qw( FS::part_event::Condition ); + +use strict; +use Tie::IxHash; +#use FS::Record qw( qsearch ); + +sub description { + 'Package Reason Type'; +} + +sub eventtable_hashref { + { 'cust_main' => 0, + 'cust_bill' => 0, + 'cust_pkg' => 1, + 'svc_acct' => 1, + }; +} + +tie my %actions, 'Tie::IxHash', + #'adjourn' => + 'susp' => 'Suspension', + #'expire' => + 'cancel' => 'Cancellation' +; + +sub option_fields { + ( + 'action' => { 'label' => 'Package Action', + 'type' => 'select', + 'options' => [ keys %actions ], + 'labels' => \%actions, + }, + 'typenum' => { 'label' => 'Reason Type', + 'type' => 'select-reason_type', + 'multiple' => 1, + }, + ); +} + +sub condition { + my( $self, $object ) = @_; + + my $cust_pkg = $self->cust_pkg($object); + + my $reason = $cust_pkg->last_reason( $self->option('action') ) + or return 0; + + my $hashref = $self->option('typenum') || {}; + $hashref->{ $reason->reason_type }; +} + +#sub condition_sql { +# my( $self, $table ) = @_; +# +#} + +1; diff --git a/httemplate/elements/select-reason_type.html b/httemplate/elements/select-reason_type.html new file mode 100644 index 000000000..9031e583a --- /dev/null +++ b/httemplate/elements/select-reason_type.html @@ -0,0 +1,21 @@ +<% include( '/elements/select-table.html', + 'table' => 'reason_type', + 'name_col' => 'type', + 'value' => $typenum, + #XXX? 'empty_label' => '(none)', + #XXX? 'hashref' => { 'disabled' => '' }, + %opt, + ) +%> +<%init> + +my %opt = @_; +my $typenum = $opt{'curr_value'} || $opt{'value'}; + +#my %hash = (); +#$hash{'disabled'} = '' unless $opt{'showdisabled'}; + +#$opt{'records'} = delete $opt{'reason_type'} +# if $opt{'reason_type'}; + + diff --git a/httemplate/elements/tr-select-reason_type.html b/httemplate/elements/tr-select-reason_type.html new file mode 100644 index 000000000..9ac473ce7 --- /dev/null +++ b/httemplate/elements/tr-select-reason_type.html @@ -0,0 +1,29 @@ +% if ( scalar(@{ $opt{'reason_type'} }) == 0 ) { + + + +% } else { + + <& /elements/tr-td-label.html, label => $opt{'label'} || 'Reason type', %opt &> + + + <% include( '/elements/select-reason_type.html', + 'curr_value' => $typenum, + %opt + ) + %> + + + +% } + +<%init> + +my %opt = @_; +my $typenum = $opt{'curr_value'} || $opt{'value'}; + +$opt{'reason_type'} ||= [ qsearch( 'reason_type', { disabled=>'' } ) ]; + +my $colspan = delete($opt{'colspan'}) || 1; + + -- cgit v1.2.1 From 25d9baac5e5ef0be9801b54f8365fc40b639a546 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 5 Nov 2012 14:09:50 -0800 Subject: fix ICS invoice spooling when service records are missing, #17620 --- FS/FS/cust_bill.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index dad54348e..128aaf7e0 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -2248,11 +2248,13 @@ sub print_csv { $part_svc_class->classname : ''; } - + + my $svc_x = $cust_svc->svc_x or + warn "missing svc_x record for svc#".$cust_svc->svcnum."\n"; push @details, sprintf('01%-9s%-20s%-47s', $cust_svc->svcnum, $svc_class{$svcpart}, - $cust_svc->svc_x->label, + ($svc_x ? $svc_x->label : ''), ); } #foreach $cust_svc } #if $cust_pkg -- cgit v1.2.1 From 1a7a84610a1bb67b0fda20a2eeed10e50b984178 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 5 Nov 2012 14:10:10 -0800 Subject: typo --- FS/FS/part_pkg/voip_cdr.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 28d503883..01fb99f6d 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -362,7 +362,7 @@ sub calc_usage { : 'default' ); - my $usage_nozero = $self->option->('usage_nozero', 1); + my $usage_nozero = $self->option('usage_nozero', 1); my $formatter = FS::detail_format->new($output_format, buffer => $details); -- cgit v1.2.1 From 2b2aa5664742a134da11862a7cedb37d25524423 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 6 Nov 2012 09:50:43 -0800 Subject: show deprovisioned services correctly, #17620 --- FS/FS/cust_bill.pm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 128aaf7e0..4fd9b6e37 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -2249,12 +2249,11 @@ sub print_csv { ''; } - my $svc_x = $cust_svc->svc_x or - warn "missing svc_x record for svc#".$cust_svc->svcnum."\n"; + my @h_label = $cust_svc->label(@dates, 'I'); push @details, sprintf('01%-9s%-20s%-47s', $cust_svc->svcnum, $svc_class{$svcpart}, - ($svc_x ? $svc_x->label : ''), + $h_label[1], ); } #foreach $cust_svc } #if $cust_pkg -- cgit v1.2.1 From 468c9e660eb0edb2033f0f8dbb4458f20280082c Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 6 Nov 2012 12:48:41 -0800 Subject: improved address standardization, #13763 --- FS/FS/Conf.pm | 25 ++ FS/FS/GeocodeCache.pm | 209 +++++++++++++++ FS/FS/Mason.pm | 3 +- FS/FS/Misc/Geo.pm | 154 ++++++++++- FS/FS/Schema.pm | 3 + FS/FS/cust_location.pm | 4 +- FS/FS/cust_main.pm | 16 -- FS/MANIFEST | 2 + FS/t/GeocodeCache.t | 5 + bin/generate-table-module | 2 +- bin/usps-webtools-test-script | 38 +++ httemplate/edit/cust_main.cgi | 2 + httemplate/edit/cust_main/bottomfixup.html | 10 +- httemplate/edit/cust_main/bottomfixup.js | 139 +++------- httemplate/edit/cust_main/contact.html | 4 +- httemplate/elements/location.html | 27 +- httemplate/elements/order_pkg.js | 7 +- httemplate/elements/standardize_locations.html | 2 +- httemplate/elements/standardize_locations.js | 288 +++++++++++---------- httemplate/elements/tr-select-cust_location.html | 7 +- httemplate/misc/change_pkg.cgi | 1 + httemplate/misc/confirm-address_standardize.html | 123 +++++++++ httemplate/misc/confirm-censustract.html | 78 ++++++ httemplate/misc/order_pkg.html | 1 + httemplate/misc/xmlhttp-address_standardize.html | 38 +++ .../xmlhttp-cust_main-address_standardize.html | 93 ------- 26 files changed, 896 insertions(+), 385 deletions(-) create mode 100644 FS/FS/GeocodeCache.pm create mode 100644 FS/t/GeocodeCache.t create mode 100755 bin/usps-webtools-test-script create mode 100644 httemplate/misc/confirm-address_standardize.html create mode 100644 httemplate/misc/confirm-censustract.html create mode 100644 httemplate/misc/xmlhttp-address_standardize.html delete mode 100644 httemplate/misc/xmlhttp-cust_main-address_standardize.html diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index e74c19faa..02869b16d 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -4064,6 +4064,17 @@ and customer address. Include units.', 'type' => 'checkbox', }, + { + 'key' => 'address_standardize_method', + 'section' => 'UI', #??? + 'description' => 'Method for standardizing customer addresses.', + 'type' => 'select', + 'select_hash' => [ '' => '', + 'usps' => 'U.S. Postal Service', + 'ezlocate' => 'EZLocate', + ], + }, + { 'key' => 'usps_webtools-userid', 'section' => 'UI', @@ -4078,6 +4089,20 @@ and customer address. Include units.', 'type' => 'text', }, + { + 'key' => 'ezlocate-userid', + 'section' => 'UI', + 'description' => 'User ID for EZ-Locate service. See the TomTom website for access and pricing information.', + 'type' => 'text', + }, + + { + 'key' => 'ezlocate-password', + 'section' => 'UI', + 'description' => 'Password for EZ-Locate service.', + 'type' => 'text' + }, + { 'key' => 'cust_main-auto_standardize_address', 'section' => 'UI', diff --git a/FS/FS/GeocodeCache.pm b/FS/FS/GeocodeCache.pm new file mode 100644 index 000000000..7829c4df2 --- /dev/null +++ b/FS/FS/GeocodeCache.pm @@ -0,0 +1,209 @@ +package FS::GeocodeCache; + +use strict; +use vars qw($conf $DEBUG); +use base qw( FS::geocode_Mixin ); +use FS::Record qw( qsearch qsearchs ); +use FS::Conf; +use FS::Misc::Geo; + +use Data::Dumper; + +FS::UID->install_callback( sub { $conf = new FS::Conf; } ); + +$DEBUG = 0; + +=head1 NAME + +FS::GeocodeCache - An address undergoing the geocode process. + +=head1 SYNOPSIS + + use FS::GeocodeCache; + + $record = FS::GeocodeCache->standardize(%location_hash); + +=head1 DESCRIPTION + +An FS::GeocodeCache object represents a street address in the process of +being geocoded. FS::GeocodeCache inherits from FS::geocode_Mixin. + +Most methods on this object throw an exception on error. + +FS::GeocodeCache has the following fields, with the same meaning as in +L: + +=over 4 + +=item address1 + +=item address2 + +=item city + +=item county + +=item state + +=item zip + +=item latitude + +=item longitude + +=item addr_clean + +=item country + +=item censustract + +=item geocode + +=item district + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new cache object. For internal use. See C. + +=cut + +# minimalist constructor +sub new { + my $class = shift; + my $self = { + company => '', + address1 => '', + address2 => '', + city => '', + state => '', + zip => '', + country => '', + latitude => '', + longitude => '', + addr_clean => '', + censustract => '', + @_ + }; + bless $self, $class; +} + +# minimalist accessor, for compatibility with geocode_Mixin +sub get { + $_[0]->{$_[1]} +} + +sub set { + $_[0]->{$_[1]} = $_[2]; +} + +sub location_hash { %{$_[0]} }; + +=item set_censustract + +Look up the censustract, if it's not already filled in, and return it. +On error, sets 'error' and returns nothing. + +This uses the "get_censustract_*" methods in L; currently +the only one is 'ffiec'. + +=cut + +sub set_censustract { + my $self = shift; + + if ( $self->get('censustract') =~ /^\d{9}\.\d{2}$/ ) { + return $self->get('censustract'); + } + my $censusyear = $conf->config('census_year'); + return if !$censusyear; + + my $method = 'ffiec'; + # configurable censustract-only lookup goes here if it's ever needed. + $method = "get_censustract_$method"; + my $censustract = eval { FS::Misc::Geo->$method($self, $censusyear) }; + $self->set("censustract_error", $@); + $self->set("censustract", $censustract); +} + +=item set_coord + +Set the latitude and longitude fields if they're not already set. Returns +those values, in order. + +=cut + +sub set_coord { # the one in geocode_Mixin will suffice + my $self = shift; + if ( !$self->get('latitude') || !$self->get('longitude') ) { + $self->SUPER::set_coord; + $self->set('coord_error', $@); + } + return $self->get('latitude'), $self->get('longitude'); +} + +=head1 CLASS METHODS + +=over 4 + +=item standardize LOCATION + +Given a location hash or L object, standardize the +address using the configured method and return an L +object. + +The methods are the "standardize_*" functions in L. + +=cut + +sub standardize { + my $class = shift; + my $location = shift; + $location = { $location->location_hash } + if UNIVERSAL::can($location, 'location_hash'); + + local $Data::Dumper::Terse = 1; + warn "standardizing location:\n".Dumper($location) if $DEBUG; + + my $method = $conf->config('address_standardize_method'); + + if ( $method ) { + $method = "standardize_$method"; + my $new_location = eval { FS::Misc::Geo->$method( $location ) }; + if ( $new_location ) { + $location = { + addr_clean => 'Y', + %$new_location + # standardize_* can return an address with addr_clean => '' if + # the address is somehow questionable + } + } + else { + # XXX need an option to decide what to do on error + $location->{'addr_clean'} = ''; + $location->{'error'} = $@; + } + warn "result:\n".Dumper($location) if $DEBUG; + } + # else $location = $location + my $cache = $class->new(%$location); + return $cache; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index f7d98a156..944a4836c 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -64,7 +64,7 @@ if ( -e $addl_handler_use_file ) { use DateTime; use DateTime::Format::Strptime; use FS::Misc::DateTime qw( parse_datetime ); - use FS::Misc::Geo qw( get_censustract get_district ); + use FS::Misc::Geo qw( get_district ); use Lingua::EN::Inflect qw(PL); Lingua::EN::Inflect::classical names=>0; #Categorys use Tie::IxHash; @@ -326,6 +326,7 @@ if ( -e $addl_handler_use_file ) { use FS::cust_bill_pkg_discount_void; use FS::agent_pkg_class; use FS::svc_export_machine; + use FS::GeocodeCache; # Sammath Naur if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Misc/Geo.pm b/FS/FS/Misc/Geo.pm index 5d6f33cb7..6bc71fc84 100644 --- a/FS/FS/Misc/Geo.pm +++ b/FS/FS/Misc/Geo.pm @@ -2,7 +2,7 @@ package FS::Misc::Geo; use strict; use base qw( Exporter ); -use vars qw( $DEBUG @EXPORT_OK ); +use vars qw( $DEBUG @EXPORT_OK $conf ); use LWP::UserAgent; use HTTP::Request; use HTTP::Request::Common qw( GET POST ); @@ -10,15 +10,19 @@ use HTML::TokeParser; use URI::Escape 3.31; use Data::Dumper; +FS::UID->install_callback( sub { + $conf = new FS::Conf; +} ); + $DEBUG = 0; -@EXPORT_OK = qw( get_censustract get_district ); +@EXPORT_OK = qw( get_district ); =head1 NAME FS::Misc::Geo - routines to fetch geographic information -=head1 FUNCTIONS +=head1 CLASS METHODS =over 4 @@ -30,7 +34,8 @@ codes) or an error message. =cut -sub get_censustract { +sub get_censustract_ffiec { + my $class = shift; my $location = shift; my $year = shift; @@ -45,7 +50,7 @@ sub get_censustract { my $res = $ua->request( GET( $url ) ); warn $res->as_string - if $DEBUG > 1; + if $DEBUG > 2; unless ($res->code eq '200') { @@ -87,12 +92,12 @@ sub get_censustract { btnSearch => 'Search', ); warn join("\n", @ffiec_args ) - if $DEBUG; + if $DEBUG > 1; push @{ $ua->requests_redirectable }, 'POST'; $res = $ua->request( POST( $url, \@ffiec_args ) ); warn $res->as_string - if $DEBUG > 1; + if $DEBUG > 2; unless ($res->code eq '200') { @@ -102,7 +107,7 @@ sub get_censustract { my @id = qw( MSACode StateCode CountyCode TractCode ); $content = $res->content; - warn $res->content if $DEBUG > 1; + warn $res->content if $DEBUG > 2; $p = new HTML::TokeParser \$content; my $prefix = 'UcGeoResult11_lb'; my $compare = @@ -127,7 +132,7 @@ sub get_censustract { } #unless ($res->code eq '200') - return "FFIEC Geocoding error: $error" if $error; + die "FFIEC Geocoding error: $error\n" if $error; $return->{'statecode'} . $return->{'countycode'} . $return->{'tractcode'}; } @@ -201,12 +206,12 @@ sub wa_sales { my $query_string = join($delim, @args ); $url .= "?$query_string"; - warn "\nrequest: $url\n\n" if $DEBUG; + warn "\nrequest: $url\n\n" if $DEBUG > 1; my $res = $ua->request( GET( "$url?$query_string" ) ); warn $res->as_string - if $DEBUG > 1; + if $DEBUG > 2; if ($res->code ne '200') { $error = $res->message; @@ -253,7 +258,7 @@ sub wa_sales { # just to make sure if ( $return->{'district'} =~ /^\d+$/ and $return->{'tax'} =~ /^.\d+$/ ) { $return->{'tax'} *= 100; #percentage - warn Dumper($return) if $DEBUG; + warn Dumper($return) if $DEBUG > 1; return $return; } else { @@ -267,6 +272,131 @@ sub wa_sales { die "WA tax district lookup error: $error"; } +sub standardize_usps { + my $class = shift; + + eval "use Business::US::USPS::WebTools::AddressStandardization"; + die $@ if $@; + + my $location = shift; + if ( $location->{country} ne 'US' ) { + # soft failure + warn "standardize_usps not for use in country ".$location->{country}."\n"; + $location->{addr_clean} = ''; + return $location; + } + my $userid = $conf->config('usps_webtools-userid'); + my $password = $conf->config('usps_webtools-password'); + my $verifier = Business::US::USPS::WebTools::AddressStandardization->new( { + UserID => $userid, + Password => $password, + Testing => 0, + } ) or die "error starting USPS WebTools\n"; + + my($zip5, $zip4) = split('-',$location->{'zip'}); + + my %usps_args = ( + FirmName => $location->{company}, + Address2 => $location->{address1}, + Address1 => $location->{address2}, + City => $location->{city}, + State => $location->{state}, + Zip5 => $zip5, + Zip4 => $zip4, + ); + warn join('', map "$_: $usps_args{$_}\n", keys %usps_args ) + if $DEBUG > 1; + + my $hash = $verifier->verify_address( %usps_args ); + + warn $verifier->response + if $DEBUG > 1; + + die "USPS WebTools error: ".$verifier->{error}{description} ."\n" + if $verifier->is_error; + + my $zip = $hash->{Zip5}; + $zip .= '-' . $hash->{Zip4} if $hash->{Zip4} =~ /\d/; + + { company => $hash->{FirmName}, + address1 => $hash->{Address2}, + address2 => $hash->{Address1}, + city => $hash->{City}, + state => $hash->{State}, + zip => $zip, + country => 'US', + addr_clean=> 'Y' } +} + +my %ezlocate_error = ( # USA_Geo_002 documentation + 10 => 'State not found', + 11 => 'City not found', + 12 => 'Invalid street address', + 14 => 'Street name not found', + 15 => 'Address range does not exist', + 16 => 'Ambiguous address', + 17 => 'Intersection not found', #unused? +); + +sub standardize_ezlocate { + my $self = shift; + my $location = shift; + my $class; + #if ( $location->{country} eq 'US' ) { + # $class = 'USA_Geo_004Tool'; + #} + #elsif ( $location->{country} eq 'CA' ) { + # $class = 'CAN_Geo_001Tool'; + #} + #else { # shouldn't be a fatal error, just pass through unverified address + # warn "standardize_teleatlas: address lookup in '".$location->{country}. + # "' not available\n"; + # return $location; + #} + #my $path = $conf->config('teleatlas-path') || ''; + #local @INC = (@INC, $path); + #eval "use $class;"; + #if ( $@ ) { + # die "Loading $class failed:\n$@". + # "\nMake sure the TeleAtlas Perl SDK is installed correctly.\n"; + #} + + $class = 'Geo::EZLocate'; # use our own library + eval "use $class"; + die $@ if $@; + + my $userid = $conf->config('ezlocate-userid') + or die "no ezlocate-userid configured\n"; + my $password = $conf->config('ezlocate-password') + or die "no ezlocate-password configured\n"; + + my $tool = $class->new($userid, $password); + my $match = $tool->findAddress( + $location->{address1}, + $location->{city}, + $location->{state}, + $location->{zip}, #12345-6789 format is allowed + ); + warn "ezlocate returned match:\n".Dumper($match) if $DEBUG > 1; + # error handling - B codes indicate success + die $ezlocate_error{$match->{MAT_STAT}}."\n" + unless $match->{MAT_STAT} =~ /^B\d$/; + + { + address1 => $match->{STD_ADDR}, + address2 => $location->{address2}, + city => $match->{STD_CITY}, + state => $match->{STD_ST}, + country => $location->{country}, + zip => $match->{STD_ZIP}.'-'.$match->{STD_P4}, + latitude => $match->{MAT_LAT}, + longitude => $match->{MAT_LON}, + censustract => $match->{FIPS_ST}.$match->{FIPS_CTY}. + sprintf('%04.2f',$match->{CEN_TRCT}), + addr_clean => 'Y', + }; +} + =back =cut diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 912f3e269..9eb59a09a 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1010,6 +1010,7 @@ sub tables_hashref { 'latitude', 'decimal', 'NULL', '10,7', '', '', 'longitude','decimal', 'NULL', '10,7', '', '', 'coord_auto', 'char', 'NULL', 1, '', '', + 'addr_clean', 'char', 'NULL', 1, '', '', 'daytime', 'varchar', 'NULL', 20, '', '', 'night', 'varchar', 'NULL', 20, '', '', 'fax', 'varchar', 'NULL', 12, '', '', @@ -1028,6 +1029,7 @@ sub tables_hashref { 'ship_latitude', 'decimal', 'NULL', '10,7', '', '', 'ship_longitude','decimal', 'NULL', '10,7', '', '', 'ship_coord_auto', 'char', 'NULL', 1, '', '', + 'ship_addr_clean', 'char', 'NULL', 1, '', '', 'ship_daytime', 'varchar', 'NULL', 20, '', '', 'ship_night', 'varchar', 'NULL', 20, '', '', 'ship_fax', 'varchar', 'NULL', 12, '', '', @@ -1252,6 +1254,7 @@ sub tables_hashref { 'latitude', 'decimal', 'NULL', '10,7', '', '', 'longitude', 'decimal', 'NULL', '10,7', '', '', 'coord_auto', 'char', 'NULL', 1, '', '', + 'addr_clean', 'char', 'NULL', 1, '', '', 'country', 'char', '', 2, '', '', 'geocode', 'varchar', 'NULL', 20, '', '', 'district', 'varchar', 'NULL', 20, '', '', diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm index 2810dc957..1521960d4 100644 --- a/FS/FS/cust_location.pm +++ b/FS/FS/cust_location.pm @@ -188,6 +188,7 @@ sub check { || $self->ut_coordn('latitude') || $self->ut_coordn('longitude') || $self->ut_enum('coord_auto', [ '', 'Y' ]) + || $self->ut_enum('addr_clean', [ '', 'Y' ]) || $self->ut_alphan('location_type') || $self->ut_textn('location_number') || $self->ut_enum('location_kind', [ '', 'R', 'B' ] ) @@ -208,9 +209,6 @@ sub check { return "Unit # is required"; } - $self->set_coord - unless $import || ($self->latitude && $self->longitude); - # tricky...we have to allow for the customer to not be inserted yet return "No prospect or customer!" unless $self->prospectnum || $self->custnum diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 9e39b3006..4ea4a6b9d 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -1488,20 +1488,6 @@ sub replace { return "You are not permitted to create complimentary accounts."; } - # should be unnecessary--geocode will default to null on new locations - #if ( $old->get('geocode') && $old->get('geocode') eq $self->get('geocode') - # && $conf->exists('enable_taxproducts') - # ) - #{ - # my $pre = ($conf->exists('tax-ship_address') && $self->ship_zip) - # ? 'ship_' : ''; - # $self->set('geocode', '') - # if $old->get($pre.'zip') ne $self->get($pre.'zip') - # && length($self->get($pre.'zip')) >= 10; - #} - - # set_coord/coord_auto stuff is now handled by cust_location - local($ignore_expired_card) = 1 if $old->payby =~ /^(CARD|DCRD)$/ && $self->payby =~ /^(CARD|DCRD)$/ @@ -1862,8 +1848,6 @@ sub check { } - #ship_ fields are gone - #$self->payby =~ /^(CARD|DCRD|CHEK|DCHK|LECB|BILL|COMP|PREPAY|CASH|WEST|MCRD)$/ # or return "Illegal payby: ". $self->payby; #$self->payby($1); diff --git a/FS/MANIFEST b/FS/MANIFEST index f530610e7..9c444be58 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -673,3 +673,5 @@ FS/part_export_machine.pm t/part_export_machine.t FS/svc_export_machine.pm t/svc_export_machine.t +FS/GeocodeCache.pm +t/GeocodeCache.t diff --git a/FS/t/GeocodeCache.t b/FS/t/GeocodeCache.t new file mode 100644 index 000000000..eae6f0d01 --- /dev/null +++ b/FS/t/GeocodeCache.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::GeocodeCache; +$loaded=1; +print "ok 1\n"; diff --git a/bin/generate-table-module b/bin/generate-table-module index e7fc99258..b536360c5 100755 --- a/bin/generate-table-module +++ b/bin/generate-table-module @@ -95,7 +95,7 @@ close TEST; # add them to MANIFEST ### -system('cvs edit FS/MANIFEST'); +#system('cvs edit FS/MANIFEST'); open(MANIFEST,">>FS/MANIFEST") or die $!; print MANIFEST "FS/$table.pm\n", diff --git a/bin/usps-webtools-test-script b/bin/usps-webtools-test-script new file mode 100755 index 000000000..414ae4cad --- /dev/null +++ b/bin/usps-webtools-test-script @@ -0,0 +1,38 @@ +#!/usr/bin/perl + +use FS::Misc::Geo 'standardize'; +use Data::Dumper; $Data::Dumper::Terse = 1; +my @tests = ( + { + address1 => '6406 Ivy Lane', + address2 => '', + city => 'Greenbelt', + state => 'MD', + zip => '', + }, + { + address1 => '8 Wildwood Drive', + address2 => '', + city => 'Old Lyme', + state => 'CT', + zip => '06371', + }, +); + +my ($userid, $password) = @ARGV; + +my %opt = ( + userid => $userid, + password=> $password, + test => 1, +); +my $i = 1; +foreach (@tests) { + print "Test $i\n"; + my $result = eval { standardize($_, %opt) }; + print "ERROR: $@\n\n" if $@; + print Dumper($result); + $i++; +} + +1; diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi index 2628b4e01..0aded597f 100755 --- a/httemplate/edit/cust_main.cgi +++ b/httemplate/edit/cust_main.cgi @@ -316,6 +316,8 @@ if ( $cgi->param('error') ) { $payinfo = ''; $cgi->param('tagnum', FS::part_tag->default_tags); + $cust_main->coord_auto('Y'); + $cust_main->ship_coord_auto('Y'); if ( $cgi->param('qualnum') =~ /^(\d+)$/ ) { my $qualnum = $1; diff --git a/httemplate/edit/cust_main/bottomfixup.html b/httemplate/edit/cust_main/bottomfixup.html index 60edcc111..b5d10c467 100644 --- a/httemplate/edit/cust_main/bottomfixup.html +++ b/httemplate/edit/cust_main/bottomfixup.html @@ -1,15 +1,9 @@ <& /elements/init_overlib.html &> <& /elements/xmlhttp.html, - url => $p.'misc/xmlhttp-cust_main-address_standardize.html', + url => $p.'misc/xmlhttp-address_standardize.html', subs => [ 'address_standardize' ], - #'method' => 'POST', #could get too long? -&> - -<& /elements/xmlhttp.html, - url => $p.'misc/xmlhttp-cust_main-censustract.html', - subs => [ 'censustract' ], - #'method' => 'POST', #could get too long? + method => 'POST', #could get too long? &> diff --git a/httemplate/edit/cust_main/bottomfixup.js b/httemplate/edit/cust_main/bottomfixup.js index 77d4294a6..4f3b7da42 100644 --- a/httemplate/edit/cust_main/bottomfixup.js +++ b/httemplate/edit/cust_main/bottomfixup.js @@ -7,8 +7,7 @@ my $company_longitude = $conf->config('company_longitude'); my @fixups = ('copy_payby_fields', 'standardize_locations'); -push @fixups, 'fetch_censustract' - if $conf->exists('cust_main-require_censustract'); +push @fixups, 'confirm_censustract'; push @fixups, 'check_unique' if $conf->exists('cust_main-check_unique') and !$opt{'custnum'}; @@ -18,15 +17,19 @@ push @fixups, 'do_submit'; # always last var fixups = <% encode_json(\@fixups) %>; var fixup_position; +var running = false; %# state machine to deal with all the asynchronous stuff we're doing %# call this after each fixup on success: function submit_continue() { - window[ fixups[fixup_position++] ].call(); + if ( running ) { + window[ fixups[fixup_position++] ].call(); + } } %# or on failure: function submit_abort() { + running = false; fixup_position = 0; document.CustomerForm.submitButton.disabled = false; cClick(); @@ -35,6 +38,7 @@ function submit_abort() { function bottomfixup(what) { fixup_position = 0; document.CustomerForm.submitButton.disabled = true; + running = true; submit_continue(); } @@ -63,8 +67,6 @@ function copy_payby_fields() { submit_continue(); } -%# call submit_continue() on completion... -%# otherwise not touching standardize_locations for now <% include( '/elements/standardize_locations.js', 'callback' => 'submit_continue();', 'main_prefix' => 'bill_', @@ -72,104 +74,6 @@ function copy_payby_fields() { ) %> -var prefix; -function fetch_censustract() { - - //alert('fetch census tract data'); - prefix = document.getElementById('same').checked ? 'bill_' : 'ship_'; - var cf = document.CustomerForm; - var state_el = cf.elements[prefix + 'state']; - var census_data = new Array( - 'year', <% $conf->config('census_year') || '2012' %>, - 'address1', cf.elements[prefix + 'address1'].value, - 'city', cf.elements[prefix + 'city'].value, - 'state', state_el.options[ state_el.selectedIndex ].value, - 'zip', cf.elements[prefix + 'zip'].value - ); - - censustract( census_data, update_censustract ); - -} - -var set_censustract; - -function update_censustract(arg) { - - var argsHash = eval('(' + arg + ')'); - - var cf = document.CustomerForm; - -/* var msacode = argsHash['msacode']; - var statecode = argsHash['statecode']; - var countycode = argsHash['countycode']; - var tractcode = argsHash['tractcode']; - - var newcensus = - new String(statecode) + - new String(countycode) + - new String(tractcode).replace(/\s$/, ''); // JSON 1 workaround */ - var error = argsHash['error']; - var newcensus = argsHash['censustract']; - - set_censustract = function () { - - cf.elements[prefix + 'censustract'].value = newcensus; - submit_continue(); - - } - - if (error || cf.elements[prefix + 'censustract'].value != newcensus) { - // popup an entry dialog - - if (error) { newcensus = error; } - newcensus.replace(/.*ndefined.*/, 'Not found'); - - var latitude = cf.elements[prefix + 'latitude'].value - || '<% $company_latitude %>'; - var longitude= cf.elements[prefix + 'longitude'].value - || '<% $company_longitude %>'; - - var choose_censustract = - '

Confirm censustract
' + - 'Map service module location
' + - 'Map zip code center

' + - ''; - - choose_censustract = choose_censustract + - '' + - '' + - '' + - ''; - - choose_censustract = choose_censustract + - '' + - '' + - - '
Entered census tractCalculated census tract
' + cf.elements[prefix + 'censustract'].value + - '' + newcensus + '
  
' + - '' + - '' + - '' + - '
' + - '
'; - - overlib( choose_censustract, CAPTION, 'Confirm censustract', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 ); - - } else { - - submit_continue(); - - } - -} - function copyelement(from, to) { if ( from == undefined ) { to.value = ''; @@ -192,6 +96,35 @@ function copyelement(from, to) { //alert(from + " (" + from.type + "): " + to.name + " => " + to.value); } +% # the value in 'censustract' is the confirmed censustract; if it's set, +% # do nothing here +function confirm_censustract() { + var cf = document.CustomerForm; + if ( cf.elements['censustract'].value == '' ) { + var address_info = form_address_info(); + address_info['ship_latitude'] = cf.elements['ship_latitude'].value; + address_info['ship_longitude'] = cf.elements['ship_longitude'].value; + OLpostAJAX( + '<%$p%>/misc/confirm-censustract.html', + 'q=' + encodeURIComponent(JSON.stringify(address_info)), + function() { + overlib( OLresponseAJAX, CAPTION, 'Confirm censustract', STICKY, + AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, + 576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', + TEXTSIZE, 3 ); + }, + 0); + } else submit_continue(); +} + +%# called from confirm-censustract.html +function set_censustract(tract, year) { + var cf = document.CustomerForm; + cf.elements['censustract'].value = tract; + cf.elements['censusyear'].value = year; + submit_continue(); +} + function check_unique() { var search_hash = new Object; % foreach ($conf->config('cust_main-check_unique')) { diff --git a/httemplate/edit/cust_main/contact.html b/httemplate/edit/cust_main/contact.html index 57490b962..4140ec1ea 100644 --- a/httemplate/edit/cust_main/contact.html +++ b/httemplate/edit/cust_main/contact.html @@ -174,9 +174,7 @@ $cust_main->set('stateid_state', $cust_main->state ) $opt{geocode} ||= $cust_main->get('geocode'); -if ( $conf->exists('cust_main-require_censustract') ) { - $opt{censustract} ||= $cust_main->censustract; -} +$opt{censustract} ||= $cust_main->censustract; $daytime_label = FS::Msgcat::_gettext('daytime') =~ /^(daytime)?$/ ? 'Day' diff --git a/httemplate/elements/location.html b/httemplate/elements/location.html index 5c7c888de..de844e465 100644 --- a/httemplate/elements/location.html +++ b/httemplate/elements/location.html @@ -33,7 +33,7 @@ Example: 'options' => \@location_kind_options, 'labels' => $location_kind_labels, 'curr_value' => scalar($cgi->param('location_kind')) - || $object->get($pre.'location_kind'), + || $object->get('location_kind'), ) %> @@ -164,7 +164,7 @@ Example: NAME = "<%$pre%>zip" ID = "<%$pre%>zip" VALUE = "<% $object->get('zip') |h %>" - SIZE = 10 + SIZE = 11 onChange = "<% $onchange %>" <% $disabled %> <% $style %> @@ -206,23 +206,22 @@ Example: + - % if ( $opt{enable_censustract} ) { + Census tract <% '(automatic)' %> -% } else { - -% } +% } % if ( $conf->config('tax_district_method') ) { - % if ( $opt{enable_district} ) { + Tax district <% '(automatic)' %> + % } else { % } - % } +%# For address standardization: +%# keep a clean copy of the address so we know if we need +%# to re-standardize +% foreach (qw(address1 city state country zip latitude +% longitude censustract addr_clean) ) { + +% } +%# Placeholders + + <%init> my %opt = @_; diff --git a/httemplate/elements/order_pkg.js b/httemplate/elements/order_pkg.js index 48073593a..8c1efd93a 100644 --- a/httemplate/elements/order_pkg.js +++ b/httemplate/elements/order_pkg.js @@ -19,13 +19,10 @@ function pkg_changed () { form.start_date_text.disabled = false; form.start_date.style.backgroundColor = '#ffffff'; form.start_date_button.style.display = ''; - form.start_date_button_disabled.style.display = 'none'; - form.invoice_terms.disabled = true; } else { form.start_date_text.disabled = true; form.start_date.style.backgroundColor = '#dddddd'; form.start_date_button.style.display = 'none'; - form.start_date_button_disabled.style.display = ''; } } else { @@ -44,3 +41,7 @@ function standardize_new_location() { form.submit(); } } + +function submit_abort() { + document.OrderPkgForm.submitButton.disabled = false; +} diff --git a/httemplate/elements/standardize_locations.html b/httemplate/elements/standardize_locations.html index 9f8b71c62..5a4ee0f80 100644 --- a/httemplate/elements/standardize_locations.html +++ b/httemplate/elements/standardize_locations.html @@ -1,7 +1,7 @@ <% include('/elements/init_overlib.html') %> <% include( '/elements/xmlhttp.html', - 'url' => $p.'misc/xmlhttp-cust_main-address_standardize.html', + 'url' => $p.'misc/xmlhttp-address_standardize.html', 'subs' => [ 'address_standardize' ], #'method' => 'POST', #could get too long? ) diff --git a/httemplate/elements/standardize_locations.js b/httemplate/elements/standardize_locations.js index 86f8d2be8..f6564a55e 100644 --- a/httemplate/elements/standardize_locations.js +++ b/httemplate/elements/standardize_locations.js @@ -1,179 +1,205 @@ -function standardize_locations() { - +function form_address_info() { var cf = document.<% $formname %>; - var state_el = cf.elements['<% $main_prefix %>state']; var ship_state_el = cf.elements['<% $ship_prefix %>state']; - - var address_info = new Array( + return { % if ( $onlyship ) { - 'onlyship', 1, + 'onlyship': 1, % } else { % if ( $withfirm ) { 'company', cf.elements['company'].value, % } - 'address1', cf.elements['<% $main_prefix %>address1'].value, - 'address2', cf.elements['<% $main_prefix %>address2'].value, - 'city', cf.elements['<% $main_prefix %>city'].value, - 'state', state_el.options[ state_el.selectedIndex ].value, - 'zip', cf.elements['<% $main_prefix %>zip'].value, + 'address1': cf.elements['<% $main_prefix %>address1'].value, + 'address2': cf.elements['<% $main_prefix %>address2'].value, + 'city': cf.elements['<% $main_prefix %>city'].value, + 'state': state_el.options[ state_el.selectedIndex ].value, + 'zip': cf.elements['<% $main_prefix %>zip'].value, + 'country': cf.elements['<% $main_prefix %>country'].value, % } - 'ship_address1', cf.elements['<% $ship_prefix %>address1'].value, - 'ship_address2', cf.elements['<% $ship_prefix %>address2'].value, - 'ship_city', cf.elements['<% $ship_prefix %>city'].value, - 'ship_state', ship_state_el.options[ ship_state_el.selectedIndex ].value, - 'ship_zip', cf.elements['<% $ship_prefix %>zip'].value - ); - - address_standardize( address_info, update_address ); - +% if ( $withcensus ) { + 'ship_censustract': cf.elements['enter_censustract'].value, +% } + 'ship_address1': cf.elements['<% $ship_prefix %>address1'].value, + 'ship_address2': cf.elements['<% $ship_prefix %>address2'].value, + 'ship_city': cf.elements['<% $ship_prefix %>city'].value, + 'ship_state': ship_state_el.options[ ship_state_el.selectedIndex ].value, + 'ship_zip': cf.elements['<% $ship_prefix %>zip'].value, + 'ship_country': cf.elements['<% $ship_prefix %>country'].value, + }; } -var standardize_address; - -function update_address(arg) { +function standardize_locations() { - var argsHash = eval('(' + arg + ')'); + var startup_msg = '

Verifying address...

'; + overlib(startup_msg, WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSECLICK, MIDX, 0, MIDY, 0); + var cf = document.<% $formname %>; + var address_info = form_address_info(); - var changed = argsHash['address_standardized']; - var ship_changed = argsHash['ship_address_standardized']; - var error = argsHash['error']; - var ship_error = argsHash['ship_error']; - + var changed = false; // have any of the address fields been changed? - //yay closures - standardize_address = function () { +// clear coord_auto fields if the user has changed the coordinates +% for my $pre ($ship_prefix, $onlyship ? () : $main_prefix) { +% for my $field ($pre.'latitude', $pre.'longitude') { - var cf = document.<% $formname %>; - var state_el = cf.elements['<% $main_prefix %>state']; - var ship_state_el = cf.elements['<% $ship_prefix %>state']; + if ( cf.elements['<% $field %>'].value != cf.elements['old_<% $field %>'].value ) { + cf.elements['<% $pre %>coord_auto'].value = ''; + } -% if ( !$onlyship ) { - if ( changed ) { -% if ( $withfirm ) { - cf.elements['<% $main_prefix %>company'].value = argsHash['new_company']; % } - cf.elements['<% $main_prefix %>address1'].value = argsHash['new_address1']; - cf.elements['<% $main_prefix %>address2'].value = argsHash['new_address2']; - cf.elements['<% $main_prefix %>city'].value = argsHash['new_city']; - setselect(cf.elements['<% $main_prefix %>state'], argsHash['new_state']); - cf.elements['<% $main_prefix %>zip'].value = argsHash['new_zip']; - } -% } + // but if the coordinates have been set to null, turn coord_auto on + // and standardize + if ( cf.elements['<% $pre %>latitude'].value == '' && + cf.elements['<% $pre %>longitude'].value == '' ) { + cf.elements['<% $pre %>coord_auto'].value = 'Y'; + changed = true; + } - if ( ship_changed ) { -% if ( $withfirm ) { - cf.elements['<% $ship_prefix %>company'].value = argsHash['new_ship_company']; % } - cf.elements['<% $ship_prefix %>address1'].value = argsHash['new_ship_address1']; - cf.elements['<% $ship_prefix %>address2'].value = argsHash['new_ship_address2']; - cf.elements['<% $ship_prefix %>city'].value = argsHash['new_ship_city']; - setselect(cf.elements['<% $ship_prefix %>state'], argsHash['new_ship_state']); - cf.elements['<% $ship_prefix %>zip'].value = argsHash['new_ship_zip']; - } - post_standardization(); + // standardize if the old address wasn't clean + if ( cf.elements['old_<% $ship_prefix %>addr_clean'].value == '' || + ( <% !$onlyship || 0 %> && + cf.elements['old_<% $main_prefix %>addr_clean'].value == '' ) ) { + changed = true; + + } + // or if it was clean but has been changed + for (var key in address_info) { + var old_el = cf.elements['old_'+key]; + if ( old_el && address_info[key] != old_el.value ) { + changed = true; + break; + } } +% # If address hasn't been changed, auto-confirm the existing value of +% # censustract so that we don't ask the user to confirm it again. + if ( !changed ) { + cf.elements['<% $main_prefix %>censustract'].value = + address_info['ship_censustract']; + } - if ( changed || ship_changed ) { +% if ( $conf->config('address_standardize_method') ) { + if ( changed ) { + address_standardize(JSON.stringify(address_info), confirm_standardize); + } + else { + cf.elements['ship_addr_clean'].value = 'Y'; +% if ( !$onlyship ) { + cf.elements['addr_clean'].value = 'Y'; +% } + post_standardization(); + } -% if ( $conf->exists('cust_main-auto_standardize_address') ) { +% } else { - standardize_address(); + post_standardization(); -% } else { +% } # if address_standardize_method +} - // popup a confirmation popup +var returned; - var confirm_change = - '

Confirm address standardization

' + - ''; - - if ( changed ) { +function confirm_standardize(arg) { + // contains 'old', which was what we sent, and 'new', which is what came + // back, including any errors + returned = JSON.parse(arg); - confirm_change = confirm_change + - '' + - ''; - // + ''; - - if ( argsHash['company'] || argsHash['new_company'] ) { - confirm_change = confirm_change + - ''; - } - - confirm_change = confirm_change + - '' + - '' + - '' + - ''; + if ( <% $conf->exists('cust_main-auto_standardize_address') || 0 %> ) { - } + replace_address(); // with the contents of returned['new'] + + } + else { + + var querystring = encodeURIComponent( JSON.stringify(returned) ); + // confirmation popup: knows to call replace_address(), + // post_standardization(), or submit_abort() depending on the + // user's choice. + OLpostAJAX( + '<%$p%>/misc/confirm-address_standardize.html', + 'q='+querystring, + function() { + overlib( OLresponseAJAX, CAPTION, 'Address standardization', STICKY, + AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, + 576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', + TEXTSIZE, 3 ); + }, 0); - if ( ship_changed ) { - - confirm_change = confirm_change + - '' + - ''; - // + ''; - - if ( argsHash['ship_company'] || argsHash['new_ship_company'] ) { - confirm_change = confirm_change + - ''; - } - - confirm_change = confirm_change + - '' + - '' + - '' + - ''; + } +} - } +function replace_address() { - var addresses = 'address'; - var height = 268; - if ( changed && ship_changed ) { - addresses = 'addresses'; - height = 396; // #what - } + var newaddr = returned['new']; - confirm_change = confirm_change + - '' + - '' + - - '
Entered billing addressStandardized billing address
  
' + argsHash['company'] + - '' + argsHash['new_company'] + '
' + argsHash['address1'] + - '' + argsHash['new_address1'] + '
' + argsHash['address2'] + - '' + argsHash['new_address2'] + '
' + argsHash['city'] + ', ' + argsHash['state'] + ' ' + argsHash['zip'] + - '' + argsHash['new_city'] + ', ' + argsHash['new_state'] + ' ' + argsHash['new_zip'] + '
  
Entered service addressStandardized service address
  
' + argsHash['ship_company'] + - '' + argsHash['new_ship_company'] + '
' + argsHash['ship_address1'] + - '' + argsHash['new_ship_address1'] + '
' + argsHash['ship_address2'] + - '' + argsHash['new_ship_address2'] + '
' + argsHash['ship_city'] + ', ' + argsHash['ship_state'] + ' ' + argsHash['ship_zip'] + - '' + argsHash['new_ship_city'] + ', ' + argsHash['new_ship_state'] + ' ' + argsHash['new_ship_zip'] + '
  
' + - '' + - '' + - '' + - '
' + - '
'; + var clean = newaddr['addr_clean'] == 'Y'; + var ship_clean = newaddr['ship_addr_clean'] == 'Y'; + var error = newaddr['error']; + var ship_error = newaddr['ship_error']; - overlib( confirm_change, CAPTION, 'Confirm address standardization', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, height, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 ); + var cf = document.<% $formname %>; + var state_el = cf.elements['<% $main_prefix %>state']; + var ship_state_el = cf.elements['<% $ship_prefix %>state']; +% if ( !$onlyship ) { + if ( clean ) { +% if ( $withfirm ) { + cf.elements['<% $main_prefix %>company'].value = newaddr['company']; % } + cf.elements['<% $main_prefix %>address1'].value = newaddr['address1']; + cf.elements['<% $main_prefix %>address2'].value = newaddr['address2']; + cf.elements['<% $main_prefix %>city'].value = newaddr['city']; + setselect(cf.elements['<% $main_prefix %>state'], newaddr['state']); + cf.elements['<% $main_prefix %>zip'].value = newaddr['zip']; + cf.elements['<% $main_prefix %>addr_clean'].value = 'Y'; + + if ( cf.elements['<% $main_prefix %>coord_auto'].value ) { + cf.elements['<% $main_prefix %>latitude'].value = newaddr['latitude']; + cf.elements['<% $main_prefix %>longitude'].value = newaddr['longitude']; + } + } +% } - } else { - - post_standardization(); - + if ( ship_clean ) { +% if ( $withfirm ) { + cf.elements['<% $ship_prefix %>company'].value = newaddr['ship_company']; +% } + cf.elements['<% $ship_prefix %>address1'].value = newaddr['ship_address1']; + cf.elements['<% $ship_prefix %>address2'].value = newaddr['ship_address2']; + cf.elements['<% $ship_prefix %>city'].value = newaddr['ship_city']; + setselect(cf.elements['<% $ship_prefix %>state'], newaddr['ship_state']); + cf.elements['<% $ship_prefix %>zip'].value = newaddr['ship_zip']; + cf.elements['<% $ship_prefix %>addr_clean'].value = 'Y'; + if ( cf.elements['<% $ship_prefix %>coord_auto'].value ) { + cf.elements['<% $ship_prefix %>latitude'].value = newaddr['latitude']; + cf.elements['<% $ship_prefix %>longitude'].value = newaddr['longitude']; + } + } +% if ( $withcensus ) { +% # then set the censustract if address_standardize provided one. + if ( ship_clean && newaddr['ship_censustract'] ) { + cf.elements['<% $main_prefix %>censustract'].value = newaddr['ship_censustract']; } +% } + post_standardization(); } -function post_standardization() { - +function confirm_manual_address() { +%# not much to do in this case, just confirm the censustract +% if ( $withcensus ) { var cf = document.<% $formname %>; + cf.elements['<% $main_prefix %>censustract'].value = + cf.elements['<% $main_prefix %>enter_censustract'].value; +% } + post_standardization(); +} + +function post_standardization() { % if ( $conf->exists('enable_taxproducts') ) { @@ -262,6 +288,7 @@ my %opt = @_; my $conf = new FS::Conf; my $withfirm = 1; +my $withcensus = 1; my $formname = $opt{form} || 'CustomerForm'; my $onlyship = $opt{onlyship} || ''; @@ -271,5 +298,6 @@ my $taxpre = $main_prefix; $taxpre = $ship_prefix if ( $conf->exists('tax-ship_address') || $onlyship ); my $post_geocode = $opt{callback} || 'post_geocode();'; $withfirm = 0 if $opt{no_company}; +$withcensus = 0 if $opt{no_census}; diff --git a/httemplate/elements/tr-select-cust_location.html b/httemplate/elements/tr-select-cust_location.html index b804f4548..7ffbd6c14 100644 --- a/httemplate/elements/tr-select-cust_location.html +++ b/httemplate/elements/tr-select-cust_location.html @@ -52,10 +52,11 @@ Example: if( ftype != 'SELECT') what.form.<%$_%>.style.backgroundColor = '#ffffff'; % } % if ( $opt{'alt_format'} ) { - if ( what.form.location_type.options[what.form.location_type.selectedIndex].value ) { + if ( what.form.location_type && + what.form.location_type.options[what.form.location_type.selectedIndex].value ) { what.form.location_number.disabled = false; what.form.location_number.style.backgroundColor = '#ffffff'; - } + } % } } @@ -281,6 +282,8 @@ if ( $locationnum && $locationnum > 0 ) { } } +$cust_location->coord_auto('Y'); + my $location_sort = sub { $a->country cmp $b->country or lc($a->city) cmp lc($b->city) diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi index 2ab9329a1..7b08f7b10 100755 --- a/httemplate/misc/change_pkg.cgi +++ b/httemplate/misc/change_pkg.cgi @@ -34,6 +34,7 @@ 'form' => "OrderPkgForm", 'onlyship' => 1, 'no_company' => 1, + 'no_census' => 1, 'callback' => 'document.OrderPkgForm.submit();', &> diff --git a/httemplate/misc/confirm-address_standardize.html b/httemplate/misc/confirm-address_standardize.html new file mode 100644 index 000000000..3603b95d9 --- /dev/null +++ b/httemplate/misc/confirm-address_standardize.html @@ -0,0 +1,123 @@ + +

+% if ( $new{error} or $new{ship_error} ) { +Address standardization error +% } +% else { +Confirm address standardization +% } + +

+ +% for my $pre ('', 'ship_') { +% next if !$pre and $old{onlyship}; +% my $name = $pre eq 'ship_' ? 'service' : 'billing'; +% if ( $new{$pre.'addr_clean'} ) { + + + + + +% if ( $old{$pre.'company'} ) { + + + + +% } + + + + + + + + + + + + + +% } # if addr_clean +% elsif ( $new{$pre.'error'} ) { + + + +% if ( $old{$pre.'company'} ) { + + + +% } + + + + + + + + + + +% } #if error +% } # for $pre + +%# only do this part if address standardization provided a censustract +% if ( $new{'ship_censustract'} ) { + + + + + + + + +% } #if censustract + +% if ( $new{error} or $new{ship_error} ) { + + + + +% } +% else { + + + + + +
Entered <%$name%> addressStandardized <%$name%> address
<% $old{$pre.'company'} %><% $new{$pre.'company'} %>
<% $old{$pre.'address1'} %><% $new{$pre.'address1'} %>
<% $old{$pre.'address2'} %><% $new{$pre.'address2'} %>
<% $old{$pre.'city'} %>, <% $old{$pre.'state'} %> <% $old{$pre.'zip'} %><% $new{$pre.'city'} %>, <% $new{$pre.'state'} %> <% $new{$pre.'zip'} %>
Entered <%$name%> address
<% $old{$pre.'company'} %>
<% $old{$pre.'address1'} %><% $new{$pre.'error'} %>
<% $old{$pre.'address2'} %>
<% $old{$pre.'city'} %>, <% $old{$pre.'state'} %> <% $old{$pre.'zip'} %>
Entered census tractCalculated census tract
<% $old{'ship_censustract'} %> +% if ( $new{'ship_census_error'} ) { + <% $new{'ship_census_error'} %> +% } else { + <% $new{'ship_censustract'} %> +% } +
+ +
+ +
+ +
+% } # !error +<%init> + +# slightly weird interface... +my $q = decode_json($cgi->param('q')); +#warn Dumper($q); +my %old = %{ $q->{old} }; +my %new = %{ $q->{new} }; + +my $addresses = $old{onlyship} ? 'address' : 'addresses'; + + diff --git a/httemplate/misc/confirm-censustract.html b/httemplate/misc/confirm-censustract.html new file mode 100644 index 000000000..ae0ae3a6a --- /dev/null +++ b/httemplate/misc/confirm-censustract.html @@ -0,0 +1,78 @@ +

+% if ( $error ) { +Census tract error +% } +% else { +Confirm census tract +% } +
+% my $querystring = "census_year=$year&latitude=".$cache->get('latitude').'&longitude='.$cache->get('longitude'); +Map service module location
+% $querystring = "census_year=$year&zip_code=".$cache->get('zip'); +Map zip code center
+
+ + + + + + + +% if ( $error ) { + +% } else { + +% } + + + + + + + + +
Entered census tractCalculated census tract
<% $old_tract %><% $error %><% $new_tract %>
+ + + +
+ +
+<%init> + +local $SIG{__DIE__}; #disable Mason error trap + +my $DEBUG = 0; + +my $conf = new FS::Conf; + +warn $cgi->param('q') if $DEBUG; + +my $q = decode_json($cgi->param('q')) + or die "bad argument '".$cgi->param('q')."'"; + +my %location = ( + map { $_ => $q->{'ship_'.$_} } + qw( company address1 address2 city state zip country latitude longitude ) +); + +my $old_tract = $q->{'ship_censustract'}; +my $cache = eval { FS::GeocodeCache->new(%location) }; +$cache->set_censustract; +my $year = FS::Conf->new->config('census_year'); +my $new_tract = $cache->get('censustract'); +my $error = $cache->get('censustract_error'); + +warn Dumper($cache) if $DEBUG; + + diff --git a/httemplate/misc/order_pkg.html b/httemplate/misc/order_pkg.html index c5f4509ab..bfc7b6903 100644 --- a/httemplate/misc/order_pkg.html +++ b/httemplate/misc/order_pkg.html @@ -131,6 +131,7 @@ 'form' => "OrderPkgForm", 'onlyship' => 1, 'no_company' => 1, + 'no_census' => 1, 'callback' => 'document.OrderPkgForm.submit();', &> diff --git a/httemplate/misc/xmlhttp-address_standardize.html b/httemplate/misc/xmlhttp-address_standardize.html new file mode 100644 index 000000000..f53c35fca --- /dev/null +++ b/httemplate/misc/xmlhttp-address_standardize.html @@ -0,0 +1,38 @@ +<% encode_json($return) %> +<%init> + +local $SIG{__DIE__}; #disable Mason error trap + +my $DEBUG = 0; + +my $conf = new FS::Conf; + +my $sub = $cgi->param('sub'); + +warn $cgi->param('arg') if $DEBUG; + +my %old = %{ decode_json($cgi->param('arg')) } + or die "bad argument '".$cgi->param('arg')."'"; + +my %new; + +foreach my $pre ( '', 'ship_' ) { + next unless ($pre || !$old{onlyship}); + + my $location = { + map { $_ => $old{$pre.$_} } + qw( company address1 address2 city state zip country ) + }; + + my $cache = eval { FS::GeocodeCache->standardize($location) }; + $cache->set_coord; + # don't do set_censustract here, though censustract may be set by now + + foreach ( keys(%$cache) ) { + $new{$pre.$_} = $cache->get($_); + } +} + +my $return = { old => \%old, new => \%new }; +warn "result:\n".encode_json($return) if $DEBUG; + diff --git a/httemplate/misc/xmlhttp-cust_main-address_standardize.html b/httemplate/misc/xmlhttp-cust_main-address_standardize.html deleted file mode 100644 index d0627cd59..000000000 --- a/httemplate/misc/xmlhttp-cust_main-address_standardize.html +++ /dev/null @@ -1,93 +0,0 @@ -<% objToJson($return) %> -<%init> - -my $DEBUG = 0; - -my $conf = new FS::Conf; - -my $sub = $cgi->param('sub'); - -my $return = {}; - -if ( $sub eq 'address_standardize' ) { - - my %arg = $cgi->param('arg'); - $return = \%arg; - warn join('', map "$_: $arg{$_}\n", keys %arg ) - if $DEBUG; - - my $userid = $conf->config('usps_webtools-userid'); - my $password = $conf->config('usps_webtools-password'); - - if ( length($userid) && length($password) ) { - - my $verifier = Business::US::USPS::WebTools::AddressStandardization->new( { - UserID => $userid, #$ENV{USPS_WEBTOOLS_USERID}, - Password => $password, #$ENV{USPS_WEBTOOLS_PASSWORD}, - #Testing => 1, - } ); - - foreach my $pre ( '', 'ship_' ) { - next unless ($pre || !$arg{onlyship}); - - my($zip5, $zip4) = split('-',$arg{$pre.'zip'}); - - my %usps_args = ( - FirmName => $arg{$pre.'company'}, - Address2 => $arg{$pre.'address1'}, - Address1 => $arg{$pre.'address2'}, - City => $arg{$pre.'city'}, - State => $arg{$pre.'state'}, - Zip5 => $zip5, - Zip4 => $zip4, - ); - warn join('', map "$_: $usps_args{$_}\n", keys %usps_args ) - if $DEBUG; - - my $hash = $verifier->verify_address( %usps_args ); - - warn $verifier->response - if $DEBUG; - - unless ( $verifier->is_error ) { - - my $zip = $hash->{Zip5}; - $zip .= '-'. $hash->{Zip4} if $hash->{Zip4} =~ /\d/; - - $return = { - %$return, - "new_$pre".'company' => $hash->{FirmName}, - "new_$pre".'address1' => $hash->{Address2}, - "new_$pre".'address2' => $hash->{Address1}, - "new_$pre".'city' => $hash->{City}, - "new_$pre".'state' => $hash->{State}, - "new_$pre".'zip' => $zip, - }; - - my @fields = (qw( company address1 address2 city state zip )); #hmm - - my $changed = - scalar( grep { $return->{$pre.$_} ne $return->{"new_$pre$_"} } - @fields - ) - ? 1 : 0; - - $return->{$pre.'address_standardized'} = $changed; - - } else { - - $return->{$pre.'error'} = "USPS WebTools error: ". - $verifier->{error}{description}; - - - } - - } - - } - - $return; - -} - - -- cgit v1.2.1 From a5318b8239e3a35cbbeb5510b451f5ba5f622846 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 6 Nov 2012 13:16:07 -0800 Subject: oneline CSV format: add previous balance and due date, #19741 --- FS/FS/cust_bill.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 4fd9b6e37..e4b2df4e8 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -2029,7 +2029,7 @@ header line only, with the fields: Agent number, agent name, customer number, first name, last name, address line 1, address line 2, city, state, zip, invoice date, invoice number, -amount charged, amount due, +amount charged, amount due, previous balance, due date. and then, for each line item, three columns containing the package number, description, and amount. @@ -2115,6 +2115,7 @@ sub print_csv { } elsif ( $format eq 'oneline' ) { #name my ($previous_balance) = $self->previous; + $previous_balance = sprintf('%.2f', $previous_balance); my $totaldue = sprintf('%.2f', $self->owed + $previous_balance); my @items = map { ($_->{pkgnum} || ''), @@ -2139,6 +2140,8 @@ sub print_csv { $self->invnum, $self->charged, $totaldue, + $previous_balance, + $self->due_date2str("%x"), @items, ); -- cgit v1.2.1 From 84fa358b56b89205fff99927080d5c28c01d57ff Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 9 Nov 2012 17:03:41 -0800 Subject: various customer location-related fixes, #13763 --- httemplate/edit/cust_main.cgi | 18 ++++++++++-------- httemplate/edit/cust_main/bottomfixup.js | 8 ++++---- httemplate/elements/standardize_locations.js | 9 ++++++--- httemplate/misc/confirm-address_standardize.html | 9 ++++++++- httemplate/misc/xmlhttp-address_standardize.html | 11 +++++++++-- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi index 0aded597f..be00213e2 100755 --- a/httemplate/edit/cust_main.cgi +++ b/httemplate/edit/cust_main.cgi @@ -316,8 +316,6 @@ if ( $cgi->param('error') ) { $payinfo = ''; $cgi->param('tagnum', FS::part_tag->default_tags); - $cust_main->coord_auto('Y'); - $cust_main->ship_coord_auto('Y'); if ( $cgi->param('qualnum') =~ /^(\d+)$/ ) { my $qualnum = $1; @@ -357,14 +355,18 @@ if ( $cgi->param('error') ) { my $countrydefault = $conf->config('countrydefault') || 'US'; my $statedefault = $conf->config('statedefault') || 'CA'; $cust_main->set('bill_location', - FS::cust_location->new( - { country => $countrydefault, state => $statedefault } - ) + FS::cust_location->new( { + country => $countrydefault, + state => $statedefault, + coord_auto => 'Y', + } ) ); $cust_main->set('ship_location', - FS::cust_location->new( - { country => $countrydefault, state => $statedefault } - ) + FS::cust_location->new( { + country => $countrydefault, + state => $statedefault, + coord_auto => 'Y', + } ) ); } diff --git a/httemplate/edit/cust_main/bottomfixup.js b/httemplate/edit/cust_main/bottomfixup.js index 4f3b7da42..6fc798919 100644 --- a/httemplate/edit/cust_main/bottomfixup.js +++ b/httemplate/edit/cust_main/bottomfixup.js @@ -96,11 +96,11 @@ function copyelement(from, to) { //alert(from + " (" + from.type + "): " + to.name + " => " + to.value); } -% # the value in 'censustract' is the confirmed censustract; if it's set, +% # the value in 'ship_censustract' is the confirmed censustract; if it's set, % # do nothing here function confirm_censustract() { var cf = document.CustomerForm; - if ( cf.elements['censustract'].value == '' ) { + if ( cf.elements['ship_censustract'].value == '' ) { var address_info = form_address_info(); address_info['ship_latitude'] = cf.elements['ship_latitude'].value; address_info['ship_longitude'] = cf.elements['ship_longitude'].value; @@ -120,8 +120,8 @@ function confirm_censustract() { %# called from confirm-censustract.html function set_censustract(tract, year) { var cf = document.CustomerForm; - cf.elements['censustract'].value = tract; - cf.elements['censusyear'].value = year; + cf.elements['ship_censustract'].value = tract; + cf.elements['ship_censusyear'].value = year; submit_continue(); } diff --git a/httemplate/elements/standardize_locations.js b/httemplate/elements/standardize_locations.js index f6564a55e..ff45b1826 100644 --- a/httemplate/elements/standardize_locations.js +++ b/httemplate/elements/standardize_locations.js @@ -25,6 +25,9 @@ function form_address_info() { 'ship_state': ship_state_el.options[ ship_state_el.selectedIndex ].value, 'ship_zip': cf.elements['<% $ship_prefix %>zip'].value, 'ship_country': cf.elements['<% $ship_prefix %>country'].value, +% if ( !$onlyship ) { + 'same': cf.elements['same'].checked +% } }; } @@ -86,9 +89,9 @@ function standardize_locations() { address_standardize(JSON.stringify(address_info), confirm_standardize); } else { - cf.elements['ship_addr_clean'].value = 'Y'; + cf.elements['<% $ship_prefix %>addr_clean'].value = 'Y'; % if ( !$onlyship ) { - cf.elements['addr_clean'].value = 'Y'; + cf.elements['<% $main_prefix %>addr_clean'].value = 'Y'; % } post_standardization(); } @@ -194,7 +197,7 @@ function confirm_manual_address() { % if ( $withcensus ) { var cf = document.<% $formname %>; cf.elements['<% $main_prefix %>censustract'].value = - cf.elements['<% $main_prefix %>enter_censustract'].value; + cf.elements['enter_censustract'].value; % } post_standardization(); } diff --git a/httemplate/misc/confirm-address_standardize.html b/httemplate/misc/confirm-address_standardize.html index 3603b95d9..a6f4b06e8 100644 --- a/httemplate/misc/confirm-address_standardize.html +++ b/httemplate/misc/confirm-address_standardize.html @@ -11,8 +11,15 @@ Confirm address standardization

+% my @prefixes; +% if ( $old{onlyship} ) { +% @prefixes = ('ship_'); +% } elsif ( $old{same} ) { +% @prefixes = (''); +% } else { +% @prefixes = ('', 'ship_'); +% } % for my $pre ('', 'ship_') { -% next if !$pre and $old{onlyship}; % my $name = $pre eq 'ship_' ? 'service' : 'billing'; % if ( $new{$pre.'addr_clean'} ) { diff --git a/httemplate/misc/xmlhttp-address_standardize.html b/httemplate/misc/xmlhttp-address_standardize.html index f53c35fca..e28c06f3a 100644 --- a/httemplate/misc/xmlhttp-address_standardize.html +++ b/httemplate/misc/xmlhttp-address_standardize.html @@ -16,8 +16,15 @@ my %old = %{ decode_json($cgi->param('arg')) } my %new; -foreach my $pre ( '', 'ship_' ) { - next unless ($pre || !$old{onlyship}); +my @prefixes; +if ($old{onlyship}) { + @prefixes = ('ship_'); +} elsif ( $old{same} ) { + @prefixes = (''); +} else { + @prefixes = ('', 'ship_'); +} +foreach my $pre ( @prefixes ) { my $location = { map { $_ => $old{$pre.$_} } -- cgit v1.2.1 From fead47c024e1a6c4bc49b5387a4c690dc1a4bf3d Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 11 Nov 2012 13:28:06 -0800 Subject: fix compilation errors, RT#13763 --- FS/FS/Conf.pm | 8 ++++++-- FS/FS/Misc/Geo.pm | 9 +++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 02869b16d..7f3fcaa38 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -14,7 +14,6 @@ use FS::conf; use FS::Record qw(qsearch qsearchs); use FS::UID qw(dbh datasrc use_confcompat); use FS::Misc::Invoicing qw( spool_formats ); -use FS::Misc::Geo; $base_dir = '%%%FREESIDE_CONF%%%'; @@ -4130,7 +4129,12 @@ and customer address. Include units.', 'section' => 'UI', 'description' => 'The method to use to look up tax district codes.', 'type' => 'select', - 'select_hash' => [ FS::Misc::Geo::get_district_methods() ], + #'select_hash' => [ FS::Misc::Geo::get_district_methods() ], + #after RT#13763, using FS::Misc::Geo here now causes a dependancy loop :/ + 'select_hash' => [ + '' => '', + 'wa_sales' => 'Washington sales tax', + ], }, { diff --git a/FS/FS/Misc/Geo.pm b/FS/FS/Misc/Geo.pm index 6bc71fc84..5cb10b2fb 100644 --- a/FS/FS/Misc/Geo.pm +++ b/FS/FS/Misc/Geo.pm @@ -9,6 +9,7 @@ use HTTP::Request::Common qw( GET POST ); use HTML::TokeParser; use URI::Escape 3.31; use Data::Dumper; +use FS::Conf; FS::UID->install_callback( sub { $conf = new FS::Conf; @@ -137,10 +138,10 @@ sub get_censustract_ffiec { $return->{'statecode'} . $return->{'countycode'} . $return->{'tractcode'}; } -sub get_district_methods { - '' => '', - 'wa_sales' => 'Washington sales tax', -}; +#sub get_district_methods { +# '' => '', +# 'wa_sales' => 'Washington sales tax', +#}; =item get_district LOCATION METHOD -- cgit v1.2.1 From c9015995b5ae64e0eaaa89ff75eb43c88186642c Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 11 Nov 2012 21:56:48 -0800 Subject: fix XSS --- FS/FS/UI/Web/small_custview.pm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/FS/FS/UI/Web/small_custview.pm b/FS/FS/UI/Web/small_custview.pm index 2c42a6b46..43d76130f 100644 --- a/FS/FS/UI/Web/small_custview.pm +++ b/FS/FS/UI/Web/small_custview.pm @@ -58,12 +58,13 @@ sub small_custview { $html .= ntable('#e8e8e8'). ' @@ -226,7 +226,7 @@ Example: -- cgit v1.2.1 From b2101823682f3738f5b367d2c1f2a7c6d47cdad1 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 11 Nov 2012 22:20:19 -0800 Subject: fix XSS --- FS/FS/UI/Web.pm | 5 +++-- httemplate/browse/part_event.html | 14 +++++++------- httemplate/edit/cust_main/first_pkg/svc_acct.html | 8 ++++---- httemplate/index.html | 2 +- httemplate/search/cust_main.cgi | 6 +++--- httemplate/search/elements/search-html.html | 4 ++-- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/FS/FS/UI/Web.pm b/FS/FS/UI/Web.pm index 1cc539a9f..c2ea0a61c 100644 --- a/FS/FS/UI/Web.pm +++ b/FS/FS/UI/Web.pm @@ -3,7 +3,8 @@ package FS::UI::Web; use strict; use vars qw($DEBUG @ISA @EXPORT_OK $me); use Exporter; -use Carp qw( confess );; +use Carp qw( confess ); +use HTML::Entities; use FS::Conf; use FS::Misc::DateTime qw( parse_datetime ); use FS::Record qw(dbdef); @@ -383,7 +384,7 @@ sub cust_fields { map { if ( $record->custnum ) { warn " $record -> $_" if $DEBUG > 1; - $record->$_(@_); + encode_entities( $record->$_(@_) ); } else { warn " ($record unlinked)" if $DEBUG > 1; $seen_unlinked++ ? '' : '(unlinked)'; diff --git a/httemplate/browse/part_event.html b/httemplate/browse/part_event.html index c06a14fe7..62e7ff0d9 100644 --- a/httemplate/browse/part_event.html +++ b/httemplate/browse/part_event.html @@ -47,7 +47,7 @@ my $event_sub = sub { my $onclick = include('/elements/popup_link_onclick.html', action => $p.'view/part_event-targets.html?eventpart='. $part_event->eventpart, - actionlabel => 'Event query - '.$part_event->event, + actionlabel => 'Event query', #no, XSS - '.$part_event->event, width => 650, height => 420, close_text => 'Close', @@ -55,14 +55,14 @@ my $event_sub = sub { [#rows [#subcolumns { - 'data' => $part_event->event, - 'link' => $p.'edit/part_event.html?'.$part_event->eventpart, + 'data' => encode_entities($part_event->event), + 'link' => $p.'edit/part_event.html?'.$part_event->eventpart, }, { - 'data' => ' (query) ', - 'size' => '-1', - 'data_style' => 'b', - 'onclick' => $onclick, + 'data' => ' (query) ', + 'size' => '-1', + 'data_style' => 'b', + 'onclick' => $onclick, }, ], ]; diff --git a/httemplate/edit/cust_main/first_pkg/svc_acct.html b/httemplate/edit/cust_main/first_pkg/svc_acct.html index b1ccc137c..717bf5025 100644 --- a/httemplate/edit/cust_main/first_pkg/svc_acct.html +++ b/httemplate/edit/cust_main/first_pkg/svc_acct.html @@ -5,7 +5,7 @@ @@ -51,7 +51,7 @@ % if ( $conf->exists('security_phrase') ) { - % } else { diff --git a/httemplate/index.html b/httemplate/index.html index 71926aa4e..bc51e6a52 100644 --- a/httemplate/index.html +++ b/httemplate/index.html @@ -46,7 +46,7 @@ % next unless $cust_main; - + % if ( $bgcolor eq $bgcolor1 ) { diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi index 7c3ad3384..8e3c8133e 100755 --- a/httemplate/search/cust_main.cgi +++ b/httemplate/search/cust_main.cgi @@ -54,7 +54,7 @@ % my $refcustlabel = "$referral_custnum: " . % ( $cust_main->company || $cust_main->last. ', '. $cust_main->first ); referrals of - "><% $refcustlabel %> + "><% $refcustlabel |h %> % } else { -- cgit v1.2.1 From fd826b3b08d1093f83f44fb2787bfad8bd715ad6 Mon Sep 17 00:00:00 2001 From: gjones2 Date: Tue, 20 Nov 2012 15:08:38 -0500 Subject: Update httemplate/elements/location.html Fixed closing tag. --- httemplate/elements/location.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/location.html b/httemplate/elements/location.html index 0f844531d..873fe1621 100644 --- a/httemplate/elements/location.html +++ b/httemplate/elements/location.html @@ -179,7 +179,7 @@ Example: % if ( $opt{enable_coords} ) { - -% } - +% delete $opt{$opt}; +% } +% } +% # now any that are somehow not in the options list +% foreach my $opt (keys %opt) { +% if ( length($opt{$opt}) ) { + + + + +% } +% } +% # now show any multiple-option groups +% foreach (sort keys %multiples) { +% my $set = $multiples{$_}; + +% } #foreach keys %multiples +
'. ntable("#cccccc",2). '
Billing
Address
'. - $cust_main->getfield('last'). ', '. $cust_main->first. '
'; + encode_entities($cust_main->getfield('last')). ', '. + encode_entities($cust_main->first). '
'; - $html .= $cust_main->company. '
' if $cust_main->company; - $html .= $cust_main->address1. '
'; - $html .= $cust_main->address2. '
' if $cust_main->address2; - $html .= $cust_main->city. ', '. $cust_main->state. ' '. $cust_main->zip. '
'; + $html .= encode_entities($cust_main->company). '
' if $cust_main->company; + $html .= encode_entities($cust_main->address1). '
'; + $html .= encode_entities($cust_main->address2). '
' if $cust_main->address2; + $html .= encode_entities($cust_main->city). ', '. $cust_main->state. ' '. $cust_main->zip. '
'; $html .= $cust_main->country. '
' if $cust_main->country && $cust_main->country ne $countrydefault; -- cgit v1.2.1 From f06a0610477b0ba8e1931722c3105b880fbc35c3 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 11 Nov 2012 22:18:50 -0800 Subject: fix XSS --- FS/FS/UI/Web/small_custview.pm | 2 +- httemplate/elements/location.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FS/FS/UI/Web/small_custview.pm b/FS/FS/UI/Web/small_custview.pm index 43d76130f..e4b5421a2 100644 --- a/FS/FS/UI/Web/small_custview.pm +++ b/FS/FS/UI/Web/small_custview.pm @@ -88,7 +88,7 @@ sub small_custview { $html .= '
'. ntable("#cccccc",2). '
Service
Address
'; $html .= join('
', - grep $_, + map encode_entities($_), grep $_, $cust_main->contact, $cust_main->company, $ship->address1, diff --git a/httemplate/elements/location.html b/httemplate/elements/location.html index de844e465..0f844531d 100644 --- a/httemplate/elements/location.html +++ b/httemplate/elements/location.html @@ -214,7 +214,7 @@ Example:
+ VALUE="<% $object->censustract |h %>"> <% '(automatic)' %>
+ VALUE="<% $object->district |h %>"> <% '(automatic)' %>
MAXLENGTH = <% $ulen %> > @@ -26,7 +26,7 @@ MAXLENGTH = <% $passwordmax %>> % unless ( $opt{'password_verify'} ) { @@ -41,7 +41,7 @@ MAXLENGTH = <% $passwordmax %>>
<% mt('Security Phrase') |h %> +
<% $cust_main->display_custnum %>: <% $cust_main->name %><% $cust_main->display_custnum %>: <% $cust_main->name |h %>
> - <% "$last, $first" %> + <% "$last, $first" |h %> > <% $pcompany %> diff --git a/httemplate/search/elements/search-html.html b/httemplate/search/elements/search-html.html index d7e81282b..5c8001fad 100644 --- a/httemplate/search/elements/search-html.html +++ b/httemplate/search/elements/search-html.html @@ -341,9 +341,9 @@ % $_ =~ /^\d+$/ ) { % # for the 'straight SQL' case: specify fields % # by position -% $row->[$_]; +% encode_entities($row->[$_]); % } else { -% $row->$_(); +% encode_entities($row->$_()); % } % } % @{$opt{'fields'}} -- cgit v1.2.1 From 4ee7d66497689819f80f29795b93f0ba564141e7 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 11 Nov 2012 22:34:20 -0800 Subject: fix XSS --- FS/FS/ClientAPI/MyAccount.pm | 3 +++ fs_selfservice/FS-SelfService/cgi/change_pkg.html | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 3f7c00432..d07b3834e 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -2037,6 +2037,9 @@ sub _usage_details { $p->{ending} = $end; } + die "illegal beginning" if $beginning !~ /^\d*$/; + die "illegal ending" if $ending !~ /^\d*$/; + my (@usage) = &$callback($svc_x, $p->{beginning}, $p->{ending}, %callback_opt ); diff --git a/fs_selfservice/FS-SelfService/cgi/change_pkg.html b/fs_selfservice/FS-SelfService/cgi/change_pkg.html index a841308a5..2d7b488ab 100644 --- a/fs_selfservice/FS-SelfService/cgi/change_pkg.html +++ b/fs_selfservice/FS-SelfService/cgi/change_pkg.html @@ -14,8 +14,8 @@ function enable_change_pkg () {
- - + + diff --git a/httemplate/elements/dashboard-toplist.html b/httemplate/elements/dashboard-toplist.html index c6362e0c9..f4a372519 100644 --- a/httemplate/elements/dashboard-toplist.html +++ b/httemplate/elements/dashboard-toplist.html @@ -21,7 +21,7 @@ - + @@ -70,24 +70,27 @@ Confirm address standardization % } # for $pre %# only do this part if address standardization provided a censustract -% if ( $new{'ship_censustract'} ) { +% my $pre = $old{same} ? 'bill_' : 'ship_'; +% my $censustract = $new{$pre.'censustract'}; +% my $census_error = $new{$pre.'census_error'}; +% if ( $censustract ) { - + % } #if censustract -% if ( $new{error} or $new{ship_error} ) { +% if ( $new{bill_error} or $new{ship_error} ) {
<% mt('Referring customer') |h %> - <% $cust_main->referral_custnum %>: <% $referring_cust_main->name %> + <% $cust_main->referral_custnum %>: <% $referring_cust_main->name |h %>
- <% $cust_main->name %> + <% $cust_main->name |h %> <& /elements/mcp_lint.html, 'cust_main'=>$cust_main &> diff --git a/httemplate/elements/small_prospect_view.html b/httemplate/elements/small_prospect_view.html index 4942e8dc7..26e830bc4 100644 --- a/httemplate/elements/small_prospect_view.html +++ b/httemplate/elements/small_prospect_view.html @@ -1,5 +1,5 @@ % my $link = "${p}view/prospect_main.html?". $prospect_main->prospectnum; -Prospect: <% $prospect_main->name %> +Prospect: <% $prospect_main->name |h %> <%init> my($prospect_main, %opt) = @_; diff --git a/httemplate/misc/cust_main_note-import.cgi b/httemplate/misc/cust_main_note-import.cgi index 72ac556fd..186289517 100644 --- a/httemplate/misc/cust_main_note-import.cgi +++ b/httemplate/misc/cust_main_note-import.cgi @@ -164,7 +164,7 @@ % my $i=0; % foreach (@cust_main) { - + % $i++; % } @@ -172,15 +172,15 @@ var customer_select<% $row %> = document.getElementById("cust_select<% $row %>"); customer_select<% $row %>.onchange = select_customer; - + - <% $first %> - + <% $first |h %> + - <% $last %> - + <% $last |h %> + <% $note %> diff --git a/httemplate/misc/did_order_provision.html b/httemplate/misc/did_order_provision.html index 1df9444ab..8739c1619 100644 --- a/httemplate/misc/did_order_provision.html +++ b/httemplate/misc/did_order_provision.html @@ -21,7 +21,7 @@ % my $avail = keys(%$cust_pkg_phone); % $anyavail = 1 if $avail;
<% $cust_main->name %><% $cust_main->name |h %> % if ( !$avail ) { No suitable packages exist for this customer. diff --git a/httemplate/misc/xmlhttp-cust_main-duplicates.html b/httemplate/misc/xmlhttp-cust_main-duplicates.html index 6654b3e39..7ee00af66 100644 --- a/httemplate/misc/xmlhttp-cust_main-duplicates.html +++ b/httemplate/misc/xmlhttp-cust_main-duplicates.html @@ -8,9 +8,9 @@ Choose an existing customer
<% $custnum %>: - <% $_->name %>—<%$_->ucfirst_cust_status%>
-<% $_->address1 %>
-<% $_->city %>, <% $_->state %>  <% $_->zip %> + <% $_->name |h %>—<%$_->ucfirst_cust_status%>
+<% $_->address1 |h %>
+<% $_->city |h %>, <% $_->state %>  <% $_->zip %>
-- cgit v1.2.1 From f9060f8300336b1fc792602a56308e883c27f3aa Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 12 Nov 2012 00:02:42 -0800 Subject: fix XSS --- FS/FS/ClientAPI/MyAccount.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index d07b3834e..3364b97df 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -2037,8 +2037,8 @@ sub _usage_details { $p->{ending} = $end; } - die "illegal beginning" if $beginning !~ /^\d*$/; - die "illegal ending" if $ending !~ /^\d*$/; + die "illegal beginning" if $p->{beginning} !~ /^\d*$/; + die "illegal ending" if $p->{ending} !~ /^\d*$/; my (@usage) = &$callback($svc_x, $p->{beginning}, $p->{ending}, %callback_opt -- cgit v1.2.1 From c444794974ce5f9512d5f323805db58176f26ad3 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 12 Nov 2012 04:57:25 -0800 Subject: fix self-service if RT isn't used --- FS/FS/ClientAPI/MyAccount.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 3364b97df..4477611d0 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -396,7 +396,7 @@ sub customer_info { my @tickets = $cust_main->tickets; # unavoidable false laziness w/ httemplate/view/cust_main/tickets.html - if ( FS::TicketSystem->selfservice_priority ) { + if ( $FS::TicketSystem::system && FS::TicketSystem->selfservice_priority ) { my $dir = $conf->exists('ticket_system-priority_reverse') ? -1 : 1; $return{tickets} = [ sort { -- cgit v1.2.1 From 71def0ba19307163d8a8f6fcd8bc4bb759a336a3 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 12 Nov 2012 14:36:57 -0800 Subject: remove ancient referer --- FS/FS/cust_main/Billing_Realtime.pm | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/FS/FS/cust_main/Billing_Realtime.pm b/FS/FS/cust_main/Billing_Realtime.pm index 7103e6151..80063debb 100644 --- a/FS/FS/cust_main/Billing_Realtime.pm +++ b/FS/FS/cust_main/Billing_Realtime.pm @@ -300,7 +300,10 @@ sub _bop_content { ? $options->{country} : $self->country; - $content{referer} = 'http://cleanwhisker.420.am/'; #XXX fix referer :/ + #3.0 is a good a time as any to get rid of this... add a config to pass it + # if anyone still needs it + #$content{referer} = 'http://cleanwhisker.420.am/'; + $content{phone} = $self->daytime || $self->night; my $currency = $conf->exists('business-onlinepayment-currency') @@ -1233,7 +1236,11 @@ sub realtime_botpp_capture { 'amount' => $cust_pay_pending->paid, #'invoice_number' => $options{'invnum'}, 'customer_id' => $self->custnum, - 'referer' => 'http://cleanwhisker.420.am/', + + #3.0 is a good a time as any to get rid of this... add a config to pass it + # if anyone still needs it + #'referer' => 'http://cleanwhisker.420.am/', + 'reference' => $cust_pay_pending->paypendingnum, 'email' => $email, 'phone' => $self->daytime || $self->night, @@ -1431,7 +1438,10 @@ sub realtime_refund_bop { 'password' => $password, 'order_number' => $order_number, 'amount' => $amount, - 'referer' => 'http://cleanwhisker.420.am/', #XXX fix referer :/ + + #3.0 is a good a time as any to get rid of this... add a config to pass it + # if anyone still needs it + #'referer' => 'http://cleanwhisker.420.am/', ); $content{authorization} = $auth if length($auth); #echeck/ACH transactions have an order # but no auth -- cgit v1.2.1 From e32344effc97e76f9ee26fbf4ee206bfaee47a54 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 12 Nov 2012 23:54:00 -0800 Subject: don't send countries other than US/CA/GB/UK to paymentech, RT#20222 --- FS/FS/pay_batch/paymentech.pm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/FS/FS/pay_batch/paymentech.pm b/FS/FS/pay_batch/paymentech.pm index 133f8f1ce..c687cc8e2 100644 --- a/FS/FS/pay_batch/paymentech.pm +++ b/FS/FS/pay_batch/paymentech.pm @@ -72,7 +72,9 @@ my %paytype = ( 'personal savings' => 'S', 'business checking' => 'X', 'business savings' => 'X', - ); +); + +my %paymentech_countries = map { $_ => 1 } qw( US CA GB UK ); %export_info = ( init => sub { @@ -121,7 +123,10 @@ my %paytype = ( avsCity => substr($_->city, 0, 20), avsState => $_->state, avsName => substr($_->first . ' ' . $_->last, 0, 30), - avsCountryCode => $_->country, + avsCountryCode => ( $paymentech_countries{ $_->country } + ? $_->country + : '' + ), orderID => $_->paybatchnum, amount => $_->amount * 100, ); -- cgit v1.2.1 From 2bb7db96a07599e980323c1b6b23a8c79cc17a9a Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 13 Nov 2012 15:32:31 -0800 Subject: address standardization/census tract fixes --- FS/FS/Upgrade.pm | 7 + FS/FS/cust_main/Location.pm | 3 +- httemplate/edit/cust_main/bottomfixup.js | 31 +++-- httemplate/elements/standardize_locations.js | 164 ++++++++++------------- httemplate/misc/confirm-address_standardize.html | 23 ++-- httemplate/misc/confirm-censustract.html | 5 +- httemplate/misc/xmlhttp-address_standardize.html | 4 +- 7 files changed, 118 insertions(+), 119 deletions(-) diff --git a/FS/FS/Upgrade.pm b/FS/FS/Upgrade.pm index 3f76f5116..45cba82a4 100644 --- a/FS/FS/Upgrade.pm +++ b/FS/FS/Upgrade.pm @@ -84,6 +84,13 @@ sub upgrade_config { } } + # if there's a USPS tools login, assume that's the standardization method + # you want to use + if ( length($conf->config('usps_webtools-userid')) > 0 and + !$conf->exists('address_standardize_method') ) { + $conf->set('address_standardize_method', 'usps'); + } + } sub upgrade_overlimit_groups { diff --git a/FS/FS/cust_main/Location.pm b/FS/FS/cust_main/Location.pm index 8e30bb65b..ba3513b2f 100644 --- a/FS/FS/cust_main/Location.pm +++ b/FS/FS/cust_main/Location.pm @@ -18,7 +18,8 @@ BEGIN { no strict 'refs'; @location_fields = qw( address1 address2 city county state zip country district - latitude longitude coord_auto censustract censusyear geocode ); + latitude longitude coord_auto censustract censusyear geocode + addr_clean ); foreach my $f (@location_fields) { *{"FS::cust_main::Location::$f"} = sub { diff --git a/httemplate/edit/cust_main/bottomfixup.js b/httemplate/edit/cust_main/bottomfixup.js index 6fc798919..1cfa52d8f 100644 --- a/httemplate/edit/cust_main/bottomfixup.js +++ b/httemplate/edit/cust_main/bottomfixup.js @@ -7,7 +7,8 @@ my $company_longitude = $conf->config('company_longitude'); my @fixups = ('copy_payby_fields', 'standardize_locations'); -push @fixups, 'confirm_censustract'; +push @fixups, 'confirm_censustract' + if $conf->exists('cust_main-require_censustract'); push @fixups, 'check_unique' if $conf->exists('cust_main-check_unique') and !$opt{'custnum'}; @@ -67,12 +68,11 @@ function copy_payby_fields() { submit_continue(); } -<% include( '/elements/standardize_locations.js', - 'callback' => 'submit_continue();', - 'main_prefix' => 'bill_', - 'no_company' => 1, - ) -%> +<& /elements/standardize_locations.js, + 'callback' => 'submit_continue();', + 'main_prefix' => 'bill_', + 'no_company' => 1, +&> function copyelement(from, to) { if ( from == undefined ) { @@ -96,14 +96,15 @@ function copyelement(from, to) { //alert(from + " (" + from.type + "): " + to.name + " => " + to.value); } -% # the value in 'ship_censustract' is the confirmed censustract; if it's set, +% # the value in pre+'censustract' is the confirmed censustract; if it's set, % # do nothing here function confirm_censustract() { var cf = document.CustomerForm; - if ( cf.elements['ship_censustract'].value == '' ) { + var pre = cf.elements['same'].checked ? 'bill_' : 'ship_'; + if ( cf.elements[pre+'censustract'].value == '' ) { var address_info = form_address_info(); - address_info['ship_latitude'] = cf.elements['ship_latitude'].value; - address_info['ship_longitude'] = cf.elements['ship_longitude'].value; + address_info[pre+'latitude'] = cf.elements[pre+'latitude'].value; + address_info[pre+'longitude'] = cf.elements[pre+'longitude'].value; OLpostAJAX( '<%$p%>/misc/confirm-censustract.html', 'q=' + encodeURIComponent(JSON.stringify(address_info)), @@ -120,8 +121,12 @@ function confirm_censustract() { %# called from confirm-censustract.html function set_censustract(tract, year) { var cf = document.CustomerForm; - cf.elements['ship_censustract'].value = tract; - cf.elements['ship_censusyear'].value = year; + var pre = 'ship_'; + if ( cf.elements['same'].checked ) { + pre = 'bill_'; + } + cf.elements[pre + 'censustract'].value = tract; + cf.elements[pre + 'censusyear'].value = year; submit_continue(); } diff --git a/httemplate/elements/standardize_locations.js b/httemplate/elements/standardize_locations.js index ff45b1826..d9c1df7e6 100644 --- a/httemplate/elements/standardize_locations.js +++ b/httemplate/elements/standardize_locations.js @@ -1,54 +1,51 @@ function form_address_info() { var cf = document.<% $formname %>; - var state_el = cf.elements['<% $main_prefix %>state']; - var ship_state_el = cf.elements['<% $ship_prefix %>state']; - return { -% if ( $onlyship ) { - 'onlyship': 1, -% } else { -% if ( $withfirm ) { - 'company', cf.elements['company'].value, -% } - 'address1': cf.elements['<% $main_prefix %>address1'].value, - 'address2': cf.elements['<% $main_prefix %>address2'].value, - 'city': cf.elements['<% $main_prefix %>city'].value, - 'state': state_el.options[ state_el.selectedIndex ].value, - 'zip': cf.elements['<% $main_prefix %>zip'].value, - 'country': cf.elements['<% $main_prefix %>country'].value, + + var returnobj = { onlyship: <% $onlyship ? 1 : 0 %> }; +% if ( !$onlyship ) { + returnobj['same'] = cf.elements['same'].checked; % } -% if ( $withcensus ) { - 'ship_censustract': cf.elements['enter_censustract'].value, +% if ( $withfirm ) { +% # not part of either address, really + returnobj['company'] = cf.elements['company'].value; % } - 'ship_address1': cf.elements['<% $ship_prefix %>address1'].value, - 'ship_address2': cf.elements['<% $ship_prefix %>address2'].value, - 'ship_city': cf.elements['<% $ship_prefix %>city'].value, - 'ship_state': ship_state_el.options[ ship_state_el.selectedIndex ].value, - 'ship_zip': cf.elements['<% $ship_prefix %>zip'].value, - 'ship_country': cf.elements['<% $ship_prefix %>country'].value, -% if ( !$onlyship ) { - 'same': cf.elements['same'].checked +% if ( $withcensus ) { +% # "entered" censustract always goes with the ship_ address if there is one + returnobj['ship_censustract'] = cf.elements['enter_censustract'].value; % } - }; +% for my $pre (@prefixes) { + if ( <% $pre eq 'ship_' ? 1 : 0 %> && returnobj['same'] ) { +% # special case: don't include any ship_ fields, and move the entered +% # censustract over to bill_. + returnobj['bill_censustract'] = returnobj['ship_censustract']; + delete returnobj['ship_censustract']; + } else { +% # normal case +% for my $field (qw(address1 address2 city state zip country)) { + returnobj['<% $pre %><% $field %>'] = cf.elements['<% $pre %><% $field %>'].value; +% } #for $field + } // if returnobj['same'] +% } #foreach $pre + + return returnobj; } function standardize_locations() { - var startup_msg = '

Verifying address...

'; - overlib(startup_msg, WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSECLICK, MIDX, 0, MIDY, 0); var cf = document.<% $formname %>; var address_info = form_address_info(); var changed = false; // have any of the address fields been changed? // clear coord_auto fields if the user has changed the coordinates -% for my $pre ($ship_prefix, $onlyship ? () : $main_prefix) { +% for my $pre (@prefixes) { % for my $field ($pre.'latitude', $pre.'longitude') { if ( cf.elements['<% $field %>'].value != cf.elements['old_<% $field %>'].value ) { cf.elements['<% $pre %>coord_auto'].value = ''; } -% } +% } #foreach $field // but if the coordinates have been set to null, turn coord_auto on // and standardize if ( cf.elements['<% $pre %>latitude'].value == '' && @@ -57,12 +54,11 @@ function standardize_locations() { changed = true; } -% } +% } #foreach $pre // standardize if the old address wasn't clean - if ( cf.elements['old_<% $ship_prefix %>addr_clean'].value == '' || - ( <% !$onlyship || 0 %> && - cf.elements['old_<% $main_prefix %>addr_clean'].value == '' ) ) { + if ( cf.elements['old_ship_addr_clean'].value == '' || + cf.elements['old_bill_addr_clean'].value == '' ) { changed = true; @@ -80,18 +76,24 @@ function standardize_locations() { % # censustract so that we don't ask the user to confirm it again. if ( !changed ) { - cf.elements['<% $main_prefix %>censustract'].value = - address_info['ship_censustract']; + if ( address_info['same'] ) { + cf.elements['bill_censustract'].value = + address_info['bill_censustract']; + } else { + cf.elements['ship_censustract'].value = + address_info['ship_censustract']; + } } % if ( $conf->config('address_standardize_method') ) { if ( changed ) { + var startup_msg = '

Verifying address...

'; + overlib(startup_msg, WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSECLICK, MIDX, 0, MIDY, 0); address_standardize(JSON.stringify(address_info), confirm_standardize); } else { - cf.elements['<% $ship_prefix %>addr_clean'].value = 'Y'; -% if ( !$onlyship ) { - cf.elements['<% $main_prefix %>addr_clean'].value = 'Y'; +% foreach my $pre (@prefixes) { + cf.elements['<% $pre %>addr_clean'].value = 'Y'; % } post_standardization(); } @@ -138,55 +140,26 @@ function replace_address() { var newaddr = returned['new']; - var clean = newaddr['addr_clean'] == 'Y'; - var ship_clean = newaddr['ship_addr_clean'] == 'Y'; - var error = newaddr['error']; - var ship_error = newaddr['ship_error']; - var cf = document.<% $formname %>; - var state_el = cf.elements['<% $main_prefix %>state']; - var ship_state_el = cf.elements['<% $ship_prefix %>state']; - -% if ( !$onlyship ) { +% foreach my $pre (@prefixes) { + var clean = newaddr['<% $pre %>addr_clean'] == 'Y'; + var error = newaddr['<% $pre %>error']; if ( clean ) { -% if ( $withfirm ) { - cf.elements['<% $main_prefix %>company'].value = newaddr['company']; -% } - cf.elements['<% $main_prefix %>address1'].value = newaddr['address1']; - cf.elements['<% $main_prefix %>address2'].value = newaddr['address2']; - cf.elements['<% $main_prefix %>city'].value = newaddr['city']; - setselect(cf.elements['<% $main_prefix %>state'], newaddr['state']); - cf.elements['<% $main_prefix %>zip'].value = newaddr['zip']; - cf.elements['<% $main_prefix %>addr_clean'].value = 'Y'; - - if ( cf.elements['<% $main_prefix %>coord_auto'].value ) { - cf.elements['<% $main_prefix %>latitude'].value = newaddr['latitude']; - cf.elements['<% $main_prefix %>longitude'].value = newaddr['longitude']; - } - } -% } +% foreach my $field (qw(address1 address2 city state zip addr_clean censustract)) { + cf.elements['<% $pre %><% $field %>'].value = newaddr['<% $pre %><% $field %>']; +% } #foreach $field - if ( ship_clean ) { -% if ( $withfirm ) { - cf.elements['<% $ship_prefix %>company'].value = newaddr['ship_company']; -% } - cf.elements['<% $ship_prefix %>address1'].value = newaddr['ship_address1']; - cf.elements['<% $ship_prefix %>address2'].value = newaddr['ship_address2']; - cf.elements['<% $ship_prefix %>city'].value = newaddr['ship_city']; - setselect(cf.elements['<% $ship_prefix %>state'], newaddr['ship_state']); - cf.elements['<% $ship_prefix %>zip'].value = newaddr['ship_zip']; - cf.elements['<% $ship_prefix %>addr_clean'].value = 'Y'; - if ( cf.elements['<% $ship_prefix %>coord_auto'].value ) { - cf.elements['<% $ship_prefix %>latitude'].value = newaddr['latitude']; - cf.elements['<% $ship_prefix %>longitude'].value = newaddr['longitude']; - } - } -% if ( $withcensus ) { -% # then set the censustract if address_standardize provided one. - if ( ship_clean && newaddr['ship_censustract'] ) { - cf.elements['<% $main_prefix %>censustract'].value = newaddr['ship_censustract']; - } -% } + if ( cf.elements['<% $pre %>coord_auto'].value ) { + cf.elements['<% $pre %>latitude'].value = newaddr['<% $pre %>latitude']; + cf.elements['<% $pre %>longitude'].value = newaddr['<% $pre %>longitude']; + } +% if ( $withcensus ) { + if ( clean && newaddr['<% $pre %>censustract'] ) { + cf.elements['<% $pre %>censustract'].value = newaddr['<% $pre %>censustract']; + } +% } #if $withcensus + } // if clean +% } #foreach $pre post_standardization(); @@ -196,8 +169,13 @@ function confirm_manual_address() { %# not much to do in this case, just confirm the censustract % if ( $withcensus ) { var cf = document.<% $formname %>; - cf.elements['<% $main_prefix %>censustract'].value = - cf.elements['enter_censustract'].value; + if ( cf.elements['same'] && cf.elements['same'].checked ) { + cf.elements['bill_censustract'].value = + cf.elements['enter_censustract'].value; + } else { + cf.elements['ship_censustract'].value = + cf.elements['enter_censustract'].value; + } % } post_standardization(); } @@ -295,12 +273,16 @@ my $withcensus = 1; my $formname = $opt{form} || 'CustomerForm'; my $onlyship = $opt{onlyship} || ''; -my $main_prefix = $opt{main_prefix} || ''; -my $ship_prefix = $opt{ship_prefix} || ($onlyship ? '' : 'ship_'); -my $taxpre = $main_prefix; -$taxpre = $ship_prefix if ( $conf->exists('tax-ship_address') || $onlyship ); +#my $main_prefix = $opt{main_prefix} || ''; +#my $ship_prefix = $opt{ship_prefix} || ($onlyship ? '' : 'ship_'); +# The prefixes are now 'ship_' and 'bill_'. +my $taxpre = 'bill_'; +$taxpre = 'ship_' if ( $conf->exists('tax-ship_address') || $onlyship ); my $post_geocode = $opt{callback} || 'post_geocode();'; $withfirm = 0 if $opt{no_company}; $withcensus = 0 if $opt{no_census}; +my @prefixes = ('ship_'); +unshift @prefixes, 'bill_' unless $onlyship; + diff --git a/httemplate/misc/confirm-address_standardize.html b/httemplate/misc/confirm-address_standardize.html index a6f4b06e8..57201ea5a 100644 --- a/httemplate/misc/confirm-address_standardize.html +++ b/httemplate/misc/confirm-address_standardize.html @@ -2,7 +2,7 @@ th { line-height: 150% }

-% if ( $new{error} or $new{ship_error} ) { +% if ( $new{bill_error} or $new{ship_error} ) { Address standardization error % } % else { @@ -15,11 +15,11 @@ Confirm address standardization % if ( $old{onlyship} ) { % @prefixes = ('ship_'); % } elsif ( $old{same} ) { -% @prefixes = (''); +% @prefixes = ('bill_'); % } else { -% @prefixes = ('', 'ship_'); +% @prefixes = ('bill_', 'ship_'); % } -% for my $pre ('', 'ship_') { +% for my $pre (@prefixes) { % my $name = $pre eq 'ship_' ? 'service' : 'billing'; % if ( $new{$pre.'addr_clean'} ) {
Entered census tract Calculated census tract
<% $old{'ship_censustract'} %><% $old{$pre.'censustract'} %> -% if ( $new{'ship_census_error'} ) { - <% $new{'ship_census_error'} %> +% if ( $census_error ) { + <% $census_error %> % } else { - <% $new{'ship_censustract'} %> + <% $censustract %> % }
-- cgit v1.2.1 From e7a9ba25d437b6a145a6260594c27f9dc0ac0495 Mon Sep 17 00:00:00 2001 From: gjones2 Date: Tue, 20 Nov 2012 14:50:56 -0500 Subject: Update httemplate/elements/selectlayers.html Changed '""' to 'block'. This code was generating "
This might cause unexpected behavior in some browsers and the display property should be a block element (when displayed). --- httemplate/elements/selectlayers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/selectlayers.html b/httemplate/elements/selectlayers.html index dd279bd16..01fd590ca 100644 --- a/httemplate/elements/selectlayers.html +++ b/httemplate/elements/selectlayers.html @@ -146,7 +146,7 @@ Example:
" > -- cgit v1.2.1 From bf8b70c62f5d87f1635ed323928f746891cb549f Mon Sep 17 00:00:00 2001 From: gjones2 Date: Tue, 20 Nov 2012 15:03:18 -0500 Subject: Update httemplate/elements/contact.html Changed since it's closing the opening
+
Type
<% mt('Latitude') |h %> + <% mt('Latitude') |h %> Date: Tue, 20 Nov 2012 16:12:52 -0500 Subject: Update httemplate/elements/searchbar-address2.html Fixed issue where html break tags are being escaped erroneously causing break tags to be displayed in the navigation menu. This issue can be reproduced by doing the following: 1. Change the Freeside user's preference to display the menu on the left. 2. Click "Ticketing Main" --- httemplate/elements/searchbar-address2.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/searchbar-address2.html b/httemplate/elements/searchbar-address2.html index d5e2b37d7..5f3b1f233 100644 --- a/httemplate/elements/searchbar-address2.html +++ b/httemplate/elements/searchbar-address2.html @@ -6,7 +6,7 @@
- <% $menu_position eq 'left' ? '
' : '' %> + <% $menu_position eq 'left' ? '
' : '' |n %> % } -- cgit v1.2.1 From 69e6eda22f48dde358c86113250188f40453a764 Mon Sep 17 00:00:00 2001 From: gjones2 Date: Tue, 20 Nov 2012 16:14:59 -0500 Subject: Update httemplate/elements/searchbar-cust_bill.html Fixed issue where html break tags are being escaped erroneously causing break tags to be displayed in the navigation menu. This issue can be reproduced by doing the following: 1. Change the Freeside user's preference to display the menu on the left. 2. Click "Ticketing Main" --- httemplate/elements/searchbar-cust_bill.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/searchbar-cust_bill.html b/httemplate/elements/searchbar-cust_bill.html index 7d24fbe9d..169315bf0 100644 --- a/httemplate/elements/searchbar-cust_bill.html +++ b/httemplate/elements/searchbar-cust_bill.html @@ -8,7 +8,7 @@
- <% $menu_position eq 'left' ? '

' : '' %> + <% $menu_position eq 'left' ? '

' : '' |n %> % } -- cgit v1.2.1 From aae59f21b56cdf5f5653f3c8011d688198f56db4 Mon Sep 17 00:00:00 2001 From: gjones2 Date: Tue, 20 Nov 2012 16:20:09 -0500 Subject: Update httemplate/elements/searchbar-cust_main.html Fixed issue where html break tags are being escaped erroneously causing break tags to be displayed in the navigation menu. This issue can be reproduced by doing the following: 1. Change the Freeside user's preference to display the menu on the left. 2. Click "Ticketing Main" --- httemplate/elements/searchbar-cust_main.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/searchbar-cust_main.html b/httemplate/elements/searchbar-cust_main.html index 5d79aaa5e..9a98417c8 100644 --- a/httemplate/elements/searchbar-cust_main.html +++ b/httemplate/elements/searchbar-cust_main.html @@ -5,7 +5,7 @@ <% mt('Advanced') |h %> - <% $menu_position eq 'left' ? '
' : '' %> + <% $menu_position eq 'left' ? '
' : '' |n %> % } -- cgit v1.2.1 From 54208096c3d8a75b3a21e18580059d2b1c084608 Mon Sep 17 00:00:00 2001 From: gjones2 Date: Tue, 20 Nov 2012 16:20:31 -0500 Subject: Update httemplate/elements/searchbar-cust_svc.html Fixed issue where html break tags are being escaped erroneously causing break tags to be displayed in the navigation menu. This issue can be reproduced by doing the following: 1. Change the Freeside user's preference to display the menu on the left. 2. Click "Ticketing Main" --- httemplate/elements/searchbar-cust_svc.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/searchbar-cust_svc.html b/httemplate/elements/searchbar-cust_svc.html index 766209d16..e4c2dc614 100644 --- a/httemplate/elements/searchbar-cust_svc.html +++ b/httemplate/elements/searchbar-cust_svc.html @@ -5,7 +5,7 @@ <% mt('Advanced') |h %> - <% $menu_position eq 'left' ? '
' : '' %> + <% $menu_position eq 'left' ? '
' : '' |n %> % } -- cgit v1.2.1 From 07cbc6f4f150dcd21b53684c55937ad636ff22b9 Mon Sep 17 00:00:00 2001 From: gjones2 Date: Tue, 20 Nov 2012 16:20:45 -0500 Subject: Update httemplate/elements/searchbar-prospect.html Fixed issue where html break tags are being escaped erroneously causing break tags to be displayed in the navigation menu. This issue can be reproduced by doing the following: 1. Change the Freeside user's preference to display the menu on the left. 2. Click "Ticketing Main" --- httemplate/elements/searchbar-prospect.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/searchbar-prospect.html b/httemplate/elements/searchbar-prospect.html index 68b90d4e3..ac363796e 100644 --- a/httemplate/elements/searchbar-prospect.html +++ b/httemplate/elements/searchbar-prospect.html @@ -5,7 +5,7 @@ Adv - <% $menu_position eq 'left' ? '
' : '' %> + <% $menu_position eq 'left' ? '
' : '' |n %> % } -- cgit v1.2.1 From 4c32a16b43ee00d969939d15cfc586ba8023bf47 Mon Sep 17 00:00:00 2001 From: gjones2 Date: Tue, 20 Nov 2012 16:21:06 -0500 Subject: Update httemplate/elements/searchbar-ticket.html Fixed issue where html break tags are being escaped erroneously causing break tags to be displayed in the navigation menu. This issue can be reproduced by doing the following: 1. Change the Freeside user's preference to display the menu on the left. 2. Click "Ticketing Main" --- httemplate/elements/searchbar-ticket.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/searchbar-ticket.html b/httemplate/elements/searchbar-ticket.html index 30624f7d3..ae86dbcec 100644 --- a/httemplate/elements/searchbar-ticket.html +++ b/httemplate/elements/searchbar-ticket.html @@ -5,7 +5,7 @@ <% mt('Advanced') |h %> - <% $menu_position eq 'left' ? '
' : '' %> + <% $menu_position eq 'left' ? '
' : '' |n %> % } -- cgit v1.2.1 From 5ad226c0ff7759184ea26d66292ccebd2ec00af7 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 20 Nov 2012 16:11:50 -0800 Subject: fix a confusing standardization behavior, #13763 --- httemplate/elements/standardize_locations.js | 19 +++++++++++++++---- httemplate/misc/xmlhttp-address_standardize.html | 8 +++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/httemplate/elements/standardize_locations.js b/httemplate/elements/standardize_locations.js index d9c1df7e6..15c5761a0 100644 --- a/httemplate/elements/standardize_locations.js +++ b/httemplate/elements/standardize_locations.js @@ -1,3 +1,9 @@ +function status_message(text, caption) { + text = '

' + text + '

'; + caption = caption || 'Please wait...'; + overlib(text, WIDTH, 444, HEIGHT, 168, CAPTION, caption, STICKY, AUTOSTATUSCAP, CLOSECLICK, MIDX, 0, MIDY, 0); +} + function form_address_info() { var cf = document.<% $formname %>; @@ -87,8 +93,7 @@ function standardize_locations() { % if ( $conf->config('address_standardize_method') ) { if ( changed ) { - var startup_msg = '

Verifying address...

'; - overlib(startup_msg, WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSECLICK, MIDX, 0, MIDY, 0); + status_message('Verifying address...'); address_standardize(JSON.stringify(address_info), confirm_standardize); } else { @@ -116,8 +121,14 @@ function confirm_standardize(arg) { replace_address(); // with the contents of returned['new'] - } - else { + } else if ( returned['all_same'] ) { + + // then all entered address fields are correct + // but we still need to set the lat/long fields and addr_clean + status_message('Verified'); + replace_address(); + + } else { var querystring = encodeURIComponent( JSON.stringify(returned) ); // confirmation popup: knows to call replace_address(), diff --git a/httemplate/misc/xmlhttp-address_standardize.html b/httemplate/misc/xmlhttp-address_standardize.html index 1620642cb..988057163 100644 --- a/httemplate/misc/xmlhttp-address_standardize.html +++ b/httemplate/misc/xmlhttp-address_standardize.html @@ -24,6 +24,7 @@ if ($old{onlyship}) { } else { @prefixes = ('bill_', 'ship_'); } +my $all_same = 1; foreach my $pre ( @prefixes ) { my $location = { @@ -38,8 +39,13 @@ foreach my $pre ( @prefixes ) { foreach ( keys(%$cache) ) { $new{$pre.$_} = $cache->get($_); } + + foreach ( qw(address1 address2 city state zip country) ) { + $all_same = 0 if ( $new{$pre.$_} ne $old{$pre.$_} ); + last if !$all_same; + } } -my $return = { old => \%old, new => \%new }; +my $return = { old => \%old, new => \%new, all_same => $all_same }; warn "result:\n".encode_json($return) if $DEBUG; -- cgit v1.2.1 From 064b2fa3bc7630b7234f2d3b4ce6251653ca1c61 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sat, 24 Nov 2012 13:29:34 -0800 Subject: typo --- FS/FS/cust_main/Packages.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm index 11c13e5dd..395cce7e0 100644 --- a/FS/FS/cust_main/Packages.pm +++ b/FS/FS/cust_main/Packages.pm @@ -58,7 +58,7 @@ action completes (such as running the customer's credit card successfully). Optional subject for a ticket created and attached to this customer -=item ticket_subject +=item ticket_queue Optional queue name for ticket additions -- cgit v1.2.1 From 2c4799e43db745b27b507c7c779ecdaf6628b0f3 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sat, 24 Nov 2012 13:29:43 -0800 Subject: IPifony charge download script, stage 1, #18333 --- FS/bin/freeside-ipifony-download | 198 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 FS/bin/freeside-ipifony-download diff --git a/FS/bin/freeside-ipifony-download b/FS/bin/freeside-ipifony-download new file mode 100644 index 000000000..0384926ad --- /dev/null +++ b/FS/bin/freeside-ipifony-download @@ -0,0 +1,198 @@ +#!/usr/bin/perl + +use strict; +use Getopt::Std; +use Date::Format qw(time2str); +use File::Temp qw(tempdir); +use Net::SFTP::Foreign; +use FS::UID qw(adminsuidsetup); +use FS::Record qw(qsearch qsearchs); +use FS::cust_main; +use FS::Conf; +use Text::CSV; + +my %opt; +getopts('va:', \%opt); + +#$Net::SFTP::Foreign::debug = -1; +sub HELP_MESSAGE { ' + Usage: + freeside-ipifony-download + [ -v ] + [ -a archivedir ] + freesideuser sftpuser@hostname[:path] +' } + +my @fields = ( + 'custnum', + 'date_desc', + 'quantity', + 'amount', + 'classname', +); + +my $user = shift or die &HELP_MESSAGE; +adminsuidsetup $user; + +# for statistics +my $num_charges = 0; +my $num_errors = 0; +my $sum_charges = 0; +# cache classnums +my %classnum_of; + +if ( $opt{a} ) { + die "no such directory: $opt{a}\n" + unless -d $opt{a}; + die "archive directory $opt{a} is not writable by the freeside user\n" + unless -w $opt{a}; +} + +#my $tmpdir = File::Temp->newdir(); +my $tmpdir = tempdir( CLEANUP => 1 ); #DIR=>somewhere? + +my $host = shift + or die &HELP_MESSAGE; +my ($sftpuser, $path); +$host =~ s/^(.+)\@//; +$sftpuser = $1 || $ENV{USER}; +$host =~ s/:(.*)//; +$path = $1; + +# for now assume SFTP download as the only method +print STDERR "Connecting to $sftpuser\@$host...\n" if $opt{v}; + +my $sftp = Net::SFTP::Foreign->new( + host => $host, + user => $sftpuser, + # for now we don't support passwords. use authorized_keys. + timeout => 30, + more => ($opt{v} ? '-v' : ''), +); +die "failed to connect to '$sftpuser\@$host'\n(".$sftp->error.")\n" + if $sftp->error; + +$sftp->setcwd($path) if $path; + +my $files = $sftp->ls('.', wanted => qr/\.csv$/, names_only => 1); +if (!@$files) { + print STDERR "No charge files found.\n" if $opt{v}; + exit(-1); +} +FILE: foreach my $filename (@$files) { + print STDERR "Retrieving $filename\n" if $opt{v}; + $sftp->get("$filename", "$tmpdir/$filename"); + if($sftp->error) { + warn "failed to download $filename\n"; + next FILE; + } + + #move to server archive dir + $sftp->rename("$filename", "Archive/$filename"); + if($sftp->error) { + warn "failed to archive $filename on server\n"; + } # process it anyway though + + #copy to local archive dir + if ( $opt{a} ) { + print STDERR "Copying $tmpdir/$filename to archive dir $opt{a}\n" + if $opt{v}; + copy("$tmpdir/$filename", $opt{a}); + warn "failed to copy $tmpdir/$filename to $opt{a}: $!" if $!; + } + + open my $fh, "<$tmpdir/$filename"; + my $header = <$fh>; + if ($header !~ /^cust_id/) { + warn "warning: $filename has incorrect header row:\n$header\n"; + # but try anyway + } + my $csv = Text::CSV->new; # orthodox CSV + my %hash; + while (my $line = <$fh>) { + $csv->parse($line) or do { + warn "can't parse $filename: ".$csv->error_input."\n"; + next FILE; + }; + @hash{@fields} = $csv->fields(); + my $cust_main = FS::cust_main->by_key($hash{custnum}); + if (!$cust_main) { + warn "customer #$hash{custnum} not found\n"; + next; + } + print STDERR "Found customer #$hash{custnum}: ".$cust_main->name."\n" + if $opt{v}; + + # construct arguments for $cust_main->charge + my %opt = ( + amount => $hash{amount}, + quantity => $hash{quantity}, + start_date => $cust_main->next_bill_date, + pkg => $hash{date_desc}, + ); + if (my $classname = $hash{classname}) { + if (!exists($classnum_of{$classname}) ) { + # then look it up + my $pkg_class = qsearch('pkg_class', { classname => $classname }); + $classnum_of{$classname} = $pkg_class ? $pkg_class->classnum : ''; + } + $opt{classnum} = $classnum_of{$classname}; + } + # XXX what's the tax status of these charges? + print STDERR " Charging $hash{amount}\n" + if $opt{v}; + my $error = $cust_main->charge(\%opt); + if ($error) { + warn "Error creating charge: $error" if $error; + $num_errors++; + } else { + $num_charges++; + $sum_charges += $hash{amount}; + } + } #while $line + close $fh; +} #FILE + +if ($opt{v}) { + print STDERR " +Finished! + Processed files: @$files + Created charges: $num_charges + Sum of charges: \$".sprintf('%0.2f', $sum_charges)." + Errors: $num_errors +"; +} + +=head1 NAME + +freeside-eftca-download - Retrieve payment batch responses from EFT Canada. + +=head1 SYNOPSIS + + freeside-eftca-download [ -v ] [ -a archivedir ] user + +=head1 DESCRIPTION + +Command line tool to download returned payment reports from the EFT Canada +gateway and void the returned payments. Uses the login and password from +'batchconfig-eft_canada'. + +-v: Be verbose. + +-a directory: Archive response files in the provided directory. + +user: freeside username + +=head1 BUGS + +You need to manually SFTP to ftp.eftcanada.com from the freeside account +and accept their key before running this script. + +=head1 SEE ALSO + +L + +=cut + +1; + -- cgit v1.2.1 From 642bb1970300250739af3ce7a8706a9771781e05 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 27 Nov 2012 13:03:36 -0800 Subject: ICS invoice batch: send batch and summary report in the same message, #17620 --- FS/FS/Cron/upload.pm | 55 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/FS/FS/Cron/upload.pm b/FS/FS/Cron/upload.pm index 08819fce9..65773200e 100644 --- a/FS/FS/Cron/upload.pm +++ b/FS/FS/Cron/upload.pm @@ -326,14 +326,16 @@ sub spool_upload { } } - send_report('bridgestone-confirm_template', - { - agentnum=> $agentnum, - zipfile => $zipfile, - prefix => $prefix, - seq => $seq, - rows => $rows, - } + send_email( + prepare_report('bridgestone-confirm_template', + { + agentnum=> $agentnum, + zipfile => $zipfile, + prefix => $prefix, + seq => $seq, + rows => $rows, + } + ) ); $seq++; @@ -376,16 +378,26 @@ sub spool_upload { close $reg; close $big; + # zip up all three files for transport my $zipfile = "$basename" . '.zip'; my $command = "cd $dir; zip $zipfile $regfile $bigfile"; system($command) and die "'$command' failed\n"; - my $error = $upload_target->put("$dir/$zipfile"); + # upload them, unless we're using email, in which case + # the zip file will ride along with the report. yes, this + # kind of defeats the purpose of the upload_target interface, + # but at least we have a place to store the configuration. + my $error = ''; + if ( $upload_target->protocol ne 'email' ) { + $error = $upload_target->put("$dir/$zipfile"); + } + + # create the report for (values %sum) { $_ = sprintf('%.2f', $_); } - send_report('ics-confirm_template', + my %report = prepare_report('ics-confirm_template', { agentnum => $agentnum, count => \%count, @@ -393,8 +405,23 @@ sub spool_upload { error => $error, } ); + if ( $upload_target->protocol eq 'email' ) { + $report{'to'} = + join('@', $upload_target->username, $upload_target->hostname); + $report{'subject'} = $upload_target->subject; + $report{'mimeparts'} = [ + { Path => "$dir/$zipfile", + Type => 'application/zip', + Encoding => 'base64', + Filename => $zipfile, + Disposition => 'attachment', + } + ]; + } + $error = send_email(%report); if ( $error ) { + # put the original spool file back rename "$dir/$file-$date.csv", "$dir/$file.csv"; die $error; } @@ -421,7 +448,8 @@ sub spool_upload { =item send_report CONFIG PARAMS Retrieves the config value named CONFIG, parses it as a Text::Template, -extracts "to" and "subject" headers, and sends it by email. +extracts "to" and "subject" headers, and returns a hash that can be passed +to L. PARAMS is a hashref to be passed to C. It must contain 'agentnum' to look up the per-agent config. @@ -429,7 +457,8 @@ PARAMS is a hashref to be passed to C. It must contain =cut # we used it twice, so it's now a subroutine -sub send_report { + +sub prepare_report { my ($config, $params) = @_; my $agentnum = $params->{agentnum}; @@ -452,7 +481,7 @@ sub send_report { $head =~ /^to:\s*(.*)$/im; my $to = $1; - send_email( + ( to => $to, from => $conf->config('invoice_from', $agentnum), subject => $subject, -- cgit v1.2.1 From ff55a7842fefe34d524744c3c0d511af80429ef0 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 27 Nov 2012 16:48:31 -0800 Subject: fixes for spool_upload in multiprocess mode, #6802, #18333 --- FS/FS/Cron/upload.pm | 29 ++++++++++++++++------------- FS/bin/freeside-queued | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/FS/FS/Cron/upload.pm b/FS/FS/Cron/upload.pm index 65773200e..ed08a575f 100644 --- a/FS/FS/Cron/upload.pm +++ b/FS/FS/Cron/upload.pm @@ -143,6 +143,22 @@ sub spool_upload { my $dbh = dbh; my $agentnum = $opt{agentnum}; + + # wait for any ongoing billing jobs to complete + # (should this exclude status='failed')? + if ($opt{m}) { + my $sql = "SELECT count(*) FROM queue LEFT JOIN cust_main USING(custnum) ". + "WHERE queue.job='FS::cust_main::queued_bill'"; + $sql .= " AND cust_main.agentnum = $agentnum" if $agentnum =~ /^\d+$/; + my $sth = $dbh->prepare($sql) or die $dbh->errstr; + while (1) { + $sth->execute() + or die "Unexpected error executing statement $sql: ". $sth->errstr; + last if $sth->fetchrow_arrayref->[0] == 0; + sleep 300; + } + } + my $agent; if ( $agentnum ) { $agent = qsearchs( 'agent', { agentnum => $agentnum } ) @@ -170,19 +186,6 @@ sub spool_upload { my $username = $opt{username} or die "no username for agent $agentnum\n"; my $password = $opt{password} or die "no password for agent $agentnum\n"; - # a better way? - if ($opt{m}) { - my $sql = "SELECT count(*) FROM queue LEFT JOIN cust_main USING(custnum) ". - "WHERE queue.job='FS::cust_main::queued_bill' AND cust_main.agentnum = ?"; - my $sth = $dbh->prepare($sql) or die $dbh->errstr; - while (1) { - $sth->execute( $agentnum ) - or die "Unexpected error executing statement $sql: ". $sth->errstr; - last if $sth->fetchrow_arrayref->[0]; - sleep 300; - } - } - foreach ( qw ( header detail ) ) { rename "$dir/$file-$_.csv", "$dir/$file-$date-$_.csv"; diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued index 756b699d4..f136c3910 100644 --- a/FS/bin/freeside-queued +++ b/FS/bin/freeside-queued @@ -186,7 +186,7 @@ while (1) { dbh->{'private_profile'} = {} if UNIVERSAL::can(dbh, 'sprintProfile'); #auto-use classes... - if ( $ljob->job =~ /(FS::(part_export|cust_main|cust_pkg)::\w+)::/ + if ( $ljob->job =~ /(FS::(part_export|cust_main|cust_pkg|Cron)::\w+)::/ || $ljob->job =~ /(FS::\w+)::/ ) { -- cgit v1.2.1 From cb66e7cac35892a482cf07c7e05db5ff6296c395 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 27 Nov 2012 20:22:03 -0800 Subject: adjustments to ipifony download script, #18333 --- FS/bin/freeside-ipifony-download | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/FS/bin/freeside-ipifony-download b/FS/bin/freeside-ipifony-download index 0384926ad..ac9f76400 100644 --- a/FS/bin/freeside-ipifony-download +++ b/FS/bin/freeside-ipifony-download @@ -12,7 +12,7 @@ use FS::Conf; use Text::CSV; my %opt; -getopts('va:', \%opt); +getopts('va:P:', \%opt); #$Net::SFTP::Foreign::debug = -1; sub HELP_MESSAGE { ' @@ -20,6 +20,7 @@ sub HELP_MESSAGE { ' freeside-ipifony-download [ -v ] [ -a archivedir ] + [ -P port ] freesideuser sftpuser@hostname[:path] ' } @@ -59,12 +60,18 @@ $sftpuser = $1 || $ENV{USER}; $host =~ s/:(.*)//; $path = $1; +my $port = 22; +if ( $opt{P} =~ /^(\d+)$/ ) { + $port = $1; +} + # for now assume SFTP download as the only method print STDERR "Connecting to $sftpuser\@$host...\n" if $opt{v}; my $sftp = Net::SFTP::Foreign->new( host => $host, user => $sftpuser, + port => $port, # for now we don't support passwords. use authorized_keys. timeout => 30, more => ($opt{v} ? '-v' : ''), @@ -87,11 +94,20 @@ FILE: foreach my $filename (@$files) { next FILE; } + # make sure server archive dir exists + if ( !$sftp->stat('Archive') ) { + print STDERR "Creating $path/Archive\n" if $opt{v}; + $sftp->mkdir('Archive'); + if($sftp->error) { + # something is seriously wrong + die "failed to create archive directory on server:\n".$sftp->error."\n"; + } + } #move to server archive dir $sftp->rename("$filename", "Archive/$filename"); if($sftp->error) { - warn "failed to archive $filename on server\n"; - } # process it anyway though + warn "failed to archive $filename on server:\n".$sftp->error."\n"; + } # process it anyway, I guess/ #copy to local archive dir if ( $opt{a} ) { -- cgit v1.2.1 From 226fffec6fd0154ea8798b58321d4d119341879f Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 27 Nov 2012 21:43:37 -0800 Subject: remove trailing junk from XLSX files, #20337 --- httemplate/graph/elements/report.html | 4 ++-- httemplate/search/customer_accounting_summary.html | 6 ++++-- httemplate/search/elements/search-xls.html | 2 +- httemplate/search/elements/search.html | 4 +++- httemplate/search/report_tax-xls.cgi | 3 ++- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/httemplate/graph/elements/report.html b/httemplate/graph/elements/report.html index 98b477826..b7073db31 100644 --- a/httemplate/graph/elements/report.html +++ b/httemplate/graph/elements/report.html @@ -126,8 +126,8 @@ any delimiter and linked from the elements in @data. % $workbook->close();# or die "Error creating .xls file: $!"; % % http_header('Content-Length' => length($output) ); -% -<% $output %> +% $m->print($output); +% % } elsif ( $cgi->param('_type') eq 'png' ) { % # delete any items that shouldn't be on the graph % if ( my $no_graph = $opt{'no_graph'} ) { diff --git a/httemplate/search/customer_accounting_summary.html b/httemplate/search/customer_accounting_summary.html index 5ce2e3a8f..557528325 100644 --- a/httemplate/search/customer_accounting_summary.html +++ b/httemplate/search/customer_accounting_summary.html @@ -73,9 +73,11 @@ $r++; } #$row $workbook->close; + + http_header('Content-Length' => length($output)); + $m->print($output); -<% $output %> -% } else { +% } else { <& /elements/header.html, $title &> % my $myself = $cgi->self_url;

diff --git a/httemplate/search/elements/search-xls.html b/httemplate/search/elements/search-xls.html index 94d88b096..26a51c4c7 100644 --- a/httemplate/search/elements/search-xls.html +++ b/httemplate/search/elements/search-xls.html @@ -1,4 +1,3 @@ -<% $data %> <%init> my %args = @_; @@ -148,5 +147,6 @@ if ( $opt{'footer'} ) { $workbook->close();# or die "Error creating .xls file: $!"; http_header('Content-Length' => length($data) ); +$m->print($data); diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html index eca68a2f8..5a16a22fe 100644 --- a/httemplate/search/elements/search.html +++ b/httemplate/search/elements/search.html @@ -176,7 +176,9 @@ Example: % % } elsif ( $type =~ /\.xls$/ ) { % -<% include('search-xls.html', header=>$header, rows=>$rows, opt=>\%opt ) %> +<& 'search-xls.html', header=>$header, rows=>$rows, opt=>\%opt &>\ +% # prevent the caller from polluting our output stream +% $m->abort; % % } elsif ( $type eq 'xml' ) { % diff --git a/httemplate/search/report_tax-xls.cgi b/httemplate/search/report_tax-xls.cgi index f19f85aaa..bb843a73f 100755 --- a/httemplate/search/report_tax-xls.cgi +++ b/httemplate/search/report_tax-xls.cgi @@ -1,4 +1,3 @@ -<% $data %> <%init> my $htmldoc = include('report_tax.cgi'); @@ -155,4 +154,6 @@ for my $x (0..scalar(@widths)-1) { $workbook->close; +http_header('Content-Length' => length($data)); +$m->print($data); -- cgit v1.2.1 From a2a69f909cad813d7164bae805e87f5874a9fdae Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Thu, 29 Nov 2012 22:03:29 -0800 Subject: broadband_snmp export: better MIB selection --- FS/FS/Mason.pm | 1 + FS/FS/part_export.pm | 13 + FS/FS/part_export/broadband_snmp.pm | 150 ++++++---- httemplate/browse/part_export.cgi | 48 +++- httemplate/edit/cdr_type.cgi | 22 +- .../edit/elements/part_export/broadband_snmp.html | 100 +++++++ httemplate/edit/elements/part_export/foot.html | 6 + httemplate/edit/elements/part_export/head.html | 19 ++ httemplate/edit/part_export.cgi | 9 + httemplate/edit/process/cdr_type.cgi | 1 - httemplate/edit/process/part_export.cgi | 29 +- httemplate/edit/rate_time.cgi | 41 ++- httemplate/elements/auto-table.html | 311 +++++++++++---------- httemplate/elements/select-mib-popup.html | 170 +++++++++++ httemplate/elements/xmlhttp.html | 32 ++- httemplate/misc/xmlhttp-mib-browse.html | 161 +++++++++++ 16 files changed, 877 insertions(+), 236 deletions(-) create mode 100644 httemplate/edit/elements/part_export/broadband_snmp.html create mode 100644 httemplate/edit/elements/part_export/foot.html create mode 100644 httemplate/edit/elements/part_export/head.html create mode 100644 httemplate/elements/select-mib-popup.html create mode 100644 httemplate/misc/xmlhttp-mib-browse.html diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 944a4836c..004701646 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -56,6 +56,7 @@ if ( -e $addl_handler_use_file ) { #use CGI::Carp qw(fatalsToBrowser); use CGI::Cookie; use List::Util qw( max min sum ); + use Scalar::Util qw( blessed ); use Data::Dumper; use Date::Format; use Time::Local; diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index b0f708a66..ed66b41a1 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -615,6 +615,19 @@ sub weight { export_info()->{$self->exporttype}->{'weight'} || 0; } +=item info + +Returns a reference to (a copy of) the export's %info hash. + +=cut + +sub info { + my $self = shift; + $self->{_info} ||= { + %{ export_info()->{$self->exporttype} } + }; +} + =back =head1 SUBROUTINES diff --git a/FS/FS/part_export/broadband_snmp.pm b/FS/FS/part_export/broadband_snmp.pm index 44b4dbabb..9afca0872 100644 --- a/FS/FS/part_export/broadband_snmp.pm +++ b/FS/FS/part_export/broadband_snmp.pm @@ -3,7 +3,7 @@ package FS::part_export::broadband_snmp; use strict; use vars qw(%info $DEBUG); use base 'FS::part_export'; -use Net::SNMP qw(:asn1 :snmp); +use SNMP; use Tie::IxHash; $DEBUG = 0; @@ -11,21 +11,21 @@ $DEBUG = 0; my $me = '['.__PACKAGE__.']'; tie my %snmp_version, 'Tie::IxHash', - v1 => 'snmpv1', - v2c => 'snmpv2c', - # 3 => 'v3' not implemented + v1 => '1', + v2c => '2c', + # v3 unimplemented ; -tie my %snmp_type, 'Tie::IxHash', - i => INTEGER, - u => UNSIGNED32, - s => OCTET_STRING, - n => NULL, - o => OBJECT_IDENTIFIER, - t => TIMETICKS, - a => IPADDRESS, - # others not implemented yet -; +#tie my %snmp_type, 'Tie::IxHash', +# i => INTEGER, +# u => UNSIGNED32, +# s => OCTET_STRING, +# n => NULL, +# o => OBJECT_IDENTIFIER, +# t => TIMETICKS, +# a => IPADDRESS, +# # others not implemented yet +#; tie my %options, 'Tie::IxHash', 'version' => { label=>'SNMP version', @@ -33,14 +33,11 @@ tie my %options, 'Tie::IxHash', options => [ keys %snmp_version ], }, 'community' => { label=>'Community', default=>'public' }, - ( - map { $_.'_command', - { label => ucfirst($_) . ' commands', - type => 'textarea', - default => '', - } - } qw( insert delete replace suspend unsuspend ) - ), + + 'action' => { multiple=>1 }, + 'oid' => { multiple=>1 }, + 'value' => { multiple=>1 }, + 'ip_addr_change_to_new' => { label=>'Send IP address changes to new address', type=>'checkbox' @@ -51,28 +48,14 @@ tie my %options, 'Tie::IxHash', %info = ( 'svc' => 'svc_broadband', 'desc' => 'Send SNMP requests to the service IP address', + 'config_element' => '/edit/elements/part_export/broadband_snmp.html', 'options' => \%options, 'no_machine' => 1, 'weight' => 10, 'notes' => <<'END' Send one or more SNMP SET requests to the IP address registered to the service. -Enter one command per line. Each command is a target OID, data type flag, -and value, separated by spaces. -The data type flag is one of the following: -

    -
  • i = INTEGER
  • -
  • u = UNSIGNED32
  • -
  • s = OCTET-STRING (as ASCII)
  • -
  • a = IPADDRESS
  • -
  • n = NULL
The value may interpolate fields from svc_broadband by prefixing the field name with $, or $new_ and $old_ for replace operations. -The value may contain whitespace; quotes are not necessary.
-
-For example, to set the SNMPv2-MIB "sysName.0" object to the string -"svc_broadband" followed by the service number, use the following -command:
-
1.3.6.1.2.1.1.5.0 s svc_broadband$svcnum

END ); @@ -105,19 +88,18 @@ sub export_command { my $self = shift; my ($action, $svc_new, $svc_old) = @_; - my $command_text = $self->option($action.'_command'); - return if !length($command_text); - - warn "$me parsing ${action}_command:\n" if $DEBUG; + my @a = split("\n", $self->option('action')); + my @o = split("\n", $self->option('oid')); + my @v = split("\n", $self->option('value')); my @commands; - foreach (split /\n/, $command_text) { - my ($oid, $type, $value) = split /\s/, $_, 3; - $oid =~ /^(\d+\.)*\d+$/ or die "invalid OID '$oid'\n"; - my $typenum = $snmp_type{$type} or die "unknown data type '$type'\n"; - $value = '' if !defined($value); # allow sending an empty string + warn "$me parsing $action commands:\n" if $DEBUG; + while (@a) { + my $oid = shift @o; + my $value = shift @v; + next unless shift(@a) eq $action; # ignore commands for other actions $value = $self->substitute($value, $svc_new, $svc_old); - warn "$me $oid $type $value\n" if $DEBUG; - push @commands, $oid, $typenum, $value; + warn "$me $oid :=$value\n" if $DEBUG; + push @commands, $oid, $value; } my $ip_addr = $svc_new->ip_addr; @@ -128,13 +110,13 @@ sub export_command { warn "$me opening session to $ip_addr\n" if $DEBUG; my %opt = ( - -hostname => $ip_addr, - -community => $self->option('community'), - -timeout => $self->option('timeout') || 20, + DestHost => $ip_addr, + Community => $self->option('community'), + Timeout => ($self->option('timeout') || 20) * 1000, ); my $version = $self->option('version'); - $opt{-version} = $snmp_version{$version} or die 'invalid version'; - $opt{-varbindlist} = \@commands; # just for now + $opt{Version} = $snmp_version{$version} or die 'invalid version'; + $opt{VarList} = \@commands; # for now $self->snmp_queue( $svc_new->svcnum, %opt ); } @@ -151,16 +133,22 @@ sub snmp_queue { sub snmp_request { my %opt = @_; - my $varbindlist = delete $opt{-varbindlist}; - my ($session, $error) = Net::SNMP->session(%opt); - die "Couldn't create SNMP session: $error" if !$session; + my $flatvarlist = delete $opt{VarList}; + my $session = SNMP::Session->new(%opt); warn "$me sending SET request\n" if $DEBUG; - my $result = $session->set_request( -varbindlist => $varbindlist ); - $error = $session->error(); - $session->close(); - if (!defined $result) { + my @varlist; + while (@$flatvarlist) { + my @this = splice(@$flatvarlist, 0, 2); + push @varlist, [ $this[0], 0, $this[1], undef ]; + # XXX new option to choose the IID (array index) of the object? + } + + $session->set(\@varlist); + my $error = $session->{ErrorStr}; + + if ( $session->{ErrorNum} ) { die "SNMP request failed: $error\n"; } } @@ -181,4 +169,46 @@ sub substitute { $value; } +sub _upgrade_exporttype { + eval 'use FS::Record qw(qsearch qsearchs)'; + # change from old style with numeric oid, data type flag, and value + # on consecutive lines + foreach my $export (qsearch('part_export', + { exporttype => 'broadband_snmp' } )) + { + # for the new options + my %new_options = ( + 'action' => [], + 'oid' => [], + 'value' => [], + ); + foreach my $action (qw(insert replace delete suspend unsuspend)) { + my $old_option = qsearchs('part_export_option', + { exportnum => $export->exportnum, + optionname => $action.'_command' } ); + next if !$old_option; + my $text = $old_option->optionvalue; + my @commands = split("\n", $text); + foreach (@commands) { + my ($oid, $type, $value) = split /\s/, $_, 3; + push @{$new_options{action}}, $action; + push @{$new_options{oid}}, $oid; + push @{$new_options{value}}, $value; + } + my $error = $old_option->delete; + warn "error migrating ${action}_command option: $error\n" if $error; + } + foreach (keys(%new_options)) { + my $new_option = FS::part_export_option->new({ + exportnum => $export->exportnum, + optionname => $_, + optionvalue => join("\n", @{ $new_options{$_} }) + }); + my $error = $new_option->insert; + warn "error inserting '$_' option: $error\n" if $error; + } + } #foreach $export + ''; +} + 1; diff --git a/httemplate/browse/part_export.cgi b/httemplate/browse/part_export.cgi index b7ecc00a6..91238a0fd 100755 --- a/httemplate/browse/part_export.cgi +++ b/httemplate/browse/part_export.cgi @@ -43,14 +43,56 @@ function part_export_areyousure(href) {
<% itable() %> % my %opt = $part_export->options; -% foreach my $opt ( keys %opt ) { +% my $defs = $part_export->info->{options}; +% my %multiples; +% foreach my $opt (keys %$defs) { # is a Tie::IxHash +% my $group = $defs->{$opt}->{multiple}; +% if ( $group ) { +% my @values = split("\n", $opt{$opt}); +% $multiples{$group} ||= []; +% push @{ $multiples{$group} }, [ $opt, @values ] if @values; +% delete $opt{$opt}; +% } elsif (length($opt{$opt})) { # the normal case +%# foreach my $opt ( keys %opt ) {
<% $opt %>:  <% encode_entities($opt{$opt}) %>
<% $opt %>: <% encode_entities($opt{$opt}) %>
+ +% foreach my $col (@$set) { + +% } + +% while ( 1 ) { + +% my $end = 1; +% foreach my $col (@$set) { + +% $end = 0 if @$col; +% } + +% last if $end; +% } +
<% shift @$col %>
<% shift @$col %>
diff --git a/httemplate/edit/cdr_type.cgi b/httemplate/edit/cdr_type.cgi index 5d2c66216..c69610607 100644 --- a/httemplate/edit/cdr_type.cgi +++ b/httemplate/edit/cdr_type.cgi @@ -7,11 +7,24 @@ calls and SMS messages. Each CDR type must have a set of rates configured in the rate tables.
"> -<% include('/elements/auto-table.html', - 'header' => [ 'Type#', 'Name' ], - 'fields' => [ qw( cdrtypenum cdrtypename ) ], + + + + + + + + + +<& /elements/auto-table.html, + 'template_row' => 'cdr_template', 'data' => \@data, - ) %> +&> +
Type#Name
+ + + +

<% include('/elements/footer.html') %> <%init> @@ -20,7 +33,6 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); my @data = ( - map { [ $_->cdrtypenum, $_->cdrtypename ] } qsearch({ 'table' => 'cdr_type', 'hashref' => {}, diff --git a/httemplate/edit/elements/part_export/broadband_snmp.html b/httemplate/edit/elements/part_export/broadband_snmp.html new file mode 100644 index 000000000..8df0b8e02 --- /dev/null +++ b/httemplate/edit/elements/part_export/broadband_snmp.html @@ -0,0 +1,100 @@ +<%doc> + +<& head.html, %opt &> + +<& /elements/tr-select.html, + label => 'SNMP version', + field => 'version', + options => [ '', 'v1', 'v2c' ], + labels => { v1 => '1', v2c => '2c' }, + curr_value => $part_export->option('version') &> +<& /elements/tr-input-text.html, + label => 'Community', + field => 'community', + curr_value => $part_export->option('community'), +&> +<& /elements/tr-checkbox.html, + label => 'Send IP address changes to new address', + field => 'ip_addr_change_to_new', + value => 1, + curr_value => $part_export->option('ip_addr_change_to_new'), +&> +<& /elements/tr-input-text.html, + label => 'Timeout (seconds)', + field => 'timeout', + curr_value => $part_export->option('timeout'), +&> + + + + + + + + + + + + + + + + +<& /elements/auto-table.html, + template_row => 'mytemplate', + fieldorder => ['action', 'oid', 'value'], + data => \@data, +&> + +<& foot.html, %opt &> +<%init> +my %opt = @_; +my $part_export = $opt{part_export} || FS::part_export->new; + +my @actions = split("\n", $part_export->option('action')); +my @oids = split("\n", $part_export->option('oid')); +my @values = split("\n", $part_export->option('value')); + +my @data; +while (@actions or @oids or @values) { + my @thisrow = (shift(@actions), shift(@oids), shift(@values)); + push @data, \@thisrow if grep length($_), @thisrow; +} + +my $popup_name = 'popup-'.time."-$$-".rand() * 2**32; + diff --git a/httemplate/edit/elements/part_export/foot.html b/httemplate/edit/elements/part_export/foot.html new file mode 100644 index 000000000..9cb8073ce --- /dev/null +++ b/httemplate/edit/elements/part_export/foot.html @@ -0,0 +1,6 @@ +
ActionObjectTypeValue
+ + + + + + + +
+ + +<%init> +my %opt = @_; + diff --git a/httemplate/edit/elements/part_export/head.html b/httemplate/edit/elements/part_export/head.html new file mode 100644 index 000000000..cb0ab894a --- /dev/null +++ b/httemplate/edit/elements/part_export/head.html @@ -0,0 +1,19 @@ +% if ( $export_info->{no_machine} ) { + + +% } else { +% # clone this from edit/part_export.cgi if this case ever gets used +% } + +<% ntable('cccccc', 2) %> + + <% emt('Description') %> + <% $notes %> + +<%init> +my %opt = @_; +my $layer = $opt{layer}; +my $part_export = $opt{part_export}; +my $export_info = $opt{export_info}; +my $notes = $opt{notes} || $export_info->{notes}; + diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi index 0407ee77b..4dd253be8 100644 --- a/httemplate/edit/part_export.cgi +++ b/httemplate/edit/part_export.cgi @@ -62,6 +62,15 @@ my $widget = new HTML::Widgets::SelectLayers( 'html_between' => "\n", 'layer_callback' => sub { my $layer = shift; + # create 'config_element' to generate the whole layer with a Mason component + if ( my $include = $exports->{$layer}{config_element} ) { + # might need to adjust the scope of this at some point + return $m->scomp($include, + part_export => $part_export, + layer => $layer, + export_info => $exports->{$layer} + ); + } my $html = qq!!. ntable("#cccccc",2); diff --git a/httemplate/edit/process/cdr_type.cgi b/httemplate/edit/process/cdr_type.cgi index b661de75d..ba9881dc4 100644 --- a/httemplate/edit/process/cdr_type.cgi +++ b/httemplate/edit/process/cdr_type.cgi @@ -10,7 +10,6 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); my %vars = $cgi->Vars; -warn Dumper(\%vars)."\n"; my %old = map { $_->cdrtypenum => $_ } qsearch('cdr_type', {}); diff --git a/httemplate/edit/process/part_export.cgi b/httemplate/edit/process/part_export.cgi index 6432d6b15..bcb9c0df1 100644 --- a/httemplate/edit/process/part_export.cgi +++ b/httemplate/edit/process/part_export.cgi @@ -13,15 +13,40 @@ my $exportnum = $cgi->param('exportnum'); my $old = qsearchs('part_export', { 'exportnum'=>$exportnum } ) if $exportnum; +my %vars = $cgi->Vars; #fixup options #warn join('-', split(',',$cgi->param('options'))); my %options = map { - my @values = $cgi->param($_); - my $value = scalar(@values) > 1 ? join (' ', @values) : $values[0]; + my $value = $vars{$_}; + $value =~ s/\0/ /g; # deal with multivalued options $value =~ s/\r\n/\n/g; #browsers? (textarea) $_ => $value; } split(',', $cgi->param('options')); +# deal with multiline options +# %vars should never contain incomplete rows, but just in case it does, +# we make a list of all the row indices that contain values, and +# then write a line in each option for each row, even if it's empty. +# This ensures that all values with the same row index line up. +my %optionrows; +foreach my $option (split(',', $cgi->param('multi_options'))) { + $optionrows{$option} = {}; + my %values; # bear with me + for (keys %vars) { + /^$option(\d+)/ or next; + $optionrows{$option}{$1} = $vars{$option.$1}; + $optionrows{_ALL_}{$1} = 1 if length($vars{$option.$1}); + } +} +foreach my $option (split(',', $cgi->param('multi_options'))) { + my $value = ''; + foreach my $row (sort keys %{$optionrows{_ALL_}}) { + $value .= ($optionrows{$option}{$row} || '') . "\n"; + } + chomp($value); + $options{$option} = $value; +} + my $new = new FS::part_export ( { map { $_, scalar($cgi->param($_)); diff --git a/httemplate/edit/rate_time.cgi b/httemplate/edit/rate_time.cgi index 7ee39efca..9e6b8736c 100644 --- a/httemplate/edit/rate_time.cgi +++ b/httemplate/edit/rate_time.cgi @@ -15,12 +15,34 @@ -<% include('/elements/auto-table.html', - 'header' => [ '', 'Start','','', '','End','','' ], - 'fields' => [ qw(sd sh sm sa ed eh em ea) ], - 'select' => [ ($day, $hour, $min, $ampm) x 2 ], - 'data' => \@data, - ) %> + + + + + + +% for my $pre (qw(s e)) { +% for my $f (qw(d h m a)) { # day, hour, minute, am/pm + +% } #$f +% } #$pre + +<& /elements/auto-table.html, + 'template_row' => 'mytemplate', + 'data' => \@data, + 'fieldorder' => [qw(sd sh sm sa ed eh em ea)], +&> +
StartEnd
+ +

@@ -42,7 +64,12 @@ my $day = [ 0 => 'Sun', my $hour = [ map( {$_, sprintf('%02d',$_) } 12, 1..11 )]; my $min = [ map( {$_, sprintf('%02d',$_) } 0,30 )]; my $ampm = [ 0 => 'AM', 1 => 'PM' ]; - +my %choices = ( + 'd' => $day, + 'h' => $hour, + 'm' => $min, + 'a' => $ampm, +); if($ratetimenum) { $action = 'Edit'; $rate_time = qsearchs('rate_time', {ratetimenum => $ratetimenum}) diff --git a/httemplate/elements/auto-table.html b/httemplate/elements/auto-table.html index 49222745a..ed011097e 100644 --- a/httemplate/elements/auto-table.html +++ b/httemplate/elements/auto-table.html @@ -1,166 +1,181 @@ <%doc> - -Example: -<% include('/elements/auto-table.html', - - ### - # required - ### - - 'header' => [ '#', 'Item', 'Amount' ], - 'fields' => [ 'id', 'name', 'amount' ], - - ### - # highly recommended - ### - - 'size' => [ 4, 12, 8 ], - 'maxl' => [ 4, 12, 8 ], - 'align' => [ 'right', 'left', 'right' ], - - ### - # optional - ### - - 'data' => [ [ 1, 'Widget', 25 ], - [ 12, 'Super Widget, 7 ] ], - #or - 'records' => [ qsearch('item', { } ) ], - # or any other array of FS::Record objects - - 'select' => [ '', - [ 1 => 'option 1', - 2 => 'option 2', ... - ], # options for second field - '' ], - - 'prefix' => 'mytable_', -) %> - -Values will be passed through as "mytable_id1", etc. +(within a form) + + + + + + + + + ... + +
Field 1Field 2
+<& /elements/auto-table.html, + table => 'mytable', + template_row = 'mytemplate', + rows => [ + { field1 => 'foo', field2 => 'CA', ... }, + { field1 => 'bar', field2 => 'TX', ... }, ... + ], +&> + + or if you prefer: +... + fieldorder => [ 'field1', 'field2', ... ], + rows => [ + [ 'foo', 'CA' ], + [ 'bar', 'TX' ], + ], + +In the process/ handler, something like: +my @rows; +my %vars = $cgi->Vars; +for my $k ( keys %vars ) { + $k =~ /^${pre}magic(\d+)$/ or next; + my $rownum = $1; + # find all submitted names ending in this rownum + my %thisrow = + map { $_ => $vars{$_} } + grep /^(.*[\d])$rownum$/, keys %vars; + $thisrow->{num} = delete $thisrow{"${pre}magic$rownum"}; + push @rows, $thisrow; +} - - - -% foreach (@header) { - -% } - -% my $row = 0; -% for ( $row = 0; $row < scalar @data; $row++ ) { - -% my $col = 0; -% for ( $col = 0; $col < scalar @fields; $col++ ) { -% my $id = $prefix . $fields[$col]; -% # don't suffix rownum in the final, blank row -% $id .= $row if $row < (scalar @data) - 1; - -% } -% } - - -% } -
<% $_ %>
-% my @o = @{ $select[$col] }; -% if( @o ) { - -% } -% else { - - MAXLENGTH = <% $maxl[$col] %> - STYLE = "text-align:<% $align[$col] %>" - VALUE = "<% $data[$row][$col] %>" -% if( $opt{'autoadd'} ) { - onchange = "possiblyAddRow(this);" -% } - > - - " - ALT = "X" - onclick = "deleteRow(this);" - > -
-% if( !$opt{'autoadd'} ) { -
-% } - - + <%$pre%>addRow(); +} +<%$pre%>init(); + <%init> my %opt = @_; - -my @header = @{ $opt{'header'} }; -my @fields = @{ $opt{'fields'} }; -my @data = (); -if($opt{'data'}) { - @data = @{ $opt{'data'} }; -} -elsif($opt{'records'}) { - foreach my $rec (@{ $opt{'records'} }) { - push @data, [ map { $rec->getfield($_) } @fields ]; +my $pre = ''; +$pre = $opt{'table'} . '_' if $opt{'table'}; +my $template_row = $opt{'template_row'} + or die "auto-table requires template_row\n"; # a DOM id + +my %vars = $cgi->Vars; +# rows that we will preload, as hashrefs of name => value +my @rows = @{ $opt{'data'} || [] }; +foreach (@rows) { + # allow an array of FS::Record objects to be passed + if ( blessed($_) and $_->isa('FS::Record') ) { + $_ = $_->hashref; } } -# else @data = (); -push @data, [ map {''} @fields ]; # make a blank row - -my $prefix = $opt{'prefix'}; -my @size = $opt{'size'} ? @{ $opt{'size'} } : (map {16} @fields); -my @maxl = $opt{'maxl'} ? @{ $opt{'maxl'} } : @size; -my @align = $opt{'align'} ? @{ $opt{'align'} } : (map {'right'} @fields); -my @select = @{ $opt{'select'} || [] }; -foreach (0..scalar(@fields)-1) { - $select[$_] ||= []; -} +my $fieldorder = $opt{'fieldorder'} || []; diff --git a/httemplate/elements/select-mib-popup.html b/httemplate/elements/select-mib-popup.html new file mode 100644 index 000000000..f8e3ae3da --- /dev/null +++ b/httemplate/elements/select-mib-popup.html @@ -0,0 +1,170 @@ +<& /elements/header-popup.html &> + + + + + + + + + + + + + + + + + + + + + + + + +
Module:
Object:
+ +
Module:
Data type:
+ +
+<& /elements/xmlhttp.html, + url => $p.'misc/xmlhttp-mib-browse.html', + subs => [qw( search get_module_list )], +&> + +<& /elements/footer.html &> +<%init> +my $callback = 'alert("(no callback defined)" + selected_mib.stringify)'; +$cgi->param('callback') =~ /^(\w+)$/; +if ( $1 ) { + # construct the JS function call expresssion + $callback = 'window.parent.' . $1 . '(selected_mib'; + foreach ($cgi->param('arg')) { + # pass-through arguments + /^(\w+)$/ or next; + $callback .= ",'$1'"; + } + $callback .= ')'; +} + + diff --git a/httemplate/elements/xmlhttp.html b/httemplate/elements/xmlhttp.html index ac6f9916e..a9e65c790 100644 --- a/httemplate/elements/xmlhttp.html +++ b/httemplate/elements/xmlhttp.html @@ -14,14 +14,15 @@ Example: ); -<% include( '/elements/rs_init_object.html' ) %> +<& /elements/rs_init_object.html &> +<& /elements/init_overlib.html &> @@ -69,7 +69,7 @@ function receive_mib(obj, rownum) { - + @@ -77,10 +77,10 @@ function receive_mib(obj, rownum) { <& /elements/auto-table.html, template_row => 'mytemplate', - fieldorder => ['action', 'oid', 'value'], + fieldorder => ['action', 'oid', 'datatype', 'value'], data => \@data, &> - + <& foot.html, %opt &> <%init> my %opt = @_; @@ -88,11 +88,12 @@ my $part_export = $opt{part_export} || FS::part_export->new; my @actions = split("\n", $part_export->option('action')); my @oids = split("\n", $part_export->option('oid')); +my @types = split("\n", $part_export->option('datatype')); my @values = split("\n", $part_export->option('value')); my @data; while (@actions or @oids or @values) { - my @thisrow = (shift(@actions), shift(@oids), shift(@values)); + my @thisrow = (shift(@actions), shift(@oids), shift(@types), shift(@values)); push @data, \@thisrow if grep length($_), @thisrow; } diff --git a/httemplate/elements/auto-table.html b/httemplate/elements/auto-table.html index ed011097e..9aff94e67 100644 --- a/httemplate/elements/auto-table.html +++ b/httemplate/elements/auto-table.html @@ -168,7 +168,6 @@ $pre = $opt{'table'} . '_' if $opt{'table'}; my $template_row = $opt{'template_row'} or die "auto-table requires template_row\n"; # a DOM id -my %vars = $cgi->Vars; # rows that we will preload, as hashrefs of name => value my @rows = @{ $opt{'data'} || [] }; foreach (@rows) { diff --git a/httemplate/elements/select-mib-popup.html b/httemplate/elements/select-mib-popup.html index f8e3ae3da..bd485ef65 100644 --- a/httemplate/elements/select-mib-popup.html +++ b/httemplate/elements/select-mib-popup.html @@ -1,12 +1,13 @@ <& /elements/header-popup.html &> + - + - + - + @@ -40,7 +41,7 @@ function show_info(state) { document.getElementById('mib_objectID').style.display = document.getElementById('mib_moduleID').style.display = document.getElementById('mib_type').style.display = - state ? 'block' : 'none'; + state ? '' : 'none'; } function clear_list() { @@ -48,6 +49,7 @@ function clear_list() { select_path.options.length = 0; } +var measurebox = document.getElementById('measurebox'); function add_item(value) { var select_path = document.getElementById('select_path'); var input_path = document.getElementById('input_path'); @@ -57,7 +59,21 @@ function add_item(value) { opt.className = 'leaf'; v = v.substring(0, v.length - 1); } - opt.value = opt.text = v; + var optvalue = v; // may not be the name we display + // shorten these if they don't fit in the box + if ( v.length > 30 ) { // unless they're already really short + measurebox.innerHTML = v; + while ( measurebox.clientWidth > select_path.clientWidth - 10 + && v.match(/^\..*\./) ) { + v = v.replace(/^\.[^\.]+/, ''); + measurebox.innerHTML = v; + } + if ( optvalue != v ) { + v = '...' + v; + } + } + opt.value = optvalue; + opt.text = v; opt.selected = (input_path.value == v); select_path.add(opt, null); } -- cgit v1.2.1 From 1e7597b555b007372810e576ce83ad192d803888 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 30 Nov 2012 19:36:47 -0800 Subject: have freeside-monthly take and pass a -m flag so it can tell the upload to wait for billing jobs, RT#6802 --- FS/bin/freeside-monthly | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FS/bin/freeside-monthly b/FS/bin/freeside-monthly index 0d6ea14a2..69502a01d 100755 --- a/FS/bin/freeside-monthly +++ b/FS/bin/freeside-monthly @@ -7,7 +7,7 @@ use FS::UID qw(adminsuidsetup); &untaint_argv; #what it sounds like (eww) #use vars qw($opt_d $opt_v $opt_p $opt_a $opt_s $opt_y); use vars qw(%opt); -getopts("p:a:d:vsy:", \%opt); +getopts("p:a:d:vsy:m", \%opt); my $user = shift or die &usage; adminsuidsetup $user; @@ -72,6 +72,8 @@ the bill and collect methods of a cust_main object. See L. -v: enable debugging + -m: Experimental multi-process mode (delay upload jobs until billing jobs complete) + user: From the mapsecrets file - see config.html from the base documentation custnum: if one or more customer numbers are specified, only bills those -- cgit v1.2.1 From 9f88c61407594e6c60226b607cc610b7cbde8953 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 1 Dec 2012 08:08:04 -0800 Subject: eliminate Argument "" isn't numeric in numeric le (<=) warning --- FS/FS/part_event/Condition/pkg_dundate.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_event/Condition/pkg_dundate.pm b/FS/FS/part_event/Condition/pkg_dundate.pm index f25db2ae8..fefee2022 100644 --- a/FS/FS/part_event/Condition/pkg_dundate.pm +++ b/FS/FS/part_event/Condition/pkg_dundate.pm @@ -19,7 +19,7 @@ sub condition { #my $cust_main = $self->cust_main($cust_pkg); - $cust_pkg->dundate <= $opt{time}; + ( $cust_pkg->dundate || 0 ) <= $opt{time}; } -- cgit v1.2.1 From e0f4d7c4932871a17555b93ef2db49bc6c4c2d35 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 3 Dec 2012 12:12:56 -0800 Subject: don't queue spool_upload jobs until all queued_bill jobs are finished, #6802 --- FS/FS/Cron/upload.pm | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/FS/FS/Cron/upload.pm b/FS/FS/Cron/upload.pm index ed08a575f..ccf8e1a9a 100644 --- a/FS/FS/Cron/upload.pm +++ b/FS/FS/Cron/upload.pm @@ -95,6 +95,29 @@ sub upload { } } # foreach @agents + # if there's nothing to do, don't hold up the rest of the process + return '' if !@tasks; + + # wait for any ongoing billing jobs to complete + if ($opt{m}) { + my $dbh = dbh; + my $sql = "SELECT count(*) FROM queue LEFT JOIN cust_main USING(custnum) ". + "WHERE queue.job='FS::cust_main::queued_bill' AND status != 'failed'"; + if (@agents) { + $sql .= ' AND cust_main.agentnum IN('. + join(',', map {$_->agentnum} @agents). + ')'; + } + my $sth = $dbh->prepare($sql) or die $dbh->errstr; + while (1) { + $sth->execute() + or die "Unexpected error executing statement $sql: ". $sth->errstr; + last if $sth->fetchrow_arrayref->[0] == 0; + warn "Waiting 5min for billing to complete...\n" if $DEBUG; + sleep 300; + } + } + foreach (@tasks) { my $agentnum = $_->{agentnum}; @@ -144,21 +167,6 @@ sub spool_upload { my $agentnum = $opt{agentnum}; - # wait for any ongoing billing jobs to complete - # (should this exclude status='failed')? - if ($opt{m}) { - my $sql = "SELECT count(*) FROM queue LEFT JOIN cust_main USING(custnum) ". - "WHERE queue.job='FS::cust_main::queued_bill'"; - $sql .= " AND cust_main.agentnum = $agentnum" if $agentnum =~ /^\d+$/; - my $sth = $dbh->prepare($sql) or die $dbh->errstr; - while (1) { - $sth->execute() - or die "Unexpected error executing statement $sql: ". $sth->errstr; - last if $sth->fetchrow_arrayref->[0] == 0; - sleep 300; - } - } - my $agent; if ( $agentnum ) { $agent = qsearchs( 'agent', { agentnum => $agentnum } ) -- cgit v1.2.1 From 9fa2bad9e9954ba0f838b032b4732de6847bb55b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 3 Dec 2012 20:27:16 -0800 Subject: add suspend/unsuspend to http exports, RT#20054 --- FS/FS/part_export/acct_http.pm | 12 ++++++++++++ FS/FS/part_export/broadband_http.pm | 12 ++++++++++++ FS/FS/part_export/http.pm | 22 ++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/FS/FS/part_export/acct_http.pm b/FS/FS/part_export/acct_http.pm index 23df7b37d..af358997e 100644 --- a/FS/FS/part_export/acct_http.pm +++ b/FS/FS/part_export/acct_http.pm @@ -41,6 +41,18 @@ tie %options, 'Tie::IxHash', "password \$new->_password", ), }, + 'suspend_data' => { + label => 'Suspend data', + type => 'textarea', + default => join("\n", + ), + }, + 'unsuspend_data' => { + label => 'Unsuspend data', + type => 'textarea', + default => join("\n", + ), + }, 'success_regexp' => { label => 'Success Regexp', default => '', diff --git a/FS/FS/part_export/broadband_http.pm b/FS/FS/part_export/broadband_http.pm index c1ed7fca6..5be8b6851 100644 --- a/FS/FS/part_export/broadband_http.pm +++ b/FS/FS/part_export/broadband_http.pm @@ -35,6 +35,18 @@ tie %options, 'Tie::IxHash', type => 'textarea', default => '', }, + 'suspend_data' => { + label => 'Suspend data', + type => 'textarea', + default => join("\n", + ), + }, + 'unsuspend_data' => { + label => 'Unsuspend data', + type => 'textarea', + default => join("\n", + ), + }, 'success_regexp' => { label => 'Success Regexp', default => '', diff --git a/FS/FS/part_export/http.pm b/FS/FS/part_export/http.pm index c35c89f12..0d62409fc 100644 --- a/FS/FS/part_export/http.pm +++ b/FS/FS/part_export/http.pm @@ -33,6 +33,18 @@ tie %options, 'Tie::IxHash', default => join("\n", ), }, + 'suspend_data' => { + label => 'Suspend data', + type => 'textarea', + default => join("\n", + ), + }, + 'unsuspend_data' => { + label => 'Unsuspend data', + type => 'textarea', + default => join("\n", + ), + }, 'success_regexp' => { label => 'Success Regexp', default => '', @@ -64,6 +76,16 @@ sub _export_delete { $self->_export_command('delete', @_); } +sub _export_suspend { + my $self = shift; + $self->_export_command('suspend', @_); +} + +sub _export_unsuspend { + my $self = shift; + $self->_export_command('unsuspend', @_); +} + sub _export_command { my( $self, $action, $svc_x ) = ( shift, shift, shift ); -- cgit v1.2.1 From 1ef17523c4d4c06b8f26e563d7f633ec7f2e7d99 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 4 Dec 2012 08:59:22 -0800 Subject: prepaid API respects pkg-balances config, RT#19560 --- FS/FS/ClientAPI/PrepaidPhone.pm | 20 +++++++++++++++----- FS/FS/cust_pkg.pm | 12 ++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/FS/FS/ClientAPI/PrepaidPhone.pm b/FS/FS/ClientAPI/PrepaidPhone.pm index c34617922..c7317ea23 100644 --- a/FS/FS/ClientAPI/PrepaidPhone.pm +++ b/FS/FS/ClientAPI/PrepaidPhone.pm @@ -3,6 +3,7 @@ package FS::ClientAPI::PrepaidPhone; use strict; use vars qw($DEBUG $me); use FS::Record qw(qsearchs); +use FS::Conf; use FS::rate; use FS::svc_phone; @@ -156,11 +157,15 @@ sub call_time { return \%return; } + my $conf = new FS::Conf; + my $balance = $conf->config_bool('pkg-balances') ? $cust_pkg->balance + : $cust_main->balance; + #XXX granularity? included minutes? another day... - if ( $cust_main->balance >= 0 ) { + if ( $balance >= 0 ) { return { 'error'=>'No balance' }; } else { - $return{'seconds'} = int(60 * abs($cust_main->balance) / $rate_detail->min_charge); + $return{'seconds'} = int(60 * abs($balance) / $rate_detail->min_charge); } warn "$me returning seconds: ". $return{'seconds'}; @@ -248,13 +253,18 @@ sub phonenum_balance { my $cust_pkg = $svc_phone->cust_svc->cust_pkg; - warn "$me returning ". $cust_pkg->cust_main->balance. - " balance for custnum ". $cust_pkg->custnum + my $conf = new FS::Conf; + my $balance = $conf->config_bool('pkg-balances') + ? $cust_pkg->balance + : $cust_pkg->cust_main->balance; + + warn "$me returning $balance balance for pkgnum ". $cust_pkg->pkgnum. + ", custnum ". $cust_pkg->custnum if $DEBUG; return { 'custnum' => $cust_pkg->custnum, - 'balance' => $cust_pkg->cust_main->balance, + 'balance' => $balance, }; } diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 16adea3d7..75a0d7792 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -2650,6 +2650,18 @@ sub cust_main { qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); } +=item balance + +Returns the balance for this specific package, when using +experimental package balance. + +=cut + +sub balance { + my $self = shift; + $self->cust_main->balance_pkgnum( $self->pkgnum ); +} + #these subs are in location_Mixin.pm now... unfortunately the POD doesn't mixin =item cust_location -- cgit v1.2.1 From 998b62d3f157ba546b2b100f2005934f42aa863f Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 4 Dec 2012 09:21:19 -0800 Subject: add IO::String as a proper web interface dep, RT#19732 --- FS/FS/Mason.pm | 1 + httemplate/search/customer_accounting_summary.html | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 004701646..4b1f800b6 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -83,6 +83,7 @@ if ( -e $addl_handler_use_file ) { use IO::Handle; use IO::File; use IO::Scalar; + use IO::String; #not actually using this yet anyway...# use IPC::Run3 0.036; use Net::Whois::Raw qw(whois); if ( $] < 5.006 ) { diff --git a/httemplate/search/customer_accounting_summary.html b/httemplate/search/customer_accounting_summary.html index 557528325..e01b8cd51 100644 --- a/httemplate/search/customer_accounting_summary.html +++ b/httemplate/search/customer_accounting_summary.html @@ -9,8 +9,7 @@ http_header('Content-Disposition' => qq!attachment;filename="$filename"!); my $output = ''; - use IO::String; - my $XLS = IO::String->new($output);; + my $XLS = IO::String->new($output); my $workbook = $format->{class}->new($XLS) or die "Error opening .xls file: $!"; -- cgit v1.2.1 From a9e018d378fd83aadf4c84a33001e39333c7cd30 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 4 Dec 2012 11:06:42 -0800 Subject: add Net 18, RT#17616 --- FS/FS/Conf.pm | 2 +- httemplate/elements/select-terms.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 7f3fcaa38..0aafd2531 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1478,7 +1478,7 @@ and customer address. Include units.', 'section' => 'invoicing', 'description' => 'Optional default invoice term, used to calculate a due date printed on invoices.', 'type' => 'select', - 'select_enum' => [ '', 'Payable upon receipt', 'Net 0', 'Net 3', 'Net 9', 'Net 10', 'Net 15', 'Net 20', 'Net 21', 'Net 30', 'Net 45', 'Net 60', 'Net 90' ], + 'select_enum' => [ '', 'Payable upon receipt', 'Net 0', 'Net 3', 'Net 9', 'Net 10', 'Net 15', 'Net 18', 'Net 20', 'Net 21', 'Net 30', 'Net 45', 'Net 60', 'Net 90' ], }, { diff --git a/httemplate/elements/select-terms.html b/httemplate/elements/select-terms.html index d63c49219..a66aa29ae 100644 --- a/httemplate/elements/select-terms.html +++ b/httemplate/elements/select-terms.html @@ -33,7 +33,7 @@ my $empty_label = my $empty_value = $opt{'empty_value'} || ''; my @terms = ( emt('Payable upon receipt'), - ( map "Net $_", 0, 3, 9, 10, 15, 20, 30, 45, 60, 90 ), + ( map "Net $_", 0, 3, 9, 10, 15, 18, 20, 30, 45, 60, 90 ), ); my @pre_options = $opt{pre_options} ? @{ $opt{pre_options} } : (); -- cgit v1.2.1 From 1a6848f49af5bed28f7a73c747ce18d8bbe2f31e Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 4 Dec 2012 12:15:28 -0800 Subject: add $email to acct_xmlrpc export, RT#17622 --- FS/FS/part_export/acct_xmlrpc.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/FS/FS/part_export/acct_xmlrpc.pm b/FS/FS/part_export/acct_xmlrpc.pm index 4c896b422..a493f5206 100644 --- a/FS/FS/part_export/acct_xmlrpc.pm +++ b/FS/FS/part_export/acct_xmlrpc.pm @@ -48,6 +48,8 @@ The following variables are available for interpolation (prefixed with new_ or old_ for replace operations):
  • $username +
  • $domain +
  • $email - username@domain
  • $_password
  • $crypt_password - encrypted password
  • $ldap_password - Password in LDAP/RFC2307 format (for example, "{PLAIN}himom", "{CRYPT}94pAVyK/4oIBk" or "{MD5}5426824942db4253f87a1009fd5d2d4") @@ -196,8 +198,8 @@ sub _export_value { } else { return Frontier::RPC2::String->new( $svc_acct->$value() ); } - } elsif ( $value eq 'domain' ) { - return Frontier::RPC2::String->new( $svc_acct->domain ); + } elsif ( $value =~ /^(domain|email)$/ ) { + return Frontier::RPC2::String->new( $svc_acct->$value() ); } elsif ( $value eq 'crypt_password' ) { return Frontier::RPC2::String->new( $svc_acct->crypt_password( $self->option('crypt') ) ); } elsif ( $value eq 'ldap_password' ) { @@ -207,6 +209,7 @@ sub _export_value { #XXX } +#this is the "cust_main" email, not svc_acct->email # my $cust_pkg = $svc_acct->cust_svc->cust_pkg; # if ( $cust_pkg ) { # no strict 'vars'; -- cgit v1.2.1 From fd4322f01b8c53b3f1f9e54ca15184930b0443de Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 5 Dec 2012 18:15:27 -0800 Subject: support custnum param even though we wound up not using it here, RT#18676 --- httemplate/search/cust_bill_pkg.cgi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi index 4c0fa4a56..ed3444027 100644 --- a/httemplate/search/cust_bill_pkg.cgi +++ b/httemplate/search/cust_bill_pkg.cgi @@ -200,6 +200,11 @@ if ( $cgi->param('refnum') =~ /^(\d+)$/ ) { push @where, "cust_main.refnum = $1"; } +# custnum +if ( $cgi->param('custnum') =~ /^(\d+)$/ ) { + push @where, "cust_main.custnum = $1"; +} + # the non-tax case if ( $cgi->param('nottax') ) { -- cgit v1.2.1 From 786beb09ecbf02c572ca01c61353e163f0637dbd Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 8 Dec 2012 11:07:04 -0800 Subject: fix part_pkg.comment xss --- httemplate/browse/agent_type.cgi | 4 ++-- httemplate/edit/agent_type.cgi | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/httemplate/browse/agent_type.cgi b/httemplate/browse/agent_type.cgi index 1959302d2..7711dccf7 100755 --- a/httemplate/browse/agent_type.cgi +++ b/httemplate/browse/agent_type.cgi @@ -44,9 +44,9 @@ my $agent_type = shift; [ { #'data' => $part_pkg->pkg. ' - '. $part_pkg->comment, - 'data' => $type_pkgs->pkg. ' - '. + 'data' => encode_entities($type_pkgs->pkg). ' - '. ( $type_pkgs->custom ? '(CUSTOM) ' : '' ). - $type_pkgs->comment, + encode_entities($type_pkgs->comment), 'align' => 'left', 'link' => $p. 'edit/part_pkg.cgi?'. $type_pkgs->pkgpart, }, diff --git a/httemplate/edit/agent_type.cgi b/httemplate/edit/agent_type.cgi index 8a6fbc255..b75757fb1 100755 --- a/httemplate/edit/agent_type.cgi +++ b/httemplate/edit/agent_type.cgi @@ -20,7 +20,7 @@ Select which packages agents of this type may sell to customers
    'source_obj' => $agent_type, 'link_table' => 'type_pkgs', 'target_table' => 'part_pkg', - 'name_callback' => sub { $_[0]->pkg_comment(nopkgpart => 1); }, + 'name_callback' => sub { encode_entities( $_[0]->pkg_comment(nopkgpart => 1) ); }, 'target_link' => $p.'edit/part_pkg.cgi?', 'disable-able' => 1, -- cgit v1.2.1 From b62f98268b17471c7b195d7d193b33c4a6915892 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 9 Dec 2012 10:30:44 -0800 Subject: create credits by selecting line items, RT#18676 --- FS/FS/cust_main_county.pm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/FS/FS/cust_main_county.pm b/FS/FS/cust_main_county.pm index 143f62ed3..87c1ca730 100644 --- a/FS/FS/cust_main_county.pm +++ b/FS/FS/cust_main_county.pm @@ -472,8 +472,11 @@ sub taxline { $_->taxnum($self->taxnum) foreach @new_exemptions; - if ( $cust_bill_pkg->billpkgnum ) { - die "tried to calculate tax exemptions on a previously billed line item\n"; + #if ( $cust_bill_pkg->billpkgnum ) { + + #no, need to do this to e.g. calculate tax credit amounts + #die "tried to calculate tax exemptions on a previously billed line item\n"; + # this is unnecessary # foreach my $cust_tax_exempt_pkg (@new_exemptions) { # my $error = $cust_tax_exempt_pkg->insert; @@ -482,7 +485,7 @@ sub taxline { # return "can't insert cust_tax_exempt_pkg: $error"; # } # } - } + #} # attach them to the line item push @{ $cust_bill_pkg->cust_tax_exempt_pkg }, @new_exemptions; -- cgit v1.2.1 From 93e3a52f23c3473207f29f36cda06adfe221353f Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 9 Dec 2012 10:30:54 -0800 Subject: create credits by selecting line items, RT#18676 --- FS/FS/cust_bill_pkg.pm | 17 +- FS/FS/cust_credit.pm | 255 ++++++++++++++++++++- httemplate/edit/credit-cust_bill_pkg.html | 249 ++++++++++++++++++++ httemplate/edit/cust_credit.cgi | 1 + httemplate/edit/process/credit-cust_bill_pkg.html | 41 ++++ httemplate/edit/process/cust_credit.cgi | 4 +- .../xmlhttp-cust_bill_pkg-calculate_taxes.html | 123 ++++++++++ httemplate/view/cust_main/payment_history.html | 10 + 8 files changed, 695 insertions(+), 5 deletions(-) create mode 100644 httemplate/edit/credit-cust_bill_pkg.html create mode 100644 httemplate/edit/process/credit-cust_bill_pkg.html create mode 100644 httemplate/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index 826569b25..a83af1326 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -665,8 +665,9 @@ sub set_display { =item disintegrate -Returns a list of cust_bill_pkg objects each with no more than a single class -(including setup or recur) of charge. +Returns a hash: keys are "setup", "recur" or usage classnum, values are +FS::cust_bill_pkg objects, each with no more than a single class (setup or +recur) of charge. =cut @@ -843,6 +844,18 @@ sub _X_show_zero { $self->cust_pkg->_X_show_zero($what); } +=item credited [ BEFORE, AFTER, OPTIONS ] + +Returns the sum of credits applied to this item. Arguments are the same as +owed_sql/paid_sql/credited_sql. + +=cut + +sub credited { + my $self = shift; + $self->scalar_sql('SELECT '. $self->credited_sql(@_).' FROM cust_bill_pkg WHERE billpkgnum = ?', $self->billpkgnum); +} + =back =head1 CLASS METHODS diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index 6185fc472..f7f375874 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -172,7 +172,7 @@ sub insert { $dbh->commit or die $dbh->errstr if $oldAutoCommit; - #false laziness w/ cust_credit::insert + #false laziness w/ cust_pay::insert if ( $unsuspendauto && $old_balance && $cust_main->balance <= 0 ) { my @errors = $cust_main->unsuspend; #return @@ -618,6 +618,259 @@ sub credited_sql { unapplied_sql(); } +=item credit_lineitems + +Example: + + my $error = FS::cust_credit->credit_lineitems( + #the lineitems + 'billpkgnums' => \@billpkgnums, + + #the credit + 'newreasonnum' => scalar($cgi->param('newreasonnum')), + 'newreasonnum_type' => scalar($cgi->param('newreasonnumT')), + map { $_ => scalar($cgi->param($_)) } + fields('cust_credit') + ); + +=cut + +#maybe i should just be an insert with extra args instead of a class method +use FS::cust_bill_pkg; +sub credit_lineitems { + my( $class, %arg ) = @_; + + my $curuser = $FS::CurrentUser::CurrentUser; + + #some false laziness w/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html + + my $cust_main = qsearchs({ + 'table' => 'cust_main', + 'hashref' => { 'custnum' => $arg{custnum} }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, + }) or return 'unknown customer'; + + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + #my @cust_bill_pkg = qsearch({ + # 'select' => 'cust_bill_pkg.*', + # 'table' => 'cust_bill_pkg', + # 'addl_from' => ' LEFT JOIN cust_bill USING (invnum) '. + # ' LEFT JOIN cust_main USING (custnum) ', + # 'extra_sql' => ' WHERE custnum = $custnum AND billpkgnum IN ('. + # join( ',', @{$arg{billpkgnums}} ). ')', + # 'order_by' => 'ORDER BY invnum ASC, billpkgnum ASC', + #}); + + my $error = ''; + if ($arg{reasonnum} == -1) { + + $error = 'Enter a new reason (or select an existing one)' + unless $arg{newreasonnum} !~ /^\s*$/; + my $reason = new FS::reason { + 'reason' => $arg{newreasonnum}, + 'reason_type' => $arg{newreasonnum_type}, + }; + $error ||= $reason->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error inserting reason: $error"; + } + $arg{reasonnum} = $reason->reasonnum; + } + + my $cust_credit = new FS::cust_credit ( { + map { $_ => $arg{$_} } + #fields('cust_credit') + qw( custnum _date amount reason reasonnum addlinfo ), #pkgnum eventnum + } ); + $error = $cust_credit->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error inserting credit: $error"; + } + + #my $subtotal = 0; + my $taxlisthash = {}; + my %cust_credit_bill = (); + my %cust_bill_pkg = (); + my %cust_credit_bill_pkg = (); + foreach my $billpkgnum ( @{$arg{billpkgnums}} ) { + my $setuprecur = shift @{$arg{setuprecurs}}; + my $amount = shift @{$arg{amounts}}; + + my $cust_bill_pkg = qsearchs({ + 'table' => 'cust_bill_pkg', + 'hashref' => { 'billpkgnum' => $billpkgnum }, + 'addl_from' => 'LEFT JOIN cust_bill USING (invnum)', + 'extra_sql' => 'AND custnum = '. $cust_main->custnum, + }) or die "unknown billpkgnum $billpkgnum"; + + if ( $setuprecur eq 'setup' ) { + $cust_bill_pkg->setup($amount); + $cust_bill_pkg->recur(0); + $cust_bill_pkg->unitrecur(0); + $cust_bill_pkg->type(''); + } else { + $setuprecur = 'recur'; #in case its a usage classnum? + $cust_bill_pkg->recur($amount); + $cust_bill_pkg->setup(0); + $cust_bill_pkg->unitsetup(0); + } + + push @{$cust_bill_pkg{$cust_bill_pkg->invnum}}, $cust_bill_pkg; + + #unapply any payments applied to this line item (other credits too?) + foreach my $cust_bill_pay_pkg ( $cust_bill_pkg->cust_bill_pay_pkg($setuprecur) ) { + $error = $cust_bill_pay_pkg->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error unapplying payment: $error"; + } + } + + #$subtotal += $amount; + $cust_credit_bill{$cust_bill_pkg->invnum} += $amount; + push @{ $cust_credit_bill_pkg{$cust_bill_pkg->invnum} }, + new FS::cust_credit_bill_pkg { + 'billpkgnum' => $cust_bill_pkg->billpkgnum, + 'amount' => $amount, + 'setuprecur' => $setuprecur, + 'sdate' => $cust_bill_pkg->sdate, + 'edate' => $cust_bill_pkg->edate, + }; + + my $part_pkg = $cust_bill_pkg->part_pkg; + $cust_main->_handle_taxes( $part_pkg, + $taxlisthash, + $cust_bill_pkg, + $cust_bill_pkg->cust_pkg, + $cust_bill_pkg->cust_bill->_date, + $cust_bill_pkg->cust_pkg->pkgpart, + ); + } + + ### + # now loop through %cust_credit_bill and insert those + ### + + # (hack to prevent cust_credit_bill_pkg insertion) + local($FS::cust_bill_ApplicationCommon::skip_apply_to_lineitems_hack) = 1; + + foreach my $invnum ( sort { $a <=> $b } keys %cust_credit_bill ) { + + #taxes + + if ( @{ $cust_bill_pkg{$invnum} } ) { + + my $listref_or_error = + $cust_main->calculate_taxes( $cust_bill_pkg{$invnum}, $taxlisthash, $cust_bill_pkg{$invnum}->[0]->cust_bill->_date ); + + unless ( ref( $listref_or_error ) ) { + $dbh->rollback if $oldAutoCommit; + return "Error calculating taxes: $listref_or_error"; + } + + # so, loop through the taxlines, apply just that amount to the tax line + # item (save for later insert) & add to $ + + #my @taxlines = (); + #my $taxtotal = 0; + foreach my $taxline ( @$listref_or_error ) { + + #find equivalent tax line items on the existing invoice + # (XXX need a more specific/deterministic way to find these than itemdesc..) + my $tax_cust_bill_pkg = qsearchs('cust_bill_pkg', { + 'invnum' => $invnum, + 'pkgnum' => 0, #$taxline->invnum + 'itemdesc' => $taxline->desc, + }); + + my $amount = $taxline->setup; + my $desc = $taxline->desc; + + foreach my $location ( $tax_cust_bill_pkg->cust_bill_pkg_tax_Xlocation ) { + + $location->cust_bill_pkg_desc($taxline->desc); #ugh @ that kludge + + #$taxtotal += $location->amount; + $amount -= $location->amount; + + #push @taxlines, + # #[ $location->desc, $taxline->setup, $taxlocnum, $taxratelocnum ]; + # [ $location->desc, $location->amount, $taxlocnum, $taxratelocnum ]; + $cust_credit_bill{$invnum} += $location->amount; + push @{ $cust_credit_bill_pkg{$invnum} }, + new FS::cust_credit_bill_pkg { + 'billpkgnum' => $tax_cust_bill_pkg->billpkgnum, + 'amount' => $location->amount, + 'setuprecur' => 'setup', + 'billpkgtaxlocationnum' => $location->billpkgtaxlocationnum, + 'billpkgtaxratelocationnum' => $location->billpkgtaxratelocationnum, + }; + + } + if ($amount > 0) { + #$taxtotal += $amount; + #push @taxlines, + # [ $taxline->itemdesc. ' (default)', sprintf('%.2f', $amount), '', '' ]; + + $cust_credit_bill{$invnum} += $amount; + push @{ $cust_credit_bill_pkg{$invnum} }, + new FS::cust_credit_bill_pkg { + 'billpkgnum' => $tax_cust_bill_pkg->billpkgnum, + 'amount' => $amount, + 'setuprecur' => 'setup', + }; + + } + } + + } + + #insert cust_credit_bill + + my $cust_credit_bill = new FS::cust_credit_bill { + 'crednum' => $cust_credit->crednum, + 'invnum' => $invnum, + 'amount' => $cust_credit_bill{$invnum}, + }; + $error = $cust_credit_bill->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error applying credit of $cust_credit_bill{$invnum} ". + " to invoice $invnum: $error"; + } + + #and then insert cust_credit_bill_pkg for each cust_bill_pkg + foreach my $cust_credit_bill_pkg ( @{$cust_credit_bill_pkg{$invnum}} ) { + $cust_credit_bill_pkg->creditbillnum( $cust_credit_bill->creditbillnum ); + $error = $cust_credit_bill_pkg->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error applying credit to line item: $error"; + } + } + + } + + #$return->{taxlines} = \@taxlines; + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + +} + =back =head1 BUGS diff --git a/httemplate/edit/credit-cust_bill_pkg.html b/httemplate/edit/credit-cust_bill_pkg.html new file mode 100644 index 000000000..e317936b3 --- /dev/null +++ b/httemplate/edit/credit-cust_bill_pkg.html @@ -0,0 +1,249 @@ +<& /elements/header-popup.html, 'Credit line items' &> + +
    + + + + +
Module:Module:
Object:
@@ -14,7 +15,7 @@
Module:
+ +% my $old_invnum = 0; +%# foreach my $cust_bill_pkg ( @cust_bill_pkg ) { +% foreach my $item ( @items ) { +% my( $setuprecur, $cust_bill_pkg ) = @$item; + +% my $method = $setuprecur eq 'setup' ? 'setup' : 'recur'; +% my $amount = $cust_bill_pkg->$method(); +% my $credited = $cust_bill_pkg->credited('', '', 'setuprecur'=>$method); +% $amount -= $credited; +% $amount = sprintf('%.2f', $amount); +% next unless $amount > 0; + +% if ( $cust_bill_pkg->invnum ne $old_invnum ) { + + +% $old_invnum = $cust_bill_pkg->invnum; +% } + + + + +%# show one-time/setup vs recur vs usage? + + + +% } + + + + + + + + + + + + + + + + + +
 
Invoice #<% $cust_bill_pkg->invnum %> - <% time2str($date_format, $cust_bill_pkg->cust_bill->_date) %>
+ + <% $cust_bill_pkg->desc |h %><% $money_char. $amount %>
 
Subtotal: <% $money_char %><% sprintf('%.2f', 0) %>
Taxes: <% $money_char %><% sprintf('%.2f', 0) %>
Total credit amount: + <% $money_char %><% sprintf('%.2f', 0) %> +
+ + + +<& /elements/tr-select-reason.html, + 'field' => 'reasonnum', + 'reason_class' => 'R', + #XXX reconcile both this and show_taxes wanteding to enable this + 'control_button' => "document.getElementById('credit_button')", + 'cgi' => $cgi, +&> + + + + + + +
<% mt('Additional info') |h %> + +
+ +
+ + + + +<% include( '/elements/xmlhttp.html', + 'url' => $p.'misc/xmlhttp-cust_bill_pkg-calculate_taxes.html', + 'subs' => [ 'calculate_taxes' ], + ) +%> + + +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" unless $curuser->access_right('Post credit'); + +#a tiny bit of false laziness w/search/cust_bill_pkg.cgi, but we're pretty +# specialized and a piece of UI, not a report +#slightly more false laziness w/httemplate/edit/elements/ApplicationCommon.html +# show_taxes & calc_total here/do_calculate_tax there + +my $conf = new FS::Conf; +my $money_char = $conf->config('money_char') || '$'; +my $date_format = $conf->config('date_format') || '%m/%d/%Y'; + +$cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum'; +my $custnum = $1; + +my $cust_main = qsearchs({ + 'table' => 'cust_main', + 'hashref' => { 'custnum' => $custnum }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, +}) or die 'unknown customer'; + +my @cust_bill_pkg = qsearch({ + 'select' => 'cust_bill_pkg.*', + 'table' => 'cust_bill_pkg', + 'addl_from' => 'LEFT JOIN cust_bill USING (invnum)', + 'extra_sql' => "WHERE custnum = $custnum AND pkgnum != 0", + 'order_by' => 'ORDER BY invnum ASC, billpkgnum ASC', +}); + +my @items = map { my %hash = $_->disintegrate; + map [ $_, $hash{$_} ], + keys(%hash); + } + @cust_bill_pkg; + +#omit line items which have been previously credited? would be nice + + diff --git a/httemplate/edit/cust_credit.cgi b/httemplate/edit/cust_credit.cgi index 6e8a9c989..4dba1e769 100755 --- a/httemplate/edit/cust_credit.cgi +++ b/httemplate/edit/cust_credit.cgi @@ -34,6 +34,7 @@ + % if ( $conf->exists('credits-auto-apply-disable') ) { diff --git a/httemplate/edit/process/credit-cust_bill_pkg.html b/httemplate/edit/process/credit-cust_bill_pkg.html new file mode 100644 index 000000000..d3323e6ed --- /dev/null +++ b/httemplate/edit/process/credit-cust_bill_pkg.html @@ -0,0 +1,41 @@ +%if ($error) { +% errorpage_popup($error); #XXX redirect back for correction... +%} else { +<& /elements/header-popup.html, 'Credit successful' &> + + +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Post credit'); + +my @billpkgnum_setuprecurs = + map { $_ =~ /^billpkgnum(\d+\-\w*)$/ or die 'gm#23'; $1; } + grep { $_ =~ /^billpkgnum\d+\-\w*$/ && $cgi->param($_) } $cgi->param; + +my @billpkgnums = (); +my @setuprecurs = (); +my @amounts = (); +foreach my $billpkgnum_setuprecur (@billpkgnum_setuprecurs) { + my $amount = $cgi->param("billpkgnum$billpkgnum_setuprecur"); + my( $billpkgnum, $setuprecur ) = split('-', $billpkgnum_setuprecur); + push @billpkgnums, $billpkgnum; + push @setuprecurs, $setuprecur; + push @amounts, $amount; +} + +my $error = FS::cust_credit->credit_lineitems( + 'newreasonnum' => scalar($cgi->param('newreasonnum')), + 'newreasonnum_type' => scalar($cgi->param('newreasonnumT')), + 'billpkgnums' => \@billpkgnums, + 'setuprecurs' => \@setuprecurs, + 'amounts' => \@amounts, + map { $_ => scalar($cgi->param($_)) } + #fields('cust_credit') + qw( custnum _date amount reason reasonnum addlinfo ), #pkgnum eventnum +); + + diff --git a/httemplate/edit/process/cust_credit.cgi b/httemplate/edit/process/cust_credit.cgi index 776112ac0..245f31af7 100755 --- a/httemplate/edit/process/cust_credit.cgi +++ b/httemplate/edit/process/cust_credit.cgi @@ -15,7 +15,7 @@ % % $dbh->commit or die $dbh->errstr if $oldAutoCommit; % -<% header(emt('Credit sucessful')) %> +<% header(emt('Credit successful')) %> @@ -27,7 +27,7 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Post credit'); -$cgi->param('custnum') =~ /^(\d*)$/ or die "Illegal custnum!"; +$cgi->param('custnum') =~ /^(\d+)$/ or die "Illegal custnum!"; my $custnum = $1; $cgi->param('reasonnum') =~ /^(-?\d+)$/ or die "Illegal reasonnum"; diff --git a/httemplate/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html b/httemplate/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html new file mode 100644 index 000000000..993504619 --- /dev/null +++ b/httemplate/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html @@ -0,0 +1,123 @@ +<% to_json($return) %> +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" unless $curuser->access_right('Post credit'); + +my $DEBUG = 0; + +my $conf = new FS::Conf; + +my $sub = $cgi->param('sub'); + +my $return = {}; + +if ( $sub eq 'calculate_taxes' ) { + + { + + my %arg = $cgi->param('arg'); + $return = \%arg; + warn join('', map "$_: $arg{$_}\n", keys %arg ) + if $DEBUG; + + #some false laziness w/cust_credit::credit_lineitems + + my $cust_main = qsearchs({ + 'table' => 'cust_main', + 'hashref' => { 'custnum' => $arg{custnum} }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, + }) or die 'unknown customer'; + + my @billpkgnums = split(',', $arg{billpkgnums}); + my @setuprecurs = split(',', $arg{setuprecurs}); + my @amounts = split(',', $arg{amounts}); + + my @cust_bill_pkg = (); + my $taxlisthash = {}; + while ( @billpkgnums ) { + my $billpkgnum = shift @billpkgnums; + my $setuprecur = shift @setuprecurs; + my $amount = shift @amounts; + + my $cust_bill_pkg = qsearchs({ + 'table' => 'cust_bill_pkg', + 'hashref' => { 'billpkgnum' => $billpkgnum }, + 'addl_from' => 'LEFT JOIN cust_bill USING (invnum)', + 'extra_sql' => 'AND custnum = '. $cust_main->custnum, + }) or die "unknown billpkgnum $billpkgnum"; + + #shouldn't be passed# next if $cust_bill_pkg->pkgnum == 0; + + if ( $setuprecur eq 'setup' ) { + $cust_bill_pkg->setup($amount); + $cust_bill_pkg->recur(0); + $cust_bill_pkg->unitrecur(0); + $cust_bill_pkg->type(''); + } else { + $cust_bill_pkg->recur($amount); + $cust_bill_pkg->setup(0); + $cust_bill_pkg->unitsetup(0); + } + + push @cust_bill_pkg, $cust_bill_pkg; + + my $part_pkg = $cust_bill_pkg->part_pkg; + $cust_main->_handle_taxes( $part_pkg, + $taxlisthash, + $cust_bill_pkg, + $cust_bill_pkg->cust_pkg, + $cust_bill_pkg->cust_bill->_date, + $cust_bill_pkg->cust_pkg->pkgpart, + ); + + } + + if ( @cust_bill_pkg ) { + + my $listref_or_error = + $cust_main->calculate_taxes( \@cust_bill_pkg, $taxlisthash, $cust_bill_pkg[0]->cust_bill->_date ); + + unless ( ref( $listref_or_error ) ) { + $return->{error} = $listref_or_error; + last; + } + + my @taxlines = (); + my $taxtotal = 0; + $return->{taxlines} = \@taxlines; + foreach my $taxline ( @$listref_or_error ) { + my $amount = $taxline->setup; + my $desc = $taxline->desc; + foreach my $location ( @{$taxline->cust_bill_pkg_tax_location}, @{$taxline->cust_bill_pkg_tax_rate_location} ) { + my $taxlocnum = $location->locationnum || ''; + my $taxratelocnum = $location->taxratelocationnum || ''; + $location->cust_bill_pkg_desc($taxline->desc); #ugh @ that kludge + $taxtotal += $location->amount; + push @taxlines, + #[ $location->desc, $taxline->setup, $taxlocnum, $taxratelocnum ]; + [ $location->desc, $location->amount, $taxlocnum, $taxratelocnum ]; + $amount -= $location->amount; + } + if ($amount > 0) { + $taxtotal += $amount; + push @taxlines, + [ $taxline->itemdesc. ' (default)', sprintf('%.2f', $amount), '', '' ]; + } + } + + $return->{taxlines} = \@taxlines; + $return->{taxtotal} = sprintf('%.2f', $taxtotal); + + } else { + + $return->{taxlines} = []; + $return->{taxtotal} = '0.00'; + + } + + } + +} + + diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html index 166addbf4..6630d12a5 100644 --- a/httemplate/view/cust_main/payment_history.html +++ b/httemplate/view/cust_main/payment_history.html @@ -70,6 +70,16 @@ 'actionlabel' => emt('Enter credit'), 'width' => 616, #make room for reasons #540 default &> + | + <& /elements/popup_link-cust_main.html, + 'label' => emt('Credit line items'), + #'action' => "${p}search/cust_bill_pkg.cgi?nottax=1;type=select", + 'action' => "${p}edit/credit-cust_bill_pkg.html", + 'cust_main' => $cust_main, + 'actionlabel' => emt('Credit line items'), + 'width' => 884, #763, + 'height' => 575, + &>
% } -- cgit v1.2.1 From 1af8d0fac869b4b62526eec4b8ce56d5bc2c69fe Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 9 Dec 2012 10:37:32 -0800 Subject: create credits by selecting line items, RT#18676 --- FS/FS/cust_credit.pm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index f7f375874..0251cee1d 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -623,14 +623,19 @@ sub credited_sql { Example: my $error = FS::cust_credit->credit_lineitems( - #the lineitems + + #the lineitems to credit 'billpkgnums' => \@billpkgnums, + 'setuprecurs' => \@setuprecurs, + 'amounts' => \@amounts, #the credit 'newreasonnum' => scalar($cgi->param('newreasonnum')), 'newreasonnum_type' => scalar($cgi->param('newreasonnumT')), map { $_ => scalar($cgi->param($_)) } - fields('cust_credit') + #fields('cust_credit') + qw( custnum _date amount reason reasonnum addlinfo ), #pkgnum eventnum + ); =cut -- cgit v1.2.1 From 943daa1500357a88b4554e11aa74f9599f611419 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 9 Dec 2012 10:38:42 -0800 Subject: create credits by selecting line items, RT#18676 --- FS/FS/cust_credit.pm | 2 -- 1 file changed, 2 deletions(-) diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index 0251cee1d..dfe55fb63 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -869,8 +869,6 @@ sub credit_lineitems { } - #$return->{taxlines} = \@taxlines; - $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; -- cgit v1.2.1 From 6cd8f3459488ce4cd1d9ec00452b1bab0bf03f8e Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 9 Dec 2012 12:12:15 -0800 Subject: fix suspension report, RT#20529, fallout from #16534 --- httemplate/search/cust_pkg_susp.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/search/cust_pkg_susp.html b/httemplate/search/cust_pkg_susp.html index 2ac643260..bdc3c5402 100644 --- a/httemplate/search/cust_pkg_susp.html +++ b/httemplate/search/cust_pkg_susp.html @@ -23,6 +23,6 @@ <%init> die "access denied" - unless $curuser->access_right('Summarize packages'); + unless $FS::CurrentUser::CurrentUser->access_right('Summarize packages'); -- cgit v1.2.1 From 5c7291f9b5ff6f1e529c530db6ff56135ef7055a Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 9 Dec 2012 13:11:34 -0800 Subject: add PerlChildInitHandler which calls srand to avoid collision problems with B:OP processors which generate a random number, RT#19188 --- htetc/freeside-base2.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htetc/freeside-base2.conf b/htetc/freeside-base2.conf index dcf5efa3f..49b4a243d 100644 --- a/htetc/freeside-base2.conf +++ b/htetc/freeside-base2.conf @@ -6,6 +6,8 @@ PerlModule HTML::Mason PerlSetVar MasonArgsMethod CGI PerlModule HTML::Mason::ApacheHandler +PerlChildInitHandler "sub { srand }" + PerlRequire "%%%MASON_HANDLER%%%" #Locale::SubCountry -- cgit v1.2.1 From 1bd0489531c022fbe198a0023cf3cf01861d0817 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 11 Dec 2012 13:55:53 -0800 Subject: cleanup --- httemplate/view/part_event-targets.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/httemplate/view/part_event-targets.html b/httemplate/view/part_event-targets.html index 2029fd4bc..e8b1266ef 100644 --- a/httemplate/view/part_event-targets.html +++ b/httemplate/view/part_event-targets.html @@ -65,9 +65,6 @@ When event is run on <& /elements/input-date-field.html, { %} <& /elements/footer.html &> -<%once> -use List::MoreUtils qw(uniq); - <%init> my $curuser = $FS::CurrentUser::CurrentUser; -- cgit v1.2.1 From bda74e13569c8531e77e8dcd01d9da9038f3c4d0 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 11 Dec 2012 13:56:48 -0800 Subject: auto-create package classes in ipifony download, #18333 --- FS/bin/freeside-ipifony-download | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/FS/bin/freeside-ipifony-download b/FS/bin/freeside-ipifony-download index ac9f76400..e893326e2 100644 --- a/FS/bin/freeside-ipifony-download +++ b/FS/bin/freeside-ipifony-download @@ -12,7 +12,7 @@ use FS::Conf; use Text::CSV; my %opt; -getopts('va:P:', \%opt); +getopts('va:P:C:', \%opt); #$Net::SFTP::Foreign::debug = -1; sub HELP_MESSAGE { ' @@ -21,6 +21,7 @@ sub HELP_MESSAGE { ' [ -v ] [ -a archivedir ] [ -P port ] + [ -C category ] freesideuser sftpuser@hostname[:path] ' } @@ -49,6 +50,16 @@ if ( $opt{a} ) { unless -w $opt{a}; } +my $categorynum = ''; +if ( $opt{C} ) { + # find this category (don't auto-create it, it should exist already) + my $category = qsearchs('pkg_category', { categoryname => $opt{C} }); + if (!defined($category)) { + die "Package category '$opt{C}' does not exist.\n"; + } + $categorynum = $category->categorynum; +} + #my $tmpdir = File::Temp->newdir(); my $tmpdir = tempdir( CLEANUP => 1 ); #DIR=>somewhere? @@ -149,8 +160,23 @@ FILE: foreach my $filename (@$files) { if (my $classname = $hash{classname}) { if (!exists($classnum_of{$classname}) ) { # then look it up - my $pkg_class = qsearch('pkg_class', { classname => $classname }); - $classnum_of{$classname} = $pkg_class ? $pkg_class->classnum : ''; + my $pkg_class = qsearchs('pkg_class', { + classname => $classname, + categorynum => $categorynum, + }); + if (!defined($pkg_class)) { + # then create it + $pkg_class = FS::pkg_class->new({ + classname => $classname, + categorynum => $categorynum, + }); + my $error = $pkg_class->insert; + die "Error creating package class for product code '$classname':\n". + "$error\n" + if $error; + } + + $classnum_of{$classname} = $pkg_class->classnum; } $opt{classnum} = $classnum_of{$classname}; } -- cgit v1.2.1 From 913bd0405d6eb0db41b9944dfd42eb1f97d18ca9 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 11 Dec 2012 14:38:07 -0800 Subject: system log, #18333 --- FS/FS/AccessRight.pm | 1 + FS/FS/Conf.pm | 9 + FS/FS/Cron/bill.pm | 6 + FS/FS/Cron/upload.pm | 16 +- FS/FS/Log.pm | 103 ++++++++ FS/FS/Log/Output.pm | 50 ++++ FS/FS/Mason.pm | 3 + FS/FS/Schema.pm | 27 +++ FS/FS/cust_main/Billing.pm | 5 + FS/FS/log.pm | 354 ++++++++++++++++++++++++++++ FS/FS/log_context.pm | 145 ++++++++++++ FS/MANIFEST | 4 + FS/bin/freeside-daily | 5 + FS/bin/freeside-queued | 6 + FS/t/log.t | 5 + FS/t/log_context.t | 5 + httemplate/elements/menu.html | 12 +- httemplate/search/elements/search-html.html | 18 +- httemplate/search/log.html | 221 +++++++++++++++++ 19 files changed, 991 insertions(+), 4 deletions(-) create mode 100644 FS/FS/Log.pm create mode 100644 FS/FS/Log/Output.pm create mode 100644 FS/FS/log.pm create mode 100644 FS/FS/log_context.pm create mode 100644 FS/t/log.t create mode 100644 FS/t/log_context.t create mode 100644 httemplate/search/log.html diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index b38c2671d..66624e179 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -277,6 +277,7 @@ tie my %rights, 'Tie::IxHash', 'Financial reports', { rightname=> 'List inventory', global=>1 }, { rightname=>'View email logs', global=>1 }, + { rightname=>'View system logs' }, 'Download report data', 'Services: Accounts', diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 0aafd2531..d11916faf 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -748,6 +748,15 @@ sub reason_type_options { 'type' => 'text', }, + { + 'key' => 'event_log_level', + 'section' => 'notification', + 'description' => 'Store events in the internal log if they are at least this severe. "info" is the default, "debug" is very detailed and noisy.', + 'type' => 'select', + 'select_enum' => [ '', 'debug', 'info', 'notice', 'warning', 'error', ], + # don't bother with higher levels + }, + { 'key' => 'log_sent_mail', 'section' => 'notification', diff --git a/FS/FS/Cron/bill.pm b/FS/FS/Cron/bill.pm index a9df376dc..6e110e852 100644 --- a/FS/FS/Cron/bill.pm +++ b/FS/FS/Cron/bill.pm @@ -13,6 +13,8 @@ use FS::cust_main; use FS::part_event; use FS::part_event_condition; +use FS::Log; + @ISA = qw( Exporter ); @EXPORT_OK = qw ( bill bill_where ); @@ -27,6 +29,9 @@ use FS::part_event_condition; sub bill { my %opt = @_; + my $log = FS::Log->new('Cron::bill'); + $log->info('start'); + my $check_freq = $opt{'check_freq'} || '1d'; my $debug = 0; @@ -134,6 +139,7 @@ sub bill { $cursor_dbh->commit or die $cursor_dbh->errstr; + $log->info('finish'); } # freeside-daily %opt: diff --git a/FS/FS/Cron/upload.pm b/FS/FS/Cron/upload.pm index ccf8e1a9a..628c6801b 100644 --- a/FS/FS/Cron/upload.pm +++ b/FS/FS/Cron/upload.pm @@ -9,6 +9,7 @@ use FS::Record qw( qsearch qsearchs ); use FS::Conf; use FS::queue; use FS::agent; +use FS::Log; use FS::Misc qw( send_email ); #for bridgestone use FS::upload_target; use LWP::UserAgent; @@ -33,6 +34,8 @@ $me = '[FS::Cron::upload]'; sub upload { my %opt = @_; + my $log = FS::Log->new('Cron::upload'); + $log->info('start'); my $debug = 0; $debug = 1 if $opt{'v'}; @@ -96,7 +99,10 @@ sub upload { } # foreach @agents # if there's nothing to do, don't hold up the rest of the process - return '' if !@tasks; + if (!@tasks) { + $log->info('finish (nothing to upload)'); + return ''; + } # wait for any ongoing billing jobs to complete if ($opt{m}) { @@ -142,11 +148,13 @@ sub upload { } } + $log->info('finish'); } sub spool_upload { my %opt = @_; + my $log = FS::Log->new('spool_upload'); warn "$me spool_upload called\n" if $DEBUG; my $conf = new FS::Conf; @@ -166,6 +174,7 @@ sub spool_upload { my $dbh = dbh; my $agentnum = $opt{agentnum}; + $log->debug('start', agentnum => $agentnum); my $agent; if ( $agentnum ) { @@ -184,6 +193,8 @@ sub spool_upload { { warn "$me neither $dir/$file-header.csv nor ". "$dir/$file-detail.csv found\n" if $DEBUG > 1; + $log->debug("finish (neither $file-header.csv nor ". + "$file-detail.csv found)"); $dbh->commit or die $dbh->errstr if $oldAutoCommit; return; } @@ -263,6 +274,7 @@ sub spool_upload { unless ( -f "$dir/$file.csv" ) { warn "$me $dir/$file.csv not found\n" if $DEBUG > 1; + $log->debug("finish ($dir/$file.csv not found)"); $dbh->commit or die $dbh->errstr if $oldAutoCommit; return; } @@ -451,6 +463,8 @@ sub spool_upload { } #opt{handling} + $log->debug('finish', agentnum => $agentnum); + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; diff --git a/FS/FS/Log.pm b/FS/FS/Log.pm new file mode 100644 index 000000000..b11630bc9 --- /dev/null +++ b/FS/FS/Log.pm @@ -0,0 +1,103 @@ +package FS::Log; + +use base 'Log::Dispatch'; +use FS::Record qw(qsearch qsearchs); +use FS::Conf; +use FS::Log::Output; +use FS::log; +use vars qw(@STACK @LEVELS); + +# override the stringification of @_ with something more sensible. +BEGIN { + @LEVELS = qw(debug info notice warning error critical alert emergency); + + foreach my $l (@LEVELS) { + my $sub = sub { + my $self = shift; + $self->log( level => $l, message => @_ ); + }; + no strict 'refs'; + *{$l} = $sub; + } +} + +=head1 NAME + +FS::Log - Freeside event log + +=head1 SYNOPSIS + +use FS::Log; + +sub do_something { + my $log = FS::Log->new('do_something'); # set log context to 'do_something' + + ... + if ( $error ) { + $log->error('something is wrong: '.$error); + return $error; + } + # at this scope exit, do_something is removed from context +} + +=head1 DESCRIPTION + +FS::Log provides an interface for logging errors and profiling information +to the database. FS::Log inherits from L. + +=head1 CLASS METHODS + +=over 4 + +new CONTEXT + +Constructs and returns a log handle. CONTEXT must be a known context tag +indicating what activity is going on, such as the name of the function or +script that is executing. + +Log context is a stack, and each element is removed from the stack when it +goes out of scope. So don't keep log handles in persistent places (i.e. +package variables or class-scoped lexicals). + +=cut + +sub new { + my $class = shift; + my $context = shift; + + my $min_level = FS::Conf->new->config('event_log_level') || 'info'; + + my $self = $class->SUPER::new( + outputs => [ [ '+FS::Log::Output', min_level => $min_level ] ], + ); + $self->{'index'} = scalar(@STACK); + push @STACK, $context; + return $self; +} + +=item context + +Returns the current context stack. + +=cut + +sub context { @STACK }; + +=item log LEVEL, MESSAGE[, OPTIONS ] + +Like L, but OPTIONS may include: + +- agentnum +- object (an object to reference in this log message) +- tablename and tablenum (an alternate way of specifying 'object') + +=cut + +# inherited + +sub DESTROY { + my $self = shift; + splice(@STACK, $self->{'index'}, 1); # delete the stack entry +} + +1; diff --git a/FS/FS/Log/Output.pm b/FS/FS/Log/Output.pm new file mode 100644 index 000000000..18d7f1b43 --- /dev/null +++ b/FS/FS/Log/Output.pm @@ -0,0 +1,50 @@ +package FS::Log::Output; + +use base Log::Dispatch::Output; +use FS::Record qw( dbdef ); + +sub new { # exactly by the book + my $proto = shift; + my $class = ref $proto || $proto; + + my %p = @_; + + my $self = bless {}, $class; + + $self->_basic_init(%p); + + return $self; +} + +sub log_message { + my $self = shift; + my %m = @_; + + my $object = $m{'object'}; + my ($tablename, $tablenum) = @m{'tablename', 'tablenum'}; + if ( $object and $object->isa('FS::Record') ) { + $tablename = $object->table; + $tablenum = $object->get( dbdef->table($tablename)->primary_key ); + + # get the agentnum from the object if it has one + $m{'agentnum'} ||= $object->get('agentnum'); + # maybe FS::cust_main_Mixin objects should use the customer's agentnum? + # I'm trying not to do database lookups in here, though. + } + + my $entry = FS::log->new({ + _date => time, + agentnum => $m{'agentnum'}, + tablename => ($tablename || ''), + tablenum => ($tablenum || ''), + level => $self->_level_as_number($m{'level'}), + message => $m{'message'}, + }); + my $error = $entry->insert( FS::Log->context ); + if ( $error ) { + # guh? + warn "Error writing log entry: $error"; + } +} + +1; diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 4b1f800b6..2bc1596f2 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -56,6 +56,7 @@ if ( -e $addl_handler_use_file ) { #use CGI::Carp qw(fatalsToBrowser); use CGI::Cookie; use List::Util qw( max min sum ); + use List::MoreUtils qw( first_index uniq ); use Scalar::Util qw( blessed ); use Data::Dumper; use Date::Format; @@ -329,6 +330,8 @@ if ( -e $addl_handler_use_file ) { use FS::agent_pkg_class; use FS::svc_export_machine; use FS::GeocodeCache; + use FS::log; + use FS::log_context; # Sammath Naur if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 9eb59a09a..172ac8296 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -191,6 +191,7 @@ sub dbdef_dist { foreach my $table ( grep { ! /^clientapi_session/ && ! /^h_/ + && ! /^log(_context)?$/ && ! $tables_hashref_torrus->{$_} } $dbdef->tables @@ -3972,6 +3973,32 @@ sub tables_hashref { 'index' => [], }, + 'log' => { + 'columns' => [ + 'lognum', 'serial', '', '', '', '', + '_date', 'int', '', '', '', '', + 'agentnum', 'int', 'NULL', '', '', '', + 'tablename', 'varchar', 'NULL', $char_d, '', '', + 'tablenum', 'int', 'NULL', '', '', '', + 'level', 'int', '', '', '', '', + 'message', 'text', '', '', '', '', + ], + 'primary_key' => 'lognum', + 'unique' => [], + 'index' => [ ['_date'], ['level'] ], + }, + + 'log_context' => { + 'columns' => [ + 'logcontextnum', 'serial', '', '', '', '', + 'lognum', 'int', '', '', '', '', + 'context', 'varchar', '', 32, '', '', + ], + 'primary_key' => 'logcontextnum', + 'unique' => [ [ 'lognum', 'context' ] ], + 'index' => [], + }, + %{ tables_hashref_torrus() }, # tables of ours for doing torrus virtual port combining diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index 11247a28f..3dc8f9cad 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -21,6 +21,7 @@ use FS::cust_bill_pkg_tax_rate_location; use FS::part_event; use FS::part_event_condition; use FS::pkg_category; +use FS::Log; # 1 is mostly method/subroutine entry and options # 2 traces progress of some operations @@ -104,6 +105,9 @@ options of those methods are also available. sub bill_and_collect { my( $self, %options ) = @_; + my $log = FS::Log->new('bill_and_collect'); + $log->debug('start', object => $self, agentnum => $self->agentnum); + my $error; #$options{actual_time} not $options{time} because freeside-daily -d is for @@ -168,6 +172,7 @@ sub bill_and_collect { } } $job->update_statustext('100,finished') if $job; + $log->debug('finish', object => $self, agentnum => $self->agentnum); ''; diff --git a/FS/FS/log.pm b/FS/FS/log.pm new file mode 100644 index 000000000..a4ad214d0 --- /dev/null +++ b/FS/FS/log.pm @@ -0,0 +1,354 @@ +package FS::log; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs dbdef ); +use FS::UID qw( dbh driver_name ); +use FS::log_context; + +=head1 NAME + +FS::log - Object methods for log records + +=head1 SYNOPSIS + + use FS::log; + + $record = new FS::log \%hash; + $record = new FS::log { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::log object represents a log entry. FS::log inherits from +FS::Record. The following fields are currently supported: + +=over 4 + +=item lognum - primary key + +=item _date - Unix timestamp + +=item agentnum - L to which the log pertains. If it involves a +specific customer, package, service, invoice, or other agent-specific object, +this will be set to that agentnum. + +=item tablename - table name to which the log pertains, if any. + +=item tablenum - foreign key to that table. + +=item level - log level: 'debug', 'info', 'notice', 'warning', 'error', +'critical', 'alert', 'emergency'. + +=item message - contents of the log entry + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new log entry. Use FS::Log instead of calling this directly, +please. + +=cut + +sub table { 'log'; } + +=item insert [ CONTEXT... ] + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +CONTEXT may be a list of context tags to attach to this record. + +=cut + +sub insert { + # not using process_o2m for this, because we don't have a web interface + my $self = shift; + my $error = $self->SUPER::insert; + return $error if $error; + foreach ( @_ ) { + my $context = FS::log_context->new({ + 'lognum' => $self->lognum, + 'context' => $_ + }); + $error = $context->insert; + return $error if $error; + } + ''; +} + +# the insert method can be inherited from FS::Record + +sub delete { die "Log entries can't be modified." }; + +sub replace { die "Log entries can't be modified." }; + +=item check + +Checks all fields to make sure this is a valid example. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('lognum') + || $self->ut_number('_date') + || $self->ut_numbern('agentnum') + || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum') + || $self->ut_textn('tablename') + || $self->ut_numbern('tablenum') + || $self->ut_number('level') + || $self->ut_text('message') + ; + return $error if $error; + + if ( my $tablename = $self->tablename ) { + my $dbdef_table = dbdef->table($tablename) + or return "tablename '$tablename' does not exist"; + $error = $self->ut_foreign_key('tablenum', + $tablename, + $dbdef_table->primary_key); + return $error if $error; + } + + $self->SUPER::check; +} + +=item context + +Returns the context for this log entry, as an array, from least to most +specific. + +=cut + +sub context { + my $self = shift; + map { $_->context } qsearch({ + table => 'log_context', + hashref => { lognum => $self->lognum }, + order_by => 'ORDER BY logcontextnum ASC', + }); +} + +=back + +=head1 CLASS METHODS + +=over 4 + +=item search HASHREF + +Returns a qsearch hash expression to search for parameters specified in +HASHREF. Valid parameters are: + +=over 4 + +=item agentnum + +=item date - arrayref of start and end date + +=item level - either a specific level, or an arrayref of min and max level + +=item context - a context string that the log entry must have. This may +change in the future to allow searching for combinations of context strings. + +=item object - any database object, to find log entries related to it. + +=item tablename, tablenum - alternate way of specifying 'object'. + +=item custnum - a customer number, to find log entries related to the customer +or any of their subordinate objects (invoices, packages, etc.). + +=item message - a text string to search in messages. The search will be +a case-insensitive LIKE with % appended at both ends. + +=back + +=cut + +# used for custnum search: all tables with custnums +my @table_stubs; + +sub _setup_table_stubs { + foreach my $table ( + qw( + contact + cust_attachment + cust_bill + cust_credit + cust_location + cust_main + cust_main_exemption + cust_main_note + cust_msg + cust_pay + cust_pay_batch + cust_pay_pending + cust_pay_void + cust_pkg + cust_refund + cust_statement + cust_tag + cust_tax_adjustment + cust_tax_exempt + did_order_item + qual + queue ) ) + { + my $pkey = dbdef->table($table)->primary_key; + push @table_stubs, + "log.tablename = '$table' AND ". + "EXISTS(SELECT 1 FROM $table WHERE log.tablenum = $table.$pkey AND ". + "$table.custnum = "; # needs a closing ) + } + # plus this case + push @table_stubs, + "(log.tablename LIKE 'svc_%' OR log.tablename = 'cust_svc') AND ". + "EXISTS(SELECT 1 FROM cust_svc JOIN cust_pkg USING (svcnum) WHERE ". + "cust_pkg.custnum = "; # needs a closing ) +} + +sub search { + my ($class, $params) = @_; + my @where; + + ## + # parse agent + ## + + if ( $params->{'agentnum'} =~ /^(\d+)$/ ) { + push @where, + "log.agentnum = $1"; + } + + ## + # parse custnum + ## + + if ( $params->{'custnum'} =~ /^(\d+)$/ ) { + _setup_table_stubs() unless @table_stubs; + my $custnum = $1; + my @orwhere = map { "( $_ $custnum) )" } @table_stubs; + push @where, join(' OR ', @orwhere); + } + + ## + # parse level + ## + + if ( ref $params->{'level'} eq 'ARRAY' ) { + my ($min, $max) = @{ $params->{'level'} }; + if ( $min =~ /^\d+$/ ) { + push @where, "log.level >= $min"; + } + if ( $max =~ /^\d+$/ ) { + push @where, "log.level <= $max"; + } + } elsif ( $params->{'level'} =~ /^(\d+)$/ ) { + push @where, "log.level = $1"; + } + + ## + # parse date + ## + + if ( ref $params->{'date'} eq 'ARRAY' ) { + my ($beg, $end) = @{ $params->{'date'} }; + if ( $beg =~ /^\d+$/ ) { + push @where, "log._date >= $beg"; + } + if ( $end =~ /^\d+$/ ) { + push @where, "log._date <= $end"; + } + } + + ## + # parse object + ## + + if ( $params->{'object'} and $params->{'object'}->isa('FS::Record') ) { + my $table = $params->{'object'}->table; + my $pkey = dbdef->table($table)->primary_key; + my $tablenum = $params->{'object'}->get($pkey); + if ( $table and $tablenum ) { + push @where, "log.tablename = '$table'", "log.tablenum = $tablenum"; + } + } elsif ( $params->{'tablename'} =~ /^(\w+)$/ ) { + my $table = $1; + if ( $params->{'tablenum'} =~ /^(\d+)$/ ) { + push @where, "log.tablename = '$table'", "log.tablenum = $1"; + } + } + + ## + # parse message + ## + + if ( $params->{'message'} ) { # can be anything, really, so escape it + my $quoted_message = dbh->quote('%' . $params->{'message'} . '%'); + my $op = (driver_name eq 'Pg' ? 'ILIKE' : 'LIKE'); + push @where, "log.message $op $quoted_message"; + } + + ## + # parse context + ## + + if ( $params->{'context'} ) { + my $quoted = dbh->quote($params->{'context'}); + push @where, + "EXISTS(SELECT 1 FROM log_context WHERE log.lognum = log_context.lognum ". + "AND log_context.context = $quoted)"; + } + + # agent virtualization + my $access_user = $FS::CurrentUser::CurrentUser; + push @where, $access_user->agentnums_sql( + table => 'log', + viewall_right => 'Configuration', + null => 1, + ); + + # put it together + my $extra_sql = ''; + $extra_sql .= 'WHERE ' . join(' AND ', @where) if @where; + my $count_query = 'SELECT COUNT(*) FROM log '.$extra_sql; + my $sql_query = { + 'table' => 'log', + 'hashref' => {}, + 'select' => 'log.*', + 'extra_sql' => $extra_sql, + 'count_query' => $count_query, + 'order_by' => 'ORDER BY _date ASC', + #addl_from, not needed + }; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/log_context.pm b/FS/FS/log_context.pm new file mode 100644 index 000000000..372bdaa39 --- /dev/null +++ b/FS/FS/log_context.pm @@ -0,0 +1,145 @@ +package FS::log_context; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs ); + +my @contexts = ( qw( + test + bill_and_collect + Cron::bill + Cron::upload + spool_upload + daily + queue +) ); + +=head1 NAME + +FS::log_context - Object methods for log_context records + +=head1 SYNOPSIS + + use FS::log_context; + + $record = new FS::log_context \%hash; + $record = new FS::log_context { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::log_context object represents a context tag attached to a log entry +(L). FS::log_context inherits from FS::Record. The following +fields are currently supported: + +=over 4 + +=item logcontextnum - primary key + +=item lognum - lognum (L foreign key) + +=item context - context + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new context tag. To add the example to the database, see +L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'log_context'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid example. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +# the check method should currently be supplied - FS::Record contains some +# data checking routines + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('logcontextnum') + || $self->ut_number('lognum') + || $self->ut_enum('context', \@contexts) + ; + return $error if $error; + + $self->SUPER::check; +} + +=back + +=head1 CLASS METHODS + +=over 4 + +=item contexts + +Returns a list of all valid contexts. + +=cut + +sub contexts { @contexts } + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 9c444be58..f954fe8dd 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -675,3 +675,7 @@ FS/svc_export_machine.pm t/svc_export_machine.t FS/GeocodeCache.pm t/GeocodeCache.t +FS/log.pm +t/log.t +FS/log_context.pm +t/log_context.t diff --git a/FS/bin/freeside-daily b/FS/bin/freeside-daily index 8e8ae4ff9..65e3ebd97 100755 --- a/FS/bin/freeside-daily +++ b/FS/bin/freeside-daily @@ -4,6 +4,7 @@ use strict; use Getopt::Std; use FS::UID qw(adminsuidsetup); use FS::Conf; +use FS::Log; &untaint_argv; #what it sounds like (eww) use vars qw(%opt); @@ -11,6 +12,8 @@ getopts("p:a:d:vl:sy:nmrkg:o", \%opt); my $user = shift or die &usage; adminsuidsetup $user; +my $log = FS::Log->new('daily'); +$log->info('start'); #you can skip this by not having a NetworkMonitoringSystem configured use FS::Cron::nms_report qw(nms_report); @@ -74,6 +77,8 @@ unlink <${deldir}.CGItemp*>; use FS::Cron::backup qw(backup); backup(); +$log->info('finish'); + ### # subroutines ### diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued index f136c3910..2fd80255e 100644 --- a/FS/bin/freeside-queued +++ b/FS/bin/freeside-queued @@ -11,6 +11,7 @@ use FS::Conf; use FS::Record qw(qsearch); use FS::queue; use FS::queue_depend; +use FS::Log; # no autoloading for non-FS classes... use Net::SSH 0.07; @@ -45,6 +46,7 @@ while ( $@ ) { } } +my $log = FS::Log->new('queue'); logfile( "%%%FREESIDE_LOG%%%/queuelog.". $FS::UID::datasrc ); warn "completing daemonization (detaching))\n" if $DEBUG; @@ -135,6 +137,8 @@ while (1) { foreach my $job ( @jobs ) { + $log->debug('locking queue job', object => $job); + my %hash = $job->hash; $hash{'status'} = 'locked'; my $ljob = new FS::queue ( \%hash ); @@ -205,6 +209,8 @@ while (1) { } my $eval = "&". $ljob->job. '(@args);'; + # don't put @args in the log, may expose passwords + $log->info('starting job ('.$ljob->job.')'); warn 'running "&'. $ljob->job. '('. join(', ', @args). ")\n" if $DEBUG; eval $eval; #throw away return value? suppose so if ( $@ ) { diff --git a/FS/t/log.t b/FS/t/log.t new file mode 100644 index 000000000..42c604b88 --- /dev/null +++ b/FS/t/log.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::log; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/log_context.t b/FS/t/log_context.t new file mode 100644 index 000000000..57c3b340b --- /dev/null +++ b/FS/t/log_context.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::log_context; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index bfbc179b9..66e8bf669 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -346,6 +346,14 @@ if($curuser->access_right('Financial reports')) { } # else $report_financial contains nothing. +tie my %report_logs, 'Tie::IxHash'; + $report_logs{'System log'} = [ $fsurl.'search/log.html', 'View system events and debugging information.' ], + if $curuser->access_right('View system logs') + || $curuser->access_right('Configuration'); + $report_logs{'Outgoing messages'} = [ $fsurl.'search/cust_msg.html', 'View outgoing message log' ] + if $curuser->access_right('View email logs') + || $curuser->access_right('Configuration'); + tie my %report_menu, 'Tie::IxHash'; $report_menu{'Prospects'} = [ \%report_prospects, 'Prospect reports' ] if $curuser->access_right('List prospects'); @@ -375,6 +383,8 @@ $report_menu{'Billing events'} = [ \%report_bill_event, 'Billing events' ] $report_menu{'Financial'} = [ \%report_financial, 'Financial reports' ] if $curuser->access_right('Financial reports') or $curuser->access_right('Receivables report'); +$report_menu{'Logs'} = [ \%report_logs, 'System and email logs' ] + if (keys %report_logs); # empty if the user has no rights to it $report_menu{'SQL Query'} = [ $fsurl.'search/report_sql.html', 'SQL Query' ] if $curuser->access_right('Raw SQL'); @@ -440,8 +450,6 @@ $tools_menu{'Time Queue'} = [ $fsurl.'search/report_timeworked.html', 'View pen if $curuser->access_right('Time queue'); $tools_menu{'Attachments'} = [ $fsurl.'browse/cust_attachment.html', 'View customer attachments' ] if !$conf->config('disable_cust_attachment') and $curuser->access_right('View attachments') and $curuser->access_right('Browse attachments'); -$tools_menu{'Outgoing messages'} = [ $fsurl.'search/cust_msg.html', 'View outgoing message log' ] #shouldn't this be in the reports menu? - if $curuser->access_right('View email logs'); $tools_menu{'Importing'} = [ \%tools_importing, 'Import tools' ] if $curuser->access_right('Import'); $tools_menu{'Exporting'} = [ \%tools_exporting, 'Export tools' ] diff --git a/httemplate/search/elements/search-html.html b/httemplate/search/elements/search-html.html index 5c8001fad..7ccf356ea 100644 --- a/httemplate/search/elements/search-html.html +++ b/httemplate/search/elements/search-html.html @@ -259,6 +259,7 @@ % % my $links = $opt{'links'} ? [ @{$opt{'links'}} ] : ''; % my $onclicks = $opt{'link_onclicks'} ? [ @{$opt{'link_onclicks'}} ] : []; +% my $tooltips = $opt{'tooltips'} ? [ @{$opt{'tooltips'}} ] : []; % my $aligns = $opt{'align'} ? [ @{$opt{'align'}} ] : ''; % my $colors = $opt{'color'} ? [ @{$opt{'color'}} ] : []; % my $sizes = $opt{'size'} ? [ @{$opt{'size'}} ] : []; @@ -360,6 +361,7 @@ % if ( $links ) { % my $link = shift @$links; % my $onclick = shift @$onclicks; +% my $tooltip = shift @$tooltips; % % if ( ! $opt{'agent_virt'} % || ( $null_link && ! $row->agentnum ) @@ -374,6 +376,14 @@ % if ref($onclick) eq 'CODE'; % $onclick = qq( onClick="$onclick") if $onclick; % +% $tooltip = &{$tooltip}($row) +% if ref($tooltip) eq 'CODE'; +% $tooltip = qq! id="a$id" !. +% qq! onmouseover="return overlib(!. +% $m->interp->apply_escapes($tooltip, 'h', 'js_string'). +% qq!, FGCLASS, 'tooltip', REF, 'a$id', !. +% qq!REFC, 'LL', REFP, 'UL')"! if $tooltip; +% % if ( $link ) { % my( $url, $method ) = @{$link}; % if ( ref($method) eq 'CODE' ) { @@ -381,11 +391,16 @@ % } else { % $a = $url. $row->$method(); % } -% $a = qq(); +% $a = qq(); % } % elsif ( $onclick ) { % $a = qq(); % } +% elsif ( $tooltip ) { +% $a = qq(); +% } +% $id++; + % } % % } @@ -499,4 +514,5 @@ $count_sth->execute my $count_arrayref = $count_sth->fetchrow_arrayref; my $total = $count_arrayref->[0]; +my $id = 0; diff --git a/httemplate/search/log.html b/httemplate/search/log.html new file mode 100644 index 000000000..d1bfb6cc9 --- /dev/null +++ b/httemplate/search/log.html @@ -0,0 +1,221 @@ +<& elements/search.html, + 'title' => 'System Log', + 'name_singular' => 'event', + 'html_init' => include('.head'), + 'query' => $query, + 'count_query' => $count_query, + 'header' => [ #'#', # lognum, probably not useful + 'Date', + 'Level', + 'Context', + 'Applies To', + 'Message', + ], + 'fields' => [ #'lognum', + $date_sub, + $level_sub, + $context_sub, + $object_sub, + $message_sub, + ], + 'sort_fields' => [ + '_date', + 'level', + '', + 'tablename,tablenum', + 'message', + ], + 'links' => [ + '', #date + '', #level + '', #context + $object_link_sub, + '', #message + ], + 'tooltips' => [ + '', #date + '', #level + $tt_sub, + '', #object + $tt_sub, + ], + 'color' => [ + $color_sub, + $color_sub, + '', + '', + '', + ], + # aligns + 'download_label' => 'Download this log', +&>\ +<%def .head> + +
+ + + + + + + + + + + + +
From + <& /elements/input-date-field.html, { + name => 'beginning', + value => $cgi->param('beginning'), + } &> + To + <& /elements/input-date-field.html, { + name => 'ending', + value => $cgi->param('ending') || '', + noinit => 1, + } &> +
Level + <& /elements/select.html, + field => 'min_level', + options => [ 0..7 ], + labels => { map {$_ => $FS::Log::LEVELS[$_]} 0..7 }, + curr_value => $cgi->param('min_level'), + &> + to + <& /elements/select.html, + field => 'max_level', + options => [ 0..7 ], + labels => { map {$_ => $FS::Log::LEVELS[$_]} 0..7 }, + curr_value => $cgi->param('max_level'), + &> + + Context + <& /elements/select.html, + field => 'context', + options => \@contexts, + labels => { map {$_, $_} @contexts }, + curr_value => ($cgi->param('context') || ''), + &> +
+ Containing text + <& /elements/input-text.html, + field => 'message', + size => 30, + size => 30, + curr_value => ($cgi->param('message') || ''), + &> +
+ +
+
+ +<%once> +my $date_sub = sub { time2str('%Y-%m-%d %T', $_[0]->_date) }; + +my $level_sub = sub { $FS::Log::LEVELS[$_[0]->level] }; + +my $context_sub = sub { + my $log = shift; + ($log->context)[-1] . (scalar($log->context) > 1 ? '...' : '') ; + # XXX find a way to make this use less space (dropdown?) +}; + +my $tt_sub = sub { + my $log = shift; + my @context = $log->context; + # don't create a tooltip if there's only one context entry and the + # message isn't cut off + return '' if @context == 1 and length($log->message) <= 60; + my $html = '
'.(shift @context).'
'; + my $pre = '↳'; + foreach (@context, $log->message) { + $html .= "
$pre$_
"; + $pre = '   '.$pre; + } + $html; +}; + +my $object_sub = sub { + my $log = shift; + return '' unless $log->tablename; + # this is a sysadmin log; anyone reading it should be able to understand + # 'cust_main #2319' with no trouble. + $log->tablename . ' #' . $log->tablenum; +}; + +my $message_sub = sub { + my $log = shift; + my $message = $log->message; + if ( length($message) > 60 ) { # pretty arbitrary + $message = substr($message, 0, 57) . '...'; + } + $message; +}; + +my $object_link_sub = sub { + my $log = shift; + my $table = $log->tablename or return; + # sigh + if ( grep {$_ eq $table} (qw( cust_bill cust_main cust_pkg cust_svc )) + or $table =~ /^svc_/ ) + { + + return [ $fsurl.'view/'.$table.'.cgi?'. $log->tablenum ]; + + } elsif ( grep {$_ eq $table} (qw( cust_msg cust_pay cust_pay_void + cust_refund cust_statement )) ) + { + + return [ $fsurl.'view/'.$table.'.html?', $log->tablenum ]; + + } else { # you're on your own + + return ''; + + } +}; + +my @colors = ( + '404040', #debug + '0000aa', #info + '00aa00', #notice + 'aa0066', #warning + '000000', #error + 'aa0000', #critical + 'ff0000', #alert + 'ff0000', #emergency +); + +my $color_sub = sub { $colors[ $_[0]->level ]; }; + +my @contexts = ('', sort FS::log_context->contexts); + +<%init> +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" + unless $curuser->access_right([ 'View system logs', 'Configuration' ]); + +$cgi->param('min_level', 0) unless defined($cgi->param('min_level')); +$cgi->param('max_level', 7) unless defined($cgi->param('max_level')); + +my %search = (); +$search{'date'} = [ FS::UI::Web::parse_beginning_ending($cgi) ]; +$search{'level'} = [ $cgi->param('min_level'), $cgi->param('max_level') ]; +foreach my $param (qw(agentnum context tablename tablenum custnum message)) { + if ( $cgi->param($param) ) { + $search{$param} = $cgi->param($param); + } +} +my $query = FS::log->search(\%search); # validates everything +my $count_query = delete $query->{'count_query'}; + + -- cgit v1.2.1 From a06daa0f58bed99f929b5092af9dcd381d0f0acb Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 11 Dec 2012 16:34:21 -0800 Subject: create credits by selecting line items, RT#18676 --- httemplate/edit/process/credit-cust_bill_pkg.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/httemplate/edit/process/credit-cust_bill_pkg.html b/httemplate/edit/process/credit-cust_bill_pkg.html index d3323e6ed..8b2f3f3ea 100644 --- a/httemplate/edit/process/credit-cust_bill_pkg.html +++ b/httemplate/edit/process/credit-cust_bill_pkg.html @@ -28,11 +28,14 @@ foreach my $billpkgnum_setuprecur (@billpkgnum_setuprecurs) { } my $error = FS::cust_credit->credit_lineitems( - 'newreasonnum' => scalar($cgi->param('newreasonnum')), - 'newreasonnum_type' => scalar($cgi->param('newreasonnumT')), + #the lineitems to credit 'billpkgnums' => \@billpkgnums, 'setuprecurs' => \@setuprecurs, 'amounts' => \@amounts, + + #the credit + 'newreasonnum' => scalar($cgi->param('newreasonnum')), + 'newreasonnum_type' => scalar($cgi->param('newreasonnumT')), map { $_ => scalar($cgi->param($_)) } #fields('cust_credit') qw( custnum _date amount reason reasonnum addlinfo ), #pkgnum eventnum -- cgit v1.2.1 From 85a507e3558db3663401f3ed294077a4888270c5 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 11 Dec 2012 19:42:24 -0800 Subject: promo code form, RT#20582 --- fs_selfservice/FS-SelfService/cgi/promocode.html | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/fs_selfservice/FS-SelfService/cgi/promocode.html b/fs_selfservice/FS-SelfService/cgi/promocode.html index f8ee7f6eb..0962d44b5 100644 --- a/fs_selfservice/FS-SelfService/cgi/promocode.html +++ b/fs_selfservice/FS-SelfService/cgi/promocode.html @@ -1,13 +1,8 @@ ISP Signup ISP Signup - promotional code

- - + Enter promotional code - + -- cgit v1.2.1 From d7678b9b97068dcd352f0ea101c6c8d02ae330d6 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 12 Dec 2012 10:19:25 -0800 Subject: whitespace --- fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index 61361b8ee..de0ab1a76 100755 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -843,7 +843,7 @@ sub real_port_graph { 'session_id' => $session_id, 'svcnum' => $svcnum, 'beginning' => str2time($cgi->param('start')." 00:00:00"), - 'ending' => str2time($cgi->param('end')." 23:59:59"), + 'ending' => str2time($cgi->param('end') ." 23:59:59"), ); my @usage = @{$res->{'usage'}}; my $png = $usage[0]->{'png'}; -- cgit v1.2.1 From 84f2df8931fa02e63fb21f8f0bb87dd9577b8919 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 12 Dec 2012 10:26:29 -0800 Subject: rt 4.0.8 --- rt/Makefile.in | 1 + rt/configure | 25 +- rt/configure.ac | 1 + rt/devel/tools/apache.conf | 173 ------------ rt/docs/UPGRADING-2.0 | 6 +- rt/docs/UPGRADING-3.0 | 10 +- rt/docs/UPGRADING-3.2 | 15 +- rt/docs/UPGRADING-3.4 | 11 +- rt/docs/UPGRADING-3.6 | 50 ++-- rt/docs/UPGRADING-3.8 | 191 +++++++------ rt/docs/UPGRADING-4.0 | 165 ++++++----- rt/docs/UPGRADING.mysql | 175 ++++++++---- rt/etc/RT_Config.pm.in | 13 +- rt/etc/upgrade/3.8.4/content | 2 +- rt/lib/RT/Action/SendEmail.pm | 54 ++-- rt/lib/RT/Approval/Rule/Passed.pm | 11 +- rt/lib/RT/Article.pm | 2 +- rt/lib/RT/Attachment.pm | 49 +++- rt/lib/RT/Crypt/GnuPG.pm | 27 +- rt/lib/RT/Generated.pm | 2 +- rt/lib/RT/Handle.pm | 30 +- rt/lib/RT/Interface/Email.pm | 52 ++-- rt/lib/RT/Interface/Email/Auth/GnuPG.pm | 3 +- rt/lib/RT/Interface/Web.pm | 117 ++++++-- rt/lib/RT/Interface/Web/Menu.pm | 11 +- rt/lib/RT/Pod/HTML.pm | 66 +++++ rt/lib/RT/Pod/HTMLBatch.pm | 131 +++++++++ rt/lib/RT/Pod/Search.pm | 15 + rt/lib/RT/Queue.pm | 40 ++- rt/lib/RT/Record.pm | 35 +++ rt/lib/RT/Template.pm | 1 + rt/lib/RT/Ticket.pm | 10 +- rt/lib/RT/User.pm | 1 + rt/sbin/rt-fulltext-indexer | 5 + rt/sbin/rt-fulltext-indexer.in | 5 + rt/sbin/rt-test-dependencies.in | 7 + rt/sbin/rt-validate-aliases.in | 343 +++++++++++++++++++++++ rt/share/html/Admin/Groups/Modify.html | 5 +- rt/share/html/Admin/Queues/Modify.html | 6 +- rt/share/html/Admin/Users/GnuPG.html | 15 +- rt/share/html/Elements/CSRF | 6 +- rt/share/html/Elements/GnuPG/SignEncryptWidget | 10 +- rt/share/html/Elements/Login | 2 + rt/share/html/Elements/LoginRedirectWarning | 20 ++ rt/share/html/Elements/Tabs | 1 + rt/share/html/NoAuth/css/base/login.css | 8 + rt/share/html/NoAuth/iCal/dhandler | 2 +- rt/share/html/Ticket/Elements/ShowMessageHeaders | 5 + rt/t/mail/gnupg-incoming.t | 41 ++- rt/t/web/crypt-gnupg.t | 27 +- rt/t/web/ticket_forward.t | 6 +- 51 files changed, 1393 insertions(+), 616 deletions(-) delete mode 100644 rt/devel/tools/apache.conf create mode 100644 rt/lib/RT/Pod/HTML.pm create mode 100644 rt/lib/RT/Pod/HTMLBatch.pm create mode 100644 rt/lib/RT/Pod/Search.pm create mode 100644 rt/sbin/rt-validate-aliases.in create mode 100644 rt/share/html/Elements/LoginRedirectWarning diff --git a/rt/Makefile.in b/rt/Makefile.in index b415a06db..fbe3fae9f 100644 --- a/rt/Makefile.in +++ b/rt/Makefile.in @@ -157,6 +157,7 @@ SYSTEM_BINARIES = rt-attributes-viewer \ rt-shredder \ rt-test-dependencies \ rt-validator \ + rt-validate-aliases \ standalone_httpd diff --git a/rt/configure b/rt/configure index 76ef85b92..caf3967a2 100755 --- a/rt/configure +++ b/rt/configure @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for RT rt-4.0.7. +# Generated by GNU Autoconf 2.68 for RT rt-4.0.8. # # Report bugs to . # @@ -560,8 +560,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='RT' PACKAGE_TARNAME='rt' -PACKAGE_VERSION='rt-4.0.7' -PACKAGE_STRING='RT rt-4.0.7' +PACKAGE_VERSION='rt-4.0.8' +PACKAGE_STRING='RT rt-4.0.8' PACKAGE_BUGREPORT='rt-bugs@bestpractical.com' PACKAGE_URL='' @@ -1311,7 +1311,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures RT rt-4.0.7 to adapt to many kinds of systems. +\`configure' configures RT rt-4.0.8 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1372,7 +1372,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of RT rt-4.0.7:";; + short | recursive ) echo "Configuration of RT rt-4.0.8:";; esac cat <<\_ACEOF @@ -1496,7 +1496,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -RT configure rt-4.0.7 +RT configure rt-4.0.8 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1597,7 +1597,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by RT $as_me rt-4.0.7, which was +It was created by RT $as_me rt-4.0.8, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -1954,7 +1954,7 @@ rt_version_major=4 rt_version_minor=0 -rt_version_patch=7 +rt_version_patch=8 test "x$rt_version_major" = 'x' && rt_version_major=0 test "x$rt_version_minor" = 'x' && rt_version_minor=0 @@ -3923,7 +3923,7 @@ RT_LOG_PATH_R=${exp_logfiledir} fi -ac_config_files="$ac_config_files etc/upgrade/3.8-branded-queues-extension etc/upgrade/3.8-ical-extension etc/upgrade/split-out-cf-categories etc/upgrade/generate-rtaddressregexp etc/upgrade/upgrade-articles etc/upgrade/vulnerable-passwords sbin/rt-attributes-viewer sbin/rt-preferences-viewer sbin/rt-session-viewer sbin/rt-dump-metadata sbin/rt-setup-database sbin/rt-test-dependencies sbin/rt-email-digest sbin/rt-email-dashboards sbin/rt-clean-sessions sbin/rt-shredder sbin/rt-validator sbin/rt-email-group-admin sbin/rt-server sbin/rt-server.fcgi sbin/standalone_httpd sbin/rt-setup-fulltext-index sbin/rt-fulltext-indexer bin/rt-crontool bin/rt-mailgate bin/rt" +ac_config_files="$ac_config_files etc/upgrade/3.8-branded-queues-extension etc/upgrade/3.8-ical-extension etc/upgrade/split-out-cf-categories etc/upgrade/generate-rtaddressregexp etc/upgrade/upgrade-articles etc/upgrade/vulnerable-passwords sbin/rt-attributes-viewer sbin/rt-preferences-viewer sbin/rt-session-viewer sbin/rt-dump-metadata sbin/rt-setup-database sbin/rt-test-dependencies sbin/rt-email-digest sbin/rt-email-dashboards sbin/rt-clean-sessions sbin/rt-shredder sbin/rt-validator sbin/rt-validate-aliases sbin/rt-email-group-admin sbin/rt-server sbin/rt-server.fcgi sbin/standalone_httpd sbin/rt-setup-fulltext-index sbin/rt-fulltext-indexer bin/rt-crontool bin/rt-mailgate bin/rt" ac_config_files="$ac_config_files Makefile etc/RT_Config.pm lib/RT/Generated.pm t/data/configs/apache2.2+mod_perl.conf t/data/configs/apache2.2+fastcgi.conf" @@ -4482,7 +4482,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by RT $as_me rt-4.0.7, which was +This file was extended by RT $as_me rt-4.0.8, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4535,7 +4535,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -RT config.status rt-4.0.7 +RT config.status rt-4.0.8 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" @@ -4663,6 +4663,7 @@ do "sbin/rt-clean-sessions") CONFIG_FILES="$CONFIG_FILES sbin/rt-clean-sessions" ;; "sbin/rt-shredder") CONFIG_FILES="$CONFIG_FILES sbin/rt-shredder" ;; "sbin/rt-validator") CONFIG_FILES="$CONFIG_FILES sbin/rt-validator" ;; + "sbin/rt-validate-aliases") CONFIG_FILES="$CONFIG_FILES sbin/rt-validate-aliases" ;; "sbin/rt-email-group-admin") CONFIG_FILES="$CONFIG_FILES sbin/rt-email-group-admin" ;; "sbin/rt-server") CONFIG_FILES="$CONFIG_FILES sbin/rt-server" ;; "sbin/rt-server.fcgi") CONFIG_FILES="$CONFIG_FILES sbin/rt-server.fcgi" ;; @@ -5131,6 +5132,8 @@ which seems to be undefined. Please make sure it is defined" >&2;} ;; "sbin/rt-validator":F) chmod ug+x $ac_file ;; + "sbin/rt-validate-aliases":F) chmod ug+x $ac_file + ;; "sbin/rt-email-group-admin":F) chmod ug+x $ac_file ;; "sbin/rt-server":F) chmod ug+x $ac_file diff --git a/rt/configure.ac b/rt/configure.ac index be02a684e..a168e285c 100644 --- a/rt/configure.ac +++ b/rt/configure.ac @@ -425,6 +425,7 @@ AC_CONFIG_FILES([ sbin/rt-clean-sessions sbin/rt-shredder sbin/rt-validator + sbin/rt-validate-aliases sbin/rt-email-group-admin sbin/rt-server sbin/rt-server.fcgi diff --git a/rt/devel/tools/apache.conf b/rt/devel/tools/apache.conf deleted file mode 100644 index 2ae67c651..000000000 --- a/rt/devel/tools/apache.conf +++ /dev/null @@ -1,173 +0,0 @@ -# Single-process Apache testing with mod_perl, mod_fcgi, or mod_fastcgi -# -# Start this via: -# apache2 -f `pwd`/devel/tools/apache.conf -DPERL -k start -# -# The full path to the configuration file is needed, or Apache assumes -# it is under the ServerRoot. Since the deployment strategies differ -# between RT 3 and 4, you must either supply -DRT3 if you are attempting -# to deploy an rt3 instance. You must also supply one of -DPERL, -# -DFASTCGI, or -DFCGID. -# -# The /opt/rt4/etc/apache_local.conf file should contain: -# User chmrr -# Group chmrr -# Listen 8080 -# ...or the equivilent. -# -# Apache access and error logs will be written to /opt/rt4/var/log/. -# - -Include /opt/rt4/etc/apache_local.conf - - -Include /opt/rt3/etc/apache_local.conf - - - - StartServers 1 - MinSpareServers 1 - MaxSpareServers 1 - MaxClients 1 - MaxRequestsPerChild 0 - - - - StartServers 1 - MinSpareThreads 1 - MaxSpareThreads 1 - ThreadLimit 1 - ThreadsPerChild 1 - MaxClients 1 - MaxRequestsPerChild 0 - - -ServerRoot /etc/apache2 -PidFile /opt/rt4/var/apache2.pid -LockFile /opt/rt4/var/apache2.lock -ServerAdmin root@localhost - -LoadModule authz_host_module /usr/lib/apache2/modules/mod_authz_host.so -LoadModule env_module /usr/lib/apache2/modules/mod_env.so -LoadModule alias_module /usr/lib/apache2/modules/mod_alias.so -LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so - - LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so - - - LoadModule fastcgi_module /usr/lib/apache2/modules/mod_fastcgi.so - - - LoadModule fcgid_module /usr/lib/apache2/modules/mod_fcgid.so - - -ErrorLog "/opt/rt4/var/log/apache-error.log" -TransferLog "/opt/rt4/var/log/apache-access.log" -LogLevel debug - - - Options FollowSymLinks - AllowOverride None - Order deny,allow - Deny from all - - -AddDefaultCharset UTF-8 - -DocumentRoot /var/www - - Order allow,deny - Allow from all - - -Alias /NoAuth/images/ /opt/rt4/share/html/NoAuth/images/ - - Order allow,deny - Allow from all - - - -########## 4.0 mod_perl - - PerlSetEnv RT_SITE_CONFIG /opt/rt4/etc/RT_SiteConfig.pm - - Order allow,deny - Allow from all - SetHandler modperl - PerlResponseHandler Plack::Handler::Apache2 - PerlSetVar psgi_app /opt/rt4/sbin/rt-server - - - use Plack::Handler::Apache2; - Plack::Handler::Apache2->preload("/opt/rt4/sbin/rt-server"); - - - -########## 4.0 mod_fastcgi - - FastCgiIpcDir /opt/rt4/var - FastCgiServer /opt/rt4/sbin/rt-server.fcgi -processes 1 -idle-timeout 300 - ScriptAlias / /opt/rt4/sbin/rt-server.fcgi/ - - Order allow,deny - Allow from all - Options +ExecCGI - AddHandler fastcgi-script fcgi - - - -########## 4.0 mod_fcgid - - FcgidProcessTableFile /opt/rt4/var/fcgid_shm - FcgidIPCDir /opt/rt4/var - ScriptAlias / /opt/rt4/sbin/rt-server.fcgi/ - - Order allow,deny - Allow from all - Options +ExecCGI - AddHandler fcgid-script fcgi - - - - - - -########## 3.8 mod_perl - - PerlSetEnv RT_SITE_CONFIG /opt/rt3/etc/RT_SiteConfig.pm - PerlRequire "/opt/rt3/bin/webmux.pl" - - SetHandler default - - - SetHandler perl-script - PerlResponseHandler RT::Mason - - - -########## 3.8 mod_fastcgi - - FastCgiIpcDir /opt/rt3/var - FastCgiServer /opt/rt3/bin/mason_handler.fcgi -processes 1 -idle-timeout 300 - ScriptAlias / /opt/rt3/bin/mason_handler.fcgi/ - - Order allow,deny - Allow from all - Options +ExecCGI - AddHandler fastcgi-script fcgi - - - -########## 3.8 mod_fcgid - - FcgidProcessTableFile /opt/rt3/var/fcgid_shm - FcgidIPCDir /opt/rt3/var - ScriptAlias / /opt/rt3/bin/mason_handler.fcgi/ - - Order allow,deny - Allow from all - Options +ExecCGI - AddHandler fcgid-script fcgi - - - diff --git a/rt/docs/UPGRADING-2.0 b/rt/docs/UPGRADING-2.0 index a935552b5..792276f07 100644 --- a/rt/docs/UPGRADING-2.0 +++ b/rt/docs/UPGRADING-2.0 @@ -1,7 +1,7 @@ -UPGRADING FROM 2.x: +=head1 UPGRADING FROM 2.x -The core RT distribution does not contain the tool to upgrade RT from -version 2.0; the tool, can be downloaded from CPAN at +The core RT distribution does not contain the tool to upgrade RT from version +2.0; the tool, can be downloaded from CPAN at http://search.cpan.org/dist/RT-Extension-RT2toRT3/ Further instructions may be found in that distribution's README file. diff --git a/rt/docs/UPGRADING-3.0 b/rt/docs/UPGRADING-3.0 index 625ca4baf..1bc1b55d3 100644 --- a/rt/docs/UPGRADING-3.0 +++ b/rt/docs/UPGRADING-3.0 @@ -1,18 +1,20 @@ -UPGRADING FROM 3.0.x - Changes: +=head1 UPGRADING FROM 3.0.0 AND EARLIER -= Installation = +=head2 Installation We recommend you move your existing /opt/rt3 tree completely out of the way before installing the new version of RT, to make sure that you don't inadvertently leave old files hanging around. -= Rights changes = + +=head2 Rights changes Now, if you want RT to automatically create new users upon ticket submission, you MUST grant 'Everyone' the right to create tickets. Granting this right only to "Unprivileged Users" is now insufficient. -= Web server configuration + +=head2 Web server configuration The configuration for RT's web interface has changed. Please refer to docs/web_deployment.pod for instructions. diff --git a/rt/docs/UPGRADING-3.2 b/rt/docs/UPGRADING-3.2 index c0b8cebae..4641209e4 100644 --- a/rt/docs/UPGRADING-3.2 +++ b/rt/docs/UPGRADING-3.2 @@ -1,11 +1,10 @@ -UPGRADING FROM 3.2 and earlier - Changes: +=head1 UPGRADING FROM 3.2.0 AND EARLIER -= Rights changes = +There have been a number of rights changes. Now, if you want any user to be +able to access the Admin tools (a.k.a. the Configuration tab), you must grant +that user the "ShowConfigTab" right. Making the user a privileged user is no +longer sufficient. -Now, if you want any user to be able to access the Admin tools (a.k.a. -the Configuration tab), you must grant that user the "ShowConfigTab" -right. Making the user a privileged user is no longer sufficient. - -"SuperUser" users are no longer automatically added to the list of users -who can own tickets in a queue. You now need to explicitly give them the +"SuperUser" users are no longer automatically added to the list of users who +can own tickets in a queue. You now need to explicitly give them the "OwnTicket" right. diff --git a/rt/docs/UPGRADING-3.4 b/rt/docs/UPGRADING-3.4 index 4dca0451f..89454bdef 100644 --- a/rt/docs/UPGRADING-3.4 +++ b/rt/docs/UPGRADING-3.4 @@ -1,12 +1,11 @@ -UPGRADING FROM 3.3.14 and earlier - Changes: +=head1 UPGRADING FROM 3.3.14 AND EARLIER The "ModifyObjectCustomFieldValues" right name was too long. It has been changed to "ModifyCustomField" -UPGRADING FROM 3.3.11 and earlier - Changes: +=head1 UPGRADING FROM 3.3.11 AND EARLIER -Custom Fields now have an additional right, "ModifyCustomField". This -right governs whether a user can modify an object's custom field values -for a particular custom field. This includes adding, deleting and -changing values. +Custom Fields now have an additional right, "ModifyCustomField". This right +governs whether a user can modify an object's custom field values for a +particular custom field. This includes adding, deleting and changing values. diff --git a/rt/docs/UPGRADING-3.6 b/rt/docs/UPGRADING-3.6 index 3c27709cb..da656c9e5 100644 --- a/rt/docs/UPGRADING-3.6 +++ b/rt/docs/UPGRADING-3.6 @@ -1,29 +1,27 @@ -UPGRADING FROM 3.6.X and earlier - Changes: +=head1 UPGRADING FROM 3.6.0 AND EARLIER -As there are a large number of code changes, it is highly recommended -that you install RT into a fresh directory, and then reinstall your -customizations. +As there are a large number of code changes, it is highly recommended that you +install RT into a fresh directory, and then reinstall your customizations. -The database schema has changed significantly for mysql 4.1 and above; -please read UPGRADING.mysql for more details. +The database schema has changed significantly for mysql 4.1 and above; please +read UPGRADING.mysql for more details. -The configuration format has been made stricter. All options MUST be set -using the Set function; the historical "@XXX = (...) unless @XXX;" is no -longer allowed. +The configuration format has been made stricter. All options MUST be set using +the Set function; the historical "@XXX = (...) unless @XXX;" is no longer +allowed. The RTx::Shredder extension has been integrated into core, and several features have been added, so you MUST uninstall it before upgrading. -A new interface for making links in text clickable, and doing other -arbitrary text replacements, has been integrated into RT. You can read -more in `perldoc docs/extending/clickable_links.pod`. +A new interface for making links in text clickable, and doing other arbitrary +text replacements, has been integrated into RT. You can read more in `perldoc +docs/extending/clickable_links.pod`. -A new feature has been added that allows users to forward -messages. There is a new option in the config ($ForwardFromUser), new -rights, and a new template. +A new feature has been added that allows users to forward messages. There is a +new option in the config ($ForwardFromUser), new rights, and a new template. -New global templates have been added with "Error: " prefixed to the name -to make it possible to configure error messages sent to users. +New global templates have been added with "Error: " prefixed to the name to +make it possible to configure error messages sent to users. You can read about the new GnuPG integration in `perldoc lib/RT/Crypt/GnuPG.pm`. @@ -31,19 +29,19 @@ lib/RT/Crypt/GnuPG.pm`. New scrip conditions 'On Close' and 'On Reopen' have been added. -UPGRADING FROM 3.5.7 and earlier - Changes: +=head1 UPGRADING FROM 3.5.7 AND EARLIER Scrips are now prepared and committed in order alphanumerically by -description. This means that you can prepend a number (00, 07, 15, 24) -to the beginning of each scrip's description, and they will run in that -order. Depending on your database, the old ordering may have been by -scrip id number -- if that is the case, simply prepend the scrip id -number to the beginning of its description. +description. This means that you can prepend a number (00, 07, 15, 24) to the +beginning of each scrip's description, and they will run in that order. +Depending on your database, the old ordering may have been by scrip id number +-- if that is the case, simply prepend the scrip id number to the beginning of +its description. -UPGRADING FROM 3.5.1 and earlier - Changes: +=head1 UPGRADING FROM 3.5.1 AND EARLIER The default for $RedistributeAutoGeneratedMessages has changed to 'privileged', to make out-of-the-box installations more resistant to -mail loops. If you rely on the old default of redistributing to all -watchers, you'll need to set it explicitly now. +mail loops. If you rely on the old default of redistributing to all watchers, +you'll need to set it explicitly now. diff --git a/rt/docs/UPGRADING-3.8 b/rt/docs/UPGRADING-3.8 index cb53030e4..cfe01dfbf 100644 --- a/rt/docs/UPGRADING-3.8 +++ b/rt/docs/UPGRADING-3.8 @@ -1,110 +1,111 @@ -UPGRADING FROM 3.8.8 and earlier - Changes: +=head1 UPGRADING FROM 3.8.8 AND EARLIER -Previous versions of RT used a password hashing scheme which was too -easy to reverse, which could allow attackers with read access to the RT -database to possibly compromise users' passwords. Even if RT does no -password authentication itself, it may still store these weak password -hashes -- using ExternalAuth does not guarantee that you are not -vulnerable! To upgrade stored passwords to a stronger hash, run: +Previous versions of RT used a password hashing scheme which was too easy to +reverse, which could allow attackers with read access to the RT database to +possibly compromise users' passwords. Even if RT does no password +authentication itself, it may still store these weak password hashes -- using +ExternalAuth does not guarantee that you are not vulnerable! To upgrade +stored passwords to a stronger hash, run: perl etc/upgrade/vulnerable-passwords -We have also proved that it's possible to delete a notable set of -records from Transactions table without losing functionality. To delete -these records, run the following script: +We have also proved that it's possible to delete a notable set of records from +Transactions table without losing functionality. To delete these records, run +the following script: perl -I /opt/rt4/local/lib -I /opt/rt4/lib etc/upgrade/shrink_transactions_table.pl -If you chose not to run the shrink_cgm_table.pl script when you upgraded -to 3.8, you should read more about it below and run it at this point. +If you chose not to run the shrink_cgm_table.pl script when you upgraded to +3.8, you should read more about it below and run it at this point. -The default for $MessageBoxWrap is now SOFT and $MessageBoxWidth is now -unset by default. This means the message box will expand to fill all -the available width. $MessageBoxWrap is also overridable by the user -now. These changes accommodate the new default two column layout for -ticket create and update pages. You may turn this layout off by setting -$UseSideBySideLayout to 0. To retain the original behavior, set -$MessageBoxWrap to HARD and $MessageBoxWidth to 72. +The default for $MessageBoxWrap is now SOFT and $MessageBoxWidth is now unset +by default. This means the message box will expand to fill all the available +width. $MessageBoxWrap is also overridable by the user now. These changes +accommodate the new default two column layout for ticket create and update +pages. You may turn this layout off by setting $UseSideBySideLayout to 0. To +retain the original behavior, set $MessageBoxWrap to HARD and $MessageBoxWidth +to 72. -UPGRADING FROM 3.8.7 and earlier - Changes: +=head1 UPGRADING FROM 3.8.7 AND EARLIER -RT's ChartFont option has been changed from a string to a hash which -lets you specify per-language fonts. RT now comes with a better default -font for charts, too. You should either update your 'ChartFont' option -to match the new format, or consider trying the new default. +RT's ChartFont option has been changed from a string to a hash which lets you +specify per-language fonts. RT now comes with a better default font for +charts, too. You should either update your 'ChartFont' option to match the +new format, or consider trying the new default. -RT now gives you more precise control over the order in which custom -fields are displayed. This change requires some small changes to your -currently saved custom field orders. RT will automatically clean up -your existing custom fields when you run the standard database upgrade -steps. After that cleanup, you should make sure that custom fields are -ordered in a way that you and your users find pleasing. +RT now gives you more precise control over the order in which custom fields +are displayed. This change requires some small changes to your currently +saved custom field orders. RT will automatically clean up your existing +custom fields when you run the standard database upgrade steps. After that +cleanup, you should make sure that custom fields are ordered in a way that you +and your users find pleasing. -UPGRADING FROM 3.8.6 and earlier - Changes: +=head1 UPGRADING FROM 3.8.6 AND EARLIER -For MySQL and Oracle users: -If you upgraded from a version of RT earlier than 3.7.81, you should -already have a CachedGroupMembers3 index on your CachedGroupMembers -table. If you did a clean install of RT somewhere in the 3.8 release -series, you most likely don't have this index. You can add it manually -with: +For MySQL and Oracle users: if you upgraded from a version of RT earlier than +3.7.81, you should already have a CachedGroupMembers3 index on your +CachedGroupMembers table. If you did a clean install of RT somewhere in the +3.8 release series, you most likely don't have this index. You can add it +manually with: CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId, ImmediateParentId); -UPGRADING FROM 3.8.5 and earlier - Changes: +=head1 UPGRADING FROM 3.8.5 AND EARLIER You can now forward an entire Ticket history (in addition to specific -transactions) but this requires a new Template called "Forward Ticket". -This template will be added as part of the standard database upgrade -step. +transactions) but this requires a new Template called "Forward Ticket". This +template will be added as part of the standard database upgrade step. -Custom fields with categories can optionally be split out into -hierarchical custom fields. If you wish to convert your old -category-based custom fields, run: +Custom fields with categories can optionally be split out into hierarchical +custom fields. If you wish to convert your old category-based custom fields, +run: perl etc/upgrade/split-out-cf-categories -It will prompt you for each custom field with categories that it finds, -and the name of the custom field to create to store the categories. +It will prompt you for each custom field with categories that it finds, and +the name of the custom field to create to store the categories. -If you were using the LocalizedDateTime RT::Date formatter from custom -code, and passing a DateFormat or TimeFormat argument, you need to -switch from the strftime methods to the cldr methods; that is, +If you were using the LocalizedDateTime RT::Date formatter from custom code, +and passing a DateFormat or TimeFormat argument, you need to switch from the +strftime methods to the cldr methods; that is, 'full_date_format' becomes 'date_format_full'. You may also have done this from your RT_SiteConfig.pm, using: + Set($DateTimeFormat, { Format => 'LocalizedDateTime', DateFormat => 'medium_date_format', ); + Which would need to be changed to: + Set($DateTimeFormat, { Format => 'LocalizedDateTime', DateFormat => 'date_format_medium', ); -UPGRADING FROM 3.8.3 and earlier - Changes: +=head1 UPGRADING FROM 3.8.3 AND EARLIER Arguments to the NotifyGroup Scrip Action will be updated as part of the standard database upgrade process. -UPGRADING FROM 3.8.2 and earlier - Changes: +=head1 UPGRADING FROM 3.8.2 AND EARLIER A new scrip condition, 'On Reject', has been added. -UPGRADING FROM 3.8.1 and earlier - Changes: +=head1 UPGRADING FROM 3.8.1 AND EARLIER -When using Oracle, $DatabaseName is now used as SID, so RT can connect -without environment variables or tnsnames.ora file. Because of this -change, your RT instance may loose its ability to connect to your DB; to -resolve this, you will need to update RT's configuration and restart -your web server. Example configuration: +When using Oracle, $DatabaseName is now used as SID, so RT can connect without +environment variables or tnsnames.ora file. Because of this change, your RT +instance may loose its ability to connect to your DB; to resolve this, you +will need to update RT's configuration and restart your web server. Example +configuration: Set($DatabaseType, 'Oracle'); Set($DatabaseHost, '192.168.0.1'); @@ -121,72 +122,70 @@ If you want a user to be able to access the Approvals tools (a.k.a. the Approvals tab), you must grant that user the "ShowApprovalsTab" right. -UPGRADING FROM 3.8.0 and earlier - Changes: +=head1 UPGRADING FROM 3.8.0 AND EARLIER -The TicketSQL syntax for bookmarked tickets has been changed. -Specifically, the new phrasing is "id = '__Bookmarked__'", rather than -the old "__Bookmarks__". The old form will remain, for backwards -compatibility. The standard database upgrade process will only -automatically change the global 'Bookmarked Tickets' search +The TicketSQL syntax for bookmarked tickets has been changed. Specifically, +the new phrasing is "id = '__Bookmarked__'", rather than the old +"__Bookmarks__". The old form will remain, for backwards compatibility. The +standard database upgrade process will only automatically change the +global 'Bookmarked Tickets' search -UPGRADING FROM 3.7.85 and earlier - Changes: +=head1 UPGRADING FROM 3.7.85 AND EARLIER -We have proved that it is possible to delete a large set of records from -the CachedGroupMembers table without losing functionality; in fact, -failing to do so may result in occasional problems where RT miscounts -users, particularly in the chart functionality. To delete these records -run the following script: +We have proved that it is possible to delete a large set of records from the +CachedGroupMembers table without losing functionality; in fact, failing to do +so may result in occasional problems where RT miscounts users, particularly in +the chart functionality. To delete these records run the following script: perl -I /opt/rt4/local/lib -I /opt/rt4/lib etc/upgrade/shrink_cgm_table.pl -After you run this, you will have significantly reduced the number of -records in your CachedGroupMembers table, and may need to tell your -database to refresh indexes/statistics. Please consult your DBA for -specific instructions for your database. +After you run this, you will have significantly reduced the number of records +in your CachedGroupMembers table, and may need to tell your database to +refresh indexes/statistics. Please consult your DBA for specific instructions +for your database. -UPGRADING FROM 3.7.81 and earlier - Changes: +=head1 UPGRADING FROM 3.7.81 AND EARLIER -RT::Extension::BrandedQueues has been integrated into core, and the -handling of subject tags has changed as a consequence. You will need to -modify any of your email templates which use the $rtname variable, in -order to make them respect the per-queue subject tags. To edit your -templates, log into RT as your administrative user, then click: +RT::Extension::BrandedQueues has been integrated into core, and the handling +of subject tags has changed as a consequence. You will need to modify any of +your email templates which use the $rtname variable, in order to make them +respect the per-queue subject tags. To edit your templates, log into RT as +your administrative user, then click: Configuration -> Global -> Templates -> Select -> -The only template which ships with RT which needs updating is the -"Autoreply" template, which includes this line: +The only template which ships with RT which needs updating is the "Autoreply" +template, which includes this line: - "There is no need to reply to this message right now. Your ticket - has been assigned an ID of [{$rtname} #{$Ticket->id()}]." + "There is no need to reply to this message right now. Your ticket has + been assigned an ID of [{$rtname} #{$Ticket->id()}]." Change this line to read: - "There is no need to reply to this message right now. Your ticket - has been assigned an ID of { $Ticket->SubjectTag }." + "There is no need to reply to this message right now. Your ticket has + been assigned an ID of { $Ticket->SubjectTag }." -If you were previously using RT::Extension::BrandedQueues, you MUST -uninstall it before upgrading. In addition, you must run the +If you were previously using RT::Extension::BrandedQueues, you MUST uninstall +it before upgrading. In addition, you must run the 'etc/upgrade/3.8-branded-queues-extension' perl script. This will convert the extension's configuration into the new format. Finally, in templates where you were using the Tag method ($Ticket->QueueObj->Tag), you will need to replace it with $Ticket->SubjectTag -RT::Action::LinearEscalate extension has been integrated into core, -so you MUST uninstall it before upgrading. +RT::Action::LinearEscalate extension has been integrated into core, so you +MUST uninstall it before upgrading. -RT::Extension::iCal has been integrated into core, so you MUST uninstall -it before upgrading. In addition, you must run etc/upgrade/3.8-ical-extension +RT::Extension::iCal has been integrated into core, so you MUST uninstall it +before upgrading. In addition, you must run etc/upgrade/3.8-ical-extension script to convert old data. -UPGRADING FROM 3.7.80 and earlier - Changes: +=head1 UPGRADING FROM 3.7.80 AND EARLIER -Added indexes to CachedGroupMembers for MySQL and Oracle. -If you have previously installed RTx-Shredder, you may already -have these indexes. You can see the indexes by looking at -etc/upgrade/3.7.81/schema.* +Added indexes to CachedGroupMembers for MySQL and Oracle. If you have +previously installed RTx-Shredder, you may already have these indexes. You +can see the indexes by looking at etc/upgrade/3.7.81/schema.* These indexes may take a very long time to create. diff --git a/rt/docs/UPGRADING-4.0 b/rt/docs/UPGRADING-4.0 index 4b64d2e72..ad8d87b5f 100644 --- a/rt/docs/UPGRADING-4.0 +++ b/rt/docs/UPGRADING-4.0 @@ -1,87 +1,99 @@ -Common Issues +=head1 UPGRADING FROM BEFORE 4.0.0 -RT now defaults to a database name of rt4 and an installation root of /opt/rt4. +=head2 Common issues -If you are upgrading, you will likely want to specify that your database -is still named rt3 (or import a backup of your database as rt4 so that -you can feel more confident making the upgrade). +RT now defaults to a database name of rt4 and an installation root of +/opt/rt4. -You really shouldn't install RT4 into your RT3 source tree (/opt/rt3) -and instead should be using make install to set up a clean environment. -This will allow you to evaluate your local modifications and configuration -changes as you migrate to 4.0. +If you are upgrading, you will likely want to specify that your database is +still named rt3 (or import a backup of your database as rt4 so that you can +feel more confident making the upgrade). + +You really shouldn't install RT4 into your RT3 source tree (/opt/rt3) and +instead should be using make install to set up a clean environment. This will +allow you to evaluate your local modifications and configuration changes as +you migrate to 4.0. If you choose to force RT to install into /opt/rt3, or another existing RT 3.x install location, you will encounter issues because we removed the _Overlay -files (such as Ticket_Overlay.pm) and relocated other files. You will -need to manually remove these files after the upgrade or RT will fail. -After making a complete backup of your /opt/rt3 install, you might use a -command like the following to remove the _Overlay files: +files (such as Ticket_Overlay.pm) and relocated other files. You will need to +manually remove these files after the upgrade or RT will fail. After making a +complete backup of your /opt/rt3 install, you might use a command like the +following to remove the _Overlay files: find /opt/rt3/lib/ -type f -name '*_Overlay*' -delete RT has also changed how web deployment works; you will need to review -docs/web_deployment.pod for current instructions. The old -`fastcgi_server`, `webmux.pl`, and `mason_handler.*` files will not -work with RT 4.0, and should be removed to reduce confusion. +docs/web_deployment.pod for current instructions. The old `fastcgi_server`, +`webmux.pl`, and `mason_handler.*` files will not work with RT 4.0, and should +be removed to reduce confusion. + + +=head2 RT_SiteConfig.pm + +You will need to carefully review your local settings when moving from 3.8 to +4.0. -******* -RT_SiteConfig.pm +If you were adding your own custom statuses in earlier versions of RT, using +ActiveStatus or InactiveStatus you will need to port these to use the new +Lifecycles functionality. You can read more about it in RT_Config.pm. In +most cases, you can do this by extending the default active and inactive +lists. -You will need to carefully review your local settings when moving from -3.8 to 4.0. -If you were adding your own custom statuses in earlier versions of RT, -using ActiveStatus or InactiveStatus you will need to port these to use -the new Lifecycles functionality. You can read more about it in -RT_Config.pm. In most cases, you can do this by extending the default -active and inactive lists. +=head2 Upgrading sessions on MySQL -******* -Upgrading sessions on MySQL +In 4.0.0rc2, RT began shipping an updated schema for the sesions table that +specificies a character set as well as making the table InnoDB. As part of +the upgrade process, your sessions table will be dropped and recreated with +the new schema. -In 4.0.0rc2, RT began shipping an updated schema for the sesions table -that specificies a character set as well as making the table InnoDB. As -part of the upgrade process, your sessions table will be dropped and -recreated with the new schema. -******* -UPGRADING FROM RT 3.8.x and RTFM 2.1 or greater +=head2 Upgrading from installs with RTFM -RT4 now includes an Articles functionality, merged from RTFM. -You should not install and enable the RT::FM plugin separately on RT 4. -If you have existing data in RTFM, you can use the etc/upgrade/upgrade-articles -script to upgrade that data. +RT4 now includes an Articles functionality, merged from RTFM. You should not +install and enable the RT::FM plugin separately on RT 4. If you have existing +data in RTFM, you can use the etc/upgrade/upgrade-articles script to upgrade +that data. -When running normal upgrade scripts, RT will warn if it finds existing -RTFM tables that contain data and point you to the upgrade-articles script. +When running normal upgrade scripts, RT will warn if it finds existing RTFM +tables that contain data and point you to the upgrade-articles script. -This script should be run from your RT tarball. It will immediately -begin populating your new RT4 tables with data from RTFM. If you have -browsed in the RT4 UI and created new classes and articles, this script -will fail spectacularly. Do *not* run this except on a fresh upgrade of -RT. +This script should be run from your RT tarball. It will immediately begin +populating your new RT4 tables with data from RTFM. If you have browsed in +the RT4 UI and created new classes and articles, this script will fail +spectacularly. Do *not* run this except on a fresh upgrade of RT. You can run this as etc/upgrade/upgrade-articles -It will ouput a lot of data about what it is changing. You should -review this for errors. +It will ouput a lot of data about what it is changing. You should review this +for errors. -If you are running RTFM 2.0 with a release of RT, there isn't currently an upgrade -script that can port RTFM's internal CustomField and Transaction data to RT4. +If you are running RTFM 2.0 with a release of RT, there isn't currently an +upgrade script that can port RTFM's internal CustomField and Transaction data +to RT4. You must also remove RT::FM from your @Plugins line in RT_SiteConfig.pm. -******* -The deprecated classes RT::Action::Generic, RT::Condition::Generic and RT::Search::Generic -have been removed, but you shouldn't have been using them anyway. You should have been using -RT::Action, RT::Condition and RT::Search, respectively. -* The "Rights Delegation" and "Personal Groups" features have been removed. +=head2 Removals and updates + +The deprecated classes RT::Action::Generic, RT::Condition::Generic and +RT::Search::Generic have been removed, but you shouldn't have been using them +anyway. You should have been using RT::Action, RT::Condition and RT::Search, +respectively. + +=over + +=item * + +The "Rights Delegation" and "Personal Groups" features have been removed. -* Replace the following code in templates: +=item * + +Replace the following code in templates: [{$Ticket->QueueObj->SubjectTag || $rtname} #{$Ticket->id}] @@ -89,38 +101,45 @@ with { $Ticket->SubjectTag } -* Unique names are now enforced for user defined groups. New groups cannot be - created with a duplicate name and existing groups cannot be renamed to an - in-use name. The admin interface will warn about existing groups with - duplicate names. Although the groups will still function, some parts of the - interface (rights management, subgroup membership) may not work as expected - with duplicate names. Running +=item * + +Unique names are now enforced for user defined groups. New groups cannot be +created with a duplicate name and existing groups cannot be renamed to an +in-use name. The admin interface will warn about existing groups with +duplicate names. Although the groups will still function, some parts of the +interface (rights management, subgroup membership) may not work as expected +with duplicate names. Running /opt/rt4/sbin/rt-validator --check - will report duplicate group names, and running it with --resolve will fix - duplicates by appending the group id to the name. +will report duplicate group names, and running it with --resolve will fix +duplicates by appending the group id to the name. + +Nota Bene: As a result of differing indexes in the schema files, Postgres and +SQLite RT databases have enforced group name uniqueness for many years at the +database level. + +=back - Nota Bene: As a result of differing indexes in the schema files, Postgres and - SQLite RT databases have enforced group name uniqueness for many years at the - database level. -******* -UPGRADING FROM 4.0.5 and earlier - Changes: +=head1 UPGRADING FROM 4.0.5 AND EARLIER + +=head2 Schema updates The fix for an attribute truncation bug on MySQL requires a small ALTER TABLE. Be sure you run `make upgrade-database` to apply this change automatically. The bug primarily manifested when uploading large logos in the theme editor on -MySQL. Refer to etc/upgrade/4.0.6/schema.mysql for the actual ALTER TABLE that -will be run. +MySQL. Refer to etc/upgrade/4.0.6/schema.mysql for the actual ALTER TABLE +that will be run. + + +=head2 Query Builder -******* The web-based query builder now uses Queue limits to restrict the set of displayed statuses and owners. As part of this change, the %cfqueues -parameter was renamed to %Queues; if you have local modifications to any -of the following Mason templates, this feature will not function -correctly: +parameter was renamed to %Queues; if you have local modifications to any of +the following Mason templates, this feature will not function correctly: share/html/Elements/SelectOwner share/html/Elements/SelectStatus diff --git a/rt/docs/UPGRADING.mysql b/rt/docs/UPGRADING.mysql index 77a6b389f..a62dee78b 100644 --- a/rt/docs/UPGRADING.mysql +++ b/rt/docs/UPGRADING.mysql @@ -1,85 +1,142 @@ -If you did not start by reading the README file, please start there; -these steps do not list the full upgrading process, merely a part which -is sometimes necessary. +If you did not start by reading the README file, please start there; these +steps do not list the full upgrading process, merely a part which is sometimes +necessary. This file applies if either: - 1) You are upgrading RT from a version prior to 3.8.0, on any version - of MySQL -............. OR ............. - 2) You are migrating from MySQL 4.0 to MySQL 4.1 or above +=over + +=item 1. + +You are upgrading RT from a version prior to 3.8.0, on any version +of MySQL + +=item 2. + +You are migrating from MySQL 4.0 to MySQL 4.1 or above + +=back If neither of the above cases apply, your should upgrade as per the instructions in the README. -These changes are necessary because MySQL 4.1 and greater changed some -aspects of character set handling that may result in RT failures; this -will manifest as multiple login requests, corrupted binary attachments, -and corrupted image custom fields, among others. In order to resolve -this issue, the upgrade process will need to modify the schema. +These changes are necessary because MySQL 4.1 and greater changed some aspects +of character set handling that may result in RT failures; this will manifest +as multiple login requests, corrupted binary attachments, and corrupted image +custom fields, among others. In order to resolve this issue, the upgrade +process will need to modify the schema. + +=over + +=item 1. + +If you are moving the database and/or upgrading MySQL + +=over + +=item 1a. + +Dump the database; with MySQL 4.1 and greater be sure to pass the mysqldump +command the --default-character-set=binary option. This is necessary because +the data was originally encoded in Latin1. + +=item 1b. + +Configure the new MySQL to use Latin1 as the default character set everywhere, +not UTF-8. This is necessary so the import in the next step assumes the data +is Latin1. + +=item 1c. + +Import the dump made in step 1a into the new MySQL server, using the +--default-character-set=binary option on restore. This will ensure that the +data is imported as bytes, which will be interpreted as Latin1 thanks to step +1b above. + +=item 1d. + +Test that your RT works as expected on this new database. + +=back + +=item 2. + +Backup RT's database using --default-character-set=binary Furthermore, test +that you can restore from this backup. + +=item 3. + +Follow instructions in the README file to step 6b. + +=item 4. + +Apply changes described in the README's step 6b, but only up to version +3.7.87. + +=item 5. + +Apply the RT 3.8 schema upgrades. Included in RT is the script +etc/upgrade/upgrade-mysql-schema.pl that will generate the appropriate SQL +queries: + + perl etc/upgrade/upgrade-mysql-schema.pl db user pass > queries.sql + +If your mysql database is on a remote host, you can run the script like this +instead: + + perl etc/upgrade/upgrade-mysql-schema.pl db:host user pass > queries.sql + +=item 6. + +Check the sanity of the SQL queries in the queries.sql file yourself, or +consult with your DBA. + +=item 7. + +Apply the queries. Note that this step can take a while; it may also require +additional space on your hard drive comparable with size of your tables. - 1) If you are moving the database and/or upgrading MySQL - 1a) Dump the database; with MySQL 4.1 and greater be sure to pass - the mysqldump command the --default-character-set=binary option. - This is necessary because the data was originally encoded in - Latin1. + mysql -u root -p rt3 < queries.sql - 1b) Configure the new MySQL to use Latin1 as the default character - set everywhere, not UTF-8. This is necessary so the import in - the next step assumes the data is Latin1. +NOTE that 'rt3' is the default name of the RT database, change it in the +command above if your database is named differently. - 1c) Import the dump made in step 1a into the new MySQL server, using - the --default-character-set=binary option on restore. This will - ensure that the data is imported as bytes, which will be - interpreted as Latin1 thanks to step 1b above. +This step should not produce any errors or warnings. If you see any, restore +your database from the backup you made at step 1, and send a report to the +rt-users@lists.bestpractical.com mailing list. - 1d) Test that your RT works as expected on this new database. +=item 8. - 2) Backup RT's database using --default-character-set=binary - Furthermore, test that you can restore from this backup. +Re-run the `make upgrade-database` command from step 6b of the README, +applying the rest of the upgrades, starting with 3.7.87, and follow the +README's remaining steps. - 3) Follow instructions in the README file to step 6b. +=item 9. - 4) Apply changes described in the README's step 6b, but only up to - version 3.7.87. +Test everything. The most important parts you have to test: - 5) Apply the RT 3.8 schema upgrades. Included in RT is the script - etc/upgrade/upgrade-mysql-schema.pl that will generate the - appropriate SQL queries: +=over - perl etc/upgrade/upgrade-mysql-schema.pl db user pass > queries.sql +=item * - If your mysql database is on a remote host, you can run the script - like this instead: +binary attachments, like docs, PDFs, and images - perl etc/upgrade/upgrade-mysql-schema.pl db:host user pass > queries.sql +=item * - 6) Check the sanity of the SQL queries in the queries.sql file - yourself, or consult with your DBA. +binary custom fields - 7) Apply the queries. Note that this step can take a while; it may also - require additional space on your hard drive comparable with size of - your tables. +=item * - mysql -u root -p rt3 < queries.sql +everything that may contain characters other than ASCII - NOTE that 'rt3' is the default name of the RT database, change it in - the command above if your database is named differently. +=back - This step should not produce any errors or warnings. If you see any, - restore your database from the backup you made at step 1, and send a - report to the rt-users@lists.bestpractical.com mailing list. - 8) Re-run the `make upgrade-database` command from step 6b of the - README, applying the rest of the upgrades, starting with 3.7.87, and - follow the README's remaining steps. +=item 10. - 9) Test everything. The most important parts you have to test: - * binary attachments, like docs, PDFs, and images - * binary custom fields - * everything that may contain characters other than ASCII +If you were upgrading from MySQL 4.0, you may now, if you wish, reconfigure +your newer MySQL instance to use UTF-8 as the default character set, as step 7 +above adjusted the character sets on all existing tables to contain UTF-8 +encoded data, rather than Latin1. -10) If you were upgrading from MySQL 4.0, you may now, if you wish, - reconfigure your newer MySQL instance to use UTF-8 as the default - character set, as step 7 above adjusted the character sets on all - existing tables to contain UTF-8 encoded data, rather than Latin1. +=back diff --git a/rt/etc/RT_Config.pm.in b/rt/etc/RT_Config.pm.in index 169182033..5edb54c26 100644 --- a/rt/etc/RT_Config.pm.in +++ b/rt/etc/RT_Config.pm.in @@ -348,7 +348,8 @@ Set($StoreLoops, undef); =item C<$MaxAttachmentSize> C<$MaxAttachmentSize> sets the maximum size (in bytes) of attachments -stored in the database. +stored in the database. This setting is irrelevant unless one of +$TruncateLongAttachments or $DropLongAttachments (below) are set. =cut @@ -1766,12 +1767,12 @@ Set($ForceApprovalsView, 0); =head1 Extra security -=over 4 - This is a list of extra security measures to enable that help keep your RT safe. If you don't know what these mean, you should almost certainly leave the defaults alone. +=over 4 + =item C<$DisallowExecuteCode> If set to a true value, the C right will be removed from @@ -1816,7 +1817,7 @@ backwards compatability. Set($RestrictLoginReferrer, 0); -=item C<$ReferrerWhitelist> +=item C<@ReferrerWhitelist> This is a list of hostname:port combinations that RT will treat as being part of RT's domain. This is particularly useful if you access RT as @@ -2597,7 +2598,7 @@ Set(%AdminSearchResultFormat, Queues => q{'
__id__/TITLE:#'} .q{,'__Name__/TITLE:Name'} - .q{,__Description__,__Address__,__Priority__,__DefaultDueIn__,'__Disabled__,__Lifecycle__}, + .q{,__Description__,__Address__,__Priority__,__DefaultDueIn__,__Disabled__,__Lifecycle__}, Groups => q{'__id__/TITLE:#'} @@ -2749,6 +2750,8 @@ Set($LinkTransactionsRun1Scrip, 0); This option has been deprecated. You can configure this site-wide with L (see L). +=back + =cut 1; diff --git a/rt/etc/upgrade/3.8.4/content b/rt/etc/upgrade/3.8.4/content index 38d551450..14ecba461 100644 --- a/rt/etc/upgrade/3.8.4/content +++ b/rt/etc/upgrade/3.8.4/content @@ -45,7 +45,7 @@ if ( my $struct = eval { Storable::thaw( $argument ) } ) { $new = $converter->( $struct ); } else { - $new = join /, /, grep length, split /[^0-9]+/, $argument; + $new = join ", ", grep length, split /[^0-9]+/, $argument; } next if $new eq $argument; diff --git a/rt/lib/RT/Action/SendEmail.pm b/rt/lib/RT/Action/SendEmail.pm index 4ae1a8b66..2a7a2e3c0 100755 --- a/rt/lib/RT/Action/SendEmail.pm +++ b/rt/lib/RT/Action/SendEmail.pm @@ -99,47 +99,31 @@ activated in the config. sub Commit { my $self = shift; - $self->DeferDigestRecipients() if RT->Config->Get('RecordOutgoingEmail'); + return abs $self->SendMessage( $self->TemplateObj->MIMEObj ) + unless RT->Config->Get('RecordOutgoingEmail'); + + $self->DeferDigestRecipients(); my $message = $self->TemplateObj->MIMEObj; my $orig_message; - if ( RT->Config->Get('RecordOutgoingEmail') - && RT->Config->Get('GnuPG')->{'Enable'} ) - { - - # it's hacky, but we should know if we're going to crypt things - my $attachment = $self->TransactionObj->Attachments->First; - - my %crypt; - foreach my $argument (qw(Sign Encrypt)) { - if ( $attachment - && defined $attachment->GetHeader("X-RT-$argument") ) - { - $crypt{$argument} = $attachment->GetHeader("X-RT-$argument"); - } else { - $crypt{$argument} = $self->TicketObj->QueueObj->$argument(); - } - } - if ( $crypt{'Sign'} || $crypt{'Encrypt'} ) { - $orig_message = $message->dup; - } - } + $orig_message = $message->dup if RT::Interface::Email::WillSignEncrypt( + Attachment => $self->TransactionObj->Attachments->First, + Ticket => $self->TicketObj, + ); my ($ret) = $self->SendMessage($message); - if ( $ret > 0 && RT->Config->Get('RecordOutgoingEmail') ) { - if ($orig_message) { - $message->attach( - Type => 'application/x-rt-original-message', - Disposition => 'inline', - Data => $orig_message->as_string, - ); - } - $self->RecordOutgoingMailTransaction($message); - $self->RecordDeferredRecipients(); - } - + return abs( $ret ) if $ret <= 0; - return ( abs $ret ); + if ($orig_message) { + $message->attach( + Type => 'application/x-rt-original-message', + Disposition => 'inline', + Data => $orig_message->as_string, + ); + } + $self->RecordOutgoingMailTransaction($message); + $self->RecordDeferredRecipients(); + return 1; } =head2 Prepare diff --git a/rt/lib/RT/Approval/Rule/Passed.pm b/rt/lib/RT/Approval/Rule/Passed.pm index f364bc926..000a8dc62 100644 --- a/rt/lib/RT/Approval/Rule/Passed.pm +++ b/rt/lib/RT/Approval/Rule/Passed.pm @@ -80,10 +80,8 @@ sub Commit { } } - $obj->SetStatus( - Status => $obj->QueueObj->Lifecycle->DefaultStatus('approved') || 'open', - Force => 1, - ); + $obj->SetStatus( Status => $obj->FirstActiveStatus, Force => 1 ) + if $obj->FirstActiveStatus; } my $passed = !$top->HasUnresolvedDependencies( Type => 'approval' ); @@ -98,6 +96,11 @@ sub Commit { $top->Correspond( MIMEObj => $template->MIMEObj ); if ($passed) { + my $new_status = $top->QueueObj->Lifecycle->DefaultStatus('approved') || 'open'; + if ( $new_status ne $top->Status ) { + $top->SetStatus( $new_status ); + } + $self->RunScripAction('Notify Owner', 'Approval Ready for Owner', TicketObj => $top); } diff --git a/rt/lib/RT/Article.pm b/rt/lib/RT/Article.pm index 24b952ad4..678aa1177 100644 --- a/rt/lib/RT/Article.pm +++ b/rt/lib/RT/Article.pm @@ -102,7 +102,7 @@ sub Create { @_ ); - my $class = RT::Class->new($RT::SystemUser); + my $class = RT::Class->new( $self->CurrentUser ); $class->Load( $args{'Class'} ); unless ( $class->Id ) { return ( 0, $self->loc('Invalid Class') ); diff --git a/rt/lib/RT/Attachment.pm b/rt/lib/RT/Attachment.pm index fb17da3b5..f1d9a6342 100755 --- a/rt/lib/RT/Attachment.pm +++ b/rt/lib/RT/Attachment.pm @@ -600,8 +600,8 @@ sub DelHeader { my $newheader = ''; foreach my $line ($self->_SplitHeaders) { - next if $line =~ /^\Q$tag\E:\s+(.*)$/is; - $newheader .= "$line\n"; + next if $line =~ /^\Q$tag\E:\s+/i; + $newheader .= "$line\n"; } return $self->__Set( Field => 'Headers', Value => $newheader); } @@ -617,9 +617,7 @@ sub AddHeader { my $newheader = $self->__Value( 'Headers' ); while ( my ($tag, $value) = splice @_, 0, 2 ) { - $value = '' unless defined $value; - $value =~ s/\s+$//s; - $value =~ s/\r+\n/\n /g; + $value = $self->_CanonicalizeHeaderValue($value); $newheader .= "$tag: $value\n"; } return $self->__Set( Field => 'Headers', Value => $newheader); @@ -632,24 +630,39 @@ Replace or add a Header to the attachment's headers. =cut sub SetHeader { - my $self = shift; - my $tag = shift; + my $self = shift; + my $tag = shift; + my $value = $self->_CanonicalizeHeaderValue(shift); + my $replaced = 0; my $newheader = ''; - foreach my $line ($self->_SplitHeaders) { - if (defined $tag and $line =~ /^\Q$tag\E:\s+(.*)$/i) { - $newheader .= "$tag: $_[0]\n"; - undef $tag; + foreach my $line ( $self->_SplitHeaders ) { + if ( $line =~ /^\Q$tag\E:\s+/i ) { + # replace first instance, skip all the rest + unless ($replaced) { + $newheader .= "$tag: $value\n"; + $replaced = 1; + } + } else { + $newheader .= "$line\n"; } - else { - $newheader .= "$line\n"; - } } - $newheader .= "$tag: $_[0]\n" if defined $tag; + $newheader .= "$tag: $value\n" unless $replaced; $self->__Set( Field => 'Headers', Value => $newheader); } +sub _CanonicalizeHeaderValue { + my $self = shift; + my $value = shift; + + $value = '' unless defined $value; + $value =~ s/\s+$//s; + $value =~ s/\r*\n/\n /g; + + return $value; +} + =head2 SplitHeaders Returns an array of this attachment object's headers, with one header @@ -676,6 +689,12 @@ sub _SplitHeaders { my $self = shift; my $headers = (shift || $self->_Value('Headers')); my @headers; + # XXX TODO: splitting on \n\w is _wrong_ as it treats \n[ as a valid + # continuation, which it isn't. The correct split pattern, per RFC 2822, + # is /\n(?=[^ \t]|\z)/. That is, only "\n " or "\n\t" is a valid + # continuation. Older values of X-RT-GnuPG-Status contain invalid + # continuations and rely on this bogus split pattern, however, so it is + # left as-is for now. for (split(/\n(?=\w|\z)/,$headers)) { push @headers, $_; diff --git a/rt/lib/RT/Crypt/GnuPG.pm b/rt/lib/RT/Crypt/GnuPG.pm index c5fb12bef..233047820 100644 --- a/rt/lib/RT/Crypt/GnuPG.pm +++ b/rt/lib/RT/Crypt/GnuPG.pm @@ -900,6 +900,19 @@ sub FindProtectedParts { $RT::Logger->warning( "Entity of type ". $entity->effective_type ." has no body" ); return (); } + + # Deal with "partitioned" PGP mail, which (contrary to common + # sense) unnecessarily applies a base64 transfer encoding to PGP + # mail (whose content is already base64-encoded). + if ( $entity->bodyhandle->is_encoded and $entity->head->mime_encoding ) { + pipe( my ($read_decoded, $write_decoded) ); + my $decoder = MIME::Decoder->new( $entity->head->mime_encoding ); + if ($decoder) { + eval { $decoder->decode($io, $write_decoded) }; + $io = $read_decoded; + } + } + while ( defined($_ = $io->getline) ) { next unless /^-----BEGIN PGP (SIGNED )?MESSAGE-----/; my $type = $1? 'signed': 'encrypted'; @@ -1064,9 +1077,13 @@ sub VerifyDecrypt { } if ( $args{'SetStatus'} || $args{'AddStatus'} ) { my $method = $args{'AddStatus'} ? 'add' : 'set'; + # Let the header be modified so continuations are handled + my $modify = $status_on->head->modify; + $status_on->head->modify(1); $status_on->head->$method( 'X-RT-GnuPG-Status' => $res[-1]->{'status'} ); + $status_on->head->modify($modify); } } foreach my $item( grep $_->{'Type'} eq 'encrypted', @protected ) { @@ -1083,9 +1100,13 @@ sub VerifyDecrypt { } if ( $args{'SetStatus'} || $args{'AddStatus'} ) { my $method = $args{'AddStatus'} ? 'add' : 'set'; + # Let the header be modified so continuations are handled + my $modify = $status_on->head->modify; + $status_on->head->modify(1); $status_on->head->$method( 'X-RT-GnuPG-Status' => $res[-1]->{'status'} ); + $status_on->head->modify($modify); } } return @res; @@ -2107,7 +2128,9 @@ sub GetKeysInfo { eval { local $SIG{'CHLD'} = 'DEFAULT'; my $method = $type eq 'private'? 'list_secret_keys': 'list_public_keys'; - my $pid = safe_run_child { $gnupg->$method( handles => $handles, $email? (command_args => $email) : () ) }; + my $pid = safe_run_child { $gnupg->$method( handles => $handles, $email + ? (command_args => [ "--", $email]) + : () ) }; close $handle{'stdin'}; waitpid $pid, 0; }; @@ -2301,7 +2324,7 @@ sub DeleteKey { my $pid = safe_run_child { $gnupg->wrap_call( handles => $handles, commands => ['--delete-secret-and-public-key'], - command_args => [$key], + command_args => ["--", $key], ) }; close $handle{'stdin'}; while ( my $str = readline $handle{'status'} ) { diff --git a/rt/lib/RT/Generated.pm b/rt/lib/RT/Generated.pm index 9fd946f5b..907ea77f6 100644 --- a/rt/lib/RT/Generated.pm +++ b/rt/lib/RT/Generated.pm @@ -50,7 +50,7 @@ package RT; use warnings; use strict; -our $VERSION = '4.0.7'; +our $VERSION = '4.0.8'; diff --git a/rt/lib/RT/Handle.pm b/rt/lib/RT/Handle.pm index 99d10e367..03c262bba 100644 --- a/rt/lib/RT/Handle.pm +++ b/rt/lib/RT/Handle.pm @@ -858,26 +858,28 @@ sub InsertData { @queues = @{ delete $item->{'Queue'} }; } - my ( $return, $msg ) = $new_entry->Create(%$item); - unless( $return ) { - $RT::Logger->error( $msg ); - next; - } - if ( $item->{'BasedOn'} ) { - my $basedon = RT::CustomField->new($RT::SystemUser); - my ($ok, $msg ) = $basedon->LoadByCols( Name => $item->{'BasedOn'}, - LookupType => $new_entry->LookupType ); - if ($ok) { - ($ok, $msg) = $new_entry->SetBasedOn( $basedon ); + if ( $item->{'LookupType'} ) { + my $basedon = RT::CustomField->new($RT::SystemUser); + my ($ok, $msg ) = $basedon->LoadByCols( Name => $item->{'BasedOn'}, + LookupType => $item->{'LookupType'} ); if ($ok) { - $RT::Logger->debug("Added BasedOn $item->{BasedOn}: $msg"); + $item->{'BasedOn'} = $basedon->Id; } else { - $RT::Logger->error("Failed to add basedOn $item->{BasedOn}: $msg"); + $RT::Logger->error("Unable to load $item->{BasedOn} as a $item->{LookupType} CF. Skipping BasedOn: $msg"); + delete $item->{'BasedOn'}; } } else { - $RT::Logger->error("Unable to load $item->{BasedOn} as a $item->{LookupType} CF. Skipping BasedOn"); + $RT::Logger->error("Unable to load CF $item->{BasedOn} because no LookupType was specified. Skipping BasedOn"); + delete $item->{'BasedOn'}; } + + } + + my ( $return, $msg ) = $new_entry->Create(%$item); + unless( $return ) { + $RT::Logger->error( $msg ); + next; } foreach my $value ( @{$values} ) { diff --git a/rt/lib/RT/Interface/Email.pm b/rt/lib/RT/Interface/Email.pm index 4c3ee9986..dda6f704a 100755 --- a/rt/lib/RT/Interface/Email.pm +++ b/rt/lib/RT/Interface/Email.pm @@ -318,6 +318,35 @@ header field then it's value is used =cut +sub WillSignEncrypt { + my %args = @_; + my $attachment = delete $args{Attachment}; + my $ticket = delete $args{Ticket}; + + if ( not RT->Config->Get('GnuPG')->{'Enable'} ) { + $args{Sign} = $args{Encrypt} = 0; + return wantarray ? %args : 0; + } + + for my $argument ( qw(Sign Encrypt) ) { + next if defined $args{ $argument }; + + if ( $attachment and defined $attachment->GetHeader("X-RT-$argument") ) { + $args{$argument} = $attachment->GetHeader("X-RT-$argument"); + } elsif ( $ticket and $argument eq "Encrypt" ) { + $args{Encrypt} = $ticket->QueueObj->Encrypt(); + } elsif ( $ticket and $argument eq "Sign" ) { + # Note that $queue->Sign is UI-only, and that all + # UI-generated messages explicitly set the X-RT-Crypt header + # to 0 or 1; thus this path is only taken for messages + # generated _not_ via the web UI. + $args{Sign} = $ticket->QueueObj->SignAuto(); + } + } + + return wantarray ? %args : ($args{Sign} || $args{Encrypt}); +} + sub SendEmail { my (%args) = ( Entity => undef, @@ -366,23 +395,12 @@ sub SendEmail { } if ( RT->Config->Get('GnuPG')->{'Enable'} ) { - my %crypt; - - my $attachment; - $attachment = $TransactionObj->Attachments->First - if $TransactionObj; - - foreach my $argument ( qw(Sign Encrypt) ) { - next if defined $args{ $argument }; - - if ( $attachment && defined $attachment->GetHeader("X-RT-$argument") ) { - $crypt{$argument} = $attachment->GetHeader("X-RT-$argument"); - } elsif ( $TicketObj ) { - $crypt{$argument} = $TicketObj->QueueObj->$argument(); - } - } - - my $res = SignEncrypt( %args, %crypt ); + %args = WillSignEncrypt( + %args, + Attachment => $TransactionObj ? $TransactionObj->Attachments->First : undef, + Ticket => $TicketObj, + ); + my $res = SignEncrypt( %args ); return $res unless $res > 0; } diff --git a/rt/lib/RT/Interface/Email/Auth/GnuPG.pm b/rt/lib/RT/Interface/Email/Auth/GnuPG.pm index e508908fb..87a523dad 100755 --- a/rt/lib/RT/Interface/Email/Auth/GnuPG.pm +++ b/rt/lib/RT/Interface/Email/Auth/GnuPG.pm @@ -77,8 +77,9 @@ sub GetCurrentUser { foreach my $p ( $args{'Message'}->parts_DFS ) { $p->head->delete($_) for qw( - X-RT-GnuPG-Status X-RT-Incoming-Encrypton + X-RT-GnuPG-Status X-RT-Incoming-Encryption X-RT-Incoming-Signature X-RT-Privacy + X-RT-Sign X-RT-Encrypt ); } diff --git a/rt/lib/RT/Interface/Web.pm b/rt/lib/RT/Interface/Web.pm index 1aae7581e..745a6f1e3 100644 --- a/rt/lib/RT/Interface/Web.pm +++ b/rt/lib/RT/Interface/Web.pm @@ -304,12 +304,12 @@ sub HandleRequest { } # Specially handle /index.html so that we get a nicer URL elsif ( $m->request_comp->path eq '/index.html' ) { - my $next = SetNextPage(RT->Config->Get('WebURL')); + my $next = SetNextPage($ARGS); $m->comp('/NoAuth/Login.html', next => $next, actions => [$msg]); $m->abort; } else { - TangentForLogin(results => ($msg ? LoginError($msg) : undef)); + TangentForLogin($ARGS, results => ($msg ? LoginError($msg) : undef)); } } } @@ -364,7 +364,7 @@ sub LoginError { return $key; } -=head2 SetNextPage [PATH] +=head2 SetNextPage ARGSRef [PATH] Intuits and stashes the next page in the sesssion hash. If PATH is specified, uses that instead of the value of L. Returns @@ -373,24 +373,68 @@ the hash value. =cut sub SetNextPage { - my $next = shift || IntuitNextPage(); + my $ARGS = shift; + my $next = $_[0] ? $_[0] : IntuitNextPage(); my $hash = Digest::MD5::md5_hex($next . $$ . rand(1024)); + my $page = { url => $next }; + + # If an explicit URL was passed and we didn't IntuitNextPage, then + # IsPossibleCSRF below is almost certainly unrelated to the actual + # destination. Currently explicit next pages aren't used in RT, but the + # API is available. + if (not $_[0] and RT->Config->Get("RestrictReferrer")) { + # This isn't really CSRF, but the CSRF heuristics are useful for catching + # requests which may have unintended side-effects. + my ($is_csrf, $msg, @loc) = IsPossibleCSRF($ARGS); + if ($is_csrf) { + RT->Logger->notice( + "Marking original destination as having side-effects before redirecting for login.\n" + ."Request: $next\n" + ."Reason: " . HTML::Mason::Commands::loc($msg, @loc) + ); + $page->{'HasSideEffects'} = [$msg, @loc]; + } + } - $HTML::Mason::Commands::session{'NextPage'}->{$hash} = $next; + $HTML::Mason::Commands::session{'NextPage'}->{$hash} = $page; $HTML::Mason::Commands::session{'i'}++; return $hash; } +=head2 FetchNextPage HASHKEY + +Returns the stashed next page hashref for the given hash. + +=cut + +sub FetchNextPage { + my $hash = shift || ""; + return $HTML::Mason::Commands::session{'NextPage'}->{$hash}; +} + +=head2 RemoveNextPage HASHKEY + +Removes the stashed next page for the given hash and returns it. + +=cut + +sub RemoveNextPage { + my $hash = shift || ""; + return delete $HTML::Mason::Commands::session{'NextPage'}->{$hash}; +} -=head2 TangentForLogin [HASH] +=head2 TangentForLogin ARGSRef [HASH] Redirects to C, setting the value of L as -the next page. Optionally takes a hash which is dumped into query params. +the next page. Takes a hashref of request %ARGS as the first parameter. +Optionally takes all other parameters as a hash which is dumped into query +params. =cut sub TangentForLogin { - my $hash = SetNextPage(); + my $ARGS = shift; + my $hash = SetNextPage($ARGS); my %query = (@_, next => $hash); my $login = RT->Config->Get('WebURL') . 'NoAuth/Login.html?'; $login .= $HTML::Mason::Commands::m->comp('/Elements/QueryString', %query); @@ -405,8 +449,9 @@ calls L with the appropriate results key. =cut sub TangentForLoginWithError { - my $key = LoginError(HTML::Mason::Commands::loc(@_)); - TangentForLogin( results => $key ); + my $ARGS = shift; + my $key = LoginError(HTML::Mason::Commands::loc(@_)); + TangentForLogin( $ARGS, results => $key ); } =head2 IntuitNextPage @@ -606,7 +651,8 @@ sub AttemptExternalAuth { $user =~ s/^\Q$NodeName\E\\//i; } - my $next = delete $HTML::Mason::Commands::session{'NextPage'}->{$ARGS->{'next'} || ''}; + my $next = RemoveNextPage($ARGS->{'next'}); + $next = $next->{'url'} if ref $next; InstantiateNewSession() unless _UserLoggedIn; $HTML::Mason::Commands::session{'CurrentUser'} = RT::CurrentUser->new(); $HTML::Mason::Commands::session{'CurrentUser'}->$load_method($user); @@ -645,7 +691,7 @@ sub AttemptExternalAuth { delete $HTML::Mason::Commands::session{'CurrentUser'}; if (RT->Config->Get('WebFallbackToInternalAuth')) { - TangentForLoginWithError('Cannot create user: [_1]', $msg); + TangentForLoginWithError($ARGS, 'Cannot create user: [_1]', $msg); } else { $m->abort(); } @@ -668,13 +714,13 @@ sub AttemptExternalAuth { $user = $orig_user; unless ( RT->Config->Get('WebFallbackToInternalAuth') ) { - TangentForLoginWithError('You are not an authorized user'); + TangentForLoginWithError($ARGS, 'You are not an authorized user'); } } } elsif ( RT->Config->Get('WebFallbackToInternalAuth') ) { unless ( defined $HTML::Mason::Commands::session{'CurrentUser'} ) { # XXX unreachable due to prior defaulting in HandleRequest (check c34d108) - TangentForLoginWithError('You are not an authorized user'); + TangentForLoginWithError($ARGS, 'You are not an authorized user'); } } else { @@ -705,7 +751,8 @@ sub AttemptPasswordAuthentication { # It's important to nab the next page from the session before we blow # the session away - my $next = delete $HTML::Mason::Commands::session{'NextPage'}->{$ARGS->{'next'} || ''}; + my $next = RemoveNextPage($ARGS->{'next'}); + $next = $next->{'url'} if ref $next; InstantiateNewSession(); $HTML::Mason::Commands::session{'CurrentUser'} = $user_obj; @@ -1201,6 +1248,13 @@ our %is_whitelisted_component = ( '/m/tickets/search' => 1, ); +# Components which are blacklisted from automatic, argument-based whitelisting. +# These pages are not idempotent when called with just an id. +our %is_blacklisted_component = ( + # Takes only id and toggles bookmark state + '/Helpers/Toggle/TicketBookmark' => 1, +); + sub IsCompCSRFWhitelisted { my $comp = shift; my $ARGS = shift; @@ -1223,6 +1277,10 @@ sub IsCompCSRFWhitelisted { delete $args{pass}; } + # Some pages aren't idempotent even with safe args like id; blacklist + # them from the automatic whitelisting below. + return 0 if $is_blacklisted_component{$comp}; + # Eliminate arguments that do not indicate an effectful request. # For example, "id" is acceptable because that is how RT retrieves a # record. @@ -1419,6 +1477,30 @@ sub MaybeShowInterstitialCSRFPage { # Calls abort, never gets here } +our @POTENTIAL_PAGE_ACTIONS = ( + qr'/Ticket/Create.html' => "create a ticket", # loc + qr'/Ticket/' => "update a ticket", # loc + qr'/Admin/' => "modify RT's configuration", # loc + qr'/Approval/' => "update an approval", # loc + qr'/Articles/' => "update an article", # loc + qr'/Dashboards/' => "modify a dashboard", # loc + qr'/m/ticket/' => "update a ticket", # loc + qr'Prefs' => "modify your preferences", # loc + qr'/Search/' => "modify or access a search", # loc + qr'/SelfService/Create' => "create a ticket", # loc + qr'/SelfService/' => "update a ticket", # loc +); + +sub PotentialPageAction { + my $page = shift; + my @potentials = @POTENTIAL_PAGE_ACTIONS; + while (my ($pattern, $result) = splice @potentials, 0, 2) { + return HTML::Mason::Commands::loc($result) + if $page =~ $pattern; + } + return ""; +} + package HTML::Mason::Commands; use vars qw/$r $m %session/; @@ -1645,9 +1727,8 @@ sub CreateTicket { } } - foreach my $argument (qw(Encrypt Sign)) { - $MIMEObj->head->replace( "X-RT-$argument" => $ARGS{$argument} ? 1 : 0 ) - if defined $ARGS{$argument}; + for my $argument (qw(Encrypt Sign)) { + $MIMEObj->head->replace( "X-RT-$argument" => $ARGS{$argument} ? 1 : 0 ); } my %create_args = ( diff --git a/rt/lib/RT/Interface/Web/Menu.pm b/rt/lib/RT/Interface/Web/Menu.pm index 6b351e94b..045df1fa0 100644 --- a/rt/lib/RT/Interface/Web/Menu.pm +++ b/rt/lib/RT/Interface/Web/Menu.pm @@ -150,10 +150,12 @@ treated as relative to it's parent's path, and made absolute. sub path { my $self = shift; if (@_) { - $self->{path} = shift; - $self->{path} = URI->new_abs($self->{path}, $self->parent->path . "/")->as_string - if defined $self->{path} and $self->parent and $self->parent->path; - $self->{path} =~ s!///!/! if $self->{path}; + if (defined($self->{path} = shift)) { + my $base = ($self->parent and $self->parent->path) ? $self->parent->path : ""; + $base .= "/" unless $base =~ m{/$}; + my $uri = URI->new_abs($self->{path}, $base); + $self->{path} = $uri->as_string; + } } return $self->{path}; } @@ -230,6 +232,7 @@ sub child { if ( defined $path and length $path ) { my $base_path = $HTML::Mason::Commands::r->path_info; my $query = $HTML::Mason::Commands::m->cgi_object->query_string; + $base_path =~ s!/+!/!g; $base_path .= "?$query" if defined $query and length $query; $base_path =~ s/index\.html$//; diff --git a/rt/lib/RT/Pod/HTML.pm b/rt/lib/RT/Pod/HTML.pm new file mode 100644 index 000000000..8ddce42d1 --- /dev/null +++ b/rt/lib/RT/Pod/HTML.pm @@ -0,0 +1,66 @@ +use strict; +use warnings; + +package RT::Pod::HTML; +use base 'Pod::Simple::XHTML'; + +sub new { + my $self = shift->SUPER::new(@_); + $self->index(1); + $self->anchor_items(1); + return $self; +} + +sub perldoc_url_prefix { "http://metacpan.org/module/" } + +sub html_header { '' } +sub html_footer { + my $self = shift; + my $toc = "../" x ($self->batch_mode_current_level - 1); + return '← Back to index'; +} + +sub start_Verbatim { $_[0]{'scratch'} = "
" }
+sub end_Verbatim   { $_[0]{'scratch'} .= "
"; $_[0]->emit; } + +sub _end_head { + my $self = shift; + $self->{scratch} = '' . $self->{scratch} . ''; + return $self->SUPER::_end_head(@_); +} + +sub resolve_pod_page_link { + my $self = shift; + my ($name, $section) = @_; + + # Only try to resolve local links if we're in batch mode and are linking + # outside the current document. + return $self->SUPER::resolve_pod_page_link(@_) + unless $self->batch_mode and $name; + + $section = defined $section + ? '#' . $self->idify($section, 1) + : ''; + + my $local; + if ($name =~ /^RT::/) { + $local = join "/", + map { $self->encode_entities($_) } + split /::/, $name; + } + elsif ($name =~ /^rt-/) { + $local = $self->encode_entities($name); + } + + if ($local) { + # Resolve links correctly by going up + my $depth = $self->batch_mode_current_level - 1; + return join "/", + ($depth ? ".." x $depth : ()), + "$local.html$section"; + } else { + return $self->SUPER::resolve_pod_page_link(@_) + } +} + +1; diff --git a/rt/lib/RT/Pod/HTMLBatch.pm b/rt/lib/RT/Pod/HTMLBatch.pm new file mode 100644 index 000000000..8d1b67f34 --- /dev/null +++ b/rt/lib/RT/Pod/HTMLBatch.pm @@ -0,0 +1,131 @@ +use strict; +use warnings; + +package RT::Pod::HTMLBatch; +use base 'Pod::Simple::HTMLBatch'; + +use List::MoreUtils qw/all/; + +use RT::Pod::Search; +use RT::Pod::HTML; + +sub new { + my $self = shift->SUPER::new(@_); + $self->verbose(0); + + # Per-page output options + $self->css_flurry(0); # No CSS + $self->javascript_flurry(0); # No JS + $self->no_contents_links(1); # No header/footer "Back to contents" links + + # TOC options + $self->index(1); # Write a per-page TOC + $self->contents_file("index.html"); # Write a global TOC + + $self->html_render_class('RT::Pod::HTML'); + $self->search_class('RT::Pod::Search'); + + return $self; +} + +sub classify { + my $self = shift; + my %info = (@_); + + my $is_install_doc = sub { + my %page = @_; + local $_ = $page{name}; + return 1 if /^(README|UPGRADING)/; + return 1 if $_ eq "RT_Config"; + return 1 if $_ eq "web_deployment"; + return 1 if $page{infile} =~ m{^configure(\.ac)?$}; + return 0; + }; + + my $section = $info{infile} =~ m{/plugins/([^/]+)} ? "05 Extension: $1" : + $info{infile} =~ m{/local/} ? '04 Local Documenation' : + $is_install_doc->(%info) ? '00 Install and Upgrade '. + 'Documentation' : + $info{infile} =~ m{/(docs|etc)/} ? '01 User Documentation' : + $info{infile} =~ m{/bin/} ? '02 Utilities (bin)' : + $info{infile} =~ m{/sbin/} ? '03 Utilities (sbin)' : + $info{name} =~ /^RT::Action/ ? '08 Actions' : + $info{name} =~ /^RT::Condition/ ? '09 Conditions' : + $info{name} =~ /^RT(::|$)/ ? '07 Developer Documentation' : + $info{infile} =~ m{/devel/tools/} ? '20 Utilities (devel/tools)' : + '06 Miscellaneous' ; + + if ($info{infile} =~ m{/(docs|etc)/}) { + $info{name} =~ s/_/ /g; + $info{name} = join "/", map { ucfirst } split /::/, $info{name}; + } + + return ($info{name}, $section); +} + +sub write_contents_file { + my ($self, $to) = @_; + return unless $self->contents_file; + + my $file = join "/", $to, $self->contents_file; + open my $index, ">", $file + or warn "Unable to open index file '$file': $!\n", return; + + my $pages = $self->_contents; + return unless @$pages; + + # Classify + my %toc; + for my $page (@$pages) { + my ($name, $infile, $outfile, $pieces) = @$page; + + my ($title, $section) = $self->classify( + name => $name, + infile => $infile, + ); + + (my $path = $outfile) =~ s{^\Q$to\E/?}{}; + + push @{ $toc{$section} }, { + name => $title, + path => $path, + }; + } + + # Write out index + print $index "
\n"; + + for my $key (sort keys %toc) { + next unless @{ $toc{$key} }; + + (my $section = $key) =~ s/^\d+ //; + print $index "
", esc($section), "
\n"; + print $index "
\n"; + + my @sorted = sort { + my @names = map { $_->{name} } $a, $b; + + # Sort just the upgrading docs descending within everything else + @names = reverse @names + if all { /^UPGRADING-/ } @names; + + $names[0] cmp $names[1] + } @{ $toc{$key} }; + + for my $page (@sorted) { + print $index " ", + esc($page->{name}), + "
\n"; + } + print $index "
\n"; + } + print $index '
'; + + close $index; +} + +sub esc { + Pod::Simple::HTMLBatch::esc(@_); +} + +1; diff --git a/rt/lib/RT/Pod/Search.pm b/rt/lib/RT/Pod/Search.pm new file mode 100644 index 000000000..d6ddd2daf --- /dev/null +++ b/rt/lib/RT/Pod/Search.pm @@ -0,0 +1,15 @@ +use strict; +use warnings; + +package RT::Pod::Search; +use base 'Pod::Simple::Search'; + +sub new { + my $self = shift->SUPER::new(@_); + $self->laborious(1) # Find scripts too + ->limit_re(qr/(?inc(0); # Don't look in @INC + return $self; +} + +1; diff --git a/rt/lib/RT/Queue.pm b/rt/lib/RT/Queue.pm index 406df9214..a942bb6d7 100755 --- a/rt/lib/RT/Queue.pm +++ b/rt/lib/RT/Queue.pm @@ -394,6 +394,7 @@ sub Create { FinalPriority => 0, DefaultDueIn => 0, Sign => undef, + SignAuto => undef, Encrypt => undef, _RecordTransaction => 1, @_ @@ -436,14 +437,11 @@ sub Create { } $RT::Handle->Commit; - if ( defined $args{'Sign'} ) { - my ($status, $msg) = $self->SetSign( $args{'Sign'} ); - $RT::Logger->error("Couldn't set attribute 'Sign': $msg") - unless $status; - } - if ( defined $args{'Encrypt'} ) { - my ($status, $msg) = $self->SetEncrypt( $args{'Encrypt'} ); - $RT::Logger->error("Couldn't set attribute 'Encrypt': $msg") + for my $attr (qw/Sign SignAuto Encrypt/) { + next unless defined $args{$attr}; + my $set = "Set" . $attr; + my ($status, $msg) = $self->$set( $args{$attr} ); + $RT::Logger->error("Couldn't set attribute '$attr': $msg") unless $status; } @@ -595,6 +593,32 @@ sub SetSign { return ($status, $self->loc('Signing disabled')); } +sub SignAuto { + my $self = shift; + my $value = shift; + + return undef unless $self->CurrentUserHasRight('SeeQueue'); + my $attr = $self->FirstAttribute('SignAuto') or return 0; + return $attr->Content; +} + +sub SetSignAuto { + my $self = shift; + my $value = shift; + + return ( 0, $self->loc('Permission Denied') ) + unless $self->CurrentUserHasRight('AdminQueue'); + + my ($status, $msg) = $self->SetAttribute( + Name => 'SignAuto', + Description => 'Sign auto-generated outgoing messages', + Content => $value, + ); + return ($status, $msg) unless $status; + return ($status, $self->loc('Signing enabled')) if $value; + return ($status, $self->loc('Signing disabled')); +} + sub Encrypt { my $self = shift; my $value = shift; diff --git a/rt/lib/RT/Record.pm b/rt/lib/RT/Record.pm index fd238de16..313888cbc 100755 --- a/rt/lib/RT/Record.pm +++ b/rt/lib/RT/Record.pm @@ -1483,8 +1483,35 @@ sub _DeleteLink { } +=head1 LockForUpdate +In a database transaction, gains an exclusive lock on the row, to +prevent race conditions. On SQLite, this is a "RESERVED" lock on the +entire database. +=cut + +sub LockForUpdate { + my $self = shift; + + my $pk = $self->_PrimaryKey; + my $id = @_ ? $_[0] : $self->$pk; + $self->_expire if $self->isa("DBIx::SearchBuilder::Record::Cachable"); + if (RT->Config->Get('DatabaseType') eq "SQLite") { + # SQLite does DB-level locking, upgrading the transaction to + # "RESERVED" on the first UPDATE/INSERT/DELETE. Do a no-op + # UPDATE to force the upgade. + return RT->DatabaseHandle->dbh->do( + "UPDATE " .$self->Table. + " SET $pk = $pk WHERE 1 = 0"); + } else { + return $self->_LoadFromSQL( + "SELECT * FROM ".$self->Table + ." WHERE $pk = ? FOR UPDATE", + $id, + ); + } +} =head2 _NewTransaction PARAMHASH @@ -1512,6 +1539,11 @@ sub _NewTransaction { @_ ); + my $in_txn = RT->DatabaseHandle->TransactionDepth; + RT->DatabaseHandle->BeginTransaction unless $in_txn; + + $self->LockForUpdate; + my $old_ref = $args{'OldReference'}; my $new_ref = $args{'NewReference'}; my $ref_type = $args{'ReferenceType'}; @@ -1559,6 +1591,9 @@ sub _NewTransaction { if ( RT->Config->Get('UseTransactionBatch') and $transaction ) { push @{$self->{_TransactionBatch}}, $trans if $args{'CommitScrips'}; } + + RT->DatabaseHandle->Commit unless $in_txn; + return ( $transaction, $msg, $trans ); } diff --git a/rt/lib/RT/Template.pm b/rt/lib/RT/Template.pm index 117cc3f1c..e509454b1 100755 --- a/rt/lib/RT/Template.pm +++ b/rt/lib/RT/Template.pm @@ -390,6 +390,7 @@ sub _Parse { # Unfold all headers $self->{'MIMEObj'}->head->unfold; + $self->{'MIMEObj'}->head->modify(1); return ( 1, $self->loc("Template parsed") ); diff --git a/rt/lib/RT/Ticket.pm b/rt/lib/RT/Ticket.pm index 577c44429..5f76e055f 100755 --- a/rt/lib/RT/Ticket.pm +++ b/rt/lib/RT/Ticket.pm @@ -2199,14 +2199,16 @@ sub Comment { } $args{'NoteType'} = 'Comment'; + $RT::Handle->BeginTransaction(); if ($args{'DryRun'}) { - $RT::Handle->BeginTransaction(); $args{'CommitScrips'} = 0; } my @results = $self->_RecordNote(%args); if ($args{'DryRun'}) { $RT::Handle->Rollback(); + } else { + $RT::Handle->Commit(); } return(@results); @@ -2245,10 +2247,10 @@ sub Correspond { or ( $self->CurrentUserHasRight('ModifyTicket') ) ) { return ( 0, $self->loc("Permission Denied"), undef ); } + $args{'NoteType'} = 'Correspond'; - $args{'NoteType'} = 'Correspond'; + $RT::Handle->BeginTransaction(); if ($args{'DryRun'}) { - $RT::Handle->BeginTransaction(); $args{'CommitScrips'} = 0; } @@ -2265,6 +2267,8 @@ sub Correspond { if ($args{'DryRun'}) { $RT::Handle->Rollback(); + } else { + $RT::Handle->Commit(); } return (@results); diff --git a/rt/lib/RT/User.pm b/rt/lib/RT/User.pm index e7f7c2ad6..f26ace445 100755 --- a/rt/lib/RT/User.pm +++ b/rt/lib/RT/User.pm @@ -102,6 +102,7 @@ sub _OverlayAccessible { AuthSystem => { public => 1, admin => 1 }, Gecos => { public => 1, admin => 1 }, PGPKey => { public => 1, admin => 1 }, + PrivateKey => { admin => 1 }, } } diff --git a/rt/sbin/rt-fulltext-indexer b/rt/sbin/rt-fulltext-indexer index 2a6b07e39..396ef10bd 100755 --- a/rt/sbin/rt-fulltext-indexer +++ b/rt/sbin/rt-fulltext-indexer @@ -217,6 +217,11 @@ sub attachments { VALUE => 'deleted' ); + # On newer DBIx::SearchBuilder's, indicate that making the query DISTINCT + # is unnecessary because the joins won't produce duplicates. This + # drastically improves performance when fetching attachments. + $res->{joins_are_distinct} = 1; + return goto_specific( suffix => $type, error => "Don't know how to find $type attachments", diff --git a/rt/sbin/rt-fulltext-indexer.in b/rt/sbin/rt-fulltext-indexer.in index 7e31cac84..06aa89270 100644 --- a/rt/sbin/rt-fulltext-indexer.in +++ b/rt/sbin/rt-fulltext-indexer.in @@ -217,6 +217,11 @@ sub attachments { VALUE => 'deleted' ); + # On newer DBIx::SearchBuilder's, indicate that making the query DISTINCT + # is unnecessary because the joins won't produce duplicates. This + # drastically improves performance when fetching attachments. + $res->{joins_are_distinct} = 1; + return goto_specific( suffix => $type, error => "Don't know how to find $type attachments", diff --git a/rt/sbin/rt-test-dependencies.in b/rt/sbin/rt-test-dependencies.in index 960d640c3..5ce918b02 100644 --- a/rt/sbin/rt-test-dependencies.in +++ b/rt/sbin/rt-test-dependencies.in @@ -75,6 +75,7 @@ GetOptions( 'with-DASHBOARDS', 'with-USERLOGO', 'with-SSL-MAILGATE', + 'with-HTML-DOC', 'download=s', 'repository=s', @@ -104,6 +105,7 @@ my %default = ( 'with-DASHBOARDS' => 1, 'with-USERLOGO' => 1, 'with-SSL-MAILGATE' => @RT_SSL_MAILGATE@, + 'with-HTML-DOC' => @RT_DEVEL_MODE@, ); $args{$_} = $default{$_} foreach grep !exists $args{$_}, keys %default; @@ -358,6 +360,11 @@ $deps{'USERLOGO'} = [ text_to_hash( << '.') ]; Convert::Color . +$deps{'HTML-DOC'} = [ text_to_hash( <<'.') ]; +Pod::Simple 3.17 +HTML::Entities +. + my %AVOID = ( 'DBD::Oracle' => [qw(1.23)], 'Email::Address' => [qw(1.893 1.894)], diff --git a/rt/sbin/rt-validate-aliases.in b/rt/sbin/rt-validate-aliases.in new file mode 100644 index 000000000..46ae8aac7 --- /dev/null +++ b/rt/sbin/rt-validate-aliases.in @@ -0,0 +1,343 @@ +#!@PERL@ +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# +# CONTRIBUTION SUBMISSION POLICY: +# +# (The following paragraph is not intended to limit the rights granted +# to you to modify and distribute this software under the terms of +# the GNU General Public License and is only of importance to you if +# you choose to contribute your changes and enhancements to the +# community by submitting them to Best Practical Solutions, LLC.) +# +# By intentionally submitting any modifications, corrections or +# derivatives to this work, or any other work intended for use with +# Request Tracker, to Best Practical Solutions, LLC, you confirm that +# you are the copyright holder for those contributions and you grant +# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +# royalty-free, perpetual, license to use, copy, create derivative +# works based on those contributions, and sublicense and distribute +# those contributions and any derivatives thereof. +# +# END BPS TAGGED BLOCK }}} +use strict; +use warnings; +use Text::ParseWords qw//; +use Getopt::Long; + +BEGIN { # BEGIN RT CMD BOILERPLATE + require File::Spec; + require Cwd; + my @libs = ("@RT_LIB_PATH@", "@LOCAL_LIB_PATH@"); + my $bin_path; + + for my $lib (@libs) { + unless ( File::Spec->file_name_is_absolute($lib) ) { + $bin_path ||= ( File::Spec->splitpath(Cwd::abs_path(__FILE__)) )[1]; + $lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib ); + } + unshift @INC, $lib; + } +} + +require RT; +RT::LoadConfig(); +RT::Init(); + +my ($PREFIX, $URL, $HOST) = (""); +GetOptions( + "prefix|p=s" => \$PREFIX, + "url|u=s" => \$URL, + "host|h=s" => \$HOST, +); + +unless (@ARGV) { + @ARGV = grep {-f} ("/etc/aliases", + "/etc/mail/aliases", + "/etc/postfix/aliases"); + die "Can't determine aliases file to parse!" + unless @ARGV; +} + +my %aliases = parse_lines(); +unless (%aliases) { + warn "No mailgate aliases found in @ARGV"; + exit; +} + +my %seen; +my $global_mailgate; +for my $address (sort keys %aliases) { + my ($mailgate, $opts, $extra) = @{$aliases{$address}}; + my %opts = %{$opts}; + + next if $opts{url} and $URL and $opts{url} !~ /\Q$URL\E/; + + if ($mailgate !~ /^\|/) { + warn "Missing the leading | on alias $address\n"; + $mailgate = "|$mailgate"; + } + if (($global_mailgate ||= $mailgate) ne $mailgate) { + warn "Unexpected mailgate for alias $address -- expected $global_mailgate, got $mailgate\n"; + } + + if (not defined $opts{action}) { + warn "Missing --action parameter for alias $address\n"; + } elsif ($opts{action} !~ /^(correspond|comment)$/) { + warn "Invalid --action parameter for alias $address: $opts{action}\n" + } + + my $queue = RT::Queue->new( RT->SystemUser ); + if (not defined $opts{queue}) { + warn "Missing --queue parameter for alias $address\n"; + } else { + $queue->Load( $opts{queue} ); + if (not $queue->id) { + warn "Invalid --queue parameter for alias $address: $opts{queue}\n"; + } elsif ($queue->Disabled) { + warn "Disabled --queue given for alias $address: $opts{queue}\n"; + } + } + + if (not defined $opts{url}) { + warn "Missing --url parameter for alias $address\n"; + } #XXX: Test connectivity and/or https certs? + + if ($queue->id and $opts{action} =~ /^(correspond|comment)$/) { + push @{$seen{lc $queue->Name}{$opts{action}}}, $address; + } + + warn "Unknown extra arguments for alias $address: @{$extra}\n" + if @{$extra}; +} + +# Check the global settings +my %global; +for my $action (qw/correspond comment/) { + my $setting = ucfirst($action) . "Address"; + my $value = RT->Config->Get($setting); + if (not defined $value) { + warn "$setting is not set!\n"; + next; + } + my ($local,$host) = lc($value) =~ /(.*?)\@(.*)/; + next if $HOST and $host !~ /\Q$HOST\E/; + $local = "$PREFIX$local" unless exists $aliases{$local}; + + $global{$setting} = $local; + if (not exists $aliases{$local}) { + warn "$setting $value does not exist in aliases!\n" + } elsif ($aliases{$local}[1]{action} ne $action) { + warn "$setting $value is a $aliases{$local}[1]{action} in aliases!" + } +} +warn "CorrespondAddress and CommentAddress are the same!\n" + if RT->Config->Get("CorrespondAddress") eq RT->Config->Get("CommentAddress"); + + +# Go through the queues, one at a time +my $queues = RT::Queues->new( RT->SystemUser ); +$queues->UnLimit; +while (my $q = $queues->Next) { + my $qname = $q->Name; + for my $action (qw/correspond comment/) { + my $setting = ucfirst($action) . "Address"; + my $value = $q->$setting; + + if (not $value) { + my @other = grep {$_ ne $global{$setting}} @{$seen{lc $q->Name}{$action} || []}; + warn "CorrespondAddress not set on $qname, but in aliases as " + .join(" and ", @other) . "\n" if @other; + next; + } + + if ($action eq "comment" and $q->CorrespondAddress + and $q->CorrespondAddress eq $q->CommentAddress) { + warn "CorrespondAddress and CommentAddress are set the same on $qname\n"; + next; + } + + my ($local, $host) = lc($value) =~ /(.*?)\@(.*)/; + next if $HOST and $host !~ /\Q$HOST\E/; + $local = "$PREFIX$local" unless exists $aliases{$local}; + + my @other = @{$seen{lc $q->Name}{$action} || []}; + if (not exists $aliases{$local}) { + if (@other) { + warn "$setting $value on $qname does not exist in aliases -- typo'd as " + .join(" or ", @other) . "?\n"; + } else { + warn "$setting $value on $qname does not exist in aliases!\n" + } + next; + } + + my %opt = %{$aliases{$local}[1]}; + if ($opt{action} ne $action) { + warn "$setting address $value on $qname is a $opt{action} in aliases!\n" + } + if (lc $opt{queue} ne lc $q->Name and $action ne "comment") { + warn "$setting address $value on $qname points to queue $opt{queue} in aliases!\n"; + } + + @other = grep {$_ ne $local} @other; + warn "Extra aliases for queue $qname: ".join(",",@other)."\n" + if @other; + } +} + + +sub parse_lines { + local @ARGV = @ARGV; + + my %aliases; + my $line = ""; + for (<>) { + next unless /\S/; + next if /^#/; + chomp; + if (/^\s+/) { + $line .= $_; + } else { + add_line($line, \%aliases); + $line = $_; + } + } + add_line($line, \%aliases); + + expand(\%aliases); + filter_mailgate(\%aliases); + + return %aliases; +} + +sub expand { + my ($data) = @_; + + for (1..100) { + my $expanded = 0; + for my $address (sort keys %{$data}) { + my @new; + for my $part (@{$data->{$address}}) { + if (m!^[|/]! or not $data->{$part}) { + push @new, $part; + } else { + $expanded++; + push @new, @{$data->{$part}}; + } + } + $data->{$address} = \@new; + } + return unless $expanded; + } + warn "Recursion limit exceeded -- cycle in aliases?\n"; +} + +sub filter_mailgate { + my ($data) = @_; + + for my $address (sort keys %{$data}) { + my @parts = @{delete $data->{$address}}; + + my @pipes = grep {m!^\|?.*?/rt-mailgate\b!} @parts; + next unless @pipes; + + my $pipe = shift @pipes; + warn "More than one rt-mailgate pipe for alias: $address\n" + if @pipes; + + my @args = Text::ParseWords::shellwords($pipe); + + # We allow "|/random-other-command /opt/rt4/bin/rt-mailgate ...", + # we just need to strip off enough + my $index = 0; + $index++ while $args[$index] !~ m!/rt-mailgate!; + my $mailgate = join(' ', splice(@args,0,$index+1)); + + my %opts; + local @ARGV = @args; + Getopt::Long::Configure( "pass_through" ); # Allow unknown options + my $ret = eval { + GetOptions( \%opts, "queue=s", "action=s", "url=s", + "jar=s", "debug", "extension=s", + "timeout=i", "verify-ssl!", "ca-file=s", + ); + 1; + }; + warn "Failed to parse options for $address: $@" unless $ret; + next unless %opts; + + $data->{lc $address} = [$mailgate, \%opts, [@ARGV]]; + } +} + +sub add_line { + my ($line, $data) = @_; + return unless $line =~ /\S/; + + my ($name, $parts) = parse_line($line); + return unless defined $name; + + if (defined $data->{$name}) { + warn "Duplicate definition for alias $name\n"; + return; + } + + $data->{lc $name} = $parts; +} + +sub parse_line { + my $re_name = qr/\S+/; + # Intentionally accept pipe-like aliases with a missing | -- we deal with them later + my $re_quoted_pipe = qr/"\|?[^\\"]*(?:\\[\\"][^\\"]*)*"/; + my $re_nonquoted_pipe = qr/\|[^\s,]+/; + my $re_pipe = qr/(?:$re_quoted_pipe|$re_nonquoted_pipe)/; + my $re_path = qr!/[^,\s]+!; + my $re_address = qr![^|/,\s][^,\s]*!; + my $re_value = qr/(?:$re_pipe|$re_path|$re_address)/; + my $re_values = qr/(?:$re_value(?:\s*,\s*$re_value)*)/; + + my ($line) = @_; + if ($line =~ /^($re_name):\s*($re_values)/) { + my ($name, $all_parts) = ($1, $2); + my @parts; + while ($all_parts =~ s/^(?:\s*,\s*)?($re_value)//) { + my $part = $1; + if ($part =~ /^"/) { + $part =~ s/^"//; $part =~ s/"$//; + $part =~ s/\\(.)/$1/g; + } + push @parts, $part; + } + return $name, [@parts]; + } else { + warn "Parse failure, line $. of $ARGV: $line\n"; + return (); + } +} diff --git a/rt/share/html/Admin/Groups/Modify.html b/rt/share/html/Admin/Groups/Modify.html index 148c98e1f..4491a71c8 100755 --- a/rt/share/html/Admin/Groups/Modify.html +++ b/rt/share/html/Admin/Groups/Modify.html @@ -162,10 +162,7 @@ MaybeRedirectForResults( push @results, @warnings; -unless ($Group->Disabled()) { - $EnabledChecked ='checked="checked"'; -} - +$EnabledChecked = ( $Group->Disabled() ? '' : 'checked="checked"' ); diff --git a/rt/share/html/Admin/Queues/Modify.html b/rt/share/html/Admin/Queues/Modify.html index 85cd62f16..c2cf09422 100755 --- a/rt/share/html/Admin/Queues/Modify.html +++ b/rt/share/html/Admin/Queues/Modify.html @@ -119,6 +119,8 @@ Encrypt? 'checked="checked"': '' |n%> /> <&|/l&>Encrypt by default +SignAuto? 'checked="checked"': '' |n%> /> +<&|/l_unsafe, "","","",""&>Sign all auto-generated mail. [_1]Caution[_2]: Enabling this option alters the signature from providing [_3]authentication[_4] to providing [_3]integrity[_4]. % } /> @@ -181,13 +183,13 @@ unless ($Create) { if ( $QueueObj->Id ) { $title = loc('Configuration for queue [_1]', $QueueObj->Name ); my @attribs= qw(Description CorrespondAddress CommentAddress Name - InitialPriority FinalPriority DefaultDueIn Sign Encrypt Lifecycle SubjectTag Disabled); + InitialPriority FinalPriority DefaultDueIn Sign SignAuto Encrypt Lifecycle SubjectTag Disabled); # we're asking about enabled on the web page but really care about disabled if ( $SetEnabled ) { $Disabled = $ARGS{'Disabled'} = $Enabled? 0: 1; $ARGS{$_} = 0 foreach grep !defined $ARGS{$_} || !length $ARGS{$_}, - qw(Sign Encrypt Disabled); + qw(Sign SignAuto Encrypt Disabled); } $m->callback( diff --git a/rt/share/html/Admin/Users/GnuPG.html b/rt/share/html/Admin/Users/GnuPG.html index 90408e449..ee58c4485 100644 --- a/rt/share/html/Admin/Users/GnuPG.html +++ b/rt/share/html/Admin/Users/GnuPG.html @@ -64,7 +64,7 @@ <& /Widgets/Form/Select, Name => 'PrivateKey', Description => loc('Private Key'), - Values => [ map $_->{'Key'}, @{ $keys_meta{'info'} } ], + Values => \@potential_keys, CurrentValue => $UserObj->PrivateKey, DefaultLabel => loc('No private key'), &> @@ -91,7 +91,8 @@ unless ( $UserObj->id ) { $id = $ARGS{'id'} = $UserObj->id; my $email = $UserObj->EmailAddress; -my %keys_meta = RT::Crypt::GnuPG::GetKeysForSigning( $email, 'force' ); +my %keys_meta = RT::Crypt::GnuPG::GetKeysForSigning( $email ); +my @potential_keys = map $_->{'Key'}, @{ $keys_meta{'info'} || [] }; $ARGS{'PrivateKey'} = $m->comp('/Widgets/Form/Select:Process', Name => 'PrivateKey', @@ -100,8 +101,14 @@ $ARGS{'PrivateKey'} = $m->comp('/Widgets/Form/Select:Process', ); if ( $Update ) { - my ($status, $msg) = $UserObj->SetPrivateKey( $ARGS{'PrivateKey'} ); - push @results, $msg; + if (not $ARGS{'PrivateKey'} or grep {$_ eq $ARGS{'PrivateKey'}} @potential_keys) { + if (($ARGS{'PrivateKey'}||'') ne ($UserObj->PrivateKey||'')) { + my ($status, $msg) = $UserObj->SetPrivateKey( $ARGS{'PrivateKey'} ); + push @results, $msg; + } + } else { + push @results, loc("Invalid key [_1] for address '[_2]'", $ARGS{'PrivateKey'}, $email); + } } my $title = loc("[_1]'s GnuPG keys",$UserObj->Name); diff --git a/rt/share/html/Elements/CSRF b/rt/share/html/Elements/CSRF index 4893c1216..a3c19430e 100644 --- a/rt/share/html/Elements/CSRF +++ b/rt/share/html/Elements/CSRF @@ -52,11 +52,11 @@ % my $strong_start = ""; % my $strong_end = ""; -

<&|/l_unsafe, $strong_start, $strong_end, $Reason &>RT has detected a possible [_1]cross-site request forgery[_2] for this request, because [_3]. This is possibly caused by a malicious attacker trying to perform actions against RT on your behalf. If you did not initiate this request, then you should alert your security team.

+

<&|/l_unsafe, $strong_start, $strong_end, $Reason, $action &>RT has detected a possible [_1]cross-site request forgery[_2] for this request, because [_3]. A malicious attacker may be trying to [_1][_4][_2] on your behalf. If you did not initiate this request, then you should alert your security team.

% my $start = qq||; % my $end = qq||; -

<&|/l_unsafe, $escaped_path, $start, $end &>If you really intended to visit [_1], then [_2]click here to resume your request[_3].

+

<&|/l_unsafe, $escaped_path, $action, $start, $end &>If you really intended to visit [_1] and [_2], then [_3]click here to resume your request[_4].

<& /Elements/Footer, %ARGS &> % $m->abort; @@ -71,4 +71,6 @@ $escaped_path = "$escaped_path"; my $url_with_token = URI->new($OriginalURL); $url_with_token->query_form([CSRF_Token => $Token]); + +my $action = RT::Interface::Web::PotentialPageAction($OriginalURL) || loc("perform actions"); diff --git a/rt/share/html/Elements/GnuPG/SignEncryptWidget b/rt/share/html/Elements/GnuPG/SignEncryptWidget index 0ae0f841f..2f3f1035d 100644 --- a/rt/share/html/Elements/GnuPG/SignEncryptWidget +++ b/rt/share/html/Elements/GnuPG/SignEncryptWidget @@ -129,12 +129,16 @@ if ( $self->{'Sign'} ) { $QueueObj ||= $TicketObj->QueueObj if $TicketObj; - my $address = $self->{'SignUsing'}; - $address ||= ($self->{'UpdateType'} && $self->{'UpdateType'} eq "private") + my $private = $session{'CurrentUser'}->UserObj->PrivateKey || ''; + my $queue = ($self->{'UpdateType'} && $self->{'UpdateType'} eq "private") ? ( $QueueObj->CommentAddress || RT->Config->Get('CommentAddress') ) : ( $QueueObj->CorrespondAddress || RT->Config->Get('CorrespondAddress') ); - unless ( RT::Crypt::GnuPG::DrySign( $address ) ) { + my $address = $self->{'SignUsing'} || $queue; + if ($address ne $private and $address ne $queue) { + push @{ $self->{'GnuPGCanNotSignAs'} ||= [] }, $address; + $checks_failure = 1; + } elsif ( not RT::Crypt::GnuPG::DrySign( $address ) ) { push @{ $self->{'GnuPGCanNotSignAs'} ||= [] }, $address; $checks_failure = 1; } else { diff --git a/rt/share/html/Elements/Login b/rt/share/html/Elements/Login index b86bfef16..b3f1a24ab 100755 --- a/rt/share/html/Elements/Login +++ b/rt/share/html/Elements/Login @@ -61,6 +61,8 @@
<&| /Widgets/TitleBox, title => loc('Login'), titleright => $RT::VERSION, hideable => 0 &> +<& LoginRedirectWarning, %ARGS &> + % unless (RT->Config->Get('WebExternalAuth') and !RT->Config->Get('WebFallbackToInternalAuth')) {
diff --git a/rt/share/html/Elements/LoginRedirectWarning b/rt/share/html/Elements/LoginRedirectWarning new file mode 100644 index 000000000..891e38114 --- /dev/null +++ b/rt/share/html/Elements/LoginRedirectWarning @@ -0,0 +1,20 @@ +<%args> +$next => undef + +<%init> +return unless $next; + +my $destination = RT::Interface::Web::FetchNextPage($next); +return unless ref $destination and $destination->{'HasSideEffects'}; + +my $consequence = RT::Interface::Web::PotentialPageAction($destination->{'url'}) || loc("perform actions"); + $consequence = $m->interp->apply_escapes($consequence => "h"); + +
+

+ <&|/l&>After logging in you'll be sent to your original destination: + <% $destination->{'url'} %> + <&|/l_unsafe, "$consequence" &>which may [_1] on your behalf. +

+

<&|/l&>If this is not what you expect, leave this page now without logging in.

+
diff --git a/rt/share/html/Elements/Tabs b/rt/share/html/Elements/Tabs index 3aac9d803..d899071fa 100755 --- a/rt/share/html/Elements/Tabs +++ b/rt/share/html/Elements/Tabs @@ -51,6 +51,7 @@ #my $request_path = $HTML::Mason::Commands::r->path_info; my $request_path = $m->request_comp->path; +$request_path =~ s!/{2,}!/!g; my $query_string = sub { my %args = @_; diff --git a/rt/share/html/NoAuth/css/base/login.css b/rt/share/html/NoAuth/css/base/login.css index bd05a2845..608ebf87f 100644 --- a/rt/share/html/NoAuth/css/base/login.css +++ b/rt/share/html/NoAuth/css/base/login.css @@ -100,3 +100,11 @@ margin-right:auto;margin-left:auto; padding-left: 1em; } +.redirect-warning tt { + display: block; + margin: 0.5em 0 0.5em 1em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 90%; +} diff --git a/rt/share/html/NoAuth/iCal/dhandler b/rt/share/html/NoAuth/iCal/dhandler index c86f4cf7b..0e9e81204 100644 --- a/rt/share/html/NoAuth/iCal/dhandler +++ b/rt/share/html/NoAuth/iCal/dhandler @@ -94,7 +94,7 @@ while (my $t = $tickets->Next) { my $start = Data::ICal::Entry::Event->new; my $end = Data::ICal::Entry::Event->new; $_->add_properties( - url => RT->Config->Get('WebURL') . "?q=".$t->id, + url => RT->Config->Get('WebURL') . "Ticket/Display.html?id=".$t->id, organizer => $t->OwnerObj->Name, dtstamp => $now->iCal, created => $t->CreatedObj->iCal, diff --git a/rt/share/html/Ticket/Elements/ShowMessageHeaders b/rt/share/html/Ticket/Elements/ShowMessageHeaders index 3c86162b1..5a91668c1 100755 --- a/rt/share/html/Ticket/Elements/ShowMessageHeaders +++ b/rt/share/html/Ticket/Elements/ShowMessageHeaders @@ -80,6 +80,11 @@ foreach my $f (@headers) { $m->comp('/Elements/MakeClicky', content => \$f->{'Value'}, ticket => $ticket, %ARGS); } +$m->callback( + CallbackName => 'BeforeLocalization', + headers => \@headers, +); + if ( $Localize ) { $_->{'Tag'} = loc($_->{'Tag'}) foreach @headers; } diff --git a/rt/t/mail/gnupg-incoming.t b/rt/t/mail/gnupg-incoming.t index e591add6c..6ff4f76ef 100644 --- a/rt/t/mail/gnupg-incoming.t +++ b/rt/t/mail/gnupg-incoming.t @@ -11,7 +11,7 @@ BEGIN { } use RT::Test::GnuPG - tests => 41, + tests => 49, actual_server => 1, gnupg_options => { passphrase => 'rt-test', @@ -20,6 +20,7 @@ use RT::Test::GnuPG use String::ShellQuote 'shell_quote'; use IPC::Run3 'run3'; +use MIME::Base64; my ($baseurl, $m) = RT::Test->started_ok; @@ -196,6 +197,44 @@ RT::Test->close_mailgate_ok($mail); ok(index($orig->Content, $buf) != -1, 'found original msg'); } + +# test that if it gets base64 transfer-encoded, we still get the content out +$buf = encode_base64($buf); +$mail = RT::Test->open_mailgate_ok($baseurl); +print $mail <<"EOF"; +From: recipient\@example.com +To: general\@$RT::rtname +Content-transfer-encoding: base64 +Subject: Encrypted message for queue + +$buf +EOF +RT::Test->close_mailgate_ok($mail); + +{ + my $tick = RT::Test->last_ticket; + is( $tick->Subject, 'Encrypted message for queue', + "Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef}; + + is( $msg->GetHeader('X-RT-Incoming-Encryption'), + 'Success', + 'recorded incoming mail that is encrypted' + ); + is( $msg->GetHeader('X-RT-Privacy'), + 'PGP', + 'recorded incoming mail that is encrypted' + ); + like( $attach->Content, qr/orz/); + + is( $orig->GetHeader('Content-Type'), 'application/x-rt-original-message'); + ok(index($orig->Content, $buf) != -1, 'found original msg'); +} + + # test for signed mail by other key $buf = ''; diff --git a/rt/t/web/crypt-gnupg.t b/rt/t/web/crypt-gnupg.t index 8c0eb570d..b30edc3d8 100644 --- a/rt/t/web/crypt-gnupg.t +++ b/rt/t/web/crypt-gnupg.t @@ -8,6 +8,7 @@ use RT::Test::GnuPG 'trust-model' => 'always', }; use Test::Warn; +use MIME::Head; use RT::Action::SendEmail; @@ -70,8 +71,7 @@ $user->SetEmailAddress('general@example.com'); for my $mail (@mail) { unlike $mail, qr/Some content/, "outgoing mail was encrypted"; - my ($content_type) = $mail =~ /^(Content-Type: .*)/m; - my ($mime_version) = $mail =~ /^(MIME-Version: .*)/m; + my ($content_type, $mime_version) = get_headers($mail, "Content-Type", "MIME-Version"); my $body = strip_headers($mail); $mail = << "MAIL"; @@ -139,8 +139,7 @@ for my $mail (@mail) { like $mail, qr/Some other content/, "outgoing mail was not encrypted"; like $mail, qr/-----BEGIN PGP SIGNATURE-----[\s\S]+-----END PGP SIGNATURE-----/, "data has some kind of signature"; - my ($content_type) = $mail =~ /^(Content-Type: .*)/m; - my ($mime_version) = $mail =~ /^(MIME-Version: .*)/m; + my ($content_type, $mime_version) = get_headers($mail, "Content-Type", "MIME-Version"); my $body = strip_headers($mail); $mail = << "MAIL"; @@ -212,8 +211,7 @@ ok(@mail, "got some mail"); for my $mail (@mail) { unlike $mail, qr/Some other content/, "outgoing mail was encrypted"; - my ($content_type) = $mail =~ /^(Content-Type: .*)/m; - my ($mime_version) = $mail =~ /^(MIME-Version: .*)/m; + my ($content_type, $mime_version) = get_headers($mail, "Content-Type", "MIME-Version"); my $body = strip_headers($mail); $mail = << "MAIL"; @@ -279,8 +277,7 @@ ok(@mail, "got some mail"); for my $mail (@mail) { like $mail, qr/Thought you had me figured out didya/, "outgoing mail was unencrypted"; - my ($content_type) = $mail =~ /^(Content-Type: .*)/m; - my ($mime_version) = $mail =~ /^(MIME-Version: .*)/m; + my ($content_type, $mime_version) = get_headers($mail, "Content-Type", "MIME-Version"); my $body = strip_headers($mail); $mail = << "MAIL"; @@ -326,6 +323,20 @@ MAIL like($attachments[0]->Content, qr/$RT::rtname/, "RT's mail includes this instance's name"); } +sub get_headers { + my $mail = shift; + open my $fh, "<", \$mail or die $!; + my $head = MIME::Head->read($fh); + return @{[ + map { + my $hdr = "$_: " . $head->get($_); + chomp $hdr; + $hdr; + } + @_ + ]}; +} + sub strip_headers { my $mail = shift; diff --git a/rt/t/web/ticket_forward.t b/rt/t/web/ticket_forward.t index 1d74673de..0c411b99f 100644 --- a/rt/t/web/ticket_forward.t +++ b/rt/t/web/ticket_forward.t @@ -49,7 +49,7 @@ diag "Forward Ticket" if $ENV{TEST_VERBOSE}; my ($mail) = RT::Test->fetch_caught_mails; like( $mail, qr!Subject: test forward!, 'Subject field' ); like( $mail, qr!To: rt-test, rt-to\@example.com!, 'To field' ); - like( $mail, qr!Cc: rt-cc\@example.com!, 'Cc field' ); + like( $mail, qr!Cc: rt-cc\@example.com!i, 'Cc field' ); like( $mail, qr!This is a forward of ticket!, 'content' ); like( $mail, qr!this is an attachment!, 'att content' ); like( $mail, qr!$att_name!, 'att file name' ); @@ -75,8 +75,8 @@ qr/Forwarded Transaction #\d+ to rt-test, rt-to\@example.com, rt-cc\@example.com my ($mail) = RT::Test->fetch_caught_mails; like( $mail, qr!Subject: test forward!, 'Subject field' ); like( $mail, qr!To: rt-test, rt-to\@example.com!, 'To field' ); - like( $mail, qr!Cc: rt-cc\@example.com!, 'Cc field' ); - like( $mail, qr!Bcc: rt-bcc\@example.com!, 'Bcc field' ); + like( $mail, qr!Cc: rt-cc\@example.com!i, 'Cc field' ); + like( $mail, qr!Bcc: rt-bcc\@example.com!i, 'Bcc field' ); like( $mail, qr!This is a forward of transaction!, 'content' ); like( $mail, qr!$att_name!, 'att file name' ); like( $mail, qr!this is an attachment!, 'att content' ); -- cgit v1.2.1 From 3d8f79a5a75356f4ce36b8e91c769d72447d74ba Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 12 Dec 2012 15:15:55 -0800 Subject: fix svcpart changes when usergroup is a fixed field, #20458 --- FS/FS/svc_Radius_Mixin.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FS/FS/svc_Radius_Mixin.pm b/FS/FS/svc_Radius_Mixin.pm index ac97eab58..544c7e958 100644 --- a/FS/FS/svc_Radius_Mixin.pm +++ b/FS/FS/svc_Radius_Mixin.pm @@ -68,7 +68,8 @@ sub replace { $old->usergroup; # make sure this is cached for exports - my $error = $new->process_m2m( + my $error = $new->check # make sure fixed fields are set before process_m2m + || $new->process_m2m( 'link_table' => 'radius_usergroup', 'target_table' => 'radius_group', 'params' => $new->usergroup, -- cgit v1.2.1 From 65cb00ca0af788dfd5a967c99d79ffa4d8cc8c3d Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 12 Dec 2012 15:15:57 -0800 Subject: fix warning --- FS/FS/part_export/sqlradius.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_export/sqlradius.pm b/FS/FS/part_export/sqlradius.pm index 6760d09b7..7b3097e1d 100644 --- a/FS/FS/part_export/sqlradius.pm +++ b/FS/FS/part_export/sqlradius.pm @@ -348,7 +348,7 @@ sub _export_delete { sub sqlradius_queue { my( $self, $svcnum, $method ) = (shift, shift, shift); - my %args = @_; + #my %args = @_; my $queue = new FS::queue { 'svcnum' => $svcnum, 'job' => "FS::part_export::sqlradius::sqlradius_$method", -- cgit v1.2.1 From ed6005ed23ad123899d5564671838447f7739076 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 12 Dec 2012 16:19:39 -0800 Subject: fix bad race condition --- FS/FS/part_export/sqlradius.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FS/FS/part_export/sqlradius.pm b/FS/FS/part_export/sqlradius.pm index 7b3097e1d..58cc5be95 100644 --- a/FS/FS/part_export/sqlradius.pm +++ b/FS/FS/part_export/sqlradius.pm @@ -213,6 +213,7 @@ sub _export_replace { return $error; } } + $jobnum = $err_or_queue->jobnum; # chain all of these dependencies } my @del = grep { !exists $new{$_} } keys %old; @@ -230,6 +231,7 @@ sub _export_replace { return $error; } } + $jobnum = $err_or_queue->jobnum; # chain all of these dependencies } } @@ -561,6 +563,7 @@ sub sqlreplace_usergroups { my $error = $err_or_queue->depend_insert( $jobnum ); return $error if $error; } + $jobnum = $err_or_queue->jobnum; # chain all of these dependencies } if ( @newgroups ) { -- cgit v1.2.1 From 3bed798b18bf3a01343cd53fd3cfdf3463041bea Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Thu, 13 Dec 2012 09:07:42 -0800 Subject: better error message when export_links can't find a service --- FS/FS/cust_svc.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm index 52069316d..b608b2349 100644 --- a/FS/FS/cust_svc.pm +++ b/FS/FS/cust_svc.pm @@ -479,7 +479,7 @@ Returns a listref of html elements associated with this service's exports. sub export_links { my $self = shift; my $svc_x = $self->svc_x - or return "can't find ". $self->part_svc->svcdb. '.svcnum '. $self->svcnum; + or return [ "can't find ". $self->part_svc->svcdb. '.svcnum '. $self->svcnum ]; $svc_x->export_links; } -- cgit v1.2.1 From 7c3806cdbb65e125227fc78a3acbf188097a7e33 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 14 Dec 2012 19:32:44 -0800 Subject: DID selection for fibernetics, RT#19883 --- FS/FS/part_export.pm | 4 + FS/FS/part_export/fibernetics_did.pm | 176 +++++++++++++++++++++++++++++++ FS/FS/part_export/vitelity.pm | 2 + httemplate/elements/select-did.html | 69 +++++++++--- httemplate/elements/select-phonenum.html | 10 +- httemplate/elements/select-region.html | 88 ++++++++++++++++ httemplate/misc/phonenums.cgi | 10 +- httemplate/misc/regions.cgi | 26 +++++ 8 files changed, 359 insertions(+), 26 deletions(-) create mode 100644 FS/FS/part_export/fibernetics_did.pm create mode 100644 httemplate/elements/select-region.html create mode 100644 httemplate/misc/regions.cgi diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index ed66b41a1..5d650626e 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -628,6 +628,10 @@ sub info { }; } +#default fallbacks... FS::part_export::DID_Common ? +sub get_dids_can_tollfree { 0; } +sub get_dids_npa_select { 1; } + =back =head1 SUBROUTINES diff --git a/FS/FS/part_export/fibernetics_did.pm b/FS/FS/part_export/fibernetics_did.pm new file mode 100644 index 000000000..76391e88b --- /dev/null +++ b/FS/FS/part_export/fibernetics_did.pm @@ -0,0 +1,176 @@ +package FS::part_export::fibernetics_did; +use base qw( FS::part_export ); + +use strict; +use vars qw( %info $DEBUG ); +use Data::Dumper; +use URI::Escape; +#use Locale::SubCountry; +#use FS::Record qw(qsearch dbh); +use XML::Simple; +#use Net::HTTPS::Any qw( 0.10 https_get ); +use LWP::UserAgent; +use HTTP::Request::Common; + +$DEBUG = 0; + +tie my %options, 'Tie::IxHash', + 'country' => { 'label' => 'Country', 'default' => 'CA', size=>2, }, +; + +%info = ( + 'svc' => 'svc_phone', + 'desc' => 'Provision phone numbers to Fibernetics web services API', + 'options' => \%options, + 'notes' => '', +); + +sub rebless { shift; } + +sub get_dids_can_tollfree { 0; }; +sub get_dids_npa_select { 0; }; + +# i guess we could get em from the API, but since its returning states without +# availability, there's no advantage + # not really needed, we maintain our own list of provinces, but would + # help to hide the ones without availability (need to fix the selector too) +our @states = ( + 'Alberta', + 'British Columbia', + 'Ontario', + 'Quebec', + #'Saskatchewan', + #'The Territories', + #'PEI/Nova Scotia', + #'Manitoba', + #'Newfoundland', + #'New Brunswick', +); + +sub get_dids { + my $self = shift; + my %opt = ref($_[0]) ? %{$_[0]} : @_; + + if ( $opt{'tollfree'} ) { + warn 'Fibernetics DID provisioning does not yet support toll-free numbers'; + return []; + } + + my %query_hash = (); + + #ratecenter + state: return numbers (more structured names, npa selection) + #areacode + exchange: return numbers + #areacode: return city/ratecenter/whatever + #state: return areacodes + + #region + state: return numbers (arbitrary names, no npa selection) + #state: return regions + +# if ( $opt{'areacode'} && $opt{'exchange'} ) { #return numbers +# +# $query_hash{'region'} = $opt{'exchange'}; +# +# } elsif ( $opt{'areacode'} ) { +# +# $query_hash{'npa'} = $opt{'areacode'}; + + #if ( $opt{'state'} && $opt{'region'} ) { #return numbers + if ( $opt{'region'} ) { #return numbers + + #$query_hash{'province'} = $country->full_name($opt{'state'}); + $query_hash{'region'} = $opt{'region'} + + } elsif ( $opt{'state'} ) { #return regions + + #my $country = new Locale::SubCountry( $self->option('country') ); + #$query_hash{'province'} = $country->full_name($opt{'state'}); + $query_hash{'province'} = $opt{'state'}; + $query_hash{'listregion'} = 1; + + } else { #nothing passed, return states (provinces) + + return \@states; + + } + + + my $url = 'http://'. $self->machine. '/porta/cgi-bin/porta_query.cgi'; + if ( keys %query_hash ) { + $url .= '?'. join('&', map "$_=". uri_escape($query_hash{$_}), + keys %query_hash + ); + } + warn $url if $DEBUG; + + #my( $page, $response, %reply_headers) = https_get( + # 'host' => $self->machine, + #); + + my $ua = LWP::UserAgent->new; + #my $response = $ua->$method( + # $url, \%data, + # 'Content-Type'=>'application/x-www-form-urlencoded' + #); + my $req = HTTP::Request::Common::GET( $url ); + my $response = $ua->request($req); + + die $response->error_as_HTML if $response->is_error; + + my $page = $response->content; + + my $data = XMLin( $page ); + + warn Dumper($data) if $DEBUG; + +# if ( $opt{'areacode'} && $opt{'exchange'} ) { #return numbers +# +# [ map $_->{'number'}, @{ $data->{'item'} } ]; +# +# } elsif ( $opt{'areacode'} ) { +# +# [ map $_->{'region'}, @{ $data->{'item'} } ]; +# +# } elsif ( $opt{'state'} ) { #return areacodes +# +# [ map $_->{'npa'}, @{ $data->{'item'} } ]; + + #if ( $opt{'state'} && $opt{'region'} ) { #return numbers + if ( $opt{'region'} ) { #return numbers + + [ map { $_ =~ /^(\d?)(\d{3})(\d{3})(\d{4})$/ + ? ($1 ? "$1 " : ''). "$2 $3 $4" + : $_; + } + sort { $a <=> $b } + map $_->{'phone'}, + @{ $data->{'item'} } + ]; + + } elsif ( $opt{'state'} ) { #return regions + + #[ map $_->{'region'}, @{ $data->{'item'} } ]; + my %regions = map { $_ => 1 } map $_->{'region'}, @{ $data->{'item'} }; + [ sort keys %regions ]; + + #} else { #nothing passed, return states (provinces) + # not really needed, we maintain our own list of provinces, but would + # help to hide the ones without availability (need to fix the selector too) + } + + +} + +#insert, delete, etc... handled with shellcommands + +sub _export_insert { + #my( $self, $svc_phone ) = (shift, shift); +} +sub _export_delete { + #my( $self, $svc_phone ) = (shift, shift); +} + +sub _export_replace { ''; } +sub _export_suspend { ''; } +sub _export_unsuspend { ''; } + +1; diff --git a/FS/FS/part_export/vitelity.pm b/FS/FS/part_export/vitelity.pm index 350a5ad48..3c0534fc1 100644 --- a/FS/FS/part_export/vitelity.pm +++ b/FS/FS/part_export/vitelity.pm @@ -39,6 +39,8 @@ END sub rebless { shift; } +sub get_dids_can_tollfree { 1; }; + sub get_dids { my $self = shift; my %opt = ref($_[0]) ? %{$_[0]} : @_; diff --git a/httemplate/elements/select-did.html b/httemplate/elements/select-did.html index a69450c2a..6e205d8ff 100644 --- a/httemplate/elements/select-did.html +++ b/httemplate/elements/select-did.html @@ -16,8 +16,10 @@ Example: % if ( $export->option('restrict_selection') eq 'non-tollfree' % || !$export->option('restrict_selection') ) { - + +% if ( $export->get_dids_npa_select ) { + + + + + + +% } else { + - + + + +% } + - +
<% include('/elements/select-state.html', 'prefix' => 'phonenum_', #$field.'_', @@ -29,40 +31,73 @@ Example: %>
State
+ <% include('/elements/select-areacode.html', + 'state_prefix' => 'phonenum_', #$field.'_', + 'svcpart' => $svcpart, + 'empty' => 'Select area code', + ) + %> +
Area code +
+ <% include('/elements/select-exchange.html', + 'svcpart' => $svcpart, + 'empty' => 'Select exchange', + ) + %> +
City / Exchange +
- <% include('/elements/select-areacode.html', - 'state_prefix' => 'phonenum_', #$field.'_', - 'svcpart' => $svcpart, - 'empty' => 'Select area code', - ) - %> -
Area code -
- <% include('/elements/select-exchange.html', - 'svcpart' => $svcpart, - 'empty' => 'Select exchange', + <% include('/elements/select.html', + 'field' => 'phonenum_state', + 'id' => 'phonenum_state', + 'options' => [ '', @{ $export->get_dids } ], + 'labels' => { '' => 'Select province' }, + 'onchange' => 'phonenum_state_changed(this);', ) %> -
City / Exchange +
Province
+ <% include('/elements/select-region.html', + 'state_prefix' => 'phonenum_', #$field.'_', + 'svcpart' => $svcpart, + 'empty' => 'Select region', + ) + %> +
Region +
<% include('/elements/select-phonenum.html', 'svcpart' => $svcpart, 'empty' => 'Select phone number', 'bulknum' => $bulknum, 'multiple' => $multiple, + 'region' => ! $export->get_dids_npa_select, ) %>
Phone number
% } -% if ( $export->option('restrict_selection') eq 'tollfree' -% || !$export->option('restrict_selection') ) { +% if ( ( $export->option('restrict_selection') eq 'tollfree' +% || !$export->option('restrict_selection') +% ) +% and $export->get_dids_can_tollfree +% ) { Toll-free <% include('/elements/select-phonenum.html', 'svcpart' => $svcpart, diff --git a/httemplate/elements/select-phonenum.html b/httemplate/elements/select-phonenum.html index d555bf4b6..18abe3dea 100644 --- a/httemplate/elements/select-phonenum.html +++ b/httemplate/elements/select-phonenum.html @@ -12,7 +12,7 @@ what.options[length] = optionName; } - function <% $opt{'prefix'} %>exchange_changed(what, callback) { + function <% $opt{'prefix'} %><% $previous %>_changed(what, callback) { what.form.<% $opt{'prefix'} %>phonenum.disabled = 'disabled'; what.form.<% $opt{'prefix'} %>phonenum.style.display = 'none'; @@ -21,7 +21,7 @@ var phonenumerror = document.getElementById('<% $opt{'prefix'} %>phonenumerror'); phonenumerror.style.display = 'none'; - exchange = what.options[what.selectedIndex].value; + var thing = "<% $previous eq 'region' ? '_REGION ' : '' %>" + what.options[what.selectedIndex].value; function <% $opt{'prefix'} %>update_phonenums(phonenums) { @@ -84,7 +84,7 @@ } // go get the new phonenums - <% $opt{'prefix'} %>get_phonenums( exchange, <% $opt{'svcpart'} %>, <% $opt{'prefix'} %>update_phonenums ); + <% $opt{'prefix'} %>get_phonenums( thing, <% $opt{'svcpart'} %>, <% $opt{'prefix'} %>update_phonenums ); } @@ -126,7 +126,7 @@ % unless ( $opt{'tollfree'} ) { - + % } > + + + +<%init> + +my %opt = @_; + +$opt{disabled} = 'disabled' unless exists $opt{disabled}; + + diff --git a/httemplate/misc/phonenums.cgi b/httemplate/misc/phonenums.cgi index fd5de2ae6..5084628eb 100644 --- a/httemplate/misc/phonenums.cgi +++ b/httemplate/misc/phonenums.cgi @@ -21,13 +21,13 @@ if ( $exchangestring ) { my %opts = (); if ( $exchangestring eq 'tollfree' ) { $opts{'tollfree'} = 1; - } - #elsif ( $exchangestring =~ /^([\w\s\:\,\(\)\-]+), ([A-Z][A-Z])$/ ) { - elsif ( $exchangestring =~ /^(.+), ([A-Z][A-Z])$/ ) { + } elsif ( $exchangestring =~ /^_REGION (.*)$/ ) { + $opts{'region'} = $1; + #} elsif ( $exchangestring =~ /^([\w\s\:\,\(\)\-]+), ([A-Z][A-Z])$/ ) { + } elsif ( $exchangestring =~ /^(.+), ([A-Z][A-Z])$/ ) { $opts{'ratecenter'} = $1; $opts{'state'} = $2; - } - else { + } else { $exchangestring =~ /\((\d{3})-(\d{3})-XXXX\)\s*$/i or die "unparsable exchange: $exchangestring"; my( $areacode, $exchange ) = ( $1, $2 ); diff --git a/httemplate/misc/regions.cgi b/httemplate/misc/regions.cgi new file mode 100644 index 000000000..2450ea31a --- /dev/null +++ b/httemplate/misc/regions.cgi @@ -0,0 +1,26 @@ +<% objToJson(\@regions) %> +<%init> + +my( $state, $svcpart ) = $cgi->param('arg'); + +my $part_svc = qsearchs('part_svc', { 'svcpart'=>$svcpart } ); +die "unknown svcpart $svcpart" unless $part_svc; + +my @regions = (); +if ( $state ) { + + my @exports = $part_svc->part_export_did; + if ( scalar(@exports) > 1 ) { + die "more than one DID-providing export attached to svcpart $svcpart"; + } elsif ( ! @exports ) { + die "no DID providing export attached to svcpart $svcpart"; + } + my $export = $exports[0]; + + my $something = $export->get_dids('state'=>$state); + + @regions = @{ $something }; + +} + + -- cgit v1.2.1 From 05344566bd3f5443a864eedbcee8608483a01179 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 14 Dec 2012 20:10:39 -0800 Subject: DID selection for fibernetics, RT#19883 --- FS/FS/part_export/fibernetics_did.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FS/FS/part_export/fibernetics_did.pm b/FS/FS/part_export/fibernetics_did.pm index 76391e88b..fb0378550 100644 --- a/FS/FS/part_export/fibernetics_did.pm +++ b/FS/FS/part_export/fibernetics_did.pm @@ -138,7 +138,8 @@ sub get_dids { if ( $opt{'region'} ) { #return numbers [ map { $_ =~ /^(\d?)(\d{3})(\d{3})(\d{4})$/ - ? ($1 ? "$1 " : ''). "$2 $3 $4" + #? ($1 ? "$1 " : ''). "$2 $3 $4" + ? "$2 $3 $4" : $_; } sort { $a <=> $b } -- cgit v1.2.1 From d0002d9941b90fc390bfc4c3382fd092cd5a3594 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 17 Dec 2012 12:24:48 -0800 Subject: fix XSS --- httemplate/search/customer_accounting_summary.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/search/customer_accounting_summary.html b/httemplate/search/customer_accounting_summary.html index e01b8cd51..0e9e24fa6 100644 --- a/httemplate/search/customer_accounting_summary.html +++ b/httemplate/search/customer_accounting_summary.html @@ -107,7 +107,7 @@ as ">Excel spreadsheet
% my $style = ''; % $style .= " rowspan=".$cell->{rowspan} if $cell->{rowspan} > 1; % $style .= " colspan=".$cell->{colspan} if $cell->{colspan} > 1; - <<%$td%><%$style%>><% $cell->{value} %>> + <<%$td%><%$style%>><% $cell->{value} |h %>> % } % } -- cgit v1.2.1 From 5fb29670d6be68d1f378c3a5c1216a399e022bd8 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 17 Dec 2012 13:39:43 -0800 Subject: add line item report, RT#18676, add quotation reports & reorganize report menu --- httemplate/elements/menu.html | 86 ++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 66e8bf669..b4356f2c8 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -130,6 +130,8 @@ tie my %report_invoices, 'Tie::IxHash', 'Open invoices' => [ \%report_invoices_open, 'Open invoices' ], 'All invoices' => [ $fsurl. 'search/cust_bill.html?date', 'List all invoices' ], 'Advanced invoice reports' => [ $fsurl.'search/report_cust_bill.html', 'by agent, date range, etc.' ], + 'separator' => '', + 'Line items' => [ $fsurl. 'search/report_cust_bill_pkg.html', 'Individual line item detail' ], ; tie my %report_discounts, 'Tie::IxHash', @@ -231,13 +233,13 @@ foreach my $svcdb ( FS::part_svc->svc_tables() ) { } tie my %report_packages, 'Tie::IxHash'; -if ( $curuser->access_right('Edit package definitions') - || $curuser->access_right('Edit global package definitions') - ) -{ - $report_packages{'Package definitions (by # active)'} = [ $fsurl.'browse/part_pkg.cgi?active=1', 'Package definitions by number of active packages' ]; - $report_packages{'separator'} = ''; -} +$report_packages{'Package definitions (by # active)'} = [ $fsurl.'browse/part_pkg.cgi?active=1', 'Package definitions by number of active packages' ] + if $curuser->access_right('Edit package definitions') + || $curuser->access_right('Edit global package definitions'); +$report_packages{'Package Costs Report'} = [ $fsurl.'graph/report_cust_pkg_cost.html', 'Package setup and recurring costs graph' ] + if $curuser->access_right('Financial reports'); +$report_packages{'separator'} = '' + if keys %report_packages; if ( $curuser->access_right('Financial reports') ) { $report_packages{'Package churn'} = [ $fsurl.'graph/report_cust_pkg.html', 'Orders, suspensions and cancellations summary graph' ]; $report_packages{'separator2'} = ''; @@ -292,6 +294,11 @@ tie my %report_ticketing, 'Tie::IxHash', 'Advanced ticket reports' => [ $fsurl.'rt/Search/Build.html?NewQuery=1', 'List tickets by any criteria' ], ; +tie my %report_employees, 'Tie::IxHash', + 'Employee Commission Report' => [ $fsurl.'search/report_employee_commission.html', '' ], + 'Employee Audit Report' => [ $fsurl.'search/report_employee_audit.html', 'Employee audit report' ], +; + tie my %report_bill_event, 'Tie::IxHash', 'All billing events' => [ $fsurl.'search/report_cust_event.html', 'All billing events for a date range' ], 'Billing event errors' => [ $fsurl.'search/report_cust_event.html?failed=1', 'Failed credit cards, processor or printer problems, etc.' ], @@ -313,22 +320,31 @@ $report_payments{'Unapplied Payment Aging'} = [ $fsurl.'search/report_unapplied_ $report_payments{'Deleted Payments / Payment history table'} = [ $fsurl.'search/report_h_cust_pay.html', 'Deleted payments / payment history table' ] if $conf->exists('payment-history-report'); +tie my %report_credits, 'Tie::IxHash', + 'Credit Report' => [ $fsurl.'search/report_cust_credit.html', 'Credit report (by employee and/or date range)' ], + 'Unapplied Credits' => [ $fsurl.'search/report_cust_credit.html?unapplied=1', 'Unapplied credit report (by type and/or date range)' ], +; + +tie my %report_refunds, 'Tie::IxHash', + 'Refund Report' => [ $fsurl.'search/report_cust_refund.html', 'Refund report (by type and/or date range)' ], + 'Unapplied Refunds' => [ $fsurl.'search/report_cust_refund.html?unapplied=1', 'Unapplied refund report (by type and/or date range)' ], +; + +tie my %report_sales, 'Tie::IxHash', + 'Sales, Credits and Receipts' => [ $fsurl.'graph/report_money_time.html', 'Sales, credits and receipts summary graph' ], + 'Daily Sales, Credits and Receipts' => [ $fsurl.'graph/report_money_time_daily.html', 'Sales, credits and receipts (broken down by day) summary graph' ], + 'Sales Report' => [ $fsurl.'graph/report_cust_bill_pkg.html', 'Sales report and graph (by agent, package class and/or date range)' ], + 'Rated Call Sales Report' => [ $fsurl.'graph/report_cust_bill_pkg_detail.html', 'Sales report and graph (by agent, package class, usage class and/or date range)' ], + 'Sales With Advertising Source' => [ $fsurl.'search/report_cust_bill_pkg_referral.html' ], +; + tie my %report_financial, 'Tie::IxHash'; -if($curuser->access_right('Financial reports')) { +if( $curuser->access_right('Financial reports') ) { %report_financial = ( - 'Sales, Credits and Receipts' => [ $fsurl.'graph/report_money_time.html', 'Sales, credits and receipts summary graph' ], - 'Daily Sales, Credits and Receipts' => [ $fsurl.'graph/report_money_time_daily.html', 'Sales, credits and receipts (broken down by day) summary graph' ], - 'Sales Report' => [ $fsurl.'graph/report_cust_bill_pkg.html', 'Sales report and graph (by agent, package class and/or date range)' ], - 'Rated Call Sales Report' => [ $fsurl.'graph/report_cust_bill_pkg_detail.html', 'Sales report and graph (by agent, package class, usage class and/or date range)' ], - 'Sales With Advertising Source' => [ $fsurl.'search/report_cust_bill_pkg_referral.html' ], - 'Employee Commission Report' => [ $fsurl.'search/report_employee_commission.html', '' ], - 'Credit Report' => [ $fsurl.'search/report_cust_credit.html', 'Credit report (by employee and/or date range)' ], - 'Unapplied Credits' => [ $fsurl.'search/report_cust_credit.html?unapplied=1', 'Unapplied credit report (by type and/or date range)' ], - 'Refund Report' => [ $fsurl.'search/report_cust_refund.html', 'Refund report (by type and/or date range)' ], - 'Unapplied Refunds' => [ $fsurl.'search/report_cust_refund.html?unapplied=1', 'Unapplied refund report (by type and/or date range)' ], - 'Package Costs Report' => [ $fsurl.'graph/report_cust_pkg_cost.html', 'Package setup and recurring costs graph' ], - 'Employee Audit Report' => [ $fsurl.'search/report_employee_audit.html', 'Employee audit report' ], + 'Sales' => [ \%report_sales, 'Sales reports', ], + 'Credits' => [ \%report_credits, 'Credit reports', ], + 'Refunds' => [ \%report_refunds, 'Refund reports', ], ); $report_financial{'A/R Aging'} = [ $fsurl.'search/report_receivables.html', 'Accounts Receivable Aging report' ]; $report_financial{'Prepaid Income'} = [ $fsurl.'search/report_prepaid_income.html', 'Prepaid income (unearned revenue) report' ]; @@ -355,37 +371,39 @@ tie my %report_logs, 'Tie::IxHash'; || $curuser->access_right('Configuration'); tie my %report_menu, 'Tie::IxHash'; -$report_menu{'Prospects'} = [ \%report_prospects, 'Prospect reports' ] +$report_menu{'Prospects'} = [ \%report_prospects, 'Prospect reports' ] if $curuser->access_right('List prospects'); -$report_menu{'Quotations'} = [ \%report_quotations, 'Quotation reports' ] +$report_menu{'Quotations'} = [ \%report_quotations, 'Quotation reports' ] if $curuser->access_right('List quotations'); -$report_menu{'Customers'} = [ \%report_customers, 'Customer reports' ] +$report_menu{'Customers'} = [ \%report_customers, 'Customer reports' ] if $curuser->access_right('List customers'); -$report_menu{'Invoices'} = [ \%report_invoices, 'Invoice reports' ] +$report_menu{'Invoices'} = [ \%report_invoices, 'Invoice reports' ] if $curuser->access_right('List invoices'); -$report_menu{'Discounts'} = [ \%report_discounts, 'Discount reports' ] +$report_menu{'Discounts'} = [ \%report_discounts, 'Discount reports' ] if $curuser->access_right('Financial reports'); -$report_menu{'Payments'} = [ \%report_payments, 'Payment reports' ] +$report_menu{'Payments'} = [ \%report_payments, 'Payment reports' ] if $curuser->access_right('Financial reports'); -$report_menu{'Packages'} = [ \%report_packages, 'Package reports' ] +$report_menu{'Packages'} = [ \%report_packages, 'Package reports' ] if $curuser->access_right('List packages'); -$report_menu{'Services'} = [ \%report_services, 'Services reports' ] +$report_menu{'Services'} = [ \%report_services, 'Services reports' ] if $curuser->access_right('List services'); -$report_menu{'Inventory'} = [ \%report_inventory, 'Inventory reports' ] +$report_menu{'Inventory'} = [ \%report_inventory, 'Inventory reports' ] if $curuser->access_right('Configuration'); #XXX List inventory? -$report_menu{'Usage'} = [ \%report_rating, 'Usage reports' ] +$report_menu{'Usage'} = [ \%report_rating, 'Usage reports' ] if $curuser->access_right('List rating data'); -$report_menu{'Tickets'} = [ \%report_ticketing, 'Ticket reports' ] +$report_menu{'Tickets'} = [ \%report_ticketing, 'Ticket reports' ] if $conf->config('ticket_system') ;#&& FS::TicketSystem->access_right(\%session, 'Something'); +$report_menu{'Employees'} = [ \%report_employees, 'Employee reports' ] + if $curuser->access_right('Financial reports'); $report_menu{'Billing events'} = [ \%report_bill_event, 'Billing events' ] if $curuser->access_right('Billing event reports'); -$report_menu{'Financial'} = [ \%report_financial, 'Financial reports' ] +$report_menu{'Financial'} = [ \%report_financial, 'Financial reports' ] if $curuser->access_right('Financial reports') or $curuser->access_right('Receivables report'); -$report_menu{'Logs'} = [ \%report_logs, 'System and email logs' ] +$report_menu{'Logs'} = [ \%report_logs, 'System and email logs' ] if (keys %report_logs); # empty if the user has no rights to it -$report_menu{'SQL Query'} = [ $fsurl.'search/report_sql.html', 'SQL Query' ] +$report_menu{'SQL Query'} = [ $fsurl.'search/report_sql.html', 'SQL Query'] if $curuser->access_right('Raw SQL'); tie my %tools_importing, 'Tie::IxHash', -- cgit v1.2.1 From 74b63c87c33cdd97f7b9239e626d34bded497e20 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 17 Dec 2012 13:44:22 -0800 Subject: add line item report, RT#18676 --- httemplate/search/report_cust_bill_pkg.html | 118 ++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 httemplate/search/report_cust_bill_pkg.html diff --git a/httemplate/search/report_cust_bill_pkg.html b/httemplate/search/report_cust_bill_pkg.html new file mode 100644 index 000000000..4f6ee78db --- /dev/null +++ b/httemplate/search/report_cust_bill_pkg.html @@ -0,0 +1,118 @@ +<& /elements/header.html, mt('Line item report') &> + + + + + scalar( $cgi->param('agentnum') ), + #label => emt('Line items for agent: '), + disable_empty => 0, +&> + +<& /elements/tr-select-cust_main-status.html, + label => emt('Customer status'), +&> + + + +<& /elements/tr-input-beginning_ending.html &> + + + + + + + + + + + + + + + + + +
<% mt('Omit taxes') |h %>
<% mt('Taxes only') |h %>
+ + + +
+ + + + +<& /elements/footer.html &> +<%init> + +#Financial reports? +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('List invoices'); + +my $conf = new FS::Conf; + +#other available params (cust_bill_pkg.cgi): +# +#distribute = 1 +# +#(when nottax) +# use_override something about part_pkg +# classnum package class +# taxclass / taxclassNULL +# exempt_cust +# exempt_pkg +# region (country:state:county:city:district) +# taxable +# out (of taxable region) +# usage +#(when istax) +# locationtaxid (& district/city/ciounty/state) +# out (of taxable region) +# taxclassNULL +# report_group (itemdesc) +# itemdesc +# +#taxname/taxnameNULL cust_main_county +#taxnum cust_main_county +#credit (hmm need to look more at what this does) + + + + -- cgit v1.2.1 From 65acf1fd9746f1dd98e061044657c185367f7903 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 17 Dec 2012 13:44:39 -0800 Subject: add line item report, RT#18676 --- httemplate/search/cust_bill_pkg.cgi | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi index ed3444027..0c5fbd211 100644 --- a/httemplate/search/cust_bill_pkg.cgi +++ b/httemplate/search/cust_bill_pkg.cgi @@ -205,27 +205,27 @@ if ( $cgi->param('custnum') =~ /^(\d+)$/ ) { push @where, "cust_main.custnum = $1"; } +# then we want the package and its definition +$join_pkg = +' LEFT JOIN cust_pkg USING (pkgnum) + LEFT JOIN part_pkg USING (pkgpart)'; + +my $part_pkg = 'part_pkg'; +if ( $cgi->param('use_override') ) { + # still need the real part_pkg for tax applicability, + # so alias this one + $join_pkg .= " LEFT JOIN part_pkg AS override ON ( + COALESCE(cust_bill_pkg.pkgpart_override, cust_pkg.pkgpart, 0) = part_pkg.pkgpart + )"; + $part_pkg = 'override'; +} +push @select, 'part_pkg.pkg'; # or should this use override? + # the non-tax case if ( $cgi->param('nottax') ) { push @where, 'cust_bill_pkg.pkgnum > 0'; - # then we want the package and its definition - $join_pkg = -' LEFT JOIN cust_pkg USING (pkgnum) - LEFT JOIN part_pkg USING (pkgpart)'; - - my $part_pkg = 'part_pkg'; - if ( $cgi->param('use_override') ) { - # still need the real part_pkg for tax applicability, - # so alias this one - $join_pkg .= " LEFT JOIN part_pkg AS override ON ( - COALESCE(cust_bill_pkg.pkgpart_override, cust_pkg.pkgpart, 0) = part_pkg.pkgpart - )"; - $part_pkg = 'override'; - } - push @select, 'part_pkg.pkg'; # or should this use override? - my @tax_where; # will go into a subquery my @exempt_where; # will also go into a subquery -- cgit v1.2.1 From f2e7b5d30a04b6f050e0a82afd8b95c81730bc0c Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 17 Dec 2012 16:09:09 -0800 Subject: add taxclass and paid/credit columns to line item reports, clickthrough to credit detail, RT#18676 --- httemplate/search/cust_bill_pkg.cgi | 79 ++++++++++++++++++++++++----- httemplate/search/cust_credit_bill_pkg.html | 46 +++++++++-------- 2 files changed, 92 insertions(+), 33 deletions(-) diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi index 0c5fbd211..34c89e532 100644 --- a/httemplate/search/cust_bill_pkg.cgi +++ b/httemplate/search/cust_bill_pkg.cgi @@ -6,9 +6,12 @@ 'count_addl' => \@total_desc, 'header' => [ emt('Description'), + @post_desc_header, @peritem_desc, emt('Invoice'), emt('Date'), + emt('Paid'), + emt('Credited'), FS::UI::Web::cust_header(), ], 'fields' => [ @@ -16,60 +19,76 @@ ? $_[0]->get('pkg') # possibly use override.pkg : $_[0]->get('itemdesc') # but i think this correct }, + @post_desc, #strikethrough or "N/A ($amount)" or something these when # they're not applicable to pkg_tax search @peritem_sub, 'invnum', sub { time2str('%b %d %Y', shift->_date ) }, + sub { sprintf($money_char.'%.2f', shift->get('pay_amount')) }, + sub { sprintf($money_char.'%.2f', shift->get('credit_amount')) }, \&FS::UI::Web::cust_fields, ], 'sort_fields' => [ '', + @post_desc_null, @peritem, 'invnum', '_date', + #'pay_amount', + #'credit_amount', ], 'links' => [ #'', '', + @post_desc_null, @peritem_null, $ilink, $ilink, + $pay_link, + $credit_link, ( map { $_ ne 'Cust. Status' ? $clink : '' } FS::UI::Web::cust_header() ), ], #'align' => 'rlrrrc'.FS::UI::Web::cust_aligns(), 'align' => 'l'. + $post_desc_align. $peritem_align. - 'rc'. + 'rcrr'. FS::UI::Web::cust_aligns(), 'color' => [ #'', '', + @post_desc_null, @peritem_null, '', '', + '', + '', FS::UI::Web::cust_colors(), ], 'style' => [ #'', '', + @post_desc_null, @peritem_null, '', '', + '', + '', FS::UI::Web::cust_styles(), ], &> <%doc> -Output parameters: +Output control parameters: - distribute: Boolean. If true, recurring fees will be "prorated" for the portion of the package date range (sdate-edate) that falls within the date range of the report. Line items will be limited to those for which this portion is > 0. This disables filtering on invoice date. -- use_usage: Separate usage (cust_bill_pkg_detail records) from +- usage: Separate usage (cust_bill_pkg_detail records) from recurring charges. If set to "usage", will show usage instead of recurring charges. If set to "recurring", will deduct usage and only show the flat rate charge. If not passed, the "recurring charge" column @@ -155,13 +174,24 @@ my $money_char = $conf->config('money_char') || '$'; my @select = ( 'cust_bill_pkg.*', 'cust_bill._date' ); my @total = ( 'COUNT(*)', 'SUM(cust_bill_pkg.setup + cust_bill_pkg.recur)'); my @total_desc = ( '%d line items', $money_char.'%.2f total' ); # sprintf strings + my @peritem = ( 'setup', 'recur' ); my @peritem_desc = ( 'Setup charge', 'Recurring charge' ); -my ($join_cust, $join_pkg ) = ('', ''); -my $use_usage; + +my @post_desc_header = (); +my @post_desc = (); +my @post_desc_null = (); +my $post_desc_align = ''; +if ( $conf->exists('enable_taxclasses') ) { + push @post_desc_header, 'Tax class'; + push @post_desc, 'taxclass'; + push @post_desc_null, ''; + $post_desc_align .= 'l'; + push @select, 'part_pkg.taxclass'; # or should this use override? +} # valid in both the tax and non-tax cases -$join_cust = +my $join_cust = " LEFT JOIN cust_bill USING (invnum) LEFT JOIN cust_main USING (custnum) "; @@ -205,8 +235,8 @@ if ( $cgi->param('custnum') =~ /^(\d+)$/ ) { push @where, "cust_main.custnum = $1"; } -# then we want the package and its definition -$join_pkg = +# we want the package and its definition if available +my $join_pkg = ' LEFT JOIN cust_pkg USING (pkgnum) LEFT JOIN part_pkg USING (pkgpart)'; @@ -379,8 +409,7 @@ if ( $cgi->param('nottax') ) { } # recur/usage separation - $use_usage = $cgi->param('usage'); - if ( $use_usage eq 'recurring' ) { + if ( $cgi->param('usage') eq 'recurring' ) { my $recur_no_usage = FS::cust_bill_pkg->charged_sql('', '', no_usage => 1); push @select, "($recur_no_usage) AS recur_no_usage"; @@ -388,7 +417,7 @@ if ( $cgi->param('nottax') ) { $total[1] = "SUM(cust_bill_pkg.setup + $recur_no_usage)"; $total_desc[1] .= ' (excluding usage)'; - } elsif ( $use_usage eq 'usage' ) { + } elsif ( $cgi->param('usage') eq 'usage' ) { my $usage = FS::cust_bill_pkg->usage_sql(); push @select, "($usage) AS _usage"; @@ -491,6 +520,16 @@ if ( $cgi->param('nottax') ) { } # nottax / istax + +#total payments +my $pay_sub = "SELECT SUM(cust_bill_pay_pkg.amount) AS pay_amount, + billpkgnum + FROM cust_bill_pay_pkg + GROUP BY billpkgnum"; +$join_pkg .= " LEFT JOIN ($pay_sub) AS item_pay USING (billpkgnum)"; +push @select, 'item_pay.pay_amount'; + + # credit if ( $cgi->param('credit') ) { @@ -549,7 +588,20 @@ if ( $cgi->param('credit') ) { push @peritem_desc, 'Credited', 'By', 'Reason'; push @total, 'SUM(credit_amount)'; push @total_desc, "$money_char%.2f credited"; -} # if credit + +} else { + + #still want a credit total column + + my $credit_sub = "SELECT SUM(cust_credit_bill_pkg.amount) AS credit_amount, + billpkgnum + FROM cust_credit_bill_pkg + GROUP BY billpkgnum"; + $join_pkg .= " LEFT JOIN ($credit_sub) AS item_credit USING (billpkgnum)"; + + push @select, 'item_credit.credit_amount'; + +} push @select, 'cust_main.custnum', FS::UI::Web::cust_sql_fields(); @@ -587,6 +639,9 @@ my $peritem_align = 'r' x scalar(@peritem); my $ilink = [ "${p}view/cust_bill.cgi?", 'invnum' ]; my $clink = [ "${p}view/cust_main.cgi?", 'custnum' ]; +my $pay_link = ''; #[, 'billpkgnum', ]; +my $credit_link = [ "${p}search/cust_credit_bill_pkg.html?billpkgnum=", 'billpkgnum', ]; + warn "\n\nQUERY:\n".Dumper($query)."\n\nCOUNT_QUERY:\n$count_query\n\n" if $cgi->param('debug'); diff --git a/httemplate/search/cust_credit_bill_pkg.html b/httemplate/search/cust_credit_bill_pkg.html index 4612118a2..a57a5ae1a 100644 --- a/httemplate/search/cust_credit_bill_pkg.html +++ b/httemplate/search/cust_credit_bill_pkg.html @@ -1,10 +1,10 @@ <% include( 'elements/search.html', - 'title' => 'Tax credits', #well, actually application of - 'name' => 'tax credits', # credit to line item - 'query' => $query, - 'count_query' => $count_query, - 'count_addl' => [ $money_char. '%.2f total', ], - 'header' => [ + 'title' => 'Credit application detail', #to line item + 'name_singular' => 'credit application', + 'query' => $query, + 'count_query' => $count_query, + 'count_addl' => [ $money_char. '%.2f total', ], + 'header' => [ #'#', 'Amount', @@ -21,8 +21,8 @@ 'Invoice', 'Date', FS::UI::Web::cust_header(), - ], - 'fields' => [ + ], + 'fields' => [ #'creditbillpkgnum', sub { sprintf($money_char.'%.2f', shift->amount ) }, @@ -37,8 +37,8 @@ 'invnum', sub { time2str('%b %d %Y', shift->_date ) }, \&FS::UI::Web::cust_fields, - ], - 'sort_fields' => [ + ], + 'sort_fields' => [ 'amount', 'cust_credit_date', '', #'otaker', @@ -47,8 +47,8 @@ 'invnum', '_date', #cust fields - ], - 'links' => [ + ], + 'links' => [ '', '', '', @@ -59,9 +59,9 @@ ( map { $_ ne 'Cust. Status' ? $clink : '' } FS::UI::Web::cust_header() ), - ], - 'align' => 'rrlllrr'.FS::UI::Web::cust_aligns(), - 'color' => [ + ], + 'align' => 'rrlllrr'.FS::UI::Web::cust_aligns(), + 'color' => [ '', '', '', @@ -71,7 +71,7 @@ '', FS::UI::Web::cust_colors(), ], - 'style' => [ + 'style' => [ '', '', '', @@ -80,7 +80,7 @@ '', '', FS::UI::Web::cust_styles(), - ], + ], ) %> <%init> @@ -106,6 +106,10 @@ if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { push @where, "cust_main.agentnum = $1"; } +if ( $cgi->param('billpkgnum') =~ /^(\d+)$/ ) { + push @where, "billpkgnum = $1"; +} + #classnum # not specified: all classes # 0: empty class @@ -346,7 +350,7 @@ if ( $cgi->param('cust_tax') ) { push @where, $cust_exempt; } -my $count_query = "SELECT COUNT(DISTINCT billpkgnum), +my $count_query = "SELECT COUNT(DISTINCT creditbillpkgnum), SUM(cust_credit_bill_pkg.amount)"; my $join_cust = @@ -412,8 +416,8 @@ my $join_credit = ' LEFT JOIN cust_credit_bill USING ( creditbillnum ) LEFT JOIN cust_credit USING ( crednum ) '; $count_query .= " FROM cust_credit_bill_pkg - $join_pkg $join_cust_bill_pkg + $join_pkg $join_credit $join_cust $where"; @@ -430,8 +434,8 @@ push @select, 'cust_main.custnum', my $query = { 'table' => 'cust_credit_bill_pkg', - 'addl_from' => "$join_pkg - $join_cust_bill_pkg + 'addl_from' => "$join_cust_bill_pkg + $join_pkg $join_credit $join_cust", 'hashref' => {}, -- cgit v1.2.1 From e79a41389fddf82c99c64e20d006ba33469188c5 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 17 Dec 2012 17:08:10 -0800 Subject: credit application detail report, RT#18676 --- httemplate/elements/menu.html | 1 + 1 file changed, 1 insertion(+) diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index b4356f2c8..4e6109687 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -322,6 +322,7 @@ $report_payments{'Deleted Payments / Payment history table'} = [ $fsurl.'search/ tie my %report_credits, 'Tie::IxHash', 'Credit Report' => [ $fsurl.'search/report_cust_credit.html', 'Credit report (by employee and/or date range)' ], + 'Credit application detail' => [ $fsurl.'search/report_cust_credit_bill_pkg.html', 'Line item application detail' ], 'Unapplied Credits' => [ $fsurl.'search/report_cust_credit.html?unapplied=1', 'Unapplied credit report (by type and/or date range)' ], ; -- cgit v1.2.1 From 2cec1a0e7dfdb00a866a3c9a2947f61c1e9fbffd Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 17 Dec 2012 17:08:25 -0800 Subject: credit application detail report, RT#18676 --- httemplate/search/cust_credit_bill_pkg.html | 37 +++++++- httemplate/search/report_cust_credit_bill_pkg.html | 104 +++++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 httemplate/search/report_cust_credit_bill_pkg.html diff --git a/httemplate/search/cust_credit_bill_pkg.html b/httemplate/search/cust_credit_bill_pkg.html index a57a5ae1a..06fd881a8 100644 --- a/httemplate/search/cust_credit_bill_pkg.html +++ b/httemplate/search/cust_credit_bill_pkg.html @@ -16,6 +16,7 @@ # line item 'Description', + @post_desc_header, #invoice 'Invoice', @@ -34,6 +35,7 @@ ? $_[0]->get('pkg') # possibly use override.pkg : $_[0]->get('itemdesc') # but i think this correct }, + @post_desc, 'invnum', sub { time2str('%b %d %Y', shift->_date ) }, \&FS::UI::Web::cust_fields, @@ -44,6 +46,7 @@ '', #'otaker', '', #reason '', #line item description + @post_desc_null, 'invnum', '_date', #cust fields @@ -54,19 +57,24 @@ '', '', '', + @post_desc_null, $ilink, $ilink, ( map { $_ ne 'Cust. Status' ? $clink : '' } FS::UI::Web::cust_header() ), ], - 'align' => 'rrlllrr'.FS::UI::Web::cust_aligns(), + 'align' => 'rrlll'. + $post_desc_align. + 'rr'. + FS::UI::Web::cust_aligns(), 'color' => [ '', '', '', '', '', + @post_desc_null, '', '', FS::UI::Web::cust_colors(), @@ -77,6 +85,7 @@ '', '', '', + @post_desc_null, '', '', FS::UI::Web::cust_styles(), @@ -86,6 +95,7 @@ <%init> #LOTS of false laziness below w/cust_bill_pkg.cgi +# and a little w/cust_credit.html die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); @@ -98,10 +108,23 @@ my $agentnums_sql = my @where = ( $agentnums_sql ); +if ( $cgi->param('usernum') =~ /^(\d+)$/ ) { + push @where, "cust_credit.usernum = $1"; +} + my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi); push @where, "cust_bill._date >= $beginning", "cust_bill._date <= $ending"; +my($cr_begin, $cr_end) = FS::UI::Web::parse_beginning_ending($cgi, 'credit'); +push @where, "cust_credit._date >= $cr_begin", + "cust_credit._date <= $cr_end"; + +#credit amount? seems more what is expected than the applied amount +my @lt_gt = FS::UI::Web::parse_lt_gt($cgi, 'amount' ); +s/amount/cust_credit.amount/g foreach (@lt_gt); +push @where, @lt_gt; + if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { push @where, "cust_main.agentnum = $1"; } @@ -432,6 +455,18 @@ push @select, 'part_pkg.pkg' unless $cgi->param('istax'); push @select, 'cust_main.custnum', FS::UI::Web::cust_sql_fields(); +my @post_desc_header = (); +my @post_desc = (); +my @post_desc_null = (); +my $post_desc_align = ''; +if ( $conf->exists('enable_taxclasses') ) { + push @post_desc_header, 'Tax class'; + push @post_desc, 'taxclass'; + push @post_desc_null, ''; + $post_desc_align .= 'l'; + push @select, 'part_pkg.taxclass'; # or should this use override? +} + my $query = { 'table' => 'cust_credit_bill_pkg', 'addl_from' => "$join_cust_bill_pkg diff --git a/httemplate/search/report_cust_credit_bill_pkg.html b/httemplate/search/report_cust_credit_bill_pkg.html new file mode 100644 index 000000000..2b9e1e69d --- /dev/null +++ b/httemplate/search/report_cust_credit_bill_pkg.html @@ -0,0 +1,104 @@ +<& /elements/header.html, mt('Credit application report') &> + +
+ + + emt('Employee: '), + 'access_user' => \%access_user, +&> + +<& /elements/tr-select-agent.html, + curr_value => scalar( $cgi->param('agentnum') ), + #label => emt('Line items for agent: '), + disable_empty => 0, +&> + + + + + + +<& /elements/tr-input-beginning_ending.html, + 'prefix' => 'credit', +&> + +<& /elements/tr-input-lessthan_greaterthan.html, + label => emt('Amount'), + field => 'amount', +&> + + + + + +
+ +
+ + +
+ +<& /elements/footer.html &> +<%init> + +#Financial reports? +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + +#false laziness w/report_cust_credit.html +my $sth = dbh->prepare("SELECT DISTINCT usernum FROM cust_credit") + or die dbh->errstr; +$sth->execute or die $sth->errstr; +my @usernum = map $_->[0], @{$sth->fetchall_arrayref}; +my %access_user = + map { $_ => qsearchs('access_user',{'usernum'=>$_})->username } + @usernum; + +my $conf = new FS::Conf; + + + -- cgit v1.2.1 From f35dc3162276739ca95bc380490e83ede5b73393 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 19 Dec 2012 12:06:59 -0800 Subject: fix customer import, #20695 --- FS/FS/cust_main/Import.pm | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/FS/FS/cust_main/Import.pm b/FS/FS/cust_main/Import.pm index eadcc1a55..e5a4485f9 100644 --- a/FS/FS/cust_main/Import.pm +++ b/FS/FS/cust_main/Import.pm @@ -22,6 +22,8 @@ install_callback FS::UID sub { $conf = new FS::Conf; }; +my %is_location = map { $_ => 1 } FS::cust_main::Location->location_fields; + =head1 NAME FS::cust_main::Import - Batch customer importing @@ -316,13 +318,14 @@ sub batch_import { custbatch => $custbatch, agentnum => $agentnum, refnum => $refnum, - country => $conf->config('countrydefault') || 'US', payby => $payby, #default paydate => '12/2037', #default ); my $billtime = time; my %cust_pkg = ( pkgpart => $pkgpart ); my %svc_x = (); + my %bill_location = (); + my %ship_location = (); foreach my $field ( @fields ) { if ( $field =~ /^cust_pkg\.(pkgpart|setup|bill|susp|adjourn|expire|cancel)$/ ) { @@ -351,6 +354,14 @@ sub batch_import { $svc_x{$1} = shift @columns; + } elsif ( $is_location{$field} ) { + + $bill_location{$field} = shift @columns; + + } elsif ( $field =~ /^ship_(.*)$/ and $is_location{$1} ) { + + $ship_location{$1} = shift @columns; + } else { #refnum interception @@ -379,6 +390,16 @@ sub batch_import { my $value = shift @columns; $cust_main{$field} = $value if length($value); } + } # foreach my $field + # finished importing columns + + $bill_location{'country'} ||= $conf->config('countrydefault') || 'US'; + $cust_main{'bill_location'} = FS::cust_location->new(\%bill_location); + if ( grep $_, values(%ship_location) ) { + $ship_location{'country'} ||= $conf->config('countrydefault') || 'US'; + $cust_main{'ship_location'} = FS::cust_location->new(\%ship_location); + } else { + $cust_main{'ship_location'} = $cust_main{'bill_location'}; } if ( defined $cust_main{'payinfo'} && length $cust_main{'payinfo'} ) { -- cgit v1.2.1 From f197bdbaa16df592a82971c63aa4321a4788d335 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 19 Dec 2012 12:33:48 -0800 Subject: fix in-use test for IP addresses in cases where blocknum is not set --- FS/FS/svc_IP_Mixin.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/svc_IP_Mixin.pm b/FS/FS/svc_IP_Mixin.pm index 7026205a5..7eda7e02c 100644 --- a/FS/FS/svc_IP_Mixin.pm +++ b/FS/FS/svc_IP_Mixin.pm @@ -93,7 +93,7 @@ sub _used_addresses { # in use, yes? my %hash = ( $ip_field => { op => '!=', value => '' } ); - $hash{'blocknum'} = $block->blocknum if $block; + #$hash{'blocknum'} = $block->blocknum if $block; $hash{'svcnum'} = { op => '!=', value => $exclude->svcnum } if ref $exclude; map { $_->NetAddr->addr } qsearch($class->table, \%hash); } -- cgit v1.2.1 From 0f701fc214468f8fb242435893de3fe084ba63f5 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 19 Dec 2012 12:41:57 -0800 Subject: fix JS error when pkgpart-lineage is off --- httemplate/edit/part_pkg.cgi | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index f3ad8f52d..50aeb4595 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -622,23 +622,23 @@ END my $warning = 'Changing the setup or recurring fee will create a new package definition. '. 'Continue?'; - + +$javascript .= "function confirm_submit(f) {"; if ( $conf->exists('part_pkg-lineage') ) { $javascript .= " - function confirm_submit(f) { - - var fields = Array('setup_fee','recur_fee'); - for(var i=0; i < fields.length; i++) { - if ( f[fields[i]].value != f[fields[i]].defaultValue ) { - return confirm('$warning'); - } - } - return true; + + var fields = Array('setup_fee','recur_fee'); + for(var i=0; i < fields.length; i++) { + if ( f[fields[i]].value != f[fields[i]].defaultValue ) { + return confirm('$warning'); + } } "; } - -$javascript .= ''; +$javascript .= " + return true; +} +"; tie my %plans, 'Tie::IxHash', %{ FS::part_pkg::plan_info() }; -- cgit v1.2.1 From e5c1e2e0ca42e5857b27890307bca616ee8982aa Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 19 Dec 2012 13:53:52 -0800 Subject: ignore pkg_svc quantities when changing a customer location, #20588 --- FS/FS/cust_location.pm | 3 +++ FS/FS/cust_pkg.pm | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm index 1521960d4..b86529b3d 100644 --- a/FS/FS/cust_location.pm +++ b/FS/FS/cust_location.pm @@ -324,6 +324,9 @@ sub move_to { my $dbh = dbh; my $error = ''; + # prevent this from failing because of pkg_svc quantity limits + local( $FS::cust_svc::ignore_quantity ) = 1; + if ( !$new->locationnum ) { $error = $new->insert; if ( $error ) { diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 75a0d7792..22a7b2c03 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -2889,7 +2889,8 @@ sub transfer { } foreach my $cust_svc ($self->cust_svc) { - if($target{$cust_svc->svcpart} > 0) { + if($target{$cust_svc->svcpart} > 0 + or $FS::cust_svc::ignore_quantity) { # maybe should be a 'force' option $target{$cust_svc->svcpart}--; my $new = new FS::cust_svc { $cust_svc->hash }; $new->pkgnum($dest_pkgnum); -- cgit v1.2.1 From 7031d0c599829fa3f3f6d8a24e955146cea883f5 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 19 Dec 2012 16:11:53 -0800 Subject: eft_canada: don't zero-pad account numbers, RT#20023 --- FS/FS/pay_batch/eft_canada.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/pay_batch/eft_canada.pm b/FS/FS/pay_batch/eft_canada.pm index ea9d58402..220fecb3d 100644 --- a/FS/FS/pay_batch/eft_canada.pm +++ b/FS/FS/pay_batch/eft_canada.pm @@ -112,7 +112,7 @@ my %holiday = ( } push @fields, sprintf('%05s', $branch), sprintf('%03s', $bankno), - sprintf('%012s', $account), + $account, sprintf('%.02f', $cust_pay_batch->amount); # DB = debit push @fields, 'DB', $trans_code, $process_date; -- cgit v1.2.1 From bfa1e79d41fe82808c79d064a65633d828c0e0b3 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 19 Dec 2012 20:16:06 -0800 Subject: not much of an experiment anymore if many of our big customers are doing it, RT#6802 --- FS/bin/freeside-daily | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/bin/freeside-daily b/FS/bin/freeside-daily index 65e3ebd97..ac93aaf2f 100755 --- a/FS/bin/freeside-daily +++ b/FS/bin/freeside-daily @@ -143,7 +143,7 @@ the bill and collect methods of a cust_main object. See L. -l: debugging level - -m: Experimental multi-process mode uses the job queue for multi-process and/or multi-machine billing. + -m: Multi-process mode uses the job queue for multi-process and/or multi-machine billing. -r: Multi-process mode dry run option -- cgit v1.2.1 From dfe7dc2e2fd943016ce324609d532f5429deb1dd Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 19 Dec 2012 23:31:49 -0800 Subject: translate 'Adv' in prospect searchbar, thanks to Fernando M. Kiernan for the patch --- httemplate/elements/searchbar-prospect.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/searchbar-prospect.html b/httemplate/elements/searchbar-prospect.html index ac363796e..a604467b1 100644 --- a/httemplate/elements/searchbar-prospect.html +++ b/httemplate/elements/searchbar-prospect.html @@ -2,7 +2,7 @@

- Adv + <% mt('Adv') |h %>
<% $menu_position eq 'left' ? '
' : '' |n %> -- cgit v1.2.1 From 578ec27f71498b63102e4cca204575c01c1f8fa9 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 19 Dec 2012 23:36:21 -0800 Subject: translate the instructions at least on this page, hanks to Fernando M. Kiernan for the patch --- httemplate/pref/pref.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/pref/pref.html b/httemplate/pref/pref.html index 575b8045b..1e9671dcc 100644 --- a/httemplate/pref/pref.html +++ b/httemplate/pref/pref.html @@ -5,7 +5,7 @@ <% include('/elements/error.html') %> -Change password (leave blank for no change) +<% mt('Change password (leave blank for no change)') |h %> <% ntable("#cccccc",2) %> -- cgit v1.2.1 From 2ee09c1343daa939da146c102dbca72f0a98d2bf Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 01:51:24 -0800 Subject: add "with email address(es)" and "without postal mail invoices" to adv. customer search, RT#20708 --- FS/FS/cust_main/Search.pm | 21 +++++++++++++++++++++ httemplate/search/cust_main.html | 3 ++- httemplate/search/report_cust_main.html | 10 ++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/FS/FS/cust_main/Search.pm b/FS/FS/cust_main/Search.pm index b07223ec5..1047890c3 100644 --- a/FS/FS/cust_main/Search.pm +++ b/FS/FS/cust_main/Search.pm @@ -632,6 +632,27 @@ sub search { push @where, "geocode is not null" if $params->{'with_geocode'}; + ## + # "with email address(es)" checkbox + ## + + push @where, + 'EXISTS ( SELECT 1 FROM cust_main_invoice + WHERE cust_main_invoice.custnum = cust_main.custnum + AND length(dest) > 5 + )' # AND dest LIKE '%@%' + if $params->{'with_email'}; + + ## + # "without postal mail invoices" checkbox + ## + + push @where, + "NOT EXISTS ( SELECT 1 FROM cust_main_invoice + WHERE cust_main_invoice.custnum = cust_main.custnum + AND dest = 'POST' )" + if $params->{'no_POST'}; + ## # dates ## diff --git a/httemplate/search/cust_main.html b/httemplate/search/cust_main.html index fa79b4dfb..8b39ea962 100755 --- a/httemplate/search/cust_main.html +++ b/httemplate/search/cust_main.html @@ -42,7 +42,8 @@ my %search_hash = (); #scalars my @scalars = qw ( agentnum status address zip paydate_year paydate_month invoice_terms - no_censustract with_geocode custbatch usernum + no_censustract with_geocode with_email no_POST + custbatch usernum cancelled_pkgs cust_fields flattened_pkgs ); diff --git a/httemplate/search/report_cust_main.html b/httemplate/search/report_cust_main.html index 3e7181d4f..acc49aec6 100755 --- a/httemplate/search/report_cust_main.html +++ b/httemplate/search/report_cust_main.html @@ -168,6 +168,16 @@ % } + + <% mt('With email address(es)') |h %> + + + + + <% mt('Without postal mail invoices') |h %> + + +   -- cgit v1.2.1 From dc2442a29ef550dea824e52f348a45c92b7710b4 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 02:44:59 -0800 Subject: use_carrierid now accepts multiple values, RT#20706 --- FS/FS/part_pkg/voip_cdr.pm | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 01fb99f6d..84b00e99d 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -149,7 +149,7 @@ tie my %unrateable_opts, 'Tie::IxHash', 'type' => 'checkbox', }, - 'use_carrierid' => { 'name' => 'Only charge for CDRs where the Carrier ID is set to: ', + 'use_carrierid' => { 'name' => 'Only charge for CDRs where the Carrier ID is set to any of these (comma-separated) values: ', }, 'use_cdrtypenum' => { 'name' => 'Only charge for CDRs where the CDR Type is set to: ', @@ -466,11 +466,11 @@ sub check_chargable { return 'amaflags != 2' if $self->option_cacheable('use_amaflags') && $cdr->amaflags != 2; - return "disposition NOT IN ( $self->option_cacheable('disposition_in') )" + return "disposition NOT IN ( ". $self->option_cacheable('disposition_in')." )" if $self->option_cacheable('disposition_in') =~ /\S/ && !grep { $cdr->disposition eq $_ } split(/\s*,\s*/, $self->option_cacheable('disposition_in')); - return "disposition IN ( $self->option_cacheable('ignore_disposition') )" + return "disposition IN ( ". $self->option_cacheable('ignore_disposition')." )" if $self->option_cacheable('ignore_disposition') =~ /\S/ && grep { $cdr->disposition eq $_ } split(/\s*,\s*/, $self->option_cacheable('ignore_disposition')); @@ -479,26 +479,26 @@ sub check_chargable { if length($_) && substr($cdr->dst,0,length($_)) eq $_; } - return "carrierid != $self->option_cacheable('use_carrierid')" - if length($self->option_cacheable('use_carrierid')) - && $cdr->carrierid ne $self->option_cacheable('use_carrierid') #ne otherwise 0 matches '' + return "carrierid NOT IN ( ". $self->option_cacheable('use_carrierid'). " )" + if $self->option_cacheable('use_carrierid') =~ /\S/ + && !grep { $cdr->carrierid eq $_ } split(/\s*,\s*/, $self->option_cacheable('use_carrierid')) #eq otherwise 0 matches '' && ! $flags{'da_rewrote'}; # unlike everything else, use_cdrtypenum is applied in FS::svc_x::get_cdrs. - return "cdrtypenum != $self->option_cacheable('use_cdrtypenum')" + return "cdrtypenum != ". $self->option_cacheable('use_cdrtypenum') if length($self->option_cacheable('use_cdrtypenum')) && $cdr->cdrtypenum ne $self->option_cacheable('use_cdrtypenum'); #ne otherwise 0 matches '' - return "cdrtypenum == $self->option_cacheable('ignore_cdrtypenum')" + return "cdrtypenum == ". $self->option_cacheable('ignore_cdrtypenum') if length($self->option_cacheable('ignore_cdrtypenum')) && $cdr->cdrtypenum eq $self->option_cacheable('ignore_cdrtypenum'); #eq otherwise 0 matches '' - return "dcontext IN ( $self->option_cacheable('skip_dcontext') )" + return "dcontext IN ( ". $self->option_cacheable('skip_dcontext'). " )" if $self->option_cacheable('skip_dcontext') =~ /\S/ && grep { $cdr->dcontext eq $_ } split(/\s*,\s*/, $self->option_cacheable('skip_dcontext')); my $len_prefix = length($self->option_cacheable('skip_dstchannel_prefix')); - return "dstchannel starts with $self->option_cacheable('skip_dstchannel_prefix')" + return "dstchannel starts with ". $self->option_cacheable('skip_dstchannel_prefix') if $len_prefix && substr($cdr->dstchannel,0,$len_prefix) eq $self->option_cacheable('skip_dstchannel_prefix'); @@ -509,7 +509,7 @@ sub check_chargable { && $cdr->is_tollfree('accountcode') ); - return "lastapp is $self->option_cacheable('skip_lastapp')" + return "lastapp is ". $self->option_cacheable('skip_lastapp') if length($self->option_cacheable('skip_lastapp')) && $cdr->lastapp eq $self->option_cacheable('skip_lastapp'); my $src_length = $self->option_cacheable('skip_src_length_more'); -- cgit v1.2.1 From 9ff8902948074943f59ebad50842253574c45af2 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 10:59:05 -0800 Subject: add pkgnum var to phone_shellcommands export, RT#20725 --- FS/FS/part_export/phone_shellcommands.pm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FS/FS/part_export/phone_shellcommands.pm b/FS/FS/part_export/phone_shellcommands.pm index 5c1ae0153..9ace21355 100644 --- a/FS/FS/part_export/phone_shellcommands.pm +++ b/FS/FS/part_export/phone_shellcommands.pm @@ -49,6 +49,7 @@ old_ for replace operations):
  • $sip_password - SIP secret (quoted for the shell)
  • $pin - Personal identification number
  • $cust_name - Customer name (quoted for the shell) +
  • $pkgnum - Internal package number END ); @@ -87,6 +88,7 @@ sub _export_command { ${$_} = $svc_phone->getfield($_) foreach $svc_phone->fields; } my $cust_pkg = $svc_phone->cust_svc->cust_pkg; + my $pkgnum = $cust_pkg ? $cust_pkg->pkgnum : ''; my $cust_name = $cust_pkg ? $cust_pkg->cust_main->name : ''; $cust_name = shell_quote $cust_name; my $sip_password = shell_quote $svc_phone->sip_password; @@ -111,7 +113,10 @@ sub _export_replace { ${"new_$_"} = $new->getfield($_) foreach $new->fields; } + my $old_cust_pkg = $old->cust_svc->cust_pkg; + my $old_pkgnum = $old_cust_pkg ? $old_cust_pkg->pkgnum : ''; my $cust_pkg = $new->cust_svc->cust_pkg; + my $new_pkgnum = $cust_pkg ? $cust_pkg->pkgnum : ''; my $new_cust_name = $cust_pkg ? $cust_pkg->cust_main->name : ''; $new_cust_name = shell_quote $new_cust_name; #done setting variables for the command -- cgit v1.2.1 From 452da5c4005c7dccc504db38578b9af2227d6e15 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Thu, 20 Dec 2012 11:50:46 -0800 Subject: improve display of ticket service links, #17067 --- FS/FS/UI/Web/small_custview.pm | 2 +- rt/lib/RT/URI/freeside/Internal.pm | 22 +++++++--- rt/share/html/Ticket/Elements/AddCustomers | 4 ++ rt/share/html/Ticket/Elements/Customers | 62 +++++++++++++++++++++++++++++ rt/share/html/Ticket/Elements/EditCustomers | 36 ++++++++++++----- rt/share/html/Ticket/Elements/ShowCustomers | 23 +++++++---- 6 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 rt/share/html/Ticket/Elements/Customers diff --git a/FS/FS/UI/Web/small_custview.pm b/FS/FS/UI/Web/small_custview.pm index e4b5421a2..ae0a4211b 100644 --- a/FS/FS/UI/Web/small_custview.pm +++ b/FS/FS/UI/Web/small_custview.pm @@ -29,7 +29,7 @@ sub small_custview { : qsearchs('cust_main', { 'custnum' => $arg } ) or die "unknown custnum $arg"; - my $html = '
    '; + my $html = '
    '; $html = qq!View ' if $url; diff --git a/rt/lib/RT/URI/freeside/Internal.pm b/rt/lib/RT/URI/freeside/Internal.pm index b5e56ee1f..61b256ef9 100644 --- a/rt/lib/RT/URI/freeside/Internal.pm +++ b/rt/lib/RT/URI/freeside/Internal.pm @@ -161,12 +161,12 @@ sub _FreesideURILabelLong { } elsif ( $table eq 'cust_svc' ) { my $string = ''; - my $cust = $self->CustomerResolver; - if ( $cust ) { - $string = $cust->AsStringLong; - } - $string .= '' . - $self->AsString . ''; + # we now do this within the UI + #my $cust = $self->CustomerResolver; + #if ( $cust ) { + # $string = $cust->AsStringLong; + #} + $string .= $self->AsString; return $string; } else { @@ -177,6 +177,16 @@ sub _FreesideURILabelLong { } +sub AsString { + my $self = shift; + if ( $self->{'fstable'} eq 'cust_svc' ) { + return '' . + $self->_FreesideURILabel . ''; + } else { + $self->SUPER::AsString; + } +} + sub CustomerResolver { my $self = shift; if ( $self->{fstable} eq 'cust_main' ) { diff --git a/rt/share/html/Ticket/Elements/AddCustomers b/rt/share/html/Ticket/Elements/AddCustomers index 13fb2f010..0ae4f9eaa 100644 --- a/rt/share/html/Ticket/Elements/AddCustomers +++ b/rt/share/html/Ticket/Elements/AddCustomers @@ -21,6 +21,8 @@ > + + <& .small_custview, $customer &> @@ -30,6 +32,8 @@ > + + <& .small_custview, $service &> <& .small_svcview, $service &> diff --git a/rt/share/html/Ticket/Elements/Customers b/rt/share/html/Ticket/Elements/Customers new file mode 100644 index 000000000..d90ef1c44 --- /dev/null +++ b/rt/share/html/Ticket/Elements/Customers @@ -0,0 +1,62 @@ +%# Copyright (c) 2004 Ivan Kohler +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +<%doc> +Provides resolver objects (RT::URI::freeside) for customer/service links +to a specified ticket. + +Do this: +%hash = $m->comp('Customers', Ticket => $ticket); + +%hash contains four elements: +- "custnums", an arrayref of customer numbers that are linked to the ticket, + in order. +- "cust_main", a hashref of custnum => customer object, for each custnum. +- "cust_linked", a hashref of custnum => boolean flag. If the flag is true, + then the customer is _explicitly_ linked (i.e. there is a + 'freeside://freeside/cust_main/' record in the Links table). Otherwise, + the customer link is implied by a service link but doesn't exist in its + own right. +- "cust_svc", a hashref of custnum => an arrayref of service objects that + are linked to the ticket and belong to that customer. + +<%init> +my @custnums; +my %cust_main; +my %cust_svc; +my %cust_linked; +my $customers = $Ticket->Customers; +# ensure each customer is displayed only once +while (my $link = $customers->Next) { + my $uri = $link->Target; + if ( $uri =~ /cust_main\/(\d+)/ ) { + $cust_main{$1} = $link->TargetURI->Resolver; + $cust_linked{$1} = 1; + } elsif ( $uri =~ /cust_svc\/(\d+)/ ) { + my $svc = $link->TargetURI->Resolver; + my $cust = $svc->CustomerResolver; + my $custnum = $cust->{fspkey}; + $cust_main{$custnum} ||= $cust; + $cust_svc{$custnum} ||= []; + push @{$cust_svc{$custnum}}, $svc; + } +} +@custnums = sort { $a <=> $b } keys %cust_main; +return ( + 'custnums' => \@custnums, + 'cust_main' => \%cust_main, + 'cust_svc' => \%cust_svc, + 'cust_linked' => \%cust_linked, +); + +<%ARGS> +$Ticket => undef + diff --git a/rt/share/html/Ticket/Elements/EditCustomers b/rt/share/html/Ticket/Elements/EditCustomers index 96207f4cc..e8aa69edc 100644 --- a/rt/share/html/Ticket/Elements/EditCustomers +++ b/rt/share/html/Ticket/Elements/EditCustomers @@ -15,22 +15,36 @@

    <&|/l&>Current Customers

    +% my %data = $m->comp('Customers', Ticket => $Ticket); +% if ( @{ $data{custnums} } ) { + - + +% foreach my $custnum ( @{ $data{custnums} } ) { +% foreach my $resolver +% ( $data{cust_main}{$custnum}, @{ $data{cust_svc}{$custnum} } ) +% { + +% } +% }
    <&|/l&>(Check box to disassociate)<&|/l&>(Check box to disassociate)
    -% foreach my $link ( @{ $Ticket->Customers->ItemsArrayRef } ) { - - -%# <& ShowLink, URI => $link->TargetURI &>
    - <% $link->TargetURI->Resolver->AsStringLong |n %> -

    -% } +% if ( $resolver->URI !~ /cust_main/ or $data{cust_linked}{$custnum} ) { +% # don't show a checkbox for implicit cust_main links + +% } +
    + <% $resolver->AsStringLong |n %>
    +% } @@ -38,15 +52,15 @@

    <&|/l&>New Customer Links

    - + %# rowspan - + <&|/l&>Find customer

    cust #, name, company or phone - + <&|/l&>Find service
    diff --git a/rt/share/html/Ticket/Elements/ShowCustomers b/rt/share/html/Ticket/Elements/ShowCustomers index add562440..175822f52 100644 --- a/rt/share/html/Ticket/Elements/ShowCustomers +++ b/rt/share/html/Ticket/Elements/ShowCustomers @@ -9,20 +9,29 @@ %# WITHOUT ANY WARRANTY; without even the implied warranty of %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %# General Public License for more details. +<%init> +my %data = $m->comp('Customers', Ticket => $Ticket); + + -% my @cust = map { $_->TargetURI->Resolver } -% @{ $Ticket->Customers->ItemsArrayRef }; -% -% foreach my $custResolver ( @cust ) { +% foreach my $custnum (@{ $data{custnums} }) { +% my $cust = $data{cust_main}{$custnum}; % } -% unless ( @cust ) { +% unless ( @{ $data{custnums} } ) { - + + % $old_invnum = $cust_bill_pkg->invnum; % } +% my $el_name = 'billpkgnum'. $cust_bill_pkg->billpkgnum. '-'. $setuprecur; %# show one-time/setup vs recur vs usage? + % } - + - + - + - @@ -183,12 +194,21 @@ function calc_total(what) { var setuprecurs = []; var amounts = []; for (var i=0; iparam("billpkgnum$billpkgnum_setuprecur"); + my $amount = $cgi->param("billpkgnum$billpkgnum_setuprecur-amount"); my( $billpkgnum, $setuprecur ) = split('-', $billpkgnum_setuprecur); push @billpkgnums, $billpkgnum; push @setuprecurs, $setuprecur; diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html index 6630d12a5..942b42f54 100644 --- a/httemplate/view/cust_main/payment_history.html +++ b/httemplate/view/cust_main/payment_history.html @@ -77,7 +77,7 @@ 'action' => "${p}edit/credit-cust_bill_pkg.html", 'cust_main' => $cust_main, 'actionlabel' => emt('Credit line items'), - 'width' => 884, #763, + 'width' => 968, #763, 'height' => 575, &>
    -- cgit v1.2.1 From 8ae921f9d6b1405e3712a7626b80014cd29d5259 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 23:01:42 -0800 Subject: credit line items interface: set credit amounts, RT#18676 --- FS/FS/cust_credit.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index 9fd2d01a4..18d8bedb3 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -812,7 +812,6 @@ sub credit_lineitems { # do so evenly...) my $loc_amount = min( $amount, $location->amount); - #$taxtotal += $loc_amount $amount -= $loc_amount; #push @taxlines, -- cgit v1.2.1 From c6e21dc3379f34f23896f2a09731c34981ab6018 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 21 Dec 2012 00:07:41 -0800 Subject: add option _not_ to apply a lineitem credit, RT#18676 --- FS/FS/cust_credit.pm | 6 ++++++ httemplate/edit/credit-cust_bill_pkg.html | 9 +++++++++ httemplate/edit/process/credit-cust_bill_pkg.html | 1 + 3 files changed, 16 insertions(+) diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index 18d8bedb3..fe9572f6b 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -629,6 +629,7 @@ Example: 'billpkgnums' => \@billpkgnums, 'setuprecurs' => \@setuprecurs, 'amounts' => \@amounts, + 'apply' => 1, #0 leaves the credit unapplied #the credit 'newreasonnum' => scalar($cgi->param('newreasonnum')), @@ -706,6 +707,11 @@ sub credit_lineitems { return "Error inserting credit: $error"; } + unless ( $arg{'apply'} ) { + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + return ''; + } + #my $subtotal = 0; my $taxlisthash = {}; my %cust_credit_bill = (); diff --git a/httemplate/edit/credit-cust_bill_pkg.html b/httemplate/edit/credit-cust_bill_pkg.html index f5c4eefbf..e0ca04b5e 100644 --- a/httemplate/edit/credit-cust_bill_pkg.html +++ b/httemplate/edit/credit-cust_bill_pkg.html @@ -91,6 +91,15 @@ +% if ( $conf->exists('credits-auto-apply-disable') ) { + +% } else { +
    + + + +% } +
    - <% $custResolver->AsStringLong |n %> -%# includes service label and view/svc_ link for cust_svc links + <% $cust->AsStringLong |n %> +% foreach my $svc ( @{ $data{cust_svc}{$custnum} || [] } ) { + <% $svc->AsString |n %> +
    +% }
    (none) -- cgit v1.2.1 From 825e0f0fdb1fb45c8b9523e795da816773f04295 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 12:06:13 -0800 Subject: fix "Use of implicit split to @_ is deprecated" warning, RT#20731, RT#20706 --- FS/FS/part_pkg/voip_cdr.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 84b00e99d..aae51e96c 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -481,8 +481,8 @@ sub check_chargable { return "carrierid NOT IN ( ". $self->option_cacheable('use_carrierid'). " )" if $self->option_cacheable('use_carrierid') =~ /\S/ - && !grep { $cdr->carrierid eq $_ } split(/\s*,\s*/, $self->option_cacheable('use_carrierid')) #eq otherwise 0 matches '' - && ! $flags{'da_rewrote'}; + && ! $flags{'da_rewrote'} #why? + && !grep { $cdr->carrierid eq $_ } split(/\s*,\s*/, $self->option_cacheable('use_carrierid')); #eq otherwise 0 matches '' # unlike everything else, use_cdrtypenum is applied in FS::svc_x::get_cdrs. return "cdrtypenum != ". $self->option_cacheable('use_cdrtypenum') -- cgit v1.2.1 From 89bdc751a892188eebca4a193c8e8e37af8efc35 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 18:25:07 -0800 Subject: fix state selection w/voip innovations API, add better error logging, RT#15150 --- FS/FS/part_export/globalpops_voip.pm | 10 ++++++++-- httemplate/elements/select-state.html | 21 +++++++++++++-------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/FS/FS/part_export/globalpops_voip.pm b/FS/FS/part_export/globalpops_voip.pm index 9fe45ba0a..59e0bc46f 100644 --- a/FS/FS/part_export/globalpops_voip.pm +++ b/FS/FS/part_export/globalpops_voip.pm @@ -5,6 +5,7 @@ use Tie::IxHash; use FS::Record qw(qsearch dbh); use FS::part_export; use FS::phone_avail; +use Data::Dumper; @ISA = qw(FS::part_export); @@ -74,8 +75,13 @@ sub get_dids { if ( $search->{'statuscode'} == 302200 ) { return []; } elsif ( $search->{'statuscode'} != 100 ) { - my $error = "Error running VoIP Innovations getDIDs: ". - $search->{'statuscode'}. ': '. $search->{'status'}. "\n"; + + my $error = "Error running VoIP Innovations getDIDs: "; + if ( $search->{'statuscode'} || $search->{'status'} ) { + $error .= $search->{'statuscode'}. ': '. $search->{'status'}. "\n"; + } else { + $error .= Dumper($search); + } warn $error; die $error; } diff --git a/httemplate/elements/select-state.html b/httemplate/elements/select-state.html index 490dafa80..115a98d98 100644 --- a/httemplate/elements/select-state.html +++ b/httemplate/elements/select-state.html @@ -66,14 +66,19 @@ tie my %states, 'Tie::IxHash', states_hash( $opt{'country'} ); if ( $opt{'svcpart'} ) { - my $sth = dbh->prepare( - 'SELECT DISTINCT state FROM phone_avail WHERE svcnum IS NULL' - ) or die dbh->errstr; - $sth->execute or die $sth->errstr; - my %avail_states = map { $_->[0] => 1 } @{ $sth->fetchall_arrayref }; - - if ( %avail_states ) { - delete $states{$_} foreach grep ! $avail_states{$_}, keys %states; + my $part_svc = qsearchs('part_svc', { 'svcpart' => $opt{'svcpart'} } ); + if ( $part_svc && $part_svc->exporttype eq 'internal_diddb' ) { + + my $sth = dbh->prepare( + 'SELECT DISTINCT state FROM phone_avail WHERE svcnum IS NULL' + ) or die dbh->errstr; + $sth->execute or die $sth->errstr; + my %avail_states = map { $_->[0] => 1 } @{ $sth->fetchall_arrayref }; + + if ( %avail_states ) { + delete $states{$_} foreach grep ! $avail_states{$_}, keys %states; + } + } } -- cgit v1.2.1 From 2027c653847c5dfe77bf25f3a71337f132078e9d Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 19:34:13 -0800 Subject: fix tax-on-tax (i.e. FEDERAL UNIVERSAL SERVICE FUND) on 2.3 branch, RT#20707 --- FS/FS/cust_main/Billing.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index 3dc8f9cad..0ec6b5429 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -831,7 +831,7 @@ sub calculate_taxes { my $taxables = $taxlisthash->{$tax}; my $tax_object = shift @$taxables; # the rest are line items foreach my $cust_bill_pkg ( @$taxables ) { - next unless ref($cust_bill_pkg) eq 'FS::cust_bill_pkg'; + next unless ref($cust_bill_pkg) eq 'FS::cust_bill_pkg'; #IS needed for CCH tax-on-tax my @cust_tax_exempt_pkg = splice @{ $cust_bill_pkg->cust_tax_exempt_pkg }; -- cgit v1.2.1 From 94ff30dbfd8bcdd47170b3a93f8112dd2da68aa9 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 20:52:30 -0800 Subject: fix tax detail reporting fallout from package level credits feature, RT#18676 --- httemplate/search/cust_bill_pkg.cgi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi index 34c89e532..5f02588e9 100644 --- a/httemplate/search/cust_bill_pkg.cgi +++ b/httemplate/search/cust_bill_pkg.cgi @@ -452,7 +452,7 @@ if ( $cgi->param('nottax') ) { } elsif ( $cgi->param('out') ) { - $join_pkg = ' + $join_pkg .= ' LEFT JOIN cust_bill_pkg_tax_location USING (billpkgnum) '; push @where, 'cust_bill_pkg_tax_location.billpkgnum IS NULL'; @@ -463,7 +463,7 @@ if ( $cgi->param('nottax') ) { } else { # not locationtaxid or 'out'--the normal case - $join_pkg = ' + $join_pkg .= ' LEFT JOIN cust_bill_pkg_tax_location USING (billpkgnum) JOIN cust_main_county USING (taxnum) '; -- cgit v1.2.1 From 469f31f261476205bc9cf2d59335b8c30aa5e016 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 21:53:02 -0800 Subject: add pkgnum/pkgpart to line item report< RT#18676 --- httemplate/search/cust_bill_pkg.cgi | 47 ++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi index 5f02588e9..11a5095b4 100644 --- a/httemplate/search/cust_bill_pkg.cgi +++ b/httemplate/search/cust_bill_pkg.cgi @@ -5,6 +5,8 @@ 'count_query' => $count_query, 'count_addl' => \@total_desc, 'header' => [ + @pkgnum_header, + emt('Pkg Def'), emt('Description'), @post_desc_header, @peritem_desc, @@ -15,9 +17,16 @@ FS::UI::Web::cust_header(), ], 'fields' => [ + @pkgnum, sub { $_[0]->pkgnum > 0 - ? $_[0]->get('pkg') # possibly use override.pkg - : $_[0]->get('itemdesc') # but i think this correct + # possibly use override.pkg but i think this correct + ? $_[0]->get('pkgpart') + : '' + }, + sub { $_[0]->pkgnum > 0 + # possibly use override.pkg but i think this correct + ? $_[0]->get('pkg') + : $_[0]->get('itemdesc') }, @post_desc, #strikethrough or "N/A ($amount)" or something these when @@ -30,6 +39,8 @@ \&FS::UI::Web::cust_fields, ], 'sort_fields' => [ + @pkgnum_null, + '', '', @post_desc_null, @peritem, @@ -39,7 +50,8 @@ #'credit_amount', ], 'links' => [ - #'', + @pkgnum_null, + '', '', @post_desc_null, @peritem_null, @@ -52,13 +64,15 @@ ), ], #'align' => 'rlrrrc'.FS::UI::Web::cust_aligns(), - 'align' => 'l'. + 'align' => $pkgnum_align. + 'rl'. $post_desc_align. $peritem_align. 'rcrr'. FS::UI::Web::cust_aligns(), 'color' => [ - #'', + @pkgnum_null, + '', '', @post_desc_null, @peritem_null, @@ -69,7 +83,8 @@ FS::UI::Web::cust_colors(), ], 'style' => [ - #'', + @pkgnum_null, + '', '', @post_desc_null, @peritem_null, @@ -165,8 +180,9 @@ Filtering parameters: <%init> -die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" unless $curuser->access_right('Financial reports'); my $conf = new FS::Conf; my $money_char = $conf->config('money_char') || '$'; @@ -178,6 +194,18 @@ my @total_desc = ( '%d line items', $money_char.'%.2f total' ); # sprintf string my @peritem = ( 'setup', 'recur' ); my @peritem_desc = ( 'Setup charge', 'Recurring charge' ); +my @pkgnum_header = (); +my @pkgnum = (); +my @pkgnum_null; +my $pkgnum_align = ''; +if ( $curuser->option('show_pkgnum') ) { + push @select, 'cust_bill_pkg.pkgnum'; + push @pkgnum_header, 'Pkg Num'; + push @pkgnum, sub { $_[0]->pkgnum > 0 ? $_[0]->pkgnum : '' }; + push @pkgnum_null, ''; + $pkgnum_align .= 'r'; +} + my @post_desc_header = (); my @post_desc = (); my @post_desc_null = (); @@ -249,7 +277,7 @@ if ( $cgi->param('use_override') ) { )"; $part_pkg = 'override'; } -push @select, 'part_pkg.pkg'; # or should this use override? +push @select, 'part_pkg.pkgpart', 'part_pkg.pkg'; # or should this use override? # the non-tax case if ( $cgi->param('nottax') ) { @@ -644,4 +672,5 @@ my $credit_link = [ "${p}search/cust_credit_bill_pkg.html?billpkgnum=", 'billpkg warn "\n\nQUERY:\n".Dumper($query)."\n\nCOUNT_QUERY:\n$count_query\n\n" if $cgi->param('debug'); + -- cgit v1.2.1 From 61e988d7675346395d24f1d7a2e89f4d90b95a6c Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 20 Dec 2012 23:01:07 -0800 Subject: credit line items interface: set credit amounts, RT#18676 --- FS/FS/cust_credit.pm | 14 ++++--- httemplate/edit/credit-cust_bill_pkg.html | 48 ++++++++++++++++------- httemplate/edit/process/credit-cust_bill_pkg.html | 2 +- httemplate/view/cust_main/payment_history.html | 2 +- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index dfe55fb63..9fd2d01a4 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -5,6 +5,7 @@ use base qw( FS::otaker_Mixin FS::cust_main_Mixin FS::Record ); use vars qw( $conf $unsuspendauto $me $DEBUG $otaker_upgrade_kludge $ignore_empty_reasonnum ); +use List::Util qw( min ); use Date::Format; use FS::UID qw( dbh getotaker ); use FS::Misc qw(send_email); @@ -806,19 +807,22 @@ sub credit_lineitems { foreach my $location ( $tax_cust_bill_pkg->cust_bill_pkg_tax_Xlocation ) { - $location->cust_bill_pkg_desc($taxline->desc); #ugh @ that kludge + #support partial credits: use $amount if smaller + # (so just distribute to the first location? perhaps should + # do so evenly...) + my $loc_amount = min( $amount, $location->amount); - #$taxtotal += $location->amount; - $amount -= $location->amount; + #$taxtotal += $loc_amount + $amount -= $loc_amount; #push @taxlines, # #[ $location->desc, $taxline->setup, $taxlocnum, $taxratelocnum ]; # [ $location->desc, $location->amount, $taxlocnum, $taxratelocnum ]; - $cust_credit_bill{$invnum} += $location->amount; + $cust_credit_bill{$invnum} += $loc_amount; push @{ $cust_credit_bill_pkg{$invnum} }, new FS::cust_credit_bill_pkg { 'billpkgnum' => $tax_cust_bill_pkg->billpkgnum, - 'amount' => $location->amount, + 'amount' => $loc_amount, 'setuprecur' => 'setup', 'billpkgtaxlocationnum' => $location->billpkgtaxlocationnum, 'billpkgtaxratelocationnum' => $location->billpkgtaxratelocationnum, diff --git a/httemplate/edit/credit-cust_bill_pkg.html b/httemplate/edit/credit-cust_bill_pkg.html index e317936b3..f5c4eefbf 100644 --- a/httemplate/edit/credit-cust_bill_pkg.html +++ b/httemplate/edit/credit-cust_bill_pkg.html @@ -20,18 +20,18 @@ % next unless $amount > 0; % if ( $cust_bill_pkg->invnum ne $old_invnum ) { -
     
    Invoice #<% $cust_bill_pkg->invnum %> - <% time2str($date_format, $cust_bill_pkg->cust_bill->_date) %>
     
    Invoice #<% $cust_bill_pkg->invnum %> - <% time2str($date_format, $cust_bill_pkg->cust_bill->_date) %>
    @@ -39,24 +39,35 @@ <% $cust_bill_pkg->desc |h %><% $money_char. $amount %> + <% $money_char %> +
     
     
    Subtotal: Subtotal: <% $money_char %><% sprintf('%.2f', 0) %>
    Taxes: Taxes: <% $money_char %><% sprintf('%.2f', 0) %>
    Total credit amount: + Total credit amount: <% $money_char %><% sprintf('%.2f', 0) %>
    <% mt('Apply to selected line items') |h %>

    diff --git a/httemplate/edit/process/credit-cust_bill_pkg.html b/httemplate/edit/process/credit-cust_bill_pkg.html index 1b6199772..cbcf619ca 100644 --- a/httemplate/edit/process/credit-cust_bill_pkg.html +++ b/httemplate/edit/process/credit-cust_bill_pkg.html @@ -32,6 +32,7 @@ my $error = FS::cust_credit->credit_lineitems( 'billpkgnums' => \@billpkgnums, 'setuprecurs' => \@setuprecurs, 'amounts' => \@amounts, + 'apply' => ( $cgi->param('apply') eq 'yes' ), #the credit 'newreasonnum' => scalar($cgi->param('newreasonnum')), -- cgit v1.2.1 From d837405e32b0c698e2c13d1080a2135a7e717f1b Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 21 Dec 2012 11:47:02 -0800 Subject: taxclass for ipifony downloaded charges, #18333 --- FS/bin/freeside-ipifony-download | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/FS/bin/freeside-ipifony-download b/FS/bin/freeside-ipifony-download index e893326e2..64905e193 100644 --- a/FS/bin/freeside-ipifony-download +++ b/FS/bin/freeside-ipifony-download @@ -12,7 +12,7 @@ use FS::Conf; use Text::CSV; my %opt; -getopts('va:P:C:', \%opt); +getopts('va:P:C:T:', \%opt); #$Net::SFTP::Foreign::debug = -1; sub HELP_MESSAGE { ' @@ -22,6 +22,7 @@ sub HELP_MESSAGE { ' [ -a archivedir ] [ -P port ] [ -C category ] + [ -T taxclass ] freesideuser sftpuser@hostname[:path] ' } @@ -60,6 +61,8 @@ if ( $opt{C} ) { $categorynum = $category->categorynum; } +my $taxclass = $opt{T} || ''; + #my $tmpdir = File::Temp->newdir(); my $tmpdir = tempdir( CLEANUP => 1 ); #DIR=>somewhere? @@ -156,6 +159,7 @@ FILE: foreach my $filename (@$files) { quantity => $hash{quantity}, start_date => $cust_main->next_bill_date, pkg => $hash{date_desc}, + taxclass => $taxclass, ); if (my $classname = $hash{classname}) { if (!exists($classnum_of{$classname}) ) { @@ -180,7 +184,6 @@ FILE: foreach my $filename (@$files) { } $opt{classnum} = $classnum_of{$classname}; } - # XXX what's the tax status of these charges? print STDERR " Charging $hash{amount}\n" if $opt{v}; my $error = $cust_main->charge(\%opt); -- cgit v1.2.1 From 95cef2cea4c98d8fde7f58bacce3cf1da955c1a0 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 21 Dec 2012 15:49:42 -0800 Subject: better internal tax links and various credit_lineitems fixes, #20629 --- FS/FS/Schema.pm | 16 +- FS/FS/Upgrade.pm | 3 + FS/FS/cust_bill_pkg.pm | 11 +- FS/FS/cust_bill_pkg_tax_location.pm | 281 +++++++++++++++++++++++++++++- FS/FS/cust_credit.pm | 198 +++++++++++++-------- FS/FS/cust_main/Billing.pm | 18 +- FS/FS/log_context.pm | 2 + httemplate/edit/credit-cust_bill_pkg.html | 9 +- 8 files changed, 449 insertions(+), 89 deletions(-) diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 172ac8296..b6fd3b67b 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -805,13 +805,19 @@ sub tables_hashref { 'billpkgnum', 'int', '', '', '', '', 'taxnum', 'int', '', '', '', '', 'taxtype', 'varchar', '', $char_d, '', '', - 'pkgnum', 'int', '', '', '', '', - 'locationnum', 'int', '', '', '', '', #redundant? + 'pkgnum', 'int', '', '', '', '', #redundant + 'locationnum', 'int', '', '', '', '', #redundant 'amount', @money_type, '', '', + 'taxable_billpkgnum', 'int', 'NULL', '', '', '', ], 'primary_key' => 'billpkgtaxlocationnum', 'unique' => [], - 'index' => [ [ 'billpkgnum' ], [ 'taxnum' ], [ 'pkgnum' ], [ 'locationnum' ] ], + 'index' => [ [ 'billpkgnum' ], + [ 'taxnum' ], + [ 'pkgnum' ], + [ 'locationnum' ], + [ 'taxable_billpkgnum' ], + ], }, 'cust_bill_pkg_tax_rate_location' => { @@ -823,10 +829,12 @@ sub tables_hashref { 'locationtaxid', 'varchar', 'NULL', $char_d, '', '', 'taxratelocationnum', 'int', '', '', '', '', 'amount', @money_type, '', '', + 'taxable_billpkgnum', 'int', 'NULL', '', '', '', ], 'primary_key' => 'billpkgtaxratelocationnum', 'unique' => [], - 'index' => [ [ 'billpkgnum' ], [ 'taxnum' ], [ 'taxratelocationnum' ] ], + 'index' => [ [ 'billpkgnum' ], [ 'taxnum' ], [ 'taxratelocationnum' ], + [ 'taxable_billpkgnum' ], ], }, 'cust_bill_pkg_void' => { diff --git a/FS/FS/Upgrade.pm b/FS/FS/Upgrade.pm index 45cba82a4..fea53a235 100644 --- a/FS/FS/Upgrade.pm +++ b/FS/FS/Upgrade.pm @@ -305,6 +305,9 @@ sub upgrade_data { #kick off tax location history upgrade 'cust_bill_pkg' => [], + + #fix taxable line item links + 'cust_bill_pkg_tax_location' => [], ; \%hash; diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index a83af1326..5cff140bb 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -1310,9 +1310,10 @@ sub upgrade_tax_location { ); $cents_remaining -= $part; push @tax_links, { - taxnum => $taxdef->taxnum, - pkgnum => $nontax->pkgnum, - cents => $part, + taxnum => $taxdef->taxnum, + pkgnum => $nontax->pkgnum, + billpkgnum => $nontax->billpkgnum, + cents => $part, }; } #foreach $nontax } #foreach $taxclass @@ -1355,6 +1356,7 @@ sub upgrade_tax_location { taxnum => $_->{taxnum}, pkgnum => $_->{pkgnum}, amount => sprintf('%.2f', $_->{cents} / 100), + taxable_billpkgnum => $_->{billpkgnum}, }); my $error = $link->insert; if ( $error ) { @@ -1443,6 +1445,9 @@ sub _upgrade_data { # Then mark the upgrade as done, so that we don't queue the job twice # and somehow run two of them concurrently. FS::upgrade_journal->set_done($upgrade); + # This upgrade now does the job of assigning taxable_billpkgnums to + # cust_bill_pkg_tax_location, so set that task done also. + FS::upgrade_journal->set_done('tax_location_taxable_billpkgnum'); } =back diff --git a/FS/FS/cust_bill_pkg_tax_location.pm b/FS/FS/cust_bill_pkg_tax_location.pm index 44dd6e3c4..723d6e0a3 100644 --- a/FS/FS/cust_bill_pkg_tax_location.pm +++ b/FS/FS/cust_bill_pkg_tax_location.pm @@ -9,6 +9,9 @@ use FS::cust_location; use FS::cust_bill_pay_pkg; use FS::cust_credit_bill_pkg; use FS::cust_main_county; +use FS::Log; + +use List::Util qw(sum min); =head1 NAME @@ -65,6 +68,11 @@ locationnum amount +=item taxable_billpkgnum + +The billpkgnum of the L that this tax was charged on. +It may specifically be on any portion of that line item (setup, recurring, +or a usage class). =back @@ -119,6 +127,7 @@ sub check { || $self->ut_foreign_key('pkgnum', 'cust_pkg', 'pkgnum' ) || $self->ut_foreign_key('locationnum', 'cust_location', 'locationnum' ) || $self->ut_money('amount') + || $self->ut_foreign_key('taxable_billpkgnum', 'cust_bill_pkg', 'billpkgnum') ; return $error if $error; @@ -127,7 +136,7 @@ sub check { =item cust_bill_pkg -Returns the associated cust_bill_pkg object +Returns the associated cust_bill_pkg object (i.e. the tax charge). =cut @@ -136,6 +145,10 @@ sub cust_bill_pkg { qsearchs( 'cust_bill_pkg', { 'billpkgnum' => $self->billpkgnum } ); } +=item taxable_cust_bill_pkg + +Returns the cust_bill_pkg object for the I charge. + =item cust_location Returns the associated cust_location object @@ -208,12 +221,274 @@ sub cust_main_county { } } +sub _upgrade_data { + eval { + use FS::queue; + use Date::Parse 'str2time'; + }; + my $class = shift; + my $upgrade = 'tax_location_taxable_billpkgnum'; + return if FS::upgrade_journal->is_done($upgrade); + my $job = FS::queue->new({ job => + 'FS::cust_bill_pkg_tax_location::upgrade_taxable_billpkgnum' + }); + $job->insert($class, 's' => str2time('2012-01-01')); + FS::upgrade_journal->set_done($upgrade); +} + +sub upgrade_taxable_billpkgnum { + # Associate these records to the correct taxable line items. + # The cust_bill_pkg upgrade now does this also for pre-3.0 records that + # aren't broken out by pkgnum, so we only need to deal with the case of + # multiple line items for the same pkgnum. + # Despite appearances, this has almost no relation to the upgrade in + # FS::cust_bill_pkg. + + my ($class, %opt) = @_; + my $dbh = FS::UID::dbh(); + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $log = FS::Log->new('upgrade_taxable_billpkgnum'); + + my $date_where = ''; + if ( $opt{s} ) { + $date_where .= " AND cust_bill._date >= $opt{s}"; + } + if ( $opt{e} ) { + $date_where .= " AND cust_bill._date < $opt{e}"; + } + + my @need_to_upgrade = qsearch({ + select => 'cust_bill_pkg_tax_location.*', + table => 'cust_bill_pkg_tax_location', + hashref => { taxable_billpkgnum => '' }, + addl_from => 'JOIN cust_bill_pkg USING (billpkgnum)'. + 'JOIN cust_bill USING (invnum)', + extra_sql => $date_where, + }); + $log->info('Starting upgrade of '.scalar(@need_to_upgrade). + ' cust_bill_pkg_tax_location records.'); + + # keys are billpkgnums + my %cust_bill_pkg; + my %tax_location; + foreach (@need_to_upgrade) { + my $tax_billpkgnum = $_->billpkgnum; + $cust_bill_pkg{ $tax_billpkgnum } ||= FS::cust_bill_pkg->by_key($tax_billpkgnum); + $tax_location{ $tax_billpkgnum } ||= []; + push @{ $tax_location{ $tax_billpkgnum } }, $_; + } + + TAX_ITEM: foreach my $tax_item (values %cust_bill_pkg) { + my $tax_locations = $tax_location{ $tax_item->billpkgnum }; + my $invnum = $tax_item->invnum; + my $cust_bill = FS::cust_bill->by_key($tax_item->invnum); + my %tax_on_pkg; # keys are tax identifiers + TAX_LOCATION: foreach my $tax_location (@$tax_locations) { + # recapitulate the "cust_main_county $taxnum $pkgnum" tax identifier, + # in a way + my $taxid = join(' ', + $tax_location->taxtype, + $tax_location->taxnum, + $tax_location->pkgnum, + $tax_location->locationnum + ); + $tax_on_pkg{$taxid} ||= []; + push @{ $tax_on_pkg{$taxid} }, $tax_location; + } + PKGNUM: foreach my $taxid (keys %tax_on_pkg) { + my ($taxtype, $taxnum, $pkgnum, $locationnum) = split(' ', $taxid); + $log->info("tax#$taxnum, pkg#$pkgnum", object => $cust_bill); + my @pkg_items = $cust_bill->cust_bill_pkg_pkgnum($pkgnum); + if (!@pkg_items) { + # then how is there tax on it? should never happen + $log->error("no line items with pkg#$pkgnum", object => $cust_bill); + next PKGNUM; + } + my $pkg_amount = 0; + foreach my $pkg_item (@pkg_items) { + # find the taxable amount of each one + my $amount = $pkg_item->setup + $pkg_item->recur; + # subtract any exemptions that apply to this taxdef + foreach (qsearch('cust_tax_exempt_pkg', { + taxnum => $taxnum, + billpkgnum => $pkg_item->billpkgnum + }) ) + { + $amount -= $_->amount; + } + $pkg_item->set('amount' => $pkg_item->setup + $pkg_item->recur); + $pkg_amount += $amount; + } #$pkg_item + next PKGNUM if $pkg_amount == 0; # probably because it's fully exempted + # now sort them descending by taxable amount + @pkg_items = sort { $b->amount <=> $a->amount } + @pkg_items; + # and do the same with the tax links + # (there should be one per taxed item) + my @tax_links = sort { $b->amount <=> $a->amount } + @{ $tax_on_pkg{$taxid} }; + + if (scalar(@tax_links) == scalar(@pkg_items)) { + # the relatively simple case: they match 1:1 + for my $i (0 .. scalar(@tax_links) - 1) { + $tax_links[$i]->set('taxable_billpkgnum', + $pkg_items[$i]->billpkgnum); + my $error = $tax_links[$i]->replace; + if ( $error ) { + $log->error("failed to set taxable_billpkgnum in tax on pkg#$pkgnum", + object => $cust_bill); + next PKGNUM; + } + } #for $i + } else { + # the more complicated case + $log->warn("mismatched charges and tax links in pkg#$pkgnum", + object => $cust_bill); + my $tax_amount = sum(map {$_->amount} @tax_links); + # remove all tax link records and recreate them to be 1:1 with + # taxable items + my (%billpaynum, %creditbillnum); + my $link_type; + foreach my $tax_link (@tax_links) { + $link_type ||= ref($tax_link); + my $error = $tax_link->delete; + if ( $error ) { + $log->error("error unlinking tax#$taxnum pkg#$pkgnum", + object => $cust_bill); + next PKGNUM; + } + my $pkey = $tax_link->primary_key; + # also remove all applications that reference this tax link + # (they will be applications to the tax item) + my %hash = ($pkey => $tax_link->get($pkey)); + foreach (qsearch('cust_bill_pay_pkg', \%hash)) { + $billpaynum{$_->billpaynum} += $_->amount; + my $error = $_->delete; + die "error unapplying payment: $error" if ( $error ); + } + foreach (qsearch('cust_credit_bill_pkg', \%hash)) { + $creditbillnum{$_->creditbillnum} += $_->amount; + my $error = $_->delete; + die "error unapplying credit: $error" if ( $error ); + } + } + @tax_links = (); + my $cents_remaining = int(100 * $tax_amount); + foreach my $pkg_item (@pkg_items) { + my $cents = int(100 * $pkg_item->amount * $tax_amount / $pkg_amount); + my $tax_link = $link_type->new({ + taxable_billpkgnum => $pkg_item->billpkgnum, + billpkgnum => $tax_item->billpkgnum, + taxnum => $taxnum, + taxtype => $taxtype, + pkgnum => $pkgnum, + locationnum => $locationnum, + cents => $cents, + }); + push @tax_links, $tax_link; + $cents_remaining -= $cents; + } + my $nlinks = scalar @tax_links; + my $i = 0; + while ($cents_remaining) { + $tax_links[$i % $nlinks]->set('cents' => + $tax_links[$i % $nlinks]->cents + 1 + ); + $cents_remaining--; + $i++; + } + foreach my $tax_link (@tax_links) { + $tax_link->set('amount' => sprintf('%.2f', $tax_link->cents / 100)); + my $error = $tax_link->insert; + if ( $error ) { + $log->error("error relinking tax#$taxnum pkg#$pkgnum", + object => $cust_bill); + next PKGNUM; + } + } + + $i = 0; + my $error; + my $left = 0; # the amount "left" on the last tax link after + # applying payments, but before credits, so that + # it can receive both a payment and a credit if + # necessary + # reapply payments/credits...this sucks + foreach my $billpaynum (keys %billpaynum) { + my $pay_amount = $billpaynum{$billpaynum}; + while ($i < $nlinks and $pay_amount > 0) { + my $this_amount = min($pay_amount, $tax_links[$i]->amount); + $left = $tax_links[$i]->amount - $this_amount; + my $app = FS::cust_bill_pay_pkg->new({ + billpaynum => $billpaynum, + billpkgnum => $tax_links[$i]->billpkgnum, + billpkgtaxlocationnum => $tax_links[$i]->billpkgtaxlocationnum, + amount => $this_amount, + setuprecur => 'setup', + # sdate/edate are null + }); + my $error ||= $app->insert; + $pay_amount -= $this_amount; + $i++ if $left == 0; + } + } + foreach my $creditbillnum (keys %creditbillnum) { + my $credit_amount = $creditbillnum{$creditbillnum}; + while ($i < $nlinks and $credit_amount > 0) { + my $this_amount = min($left, $credit_amount, $tax_links[$i]->amount); + $left = $credit_amount * 2; # just so it can't be selected twice + $i++ if $this_amount == $left + or $this_amount == $tax_links[$i]->amount; + my $app = FS::cust_credit_bill_pkg->new({ + creditbillnum => $creditbillnum, + billpkgnum => $tax_links[$i]->billpkgnum, + billpkgtaxlocationnum => $tax_links[$i]->billpkgtaxlocationnum, + amount => $this_amount, + setuprecur => 'setup', + # sdate/edate are null + }); + my $error ||= $app->insert; + $credit_amount -= $this_amount; + } + } + if ( $error ) { + # we've just unapplied a bunch of stuff, so if it won't reapply + # we really need to revert the whole transaction + die "error reapplying payments/credits: $error; upgrade halted"; + } + } # scalar(@tax_links) ?= scalar(@pkg_items) + } #taxnum/pkgnum + } #TAX_ITEM + + $log->info('finish'); + + $dbh->commit if $oldAutoCommit; + return; +} + +=cut + =back =head1 BUGS -The presense of FS::cust_main_county::delete makes the cust_main_county method -unreliable +The presence of FS::cust_main_county::delete makes the cust_main_county method +unreliable. + +Pre-3.0 versions of Freeside would only create one cust_bill_pkg_tax_location +per tax definition (taxtype/taxnum) per invoice. The pkgnum and locationnum +fields were arbitrarily set to those of the first line item subject to the +tax. This created problems if the tax contribution of each line item ever +needed to be determined (for example, when applying credits). For several +months in 2012, this was changed to create one record per tax definition +per I per invoice, which was still not specific enough to identify +a line item. + +The current behavior is to create one record per tax definition per taxable +line item, and to store the billpkgnum of the taxed line item in the record. +The upgrade will try to convert existing records to the new format, but this +is not perfectly reliable. =head1 SEE ALSO diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index fe9572f6b..7741bbee2 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -646,7 +646,6 @@ Example: use FS::cust_bill_pkg; sub credit_lineitems { my( $class, %arg ) = @_; - my $curuser = $FS::CurrentUser::CurrentUser; #some false laziness w/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html @@ -713,10 +712,11 @@ sub credit_lineitems { } #my $subtotal = 0; - my $taxlisthash = {}; + # keys in all of these are invoice numbers my %cust_credit_bill = (); my %cust_bill_pkg = (); my %cust_credit_bill_pkg = (); + my %taxlisthash = (); foreach my $billpkgnum ( @{$arg{billpkgnums}} ) { my $setuprecur = shift @{$arg{setuprecurs}}; my $amount = shift @{$arg{amounts}}; @@ -727,6 +727,8 @@ sub credit_lineitems { 'addl_from' => 'LEFT JOIN cust_bill USING (invnum)', 'extra_sql' => 'AND custnum = '. $cust_main->custnum, }) or die "unknown billpkgnum $billpkgnum"; + + my $invnum = $cust_bill_pkg->invnum; if ( $setuprecur eq 'setup' ) { $cust_bill_pkg->setup($amount); @@ -740,8 +742,9 @@ sub credit_lineitems { $cust_bill_pkg->unitsetup(0); } - push @{$cust_bill_pkg{$cust_bill_pkg->invnum}}, $cust_bill_pkg; + push @{$cust_bill_pkg{$invnum}}, $cust_bill_pkg; + my %unapplied_payments; # billpaynum => amount #unapply any payments applied to this line item (other credits too?) foreach my $cust_bill_pay_pkg ( $cust_bill_pkg->cust_bill_pay_pkg($setuprecur) ) { $error = $cust_bill_pay_pkg->delete; @@ -749,25 +752,51 @@ sub credit_lineitems { $dbh->rollback if $oldAutoCommit; return "Error unapplying payment: $error"; } + $unapplied_payments{$cust_bill_pay_pkg->billpaynum} + += $cust_bill_pay_pkg->amount; + } + # also unapply that amount from the invoice so it doesn't screw up + # application of the credit + foreach my $billpaynum (keys %unapplied_payments) { + my $cust_bill_pay = FS::cust_bill_pay->by_key($billpaynum) + or die "broken payment application $billpaynum"; + $error = $cust_bill_pay->delete; # can't replace + + my $new_cust_bill_pay = FS::cust_bill_pay->new({ + $cust_bill_pay->hash, + billpaynum => '', + amount => sprintf('%.2f', + $cust_bill_pay->amount - $unapplied_payments{$billpaynum}), + }); + + if ( $new_cust_bill_pay->amount > 0 ) { + $error ||= $new_cust_bill_pay->insert; + } + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error unapplying payment: $error"; + } } #$subtotal += $amount; - $cust_credit_bill{$cust_bill_pkg->invnum} += $amount; - push @{ $cust_credit_bill_pkg{$cust_bill_pkg->invnum} }, + $cust_credit_bill{$invnum} += $amount; + push @{ $cust_credit_bill_pkg{$invnum} }, new FS::cust_credit_bill_pkg { 'billpkgnum' => $cust_bill_pkg->billpkgnum, - 'amount' => $amount, + 'amount' => sprintf('%.2f',$amount), 'setuprecur' => $setuprecur, 'sdate' => $cust_bill_pkg->sdate, 'edate' => $cust_bill_pkg->edate, }; + # recalculate taxes with new amounts + $taxlisthash{$invnum} ||= {}; my $part_pkg = $cust_bill_pkg->part_pkg; $cust_main->_handle_taxes( $part_pkg, - $taxlisthash, + $taxlisthash{$invnum}, $cust_bill_pkg, $cust_bill_pkg->cust_pkg, - $cust_bill_pkg->cust_bill->_date, + $cust_bill_pkg->cust_bill->_date, #invoice time $cust_bill_pkg->cust_pkg->pkgpart, ); } @@ -781,83 +810,108 @@ sub credit_lineitems { foreach my $invnum ( sort { $a <=> $b } keys %cust_credit_bill ) { - #taxes + my $arrayref_or_error = + $cust_main->calculate_taxes( + $cust_bill_pkg{$invnum}, # list of taxable items that we're crediting + $taxlisthash{$invnum}, # list of tax-item bindings + $cust_bill_pkg{$invnum}->[0]->cust_bill->_date, # invoice time + ); - if ( @{ $cust_bill_pkg{$invnum} } ) { - - my $listref_or_error = - $cust_main->calculate_taxes( $cust_bill_pkg{$invnum}, $taxlisthash, $cust_bill_pkg{$invnum}->[0]->cust_bill->_date ); + unless ( ref( $arrayref_or_error ) ) { + $dbh->rollback if $oldAutoCommit; + return "Error calculating taxes: $arrayref_or_error"; + } + + my %tax_links; # {tax billpkgnum}{nontax billpkgnum} - unless ( ref( $listref_or_error ) ) { - $dbh->rollback if $oldAutoCommit; - return "Error calculating taxes: $listref_or_error"; + #taxes + foreach my $cust_bill_pkg ( @{ $cust_bill_pkg{$invnum} } ) { + my $billpkgnum = $cust_bill_pkg->billpkgnum; + my %hash = ( 'taxable_billpkgnum' => $billpkgnum ); + # gather up existing tax links (we need their billpkgtaxlocationnums) + my @tax_links = qsearch('cust_bill_pkg_tax_location', \%hash), + qsearch('cust_bill_pkg_tax_rate_location', \%hash); + + foreach ( @tax_links ) { + $tax_links{$_->billpkgnum} ||= {}; + $tax_links{$_->billpkgnum}{$_->taxable_billpkgnum} = $_; } + } - # so, loop through the taxlines, apply just that amount to the tax line - # item (save for later insert) & add to $ - - #my @taxlines = (); - #my $taxtotal = 0; - foreach my $taxline ( @$listref_or_error ) { - - #find equivalent tax line items on the existing invoice - # (XXX need a more specific/deterministic way to find these than itemdesc..) - my $tax_cust_bill_pkg = qsearchs('cust_bill_pkg', { - 'invnum' => $invnum, - 'pkgnum' => 0, #$taxline->invnum - 'itemdesc' => $taxline->desc, - }); - - my $amount = $taxline->setup; - my $desc = $taxline->desc; - - foreach my $location ( $tax_cust_bill_pkg->cust_bill_pkg_tax_Xlocation ) { - - #support partial credits: use $amount if smaller - # (so just distribute to the first location? perhaps should - # do so evenly...) - my $loc_amount = min( $amount, $location->amount); - - $amount -= $loc_amount; - - #push @taxlines, - # #[ $location->desc, $taxline->setup, $taxlocnum, $taxratelocnum ]; - # [ $location->desc, $location->amount, $taxlocnum, $taxratelocnum ]; - $cust_credit_bill{$invnum} += $loc_amount; - push @{ $cust_credit_bill_pkg{$invnum} }, - new FS::cust_credit_bill_pkg { - 'billpkgnum' => $tax_cust_bill_pkg->billpkgnum, - 'amount' => $loc_amount, - 'setuprecur' => 'setup', - 'billpkgtaxlocationnum' => $location->billpkgtaxlocationnum, - 'billpkgtaxratelocationnum' => $location->billpkgtaxratelocationnum, - }; - - } - if ($amount > 0) { - #$taxtotal += $amount; - #push @taxlines, - # [ $taxline->itemdesc. ' (default)', sprintf('%.2f', $amount), '', '' ]; - - $cust_credit_bill{$invnum} += $amount; - push @{ $cust_credit_bill_pkg{$invnum} }, - new FS::cust_credit_bill_pkg { - 'billpkgnum' => $tax_cust_bill_pkg->billpkgnum, - 'amount' => $amount, - 'setuprecur' => 'setup', - }; - + foreach my $taxline ( @$arrayref_or_error ) { + + my $amount = $taxline->setup; + + # find equivalent tax line item on the existing invoice + my $tax_item = qsearchs('cust_bill_pkg', { + 'invnum' => $invnum, + 'pkgnum' => 0, + 'itemdesc' => $taxline->desc, + }); + if (!$tax_item) { + # or should we just exit if this happens? + $cust_credit->set('amount', + sprintf('%.2f', $cust_credit->get('amount') - $amount) + ); + my $error = $cust_credit->replace; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "error correcting credit for missing tax line: $error"; } } - } + # but in the new era, we no longer have the problem of uniquely + # identifying the tax_Xlocation record. The billpkgnums of the + # tax and the taxed item are known. + foreach my $new_loc + ( @{ $taxline->get('cust_bill_pkg_tax_location') }, + @{ $taxline->get('cust_bill_pkg_tax_rate_location') } ) + { + # the existing tax_Xlocation object + my $old_loc = + $tax_links{$tax_item->billpkgnum}{$new_loc->taxable_billpkgnum}; + + next if !$old_loc; # apply the leftover amount nonspecifically + + #support partial credits: use $amount if smaller + # (so just distribute to the first location? perhaps should + # do so evenly...) + my $loc_amount = min( $amount, $new_loc->amount); + + $amount -= $loc_amount; + + $cust_credit_bill{$invnum} += $loc_amount; + push @{ $cust_credit_bill_pkg{$invnum} }, + new FS::cust_credit_bill_pkg { + 'billpkgnum' => $tax_item->billpkgnum, + 'amount' => $loc_amount, + 'setuprecur' => 'setup', + 'billpkgtaxlocationnum' => $old_loc->billpkgtaxlocationnum, + 'billpkgtaxratelocationnum' => $old_loc->billpkgtaxratelocationnum, + }; + + } #foreach my $new_loc + + # we still have to deal with the possibility that the tax links don't + # cover the whole amount of tax because of an incomplete upgrade... + if ($amount > 0) { + $cust_credit_bill{$invnum} += $amount; + push @{ $cust_credit_bill_pkg{$invnum} }, + new FS::cust_credit_bill_pkg { + 'billpkgnum' => $tax_item->billpkgnum, + 'amount' => $amount, + 'setuprecur' => 'setup', + }; + + } # if $amount > 0 + } #foreach $taxline #insert cust_credit_bill my $cust_credit_bill = new FS::cust_credit_bill { 'crednum' => $cust_credit->crednum, 'invnum' => $invnum, - 'amount' => $cust_credit_bill{$invnum}, + 'amount' => sprintf('%.2f', $cust_credit_bill{$invnum}), }; $error = $cust_credit_bill->insert; if ( $error ) { diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index 0ec6b5429..6d3ff9146 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -760,11 +760,13 @@ sub calculate_taxes { my %tax_exemption; foreach my $tax ( keys %$taxlisthash ) { - # $tax is a tax identifier + # $tax is a tax identifier (intersection of a tax definition record + # and a cust_bill_pkg record) my $tax_object = shift @{ $taxlisthash->{$tax} }; # $tax_object is a cust_main_county or tax_rate - # (with pkgnum and locationnum set) - # the rest of @{ $taxlisthash->{$tax} } is cust_bill_pkg objects + # (with billpkgnum, pkgnum, locationnum set) + # the rest of @{ $taxlisthash->{$tax} } is cust_bill_pkg component objects + # (setup, recurring, usage classes) warn "found ". $tax_object->taxname. " as $tax\n" if $DEBUG > 2; warn " ". join('/', @{ $taxlisthash->{$tax} } ). "\n" if $DEBUG > 2; # taxline calculates the tax on all cust_bill_pkgs in the @@ -808,6 +810,7 @@ sub calculate_taxes { 'pkgnum' => $tax_object->get('pkgnum'), 'locationnum' => $tax_object->get('locationnum'), 'amount' => sprintf('%.2f', $amount ), + 'taxable_billpkgnum' => $tax_object->get('billpkgnum'), }; } elsif ( ref($tax_object) eq 'FS::tax_rate' ) { @@ -820,6 +823,7 @@ sub calculate_taxes { 'amount' => sprintf('%.2f', $amount ), 'locationtaxid' => $tax_object->location, 'taxratelocationnum' => $taxratelocationnum, + 'taxable_billpkgnum' => $tax_object->get('billpkgnum'), }; } @@ -1284,6 +1288,10 @@ sub _handle_taxes { foreach (@taxes) { # These could become cust_bill_pkg_tax_location records, # or cust_tax_exempt_pkg. We'll decide later. + # + # The most important thing here: record which charge is being taxed. + $_->set('billpkgnum', $cust_bill_pkg->billpkgnum); + # also these, for historical reasons $_->set('pkgnum', $cust_pkg->pkgnum); $_->set('locationnum', $cust_pkg->tax_locationnum); } @@ -1325,8 +1333,8 @@ sub _handle_taxes { # this is the tax identifier, not the taxname my $taxname = ref( $tax ). ' '. $tax->taxnum; - $taxname .= ' pkgnum'. $cust_pkg->pkgnum; - # We need to create a separate $taxlisthash entry for each pkgnum + $taxname .= ' billpkgnum'. $cust_bill_pkg->billpkgnum; + # We need to create a separate $taxlisthash entry for each billpkgnum # on the invoice, so that cust_bill_pkg_tax_location records will # be linked correctly. diff --git a/FS/FS/log_context.pm b/FS/FS/log_context.pm index 372bdaa39..a25490588 100644 --- a/FS/FS/log_context.pm +++ b/FS/FS/log_context.pm @@ -12,6 +12,8 @@ my @contexts = ( qw( spool_upload daily queue + upgrade + upgrade_taxable_billpkgnum ) ); =head1 NAME diff --git a/httemplate/edit/credit-cust_bill_pkg.html b/httemplate/edit/credit-cust_bill_pkg.html index e0ca04b5e..3d1cf2438 100644 --- a/httemplate/edit/credit-cust_bill_pkg.html +++ b/httemplate/edit/credit-cust_bill_pkg.html @@ -80,6 +80,7 @@ 'field' => 'reasonnum', 'reason_class' => 'R', #XXX reconcile both this and show_taxes wanteding to enable this + 'id' => 'select_reason', 'control_button' => "document.getElementById('credit_button')", 'cgi' => $cgi, &> @@ -114,6 +115,8 @@ %> - <% mt('Check #:') |h %> + <% mt('Check #:') |h %> + + + + + + + + <% mt('Transaction #') |h %> + + - + diff --git a/httemplate/view/cust_pay.html b/httemplate/view/cust_pay.html index f9c8bc19c..76a24884a 100644 --- a/httemplate/view/cust_pay.html +++ b/httemplate/view/cust_pay.html @@ -77,7 +77,7 @@ <% $cust_pay->payby_name %> #<% $cust_pay->paymask %> -% if ( $cust_pay->payby =~ /^(CARD|CHEK|LECB)$/ && $cust_pay->paybatch ) { +% if ( $cust_pay->payby =~ /^(CARD|CHEK|LECB)$/ && $cust_pay->processor ) { <% mt('Processor') |h %> @@ -86,7 +86,7 @@ <% mt('Authorization #') |h %> - <% $cust_pay->authorization %> + <% $cust_pay->auth %> % if ( $cust_pay->order_number ) { diff --git a/httemplate/view/cust_refund.html b/httemplate/view/cust_refund.html index 996b4c05a..319761506 100644 --- a/httemplate/view/cust_refund.html +++ b/httemplate/view/cust_refund.html @@ -62,7 +62,7 @@ <% $cust_refund->payby_name %><% $cust_refund->paymask ? ' #'.$cust_refund->paymask : '' %> -% if ( $cust_refund->payby =~ /^(CARD|CHEK|LECB)$/ && $cust_refund->paybatch ) { +% if ( $cust_refund->payby =~ /^(CARD|CHEK|LECB)$/ && $cust_refund->processor ) { <% mt('Processor') |h %> @@ -71,7 +71,7 @@ <% mt('Authorization #') |h %> - <% $cust_refund->authorization %> + <% $cust_refund->auth %> % if ( $cust_refund->order_number ) { -- cgit v1.2.1 From 47835e6fb2ff9da30bd95ce10f1f22a3ce1cb8b5 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 2 Jan 2013 19:07:15 -0800 Subject: also allow searching by transaction for payby=CHEK --- httemplate/search/elements/report_cust_pay_or_refund.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/search/elements/report_cust_pay_or_refund.html b/httemplate/search/elements/report_cust_pay_or_refund.html index 7a1216bb6..0e04ab0dd 100644 --- a/httemplate/search/elements/report_cust_pay_or_refund.html +++ b/httemplate/search/elements/report_cust_pay_or_refund.html @@ -53,7 +53,7 @@ Examples: if ( what.value == 'BILL' ) { show('payinfo'); hide('ccpay'); - } else if ( what.value.match(/^CARD/) ) { + } else if ( what.value.match(/^CARD|CHEK/) ) { hide('payinfo'); show('ccpay'); } else { -- cgit v1.2.1 From 949114e0f65232b405e084bcfcff37b1fd9a2926 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Thu, 3 Jan 2013 12:47:41 -0800 Subject: more reasonable solution for #17067 --- rt/lib/RT/URI/freeside/Internal.pm | 28 +++++++++++++--------------- rt/share/html/Elements/CustomerFields | 2 +- rt/share/html/Ticket/Elements/EditCustomers | 4 ++++ rt/share/html/Ticket/Elements/ShowCustomers | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/rt/lib/RT/URI/freeside/Internal.pm b/rt/lib/RT/URI/freeside/Internal.pm index 61b256ef9..b0962860d 100644 --- a/rt/lib/RT/URI/freeside/Internal.pm +++ b/rt/lib/RT/URI/freeside/Internal.pm @@ -143,7 +143,7 @@ sub small_custview { } -sub _FreesideURILabelLong { +sub AsStringLong { my $self = shift; @@ -161,30 +161,28 @@ sub _FreesideURILabelLong { } elsif ( $table eq 'cust_svc' ) { my $string = ''; - # we now do this within the UI - #my $cust = $self->CustomerResolver; - #if ( $cust ) { - # $string = $cust->AsStringLong; - #} - $string .= $self->AsString; + my $cust = $self->CustomerResolver; + if ( $cust ) { + # the customer's small_custview + $string = $cust->AsStringLong(); + } + # + the service label and link + $string .= $self->ShortLink; return $string; } else { - return $self->_FreesideURILabel(); + return $self->SUPER::AsStringLong; } } -sub AsString { +sub ShortLink { + # because I don't want AsString to sometimes return a hunk of HTML, but + # on the other hand AsStringLong does something specific. my $self = shift; - if ( $self->{'fstable'} eq 'cust_svc' ) { - return '' . - $self->_FreesideURILabel . ''; - } else { - $self->SUPER::AsString; - } + '' . $self->_FreesideURILabel . ''; } sub CustomerResolver { diff --git a/rt/share/html/Elements/CustomerFields b/rt/share/html/Elements/CustomerFields index 199184b69..d5419d213 100644 --- a/rt/share/html/Elements/CustomerFields +++ b/rt/share/html/Elements/CustomerFields @@ -27,7 +27,7 @@ my @customer_fields = ( # ordered my @return = (); foreach my $c (ticket_cust_resolvers($Ticket)) { push @return, \'', - $c->_FreesideURILabel, + $c->AsString, \'', \'
    '; } diff --git a/rt/share/html/Ticket/Elements/EditCustomers b/rt/share/html/Ticket/Elements/EditCustomers index e8aa69edc..cc9956f91 100644 --- a/rt/share/html/Ticket/Elements/EditCustomers +++ b/rt/share/html/Ticket/Elements/EditCustomers @@ -38,7 +38,11 @@ % } +% if ( $resolver->URI =~ /cust_main/ ) { <% $resolver->AsStringLong |n %> +% } elsif ( $resolver->URI =~ /cust_svc/ ) { + <% $resolver->ShortLink |n %> +% } % } diff --git a/rt/share/html/Ticket/Elements/ShowCustomers b/rt/share/html/Ticket/Elements/ShowCustomers index 175822f52..f9b0133b5 100644 --- a/rt/share/html/Ticket/Elements/ShowCustomers +++ b/rt/share/html/Ticket/Elements/ShowCustomers @@ -24,7 +24,7 @@ my %data = $m->comp('Customers', Ticket => $Ticket); <% $cust->AsStringLong |n %> % foreach my $svc ( @{ $data{cust_svc}{$custnum} || [] } ) { - <% $svc->AsString |n %> + <% $svc->ShortLink |n %>
    % } -- cgit v1.2.1 From 170085d3536733f303e242503f0e034c65016b73 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 5 Jan 2013 14:49:38 -0800 Subject: cleanup noop cruft --- httemplate/search/cust_bill_pkg.cgi | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi index 11a5095b4..817238da0 100644 --- a/httemplate/search/cust_bill_pkg.cgi +++ b/httemplate/search/cust_bill_pkg.cgi @@ -189,7 +189,7 @@ my $money_char = $conf->config('money_char') || '$'; my @select = ( 'cust_bill_pkg.*', 'cust_bill._date' ); my @total = ( 'COUNT(*)', 'SUM(cust_bill_pkg.setup + cust_bill_pkg.recur)'); -my @total_desc = ( '%d line items', $money_char.'%.2f total' ); # sprintf strings +my @total_desc = ( $money_char.'%.2f total' ); # sprintf strings my @peritem = ( 'setup', 'recur' ); my @peritem_desc = ( 'Setup charge', 'Recurring charge' ); @@ -443,7 +443,7 @@ if ( $cgi->param('nottax') ) { push @select, "($recur_no_usage) AS recur_no_usage"; $peritem[1] = 'recur_no_usage'; $total[1] = "SUM(cust_bill_pkg.setup + $recur_no_usage)"; - $total_desc[1] .= ' (excluding usage)'; + $total_desc[0] .= ' (excluding usage)'; } elsif ( $cgi->param('usage') eq 'usage' ) { @@ -453,7 +453,7 @@ if ( $cgi->param('nottax') ) { $peritem[1] = '_usage'; $peritem_desc[1] = 'Usage charge'; $total[1] = "SUM($usage)"; - $total_desc[1] .= ' usage charges'; + $total_desc[0] .= ' usage charges'; } } elsif ( $cgi->param('istax') ) { @@ -650,8 +650,6 @@ my $count_query = " FROM cust_bill_pkg $join_cust $join_pkg $where"; -shift @total_desc; #the first one is implicit - @peritem_desc = map {emt($_)} @peritem_desc; my @peritem_sub = map { my $field = $_; -- cgit v1.2.1 From 53b9ba47322ee112b3f259006ce1eeb8410904b9 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 5 Jan 2013 15:48:47 -0800 Subject: 3.0 --- FS/FS.pm | 2 +- httemplate/docs/about.html | 4 ++-- httemplate/docs/credits.html | 11 ++++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/FS/FS.pm b/FS/FS.pm index 2d963b54f..2517c1fd6 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -3,7 +3,7 @@ package FS; use strict; use vars qw($VERSION); -$VERSION = '3.0git'; +$VERSION = '3.0'; #find missing entries in this file with: # for a in `ls *pm | cut -d. -f1`; do grep 'L' ../FS.pm >/dev/null || echo "missing $a" ; done diff --git a/httemplate/docs/about.html b/httemplate/docs/about.html index 33b21a3ad..c2ba4e4a0 100644 --- a/httemplate/docs/about.html +++ b/httemplate/docs/about.html @@ -28,7 +28,7 @@ % } else { % } -© 2012 Freeside Internet Services, Inc.
    +© 2013 Freeside Internet Services, Inc.
    All rights reserved.
    Licensed under the terms of the
    GNU Affero General Public License.
    @@ -56,7 +56,7 @@ GNU Affero General Public License.
    % unless ( $agentnum ) {
    - + "I can't figure out ... if it's an end or the beginning" - R. Hunter
    % } diff --git a/httemplate/docs/credits.html b/httemplate/docs/credits.html index c1d0d8705..218698fb9 100644 --- a/httemplate/docs/credits.html +++ b/httemplate/docs/credits.html @@ -26,9 +26,9 @@

    version <% $FS::VERSION %>

    -
    -
    +
    +

    Core Team

    Jeremy Davis
    @@ -36,6 +36,9 @@ Ivan Kohler
    Mark Wells

    +
    +
    +

    Core Emeritus

    Peter Bowen
    Jeff Finucane
    @@ -76,6 +79,8 @@ Sean Hanson
    Dale Hege
    Kelly Hickel
    Mark James
    +Gary Jones
    +Fernando M. Kiernan
    Frederico Caldeira Knabben
    Greg Kuhnert
    Randall Lucas
    @@ -162,7 +167,7 @@ function myHeight() { document.body.style.overflow = 'hidden'; -var startingPosition = 340; +var startingPosition = 303; //huh, adjust for firefox var ua = navigator.userAgent; -- cgit v1.2.1 From 8a54677fd5dfcc1e55188374b206de24275fd780 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 5 Jan 2013 21:24:39 -0800 Subject: the future is now --- FS/FS.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS.pm b/FS/FS.pm index 2517c1fd6..f2e37fd83 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -3,7 +3,7 @@ package FS; use strict; use vars qw($VERSION); -$VERSION = '3.0'; +$VERSION = '3.1git'; #find missing entries in this file with: # for a in `ls *pm | cut -d. -f1`; do grep 'L' ../FS.pm >/dev/null || echo "missing $a" ; done -- cgit v1.2.1 From eb70a0b5a299e8e77e64cd10ee515270fbe14044 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 5 Jan 2013 23:49:47 -0800 Subject: rewind selektah --- FS/FS.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS.pm b/FS/FS.pm index f2e37fd83..2d963b54f 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -3,7 +3,7 @@ package FS; use strict; use vars qw($VERSION); -$VERSION = '3.1git'; +$VERSION = '3.0git'; #find missing entries in this file with: # for a in `ls *pm | cut -d. -f1`; do grep 'L' ../FS.pm >/dev/null || echo "missing $a" ; done -- cgit v1.2.1 From 2be0687ad93376100101bb270d7ff838b91a869a Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 7 Jan 2013 17:14:32 -0800 Subject: application of line item credits, #20629 --- FS/FS/cust_credit.pm | 22 ++++++++++++++++------ FS/FS/cust_main_county.pm | 2 ++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index c716602a0..082b0f256 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -646,6 +646,7 @@ Example: use FS::cust_bill_pkg; sub credit_lineitems { my( $class, %arg ) = @_; + warn Data::Dumper::Dumper \%arg; my $curuser = $FS::CurrentUser::CurrentUser; #some false laziness w/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html @@ -717,8 +718,7 @@ sub credit_lineitems { my %cust_bill_pkg = (); my %cust_credit_bill_pkg = (); my %taxlisthash = (); - # except here they're billpaynums - my %unapplied_payments; + my %unapplied_payments; #invoice numbers, and then billpaynums foreach my $billpkgnum ( @{$arg{billpkgnums}} ) { my $setuprecur = shift @{$arg{setuprecurs}}; my $amount = shift @{$arg{amounts}}; @@ -753,7 +753,7 @@ sub credit_lineitems { $dbh->rollback if $oldAutoCommit; return "Error unapplying payment: $error"; } - $unapplied_payments{$cust_bill_pay_pkg->billpaynum} + $unapplied_payments{$invnum}{$cust_bill_pay_pkg->billpaynum} += $cust_bill_pay_pkg->amount; } @@ -893,27 +893,37 @@ sub credit_lineitems { $dbh->rollback if $oldAutoCommit; return "Error unapplying payment: $error"; } - $unapplied_payments{$cust_bill_pay_pkg->billpaynum} + $unapplied_payments{$invnum}{$cust_bill_pay_pkg->billpaynum} += $cust_bill_pay_pkg->amount; } } #foreach $taxline # if we unapplied any payments from line items, also unapply that # amount from the invoice - foreach my $billpaynum (keys %unapplied_payments) { + foreach my $billpaynum (keys %{$unapplied_payments{$invnum}}) { my $cust_bill_pay = FS::cust_bill_pay->by_key($billpaynum) or die "broken payment application $billpaynum"; + my @subapps = $cust_bill_pay->lineitem_applications; $error = $cust_bill_pay->delete; # can't replace my $new_cust_bill_pay = FS::cust_bill_pay->new({ $cust_bill_pay->hash, billpaynum => '', amount => sprintf('%.2f', - $cust_bill_pay->amount - $unapplied_payments{$billpaynum}), + $cust_bill_pay->amount + - $unapplied_payments{$invnum}{$billpaynum}), }); if ( $new_cust_bill_pay->amount > 0 ) { $error ||= $new_cust_bill_pay->insert; + # Also reapply it to everything it was applied to before. + # Note that we've already deleted cust_bill_pay_pkg records for the + # items we're crediting, so they aren't on this list. + foreach my $cust_bill_pay_pkg (@subapps) { + $cust_bill_pay_pkg->billpaypkgnum(''); + $cust_bill_pay_pkg->billpaynum($new_cust_bill_pay->billpaynum); + $error ||= $cust_bill_pay_pkg->insert; + } } if ( $error ) { $dbh->rollback if $oldAutoCommit; diff --git a/FS/FS/cust_main_county.pm b/FS/FS/cust_main_county.pm index db6be751d..573359571 100644 --- a/FS/FS/cust_main_county.pm +++ b/FS/FS/cust_main_county.pm @@ -498,6 +498,8 @@ sub taxline { 'taxnum' => $self->taxnum, 'taxtype' => ref($self), 'cents' => $this_tax_cents, + 'pkgnum' => $cust_bill_pkg->pkgnum, + 'locationnum' => $cust_bill_pkg->cust_pkg->tax_locationnum, 'taxable_cust_bill_pkg' => $cust_bill_pkg, 'tax_cust_bill_pkg' => $tax_item, }); -- cgit v1.2.1 From baa48df835b04f1aee3f9cd2c03f00e780585f13 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 7 Jan 2013 17:24:16 -0800 Subject: debug --- FS/FS/cust_credit.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index 082b0f256..05d961c3f 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -646,7 +646,6 @@ Example: use FS::cust_bill_pkg; sub credit_lineitems { my( $class, %arg ) = @_; - warn Data::Dumper::Dumper \%arg; my $curuser = $FS::CurrentUser::CurrentUser; #some false laziness w/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html -- cgit v1.2.1 From e006b70d3b27db3f607471852bbe13c0281d520e Mon Sep 17 00:00:00 2001 From: gjones2 Date: Wed, 9 Jan 2013 10:11:08 -0500 Subject: Update fs_selfservice/FS-SelfService/cgi/signup.html Fixed two instances where the following markup is being produced (lacking space before SELECTED):
    + +<%init> +my %opt = @_; +my $svc_acct = $opt{'svc_acct'}; +my $curr_value = $opt{'curr_value'} || ''; +my $pre = 'changepw'.$svc_acct->svcnum.'_'; +my $error = $cgi->param($pre.'error'); + diff --git a/httemplate/elements/random_pass.html b/httemplate/elements/random_pass.html new file mode 100644 index 000000000..b215b77d9 --- /dev/null +++ b/httemplate/elements/random_pass.html @@ -0,0 +1,17 @@ + + +<%init> +my $id = shift; +my $label = shift || 'Generate'; + diff --git a/httemplate/misc/process/change-password.html b/httemplate/misc/process/change-password.html new file mode 100644 index 000000000..7005439cc --- /dev/null +++ b/httemplate/misc/process/change-password.html @@ -0,0 +1,21 @@ +<%init> +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" unless $curuser->access_right('Edit password'); + +$cgi->param('svcnum') =~ /^(\d+)$/ or die "illegal svcnum"; +my $svcnum = $1; +my $svc_acct = FS::svc_acct->by_key($svcnum) + or die "svc_acct $svcnum not found"; +my $error = $svc_acct->set_password($cgi->param('password')) + || $svc_acct->replace; + +# annoyingly specific to view/svc_acct.cgi, for now... +$cgi->delete('password'); + +% if ( $error ) { +% $cgi->param('svcnum', $svcnum); +% $cgi->param("changepw${svcnum}_error", $error); +% } else { +% $cgi->query_string($svcnum); +% } +<% $cgi->redirect($fsurl.'view/svc_acct.cgi?'.$cgi->query_string) %> -- cgit v1.2.1 From 2920cfc494c2811ca7879d6ecaa353d216c9f69d Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 27 Feb 2013 12:47:34 -0800 Subject: "Edit password" ACL, #21178, part 2 --- FS/FS/AccessRight.pm | 1 + FS/FS/Schema.pm | 4 +++- FS/FS/access_right.pm | 4 +++- FS/FS/part_svc.pm | 10 +++++++++- httemplate/browse/part_svc.cgi | 15 +++++++++++---- httemplate/edit/part_svc.cgi | 16 +++++++++++++++- httemplate/edit/process/cust_svc.cgi | 2 +- httemplate/edit/svc_acct.cgi | 18 +++--------------- httemplate/misc/process/change-password.html | 7 ++++++- httemplate/view/elements/svc_Common.html | 2 +- httemplate/view/elements/svc_edit_link.html | 9 +++++++-- httemplate/view/svc_acct.cgi | 9 ++++++--- httemplate/view/svc_acct/basics.html | 26 ++++++++++++++++++++------ 13 files changed, 86 insertions(+), 37 deletions(-) diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index 50fb0e3cb..a60d033d6 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -162,6 +162,7 @@ tie my %rights, 'Tie::IxHash', 'Recharge customer service', #NEW 'Unprovision customer service', 'Change customer service', #NEWNEW + 'Edit password', 'Edit usage', #NEW 'Edit home dir', #NEW 'Edit www config', #NEW diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 774dcd239..eff4878fd 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2112,7 +2112,8 @@ sub tables_hashref { 'preserve', 'char', 'NULL', 1, '', '', 'selfservice_access', 'varchar', 'NULL', $char_d, '', '', 'classnum', 'int', 'NULL', '', '', '', - ], + 'restrict_edit_password','char', 'NULL', 1, '', '', +], 'primary_key' => 'svcpart', 'unique' => [], 'index' => [ [ 'disabled' ] ], @@ -2260,6 +2261,7 @@ sub tables_hashref { 'cgp_sendmdnmode', 'varchar', 'NULL', $char_d, '', '',#SendMDNMode #mail #XXX RPOP settings + # ], 'primary_key' => 'svcnum', #'unique' => [ [ 'username', 'domsvc' ] ], diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm index 0c61896b9..0e8bf45a9 100644 --- a/FS/FS/access_right.pm +++ b/FS/FS/access_right.pm @@ -228,7 +228,9 @@ sub _upgrade_data { # class method 'Usage: Call Detail Records (CDRs)', 'Usage: Unrateable CDRs', ], - ; + 'Provision customer service' => [ 'Edit password' ], + +; foreach my $old_acl ( keys %onetime ) { diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm index c47177171..6ca48894a 100644 --- a/FS/FS/part_svc.pm +++ b/FS/FS/part_svc.pm @@ -58,6 +58,13 @@ L, and L, among others. =item preserve - Preserve after cancellation, empty or 'Y' +=item selfservice_access - Access allowed to the service via self-service: +empty for full access, "readonly" for read-only, "hidden" to hide it entirely + +=item restrict_edit_password - Require the "Provision customer service" access +right to change the password field, rather than just "Edit password". Only +relevant to svc_acct for now. + =back =head1 METHODS @@ -391,7 +398,8 @@ sub check { || $self->ut_enum('preserve', [ '', 'Y' ] ) || $self->ut_enum('selfservice_access', [ '', 'hidden', 'readonly' ] ) || $self->ut_foreign_keyn('classnum', 'part_svc_class', 'classnum' ) - ; + || $self->ut_enum('restrict_edit_password', [ '', 'Y' ] ) +; return $error if $error; my @fields = eval { fields( $self->svcdb ) }; #might die diff --git a/httemplate/browse/part_svc.cgi b/httemplate/browse/part_svc.cgi index a8f4a7c84..f941ae586 100755 --- a/httemplate/browse/part_svc.cgi +++ b/httemplate/browse/part_svc.cgi @@ -82,6 +82,7 @@ function part_export_areyousure(href) { % } % @dfields ; % my $rowspan = scalar(@fields) || 1; +% $rowspan++ if $part_svc->restrict_edit_password; % my $url = "${p}edit/part_svc.cgi?". $part_svc->svcpart; % % if ( $bgcolor eq $bgcolor1 ) { @@ -183,15 +184,21 @@ function part_export_areyousure(href) { % } else { <% $value %> -% } +% } % $n1=""; -% } -% +% } #foreach $field +% if ( $part_svc->restrict_edit_password ) { + + + <% emt('Password editing restricted.') %> + + +% } -% } +% } #foreach $part_svc diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi index 007c24629..8a84b208a 100755 --- a/httemplate/edit/part_svc.cgi +++ b/httemplate/edit/part_svc.cgi @@ -407,6 +407,20 @@ % % } #foreach my $field (@fields) { % +% if ( $layer eq 'svc_acct' ) { +% # eww, more ugly special-caseyness +% $html .= +% ''. +% emt('Require "Provision" access right to edit password'). +% ''. +% 'restrict_edit_password ? ' CHECKED' : ''). +% '>'; +% } else { +% $html .= +% ''; +% } +% % $part_svc->svcpart('') if $clone; #undone % $html .= ""; % @@ -414,7 +428,7 @@ % $layer, #form name % [ qw(svc svcpart classnum selfservice_access % disabled preserve -% exportnum), +% exportnum restrict_edit_password), % @fields ], % 'process/part_svc.cgi', % $p.'browse/part_svc.cgi', diff --git a/httemplate/edit/process/cust_svc.cgi b/httemplate/edit/process/cust_svc.cgi index e22cbb201..7cb1d6d8f 100644 --- a/httemplate/edit/process/cust_svc.cgi +++ b/httemplate/edit/process/cust_svc.cgi @@ -6,7 +6,7 @@ %} <%init> -die 'access deined' +die 'access denied' unless $FS::CurrentUser::CurrentUser->access_right('Change customer service'); my $svcnum = $cgi->param('svcnum'); diff --git a/httemplate/edit/svc_acct.cgi b/httemplate/edit/svc_acct.cgi index c1f74551d..627791ba7 100755 --- a/httemplate/edit/svc_acct.cgi +++ b/httemplate/edit/svc_acct.cgi @@ -9,19 +9,6 @@
    % } - -
    @@ -57,10 +44,11 @@ function randomPass() { %if ( $part_svc->part_svc_column('_password')->columnflag ne 'F' ) { +% #XXX eventually should require "Edit Password" ACL <% mt('Password') |h %> - MAXLENGTH=<% $pmax %>> - + MAXLENGTH=<% $pmax %>> + <& /elements/random_pass.html, 'clear_password' &> %}else{ diff --git a/httemplate/misc/process/change-password.html b/httemplate/misc/process/change-password.html index 7005439cc..7cab9c4e3 100644 --- a/httemplate/misc/process/change-password.html +++ b/httemplate/misc/process/change-password.html @@ -1,11 +1,16 @@ <%init> my $curuser = $FS::CurrentUser::CurrentUser; -die "access denied" unless $curuser->access_right('Edit password'); $cgi->param('svcnum') =~ /^(\d+)$/ or die "illegal svcnum"; my $svcnum = $1; my $svc_acct = FS::svc_acct->by_key($svcnum) or die "svc_acct $svcnum not found"; +my $part_svc = $svc_acct->part_svc; +die "access denied" unless ( + $curuser->access_right('Provision customer service') or + ( $curuser->access_right('Edit password') and + ! $part_svc->restrict_edit_password ) + ); my $error = $svc_acct->set_password($cgi->param('password')) || $svc_acct->replace; diff --git a/httemplate/view/elements/svc_Common.html b/httemplate/view/elements/svc_Common.html index f7c685c28..46b9c28fa 100644 --- a/httemplate/view/elements/svc_Common.html +++ b/httemplate/view/elements/svc_Common.html @@ -52,7 +52,7 @@ function areyousure(href) { <% mt('Service #') |h %><% $svcnum %> % my $url = $opt{'edit_url'} || $p. 'edit/'. $opt{'table'}. '.cgi?'; -| <& /view/elements/svc_edit_link.html, 'svc' => $svc_x, 'edit_url' => $url &> +<& /view/elements/svc_edit_link.html, 'svc' => $svc_x, 'edit_url' => $url &>
    <% ntable("#cccccc") %><% ntable("#cccccc",2) %> diff --git a/httemplate/view/elements/svc_edit_link.html b/httemplate/view/elements/svc_edit_link.html index d65db0a8f..5438ed266 100644 --- a/httemplate/view/elements/svc_edit_link.html +++ b/httemplate/view/elements/svc_edit_link.html @@ -7,8 +7,12 @@ function areyousure_delete() { window.location.href = '<% $cancel_url %>'; } -<% mt("Edit this [_1]", $label) |h %> | -<% mt('Unprovision this Service') |h %> +% if ( $curuser->access_right('Provision customer service') ) { +| <% mt("Edit this [_1]", $label) |h %> +% } +% if ( $curuser->access_right('Unprovision customer service') ) { +| <% mt('Unprovision this Service') |h %> +% } % } <%init> my %opt = @_; @@ -20,4 +24,5 @@ my $cancel_url = $p . 'misc/unprovision.cgi?' . $svc_x->svcnum; my $cust_svc = $svc_x->cust_svc; # always exists my $cancel_date = $cust_svc->pkg_cancel_date; my ($label) = $cust_svc->label; +my $curuser = $FS::CurrentUser::CurrentUser; diff --git a/httemplate/view/svc_acct.cgi b/httemplate/view/svc_acct.cgi index 199591356..76631baad 100755 --- a/httemplate/view/svc_acct.cgi +++ b/httemplate/view/svc_acct.cgi @@ -37,7 +37,6 @@ &> <% mt('Service #') |h %><% $svcnum %> -| <& /view/elements/svc_edit_link.html, 'svc' => $svc_acct &> <& svc_acct/change_svc.html, 'part_svc' => \@part_svc, @@ -90,8 +89,12 @@ die "access denied" my $addl_from = ' LEFT JOIN cust_svc USING ( svcnum ) '. ' LEFT JOIN cust_pkg USING ( pkgnum ) '. ' LEFT JOIN cust_main USING ( custnum ) '; - -my($query) = $cgi->keywords; +my $query; +if ( $cgi->keywords ) { + ($query) = $cgi->keywords; +} else { + $query = $cgi->param('svcnum'); +} $query =~ /^(\d+)$/; my $svcnum = $1; my $svc_acct = qsearchs({ diff --git a/httemplate/view/svc_acct/basics.html b/httemplate/view/svc_acct/basics.html index 2d9953fcc..04e7bcff8 100644 --- a/httemplate/view/svc_acct/basics.html +++ b/httemplate/view/svc_acct/basics.html @@ -20,7 +20,7 @@ % if ( $password =~ /^\*\w+\* (.*)$/ ) { % $password = $1; % $show_pw .= '('. mt('login disabled') .') '; -% } +% } % if ( ! $password % && $svc_acct->_password_encryption ne 'plain' % && $svc_acct->_password @@ -28,13 +28,27 @@ % { % $show_pw .= '('. uc($svc_acct->_password_encryption). ' '.mt('encrypted').')'; % } elsif ( $conf->exists('showpasswords') ) { -% $show_pw .= '
    '. encode_entities($password). '
    '; +% $show_pw .= ''. encode_entities($password). ''; % } else { +% $password = ''; % $show_pw .= '('. mt('hidden') .')'; -% } -% $password = ''; -<& /view/elements/tr.html, label=>mt('Password'), value=>$show_pw &> - +% } + + <% mt('Password') %> + + <% $show_pw %> +% my $curuser = $FS::CurrentUser::CurrentUser; +% if ( $curuser->access_right('Provision customer service') or +% ($curuser->access_right('Edit password') and +% ! $part_svc->restrict_edit_password) ) +% { + <& /elements/change_password.html, + 'svc_acct' => $svc_acct, + 'curr_value' => $password, + &> +% } + + % if ( $conf->exists('security_phrase') ) { <& /view/elements/tr.html, label=>mt('Security phrase'), value=>$svc_acct->sec_phrase &> -- cgit v1.2.1 From 52e23dfa86b11c17903952a99f87893ef09db743 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 27 Feb 2013 15:43:54 -0800 Subject: don't allow selection of cust_main-check_unique in 3.0 until it works (since it borks customer add), RT#21646 --- FS/FS/Conf.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 2931f3501..4b56eae61 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -3995,7 +3995,7 @@ and customer address. Include units.', 'type' => 'select', 'multiple' => 1, 'select_hash' => [ - 'address1' => 'Billing address', + #'address1' => 'Billing address', ], }, -- cgit v1.2.1 From d04c981b5f72ffadabde71af68022059af0d52a5 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 27 Feb 2013 20:46:58 -0800 Subject: per-package bundles of voice minutes, #5738 --- FS/FS/ClientAPI/MyAccount.pm | 16 ++ FS/FS/Conf.pm | 13 ++ FS/FS/Mason.pm | 5 + FS/FS/Schema.pm | 50 ++++++ FS/FS/cdr.pm | 74 ++++++--- FS/FS/cdr_cust_pkg_usage.pm | 124 ++++++++++++++ FS/FS/cust_pkg.pm | 194 +++++++++++++++++++++- FS/FS/cust_pkg_usage.pm | 163 ++++++++++++++++++ FS/FS/part_pkg.pm | 13 ++ FS/FS/part_pkg/voip_cdr.pm | 36 ++++ FS/FS/part_pkg_usage.pm | 159 ++++++++++++++++++ FS/FS/part_pkg_usage_class.pm | 125 ++++++++++++++ FS/MANIFEST | 10 ++ FS/bin/freeside-cdrrated | 16 +- FS/t/cdr_cust_pkg_usage.t | 5 + FS/t/cust_pkg_usage.t | 5 + FS/t/part_pkg_usage.t | 5 + FS/t/part_pkg_usage_class.t | 5 + fs_selfservice/FS-SelfService/cgi/view_usage.html | 58 ++++++- httemplate/browse/part_pkg.cgi | 30 +++- httemplate/browse/part_pkg_usage.html | 112 +++++++++++++ httemplate/edit/process/part_pkg_usage.html | 67 ++++++++ httemplate/elements/auto-table.html | 59 +++++-- httemplate/view/cust_main/packages.html | 9 + httemplate/view/cust_main/packages/package.html | 33 ++++ 25 files changed, 1337 insertions(+), 49 deletions(-) create mode 100644 FS/FS/cdr_cust_pkg_usage.pm create mode 100644 FS/FS/cust_pkg_usage.pm create mode 100644 FS/FS/part_pkg_usage.pm create mode 100644 FS/FS/part_pkg_usage_class.pm create mode 100644 FS/t/cdr_cust_pkg_usage.t create mode 100644 FS/t/cust_pkg_usage.t create mode 100644 FS/t/part_pkg_usage.t create mode 100644 FS/t/part_pkg_usage_class.t create mode 100644 httemplate/browse/part_pkg_usage.html create mode 100644 httemplate/edit/process/part_pkg_usage.html diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 38139e11b..775131e5a 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -1643,15 +1643,26 @@ sub list_svcs { } my @cust_svc = (); + my @cust_pkg_usage = (); #foreach my $cust_pkg ( $cust_main->ncancelled_pkgs ) { foreach my $cust_pkg ( $p->{'ncancelled'} ? $cust_main->ncancelled_pkgs : $cust_main->unsuspended_pkgs ) { next if $pkgnum && $cust_pkg->pkgnum != $pkgnum; push @cust_svc, @{[ $cust_pkg->cust_svc ]}; #@{[ ]} to force array context + push @cust_pkg_usage, $cust_pkg->cust_pkg_usage; } @cust_svc = grep { $_->part_svc->selfservice_access ne 'hidden' } @cust_svc; + my %usage_pools; + foreach (@cust_pkg_usage) { + my $part = $_->part_pkg_usage; + my $tag = $part->description . ($part->shared ? 1 : 0); + my $row = $usage_pools{$tag} + ||= [ $part->description, 0, 0, $part->shared ? 1 : 0 ]; + $row->[1] += $_->minutes; # minutes remaining + $row->[2] += $part->minutes; # minutes total + } if ( $p->{'svcdb'} ) { my $svcdb = ref($p->{'svcdb'}) eq 'HASH' @@ -1761,6 +1772,11 @@ sub list_svcs { } @cust_svc ], + 'usage_pools' => [ + map { $usage_pools{$_} } + sort { $a cmp $b } + keys %usage_pools + ], }; } diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 4b56eae61..e8747f28a 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -5347,6 +5347,19 @@ and customer address. Include units.', $cdr_type ? $cdr_type->cdrtypename : ''; }, }, + + { + 'key' => 'cdr-minutes_priority', + 'section' => 'telephony', + 'description' => 'Priority rule for assigning included minutes to CDRs.', + 'type' => 'select', + 'select_hash' => [ + '' => 'No specific order', + 'time' => 'Chronological', + 'rate_high' => 'Highest rate first', + 'rate_low' => 'Lowest rate first', + ], + }, { 'key' => 'brand-agent', diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 2bc1596f2..ae75539ac 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -332,6 +332,11 @@ if ( -e $addl_handler_use_file ) { use FS::GeocodeCache; use FS::log; use FS::log_context; + use FS::part_pkg_usage_class; + use FS::cust_pkg_usage; + use FS::part_pkg_usage_class; + use FS::part_pkg_usage; + use FS::cdr_cust_pkg_usage; # Sammath Naur if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index eff4878fd..717e49844 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1815,6 +1815,30 @@ sub tables_hashref { 'index' => [ [ 'pkgnum' ], [ 'discountnum' ], [ 'usernum' ], ], }, + 'cust_pkg_usage' => { + 'columns' => [ + 'pkgusagenum', 'serial', '', '', '', '', + 'pkgnum', 'int', '', '', '', '', + 'minutes', 'int', '', '', '', '', + 'pkgusagepart', 'int', '', '', '', '', + ], + 'primary_key' => 'pkgusagenum', + 'unique' => [], + 'index' => [ [ 'pkgnum' ], [ 'pkgusagepart' ] ], + }, + + 'cdr_cust_pkg_usage' => { + 'columns' => [ + 'cdrusagenum', 'bigserial', '', '', '', '', + 'acctid', 'bigint', '', '', '', '', + 'pkgusagenum', 'int', '', '', '', '', + 'minutes', 'int', '', '', '', '', + ], + 'primary_key' => 'cdrusagenum', + 'unique' => [], + 'index' => [ [ 'pkgusagenum' ], [ 'acctid' ] ], + }, + 'cust_bill_pkg_discount' => { 'columns' => [ 'billpkgdiscountnum', 'serial', '', '', '', '', @@ -3021,6 +3045,32 @@ sub tables_hashref { 'index' => [ [ 'disabled' ] ], }, + 'part_pkg_usage' => { + 'columns' => [ + 'pkgusagepart', 'serial', '', '', '', '', + 'pkgpart', 'int', '', '', '', '', + 'minutes', 'int', '', '', '', '', + 'priority', 'int', 'NULL', '', '', '', + 'shared', 'char', 'NULL', 1, '', '', + 'rollover', 'char', 'NULL', 1, '', '', + 'description', 'varchar', 'NULL', $char_d, '', '', + ], + 'primary_key' => 'pkgusagepart', + 'unique' => [], + 'index' => [ [ 'pkgpart' ] ], + }, + + 'part_pkg_usage_class' => { + 'columns' => [ + 'num', 'serial', '', '', '', '', + 'pkgusagepart', 'int', '', '', '', '', + 'classnum', 'int','NULL', '', '', '', + ], + 'primary_key' => 'num', + 'unique' => [ [ 'pkgusagepart', 'classnum' ] ], + 'index' => [], + }, + 'rate' => { 'columns' => [ 'ratenum', 'serial', '', '', '', '', diff --git a/FS/FS/cdr.pm b/FS/FS/cdr.pm index 5e986ab50..9a3114442 100644 --- a/FS/FS/cdr.pm +++ b/FS/FS/cdr.pm @@ -426,12 +426,25 @@ sub set_charged_party { Sets the status to the provided string. If there is an error, returns the error, otherwise returns false. +If status is being changed from 'rated' to some other status, also removes +any usage allocations to this CDR. + =cut sub set_status { my($self, $status) = @_; + my $old_status = $self->freesidestatus; $self->freesidestatus($status); - $self->replace; + my $error = $self->replace; + if ( $old_status eq 'rated' and $status ne 'done' ) { + # deallocate any usage + foreach (qsearch('cdr_cust_pkg_usage', {acctid => $self->acctid})) { + my $cust_pkg_usage = $_->cust_pkg_usage; + $cust_pkg_usage->set('minutes', $cust_pkg_usage->minutes + $_->minutes); + $error ||= $cust_pkg_usage->replace || $_->delete; + } + } + $error; } =item set_status_and_rated_price STATUS RATED_PRICE [ SVCNUM [ OPTION => VALUE ... ] ] @@ -578,7 +591,7 @@ reference of the number of included minutes and will be decremented by the rated minutes of this CDR. region_group_included_minutes_hashref is required for prefix price plans which -have included minues (otehrwise unused/ignored). It should be set to an empty +have included minues (otherwise unused/ignored). It should be set to an empty hashref at the start of a month's rating and then preserved across CDRs. =cut @@ -603,6 +616,7 @@ our %interval_cache = (); # for timed rates sub rate_prefix { my( $self, %opt ) = @_; my $part_pkg = $opt{'part_pkg'} or return "No part_pkg specified"; + my $cust_pkg = $opt{'cust_pkg'}; my $da_rewrote = 0; # this will result in those CDRs being marked as done... is that @@ -828,11 +842,6 @@ sub rate_prefix { $seconds_left -= $charge_sec; - my $included_min = $opt{'region_group_included_min_hashref'} || {}; - - $included_min->{$regionnum}{$ratetimenum} = $rate_detail->min_included - unless exists $included_min->{$regionnum}{$ratetimenum}; - my $granularity = $rate_detail->sec_granularity; my $minutes; @@ -850,20 +859,40 @@ sub rate_prefix { $seconds += $charge_sec; + if ( $rate_detail->min_included ) { + # the old, kind of deprecated way to do this + my $included_min = $opt{'region_group_included_min_hashref'} || {}; - my $region_group = ($part_pkg->option_cacheable('min_included') || 0) > 0; + # by default, set the included minutes for this region/time to + # what's in the rate_detail + $included_min->{$regionnum}{$ratetimenum} = $rate_detail->min_included + unless exists $included_min->{$regionnum}{$ratetimenum}; - ${$opt{region_group_included_min}} -= $minutes - if $region_group && $rate_detail->region_group; + # the way that doesn't work + #my $region_group = ($part_pkg->option_cacheable('min_included') || 0) > 0; + + #${$opt{region_group_included_min}} -= $minutes + # if $region_group && $rate_detail->region_group; + + if ( $included_min->{$regionnum}{$ratetimenum} > $minutes ) { + $charge_sec = 0; + $included_min->{$regionnum}{$ratetimenum} -= $minutes; + } else { + $charge_sec -= ($included_min->{$regionnum}{$ratetimenum} * 60); + $included_min->{$regionnum}{$ratetimenum} = 0; + } + } else { + # the new way! + my $applied_min = $cust_pkg->apply_usage( + 'cdr' => $self, + 'rate_detail' => $rate_detail, + 'minutes' => $minutes + ); + # for now, usage pools deal only in whole minutes + $charge_sec -= $applied_min * 60; + } - $included_min->{$regionnum}{$ratetimenum} -= $minutes; - if ( - $included_min->{$regionnum}{$ratetimenum} <= 0 - && ( ${$opt{region_group_included_min}} <= 0 - || ! $rate_detail->region_group - ) - ) - { + if ( $charge_sec > 0 ) { #NOW do connection charges here... right? #my $conn_seconds = min($seconds_left, $rate_detail->conn_sec); @@ -876,16 +905,9 @@ sub rate_prefix { } #should preserve (display?) this - my $charge_min = 0 - $included_min->{$regionnum}{$ratetimenum} - ( $conn_seconds / 60 ); - $included_min->{$regionnum}{$ratetimenum} = 0; + my $charge_min = ( $charge_sec - $conn_seconds ) / 60; $charge += ($rate_detail->min_charge * $charge_min) if $charge_min > 0; #still not rounded - } elsif ( ${$opt{region_group_included_min}} > 0 - && $region_group - && $rate_detail->region_group - ) - { - $included_min->{$regionnum}{$ratetimenum} = 0 } # choose next rate_detail diff --git a/FS/FS/cdr_cust_pkg_usage.pm b/FS/FS/cdr_cust_pkg_usage.pm new file mode 100644 index 000000000..6ef7f2dea --- /dev/null +++ b/FS/FS/cdr_cust_pkg_usage.pm @@ -0,0 +1,124 @@ +package FS::cdr_cust_pkg_usage; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs ); + +=head1 NAME + +FS::cdr_cust_pkg_usage - Object methods for cdr_cust_pkg_usage records + +=head1 SYNOPSIS + + use FS::cdr_cust_pkg_usage; + + $record = new FS::cdr_cust_pkg_usage \%hash; + $record = new FS::cdr_cust_pkg_usage { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::cdr_cust_pkg_usage object represents an allocation of included +usage minutes to a call. FS::cdr_cust_pkg_usage inherits from +FS::Record. The following fields are currently supported: + +=over 4 + +=item cdrusagenum - primary key + +=item acctid - foreign key to cdr.acctid + +=item pkgusagenum - foreign key to cust_pkg_usage.pkgusagenum + +=item minutes - the number of minutes allocated + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new example. To add the example to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'cdr_cust_pkg_usage'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=item check + +Checks all fields to make sure this is a valid example. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('cdrusagenum') + || $self->ut_foreign_key('acctid', 'cdr', 'acctid') + || $self->ut_foreign_key('pkgusagenum', 'cust_pkg_usage', 'pkgusagenum') + || $self->ut_number('minutes') + ; + return $error if $error; + + $self->SUPER::check; +} + +=item cust_pkg_usage + +Returns the L object that this usage allocation came from. + +=item cdr + +Returns the L object that the usage was applied to. + +=cut + +sub cust_pkg_usage { + FS::cust_pkg_usage->by_key($_[0]->pkgusagenum); +} + +sub cdr { + FS::cdr->by_key($_[0]->acctid); +} + +=back + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 9c3d16a79..55a55ee8d 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -6,7 +6,7 @@ use base qw( FS::otaker_Mixin FS::cust_main_Mixin FS::location_Mixin use vars qw($disable_agentcheck $DEBUG $me); use Carp qw(cluck); use Scalar::Util qw( blessed ); -use List::Util qw(max); +use List::Util qw(min max); use Tie::IxHash; use Time::Local qw( timelocal timelocal_nocheck ); use MIME::Entity; @@ -21,6 +21,8 @@ use FS::cust_location; use FS::pkg_svc; use FS::cust_bill_pkg; use FS::cust_pkg_detail; +use FS::cust_pkg_usage; +use FS::cdr_cust_pkg_usage; use FS::cust_event; use FS::h_cust_svc; use FS::reg_code; @@ -861,6 +863,14 @@ sub cancel { } } + foreach my $usage ( $self->cust_pkg_usage ) { + $error = $usage->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "deleting usage pools: $error"; + } + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; return '' if $date; #no errors @@ -1825,6 +1835,16 @@ sub change { $dbh->rollback if $oldAutoCommit; return "Error setting usage values: $error"; } + } else { + # if NOT changing pkgpart, transfer any usage pools over + foreach my $usage ($self->cust_pkg_usage) { + $usage->set('pkgnum', $cust_pkg->pkgnum); + $error = $usage->replace; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error transferring usage pools: $error"; + } + } } # Order any supplemental packages. @@ -3269,7 +3289,175 @@ sub cust_pkg_discount_active { grep { $_->status eq 'active' } $self->cust_pkg_discount; } -=back +=item cust_pkg_usage + +Returns a list of all voice usage counters attached to this package. + +=cut + +sub cust_pkg_usage { + my $self = shift; + qsearch('cust_pkg_usage', { pkgnum => $self->pkgnum }); +} + +=item apply_usage OPTIONS + +Takes the following options: +- cdr: a call detail record (L) +- rate_detail: the rate determined for this call (L) +- minutes: the maximum number of minutes to be charged + +Finds available usage minutes for a call of this class, and subtracts +up to that many minutes from the usage pool. If the usage pool is empty, +and the C global config option is set, minutes may +be taken from other calls as well. Either way, an allocation record will +be created (L) and this method will return the +number of minutes of usage applied to the call. + +=cut + +sub apply_usage { + my ($self, %opt) = @_; + my $cdr = $opt{cdr}; + my $rate_detail = $opt{rate_detail}; + my $minutes = $opt{minutes}; + my $classnum = $rate_detail->classnum; + my $pkgnum = $self->pkgnum; + my $custnum = $self->custnum; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + my $order = FS::Conf->new->config('cdr-minutes_priority'); + + my @usage_recs = qsearch({ + 'table' => 'cust_pkg_usage', + 'addl_from' => ' JOIN part_pkg_usage USING (pkgusagepart)'. + ' JOIN cust_pkg USING (pkgnum)'. + ' JOIN part_pkg_usage_class USING (pkgusagepart)', + 'select' => 'cust_pkg_usage.*', + 'extra_sql' => " WHERE ( cust_pkg.pkgnum = $pkgnum OR ". + " ( cust_pkg.custnum = $custnum AND ". + " part_pkg_usage.shared IS NOT NULL ) ) AND ". + " part_pkg_usage_class.classnum = $classnum AND ". + " cust_pkg_usage.minutes > 0", + 'order_by' => " ORDER BY priority ASC", + }); + + my $orig_minutes = $minutes; + my $error; + while (!$error and $minutes > 0 and @usage_recs) { + my $cust_pkg_usage = shift @usage_recs; + $cust_pkg_usage->select_for_update; + my $cdr_cust_pkg_usage = FS::cdr_cust_pkg_usage->new({ + pkgusagenum => $cust_pkg_usage->pkgusagenum, + acctid => $cdr->acctid, + minutes => min($cust_pkg_usage->minutes, $minutes), + }); + $cust_pkg_usage->set('minutes', + sprintf('%.0f', $cust_pkg_usage->minutes - $cdr_cust_pkg_usage->minutes) + ); + $error = $cust_pkg_usage->replace || $cdr_cust_pkg_usage->insert; + $minutes -= $cdr_cust_pkg_usage->minutes; + } + if ( $order and $minutes > 0 and !$error ) { + # then try to steal minutes from another call + my %search = ( + 'table' => 'cdr_cust_pkg_usage', + 'addl_from' => ' JOIN cust_pkg_usage USING (pkgusagenum)'. + ' JOIN part_pkg_usage USING (pkgusagepart)'. + ' JOIN cust_pkg USING (pkgnum)'. + ' JOIN part_pkg_usage_class USING (pkgusagepart)'. + ' JOIN cdr USING (acctid)', + 'select' => 'cdr_cust_pkg_usage.*', + 'extra_sql' => " WHERE cdr.freesidestatus = 'rated' AND ". + " ( cust_pkg.pkgnum = $pkgnum OR ". + " ( cust_pkg.custnum = $custnum AND ". + " part_pkg_usage.shared IS NOT NULL ) ) AND ". + " part_pkg_usage_class.classnum = $classnum", + 'order_by' => ' ORDER BY part_pkg_usage.priority ASC', + ); + if ( $order eq 'time' ) { + # find CDRs that are using minutes, but have a later startdate + # than this call + my $startdate = $cdr->startdate; + if ($startdate !~ /^\d+$/) { + die "bad cdr startdate '$startdate'"; + } + $search{'extra_sql'} .= " AND cdr.startdate > $startdate"; + # minimize needless reshuffling + $search{'order_by'} .= ', cdr.startdate DESC'; + } else { + # XXX may not work correctly with rate_time schedules. Could + # fix this by storing ratedetailnum in cdr_cust_pkg_usage, I + # think... + $search{'addl_from'} .= + ' JOIN rate_detail'. + ' ON (cdr.rated_ratedetailnum = rate_detail.ratedetailnum)'; + if ( $order eq 'rate_high' ) { + $search{'extra_sql'} .= ' AND rate_detail.min_charge < '. + $rate_detail->min_charge; + $search{'order_by'} .= ', rate_detail.min_charge ASC'; + } elsif ( $order eq 'rate_low' ) { + $search{'extra_sql'} .= ' AND rate_detail.min_charge > '. + $rate_detail->min_charge; + $search{'order_by'} .= ', rate_detail.min_charge DESC'; + } else { + # this should really never happen + die "invalid cdr-minutes_priority value '$order'\n"; + } + } + my @cdr_usage_recs = qsearch(\%search); + my %reproc_cdrs; + while (!$error and @cdr_usage_recs and $minutes > 0) { + my $cdr_cust_pkg_usage = shift @cdr_usage_recs; + my $cust_pkg_usage = $cdr_cust_pkg_usage->cust_pkg_usage; + my $old_cdr = $cdr_cust_pkg_usage->cdr; + $reproc_cdrs{$old_cdr->acctid} = $old_cdr; + $cdr_cust_pkg_usage->select_for_update; + $old_cdr->select_for_update; + $cust_pkg_usage->select_for_update; + # in case someone else stole the usage from this CDR + # while waiting for the lock... + next if $old_cdr->acctid != $cdr_cust_pkg_usage->acctid; + # steal the usage allocation and flag the old CDR for reprocessing + $cdr_cust_pkg_usage->set('acctid', $cdr->acctid); + # if the allocation is more minutes than we need, adjust it... + my $delta = $cdr_cust_pkg_usage->minutes - $minutes; + if ( $delta > 0 ) { + $cdr_cust_pkg_usage->set('minutes', $minutes); + $cust_pkg_usage->set('minutes', $cust_pkg_usage->minutes + $delta); + $error = $cust_pkg_usage->replace; + } + warn 'CDR '.$cdr->acctid . ' stealing allocation '.$cdr_cust_pkg_usage->cdrusagenum.' from CDR '.$old_cdr->acctid."\n"; + $error ||= $cdr_cust_pkg_usage->replace; + # deduct the stolen minutes + $minutes -= $cdr_cust_pkg_usage->minutes; + } + # after all minute-stealing is done, reset the affected CDRs + foreach (values %reproc_cdrs) { + $error ||= $_->set_status(''); + # XXX or should we just call $cdr->rate right here? + # it's not like we can create a loop this way, since the min_charge + # or call time has to go monotonically in one direction. + # we COULD get some very deep recursions going, though... + } + } # if $order and $minutes + if ( $error ) { + $dbh->rollback; + die "error applying included minutes\npkgnum ".$self->pkgnum.", class $classnum, acctid ".$cdr->acctid."\n$error\n" + } else { + $dbh->commit if $oldAutoCommit; + return $orig_minutes - $minutes; + } +} =item supplemental_pkgs @@ -3296,6 +3484,8 @@ sub main_pkg { return; } +=back + =head1 CLASS METHODS =over 4 diff --git a/FS/FS/cust_pkg_usage.pm b/FS/FS/cust_pkg_usage.pm new file mode 100644 index 000000000..0eefd7480 --- /dev/null +++ b/FS/FS/cust_pkg_usage.pm @@ -0,0 +1,163 @@ +package FS::cust_pkg_usage; + +use strict; +use base qw( FS::Record ); +use FS::cust_pkg; +use FS::part_pkg_usage; +use FS::Record qw( qsearch qsearchs ); + +=head1 NAME + +FS::cust_pkg_usage - Object methods for cust_pkg_usage records + +=head1 SYNOPSIS + + use FS::cust_pkg_usage; + + $record = new FS::cust_pkg_usage \%hash; + $record = new FS::cust_pkg_usage { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::cust_pkg_usage object represents a counter of remaining included +minutes on a voice-call package. FS::cust_pkg_usage inherits from +FS::Record. The following fields are currently supported: + +=over 4 + +=item pkgusagenum - primary key + +=item pkgnum - the package (L) containing the usage + +=item pkgusagepart - the usage stock definition (L). +This record in turn links to the call usage classes that are eligible to +use these minutes. + +=item minutes - the remaining minutes + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +# the new method can be inherited from FS::Record, if a table method is defined + +=cut + +sub table { 'cust_pkg_usage'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +sub delete { + my $self = shift; + my $error = $self->reset || $self->SUPER::delete; +} + +=item reset + +Remove all allocations of this usage to CDRs. + +=cut + +sub reset { + my $self = shift; + my $error = ''; + foreach (qsearch('cdr_cust_pkg_usage', { pkgusagenum => $self->pkgusagenum })) + { + $error ||= $_->delete; + } + $error; +} + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid example. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +# the check method should currently be supplied - FS::Record contains some +# data checking routines + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('pkgusagenum') + || $self->ut_foreign_key('pkgnum', 'cust_pkg', 'pkgnum') + || $self->ut_numbern('minutes') + || $self->ut_foreign_key('pkgusagepart', 'part_pkg_usage', 'pkgusagepart') + ; + return $error if $error; + + if ( $self->minutes eq '' ) { + $self->set(minutes => $self->part_pkg_usage->minutes); + } + + $self->SUPER::check; +} + +=item cust_pkg + +Return the L linked to this record. + +=item part_pkg_usage + +Return the L linked to this record. + +=cut + +sub cust_pkg { + my $self = shift; + FS::cust_pkg->by_key($self->pkgnum); +} + +sub part_pkg_usage { + my $self = shift; + FS::part_pkg_usage->by_key($self->pkgusagepart); +} + +=back + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 1b887a2f0..856a693dd 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -21,6 +21,7 @@ use FS::part_pkg_taxoverride; use FS::part_pkg_taxproduct; use FS::part_pkg_link; use FS::part_pkg_discount; +use FS::part_pkg_usage; use FS::part_pkg_vendor; @ISA = qw( FS::m2m_Common FS::option_Common ); @@ -1397,6 +1398,18 @@ sub part_pkg_discount { qsearch('part_pkg_discount', { 'pkgpart' => $self->pkgpart }); } +=item part_pkg_usage + +Returns the voice usage pools (see L) defined for +this package. + +=cut + +sub part_pkg_usage { + my $self = shift; + qsearch('part_pkg_usage', { 'pkgpart' => $self->pkgpart }); +} + =item _rebless Reblesses the object into the FS::part_pkg::PLAN class (if available), where diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 04098a897..67ddfb5e9 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -434,6 +434,7 @@ sub calc_usage { my $error = $cdr->rate( 'part_pkg' => $self, + 'cust_pkg' => $cust_pkg, 'svcnum' => $svc_x->svcnum, 'single_price_included_min' => \$included_min, 'region_group_included_min' => \$region_group_included_min, @@ -581,6 +582,41 @@ sub calc_units { $count; } +sub reset_usage { + my ($self, $cust_pkg, %opt) = @_; + my @part_pkg_usage = $self->part_pkg_usage or return ''; + warn " resetting usage minutes\n" if $opt{debug}; + my %cust_pkg_usage = map { $_->pkgusagepart, $_ } $cust_pkg->cust_pkg_usage; + foreach my $part_pkg_usage (@part_pkg_usage) { + my $part = $part_pkg_usage->pkgusagepart; + my $usage = $cust_pkg_usage{$part} || + FS::cust_pkg_usage->new({ + 'pkgnum' => $cust_pkg->pkgnum, + 'pkgusagepart' => $part, + 'minutes' => $part_pkg_usage->minutes, + }); + foreach my $cdr_usage ( + qsearch('cdr_cust_pkg_usage', {'cdrusagenum' => $usage->cdrusagenum}) + ) { + my $error = $cdr_usage->delete; + warn " error resetting CDR usage: $error\n"; + } + + if ( $usage->pkgusagenum ) { + if ( $part_pkg_usage->rollover ) { + $usage->set('minutes', $part_pkg_usage->minutes + $usage->minutes); + } else { + $usage->set('minutes', $part_pkg_usage->minutes); + } + my $error = $usage->replace; + warn " error resetting usage minutes: $error\n" if $error; + } else { + my $error = $usage->insert; + warn " error resetting usage minutes: $error\n" if $error; + } + } #foreach $part_pkg_usage +} + # tells whether cust_bill_pkg_detail should return a single line for # each phonenum sub sum_usage { diff --git a/FS/FS/part_pkg_usage.pm b/FS/FS/part_pkg_usage.pm new file mode 100644 index 000000000..99014d398 --- /dev/null +++ b/FS/FS/part_pkg_usage.pm @@ -0,0 +1,159 @@ +package FS::part_pkg_usage; + +use strict; +use base qw( FS::m2m_Common FS::Record ); +use FS::Record qw( qsearch qsearchs ); +use Scalar::Util qw(blessed); + +=head1 NAME + +FS::part_pkg_usage - Object methods for part_pkg_usage records + +=head1 SYNOPSIS + + use FS::part_pkg_usage; + + $record = new FS::part_pkg_usage \%hash; + $record = new FS::part_pkg_usage { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::part_pkg_usage object represents a stock of usage minutes (generally +for voice services) included in a package definition. FS::part_pkg_usage +inherits from FS::Record. The following fields are currently supported: + +=over 4 + +=item pkgusagepart - primary key + +=item pkgpart - the package definition (L) + +=item minutes - the number of minutes included per billing cycle + +=item priority - the relative order in which to use this stock of minutes. + +=item shared - 'Y' to allow these minutes to be shared with other packages +belonging to the same customer. Otherwise, only usage allocated to this +package will use this stock of minutes. + +=item rollover - 'Y' to allow unused minutes to carry over between billing +cycles. Otherwise, the available minutes will reset to the value of the +"minutes" field upon billing. + +=item description - a text description of this stock of minutes + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +=item insert CLASSES + +=item replace CLASSES + +CLASSES can be an array or hash of usage classnums (see L) +to link to this record. + +=item delete + +=cut + +sub table { 'part_pkg_usage'; } + +sub insert { + my $self = shift; + my $opt = ref($_[0]) eq 'HASH' ? shift : { @_ }; + + $self->SUPER::insert + || $self->process_m2m( 'link_table' => 'part_pkg_usage_class', + 'target_table' => 'usage_class', + 'params' => $opt, + ); +} + +sub replace { + my $self = shift; + my $old = ( blessed($_[0]) && $_[0]->isa('FS::Record') ) + ? shift + : $self->replace_old; + my $opt = ref($_[0]) eq 'HASH' ? $_[0] : { @_ }; + $self->SUPER::replace($old) + || $self->process_m2m( 'link_table' => 'part_pkg_usage_class', + 'target_table' => 'usage_class', + 'params' => $opt, + ); +} + +sub delete { + my $self = shift; + $self->process_m2m( 'link_table' => 'part_pkg_usage_class', + 'target_table' => 'usage_class', + 'params' => {}, + ) || $self->SUPER::delete; +} + +=item check + +Checks all fields to make sure this is a valid example. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('pkgusagepart') + || $self->ut_foreign_key('pkgpart', 'part_pkg', 'pkgpart') + || $self->ut_number('minutes') + || $self->ut_numbern('priority') + || $self->ut_flag('shared') + || $self->ut_flag('rollover') + || $self->ut_textn('description') + ; + return $error if $error; + + $self->SUPER::check; +} + +=item classnums + +Returns the usage class numbers that are allowed to use minutes from this +pool. + +=cut + +sub classnums { + my $self = shift; + if (!$self->get('classnums')) { + my $classnums = [ + map { $_->classnum } + qsearch('part_pkg_usage_class', { 'pkgusagepart' => $self->pkgusagepart }) + ]; + $self->set('classnums', $classnums); + } + @{ $self->get('classnums') }; +} + +=back + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/part_pkg_usage_class.pm b/FS/FS/part_pkg_usage_class.pm new file mode 100644 index 000000000..9a99783af --- /dev/null +++ b/FS/FS/part_pkg_usage_class.pm @@ -0,0 +1,125 @@ +package FS::part_pkg_usage_class; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs ); + +=head1 NAME + +FS::part_pkg_usage_class - Object methods for part_pkg_usage_class records + +=head1 SYNOPSIS + + use FS::part_pkg_usage_class; + + $record = new FS::part_pkg_usage_class \%hash; + $record = new FS::part_pkg_usage_class { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::part_pkg_usage_class object is a link between a package usage stock +(L) and a voice usage class (L. +FS::part_pkg_usage_class inherits from FS::Record. The following fields +are currently supported: + +=over 4 + +=item num - primary key + +=item pkgusagepart - L key + +=item classnum - L key. Set to null to allow this stock +to be used for calls that have no usage class. To avoid confusion, you +should only do this if you don't use usage classes on your system. + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new example. To add the example to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'part_pkg_usage_class'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid record. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +# the check method should currently be supplied - FS::Record contains some +# data checking routines + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('num') + || $self->ut_foreign_key('pkgusagepart', 'part_pkg_usage', 'pkgusagepart') + || $self->ut_foreign_keyn('classnum', 'usage_class', 'classnum') + ; + return $error if $error; + + $self->SUPER::check; +} + +=back + +=head1 BUGS + +The author forgot to customize this manpage. + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 0214fe7bc..860f45fe2 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -677,3 +677,13 @@ FS/log.pm t/log.t FS/log_context.pm t/log_context.t +FS/part_pkg_usage_class.pm +t/part_pkg_usage_class.t +FS/cust_pkg_usage.pm +t/cust_pkg_usage.t +FS/part_pkg_usage_class.pm +t/part_pkg_usage_class.t +FS/part_pkg_usage.pm +t/part_pkg_usage.t +FS/cdr_cust_pkg_usage.pm +t/cdr_cust_pkg_usage.t diff --git a/FS/bin/freeside-cdrrated b/FS/bin/freeside-cdrrated index 131b56a7e..99ea67594 100644 --- a/FS/bin/freeside-cdrrated +++ b/FS/bin/freeside-cdrrated @@ -33,9 +33,11 @@ if ( @cdrtypenums ) { $extra_sql .= ' AND cdrtypenum IN ('. join(',', @cdrtypenums ). ')'; } -our %svcnum = (); -our %pkgpart = (); -our %part_pkg = (); +our %svcnum = (); # phonenum => svcnum +our %pkgnum = (); # phonenum => pkgnum +our %cust_pkg = (); # pkgnum => cust_pkg (NOT phonenum => cust_pkg!) +our %pkgpart = (); # phonenum => pkgpart +our %part_pkg = (); # phonenum => part_pkg #some false laziness w/freeside-cdrrewrited @@ -91,6 +93,9 @@ while (1) { next; } + $pkgnum{$number} = $cust_pkg->pkgnum; + $cust_pkg{$cust_pkg->pkgnum} ||= $cust_pkg; + #get the package, search through the part_pkg and linked for a voip_cdr def w/matching cdrtypenum (or no use_cdrtypenum) my @part_pkg = grep { $_->plan eq 'voip_cdr' @@ -126,10 +131,11 @@ while (1) { #} #XXX if $part_pkg->option('min_included') then we can't prerate this CDR - + my $error = $cdr->rate( 'part_pkg' => $part_pkg{ $pkgpart{$number} }, - 'svcnum' => $svcnum{ $number }, + 'cust_pkg' => $cust_pkg{ $pkgnum{$number} }, + 'svcnum' => $svcnum{$number}, ); if ( $error ) { #XXX ??? diff --git a/FS/t/cdr_cust_pkg_usage.t b/FS/t/cdr_cust_pkg_usage.t new file mode 100644 index 000000000..1e2060e96 --- /dev/null +++ b/FS/t/cdr_cust_pkg_usage.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::cdr_cust_pkg_usage; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/cust_pkg_usage.t b/FS/t/cust_pkg_usage.t new file mode 100644 index 000000000..23a7b299e --- /dev/null +++ b/FS/t/cust_pkg_usage.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::cust_pkg_usage; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/part_pkg_usage.t b/FS/t/part_pkg_usage.t new file mode 100644 index 000000000..ba5ccb6c8 --- /dev/null +++ b/FS/t/part_pkg_usage.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_pkg_usage; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/part_pkg_usage_class.t b/FS/t/part_pkg_usage_class.t new file mode 100644 index 000000000..e46ff0648 --- /dev/null +++ b/FS/t/part_pkg_usage_class.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_pkg_usage_class; +$loaded=1; +print "ok 1\n"; diff --git a/fs_selfservice/FS-SelfService/cgi/view_usage.html b/fs_selfservice/FS-SelfService/cgi/view_usage.html index f7076684e..35d128998 100644 --- a/fs_selfservice/FS-SelfService/cgi/view_usage.html +++ b/fs_selfservice/FS-SelfService/cgi/view_usage.html @@ -1,7 +1,20 @@ <%= $url = "$selfurl?session=$session_id;action="; - @svc_acct = grep { $_->{svcdb} eq 'svc_acct' } @svcs; - @svc_phone = grep { $_->{svcdb} eq 'svc_phone' } @svcs; - @svc_port = grep { $_->{svcdb} eq 'svc_port' } @svcs; + %by_pkg_label = (); # not used yet, but I'm sure it will be... + @svc_acct = (); + @svc_phone = (); + @svc_port = (); + + foreach (@svcs) { + $by_pkg_label{ $_->{pkg_label} } ||= []; + push @{ $by_pkg_label{ $_->{pkg_label} } }, $_; + if ( $_->{svcdb} eq 'svc_acct' ) { + push @svc_acct, $_; + } elsif ( $_->{svcdb} eq 'svc_phone' ) { + push @svc_phone, $_; + } elsif ( $_->{svcdb} eq 'svc_port' ) { + push @svc_port, $_; + } + } ''; %> <%= include('header', 'Account usage') %> @@ -67,7 +80,7 @@ $any{$dir} = grep { $_->{$dir} } @svc_phone; } $OUT.= 'Call usage

    - +
    '; if ( $any{outbound} ) { @@ -110,7 +123,42 @@ ''; %> -<%= scalar(@svc_phone) ? '
    Number


    ' : '' %> +<%= if ( @usage_pools ) { + $OUT .= ' + + + '; + my $any_shared = 0; + foreach my $usage (@usage_pools) { + # false laziness with the back office side + my ($description, $remain, $total, $shared) = @$usage; + if ( $shared ) { + $any_shared = 1; + $description .= '*'; + } + my $ratio = 255 * ($remain/$total); + $ratio = 255 if $color > 255; + my $color = + sprintf('STYLE="font-weight: bold; color: #%02x%02x00"', + 255 - $ratio, $ratio); + $OUT .= + qq! + + + + + !; + } + if ( $any_shared ) { + $OUT .= ''. + ''; + } +} +if ( scalar(@svc_phone) or scalar(@usage_pools) ) { + $OUT .= '
    Remaining minutes
    $description$remain / $total
    * shared among all your phone plans


    '; +} +''; +%> <%= if ( @svc_port ) { $OUT.= 'Bandwidth Graphs

    diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi index 5dee5b8d1..bb5bc5215 100755 --- a/httemplate/browse/part_pkg.cgi +++ b/httemplate/browse/part_pkg.cgi @@ -1,5 +1,6 @@ <% include( 'elements/browse.html', 'title' => 'Package Definitions', + 'menubar' => \@menubar, 'html_init' => $html_init, 'html_form' => $html_form, 'html_posttotal' => $html_posttotal, @@ -517,6 +518,8 @@ push @fields, sub { my $part_pkg = shift; + my @part_pkg_usage = sort { $a->priority <=> $b->priority } + $part_pkg->part_pkg_usage; [ (map { @@ -559,7 +562,27 @@ push @fields, ] } $part_pkg->svc_part_pkg_link - ) + ), + ( scalar(@part_pkg_usage) ? + [ { data => 'Usage minutes', + align => 'center', + colspan => 2, + data_style => 'b', + link => $p.'browse/part_pkg_usage.html#pkgpart'. + $part_pkg->pkgpart + } ] + : () + ), + ( map { + [ { data => $_->minutes, + align => 'right' + }, + { data => $_->description, + align => 'left' + }, + ] + } @part_pkg_usage + ), ]; }; @@ -590,4 +613,9 @@ if ( $acl_edit_bulk ) { ) . ''; } +my @menubar; +# show this if there are any voip_cdr packages defined +if ( FS::part_pkg->count("plan = 'voip_cdr'") ) { + push @menubar, 'Per-package usage minutes' => $p.'browse/part_pkg_usage.html'; +} diff --git a/httemplate/browse/part_pkg_usage.html b/httemplate/browse/part_pkg_usage.html new file mode 100644 index 000000000..209fd3a01 --- /dev/null +++ b/httemplate/browse/part_pkg_usage.html @@ -0,0 +1,112 @@ +<& /elements/header.html, 'Package usage minutes' &> +<& /elements/menubar.html, 'Package definitions', $p.'browse/part_pkg.cgi' &> + +
    + + + + + + + +% foreach my $class (@usage_class) { + +% } + + +% my $error = $cgi->param('error'); +% foreach my $part_pkg (@part_pkg) { +% my $pkgpart = $part_pkg->pkgpart; +% my @part_pkg_usage; +% if ( $error ) { +% @part_pkg_usage = @{ $error->{$pkgpart} }; +% } else { +% @part_pkg_usage = $part_pkg->part_pkg_usage; +% foreach my $usage (@part_pkg_usage) { +% foreach ($usage->classnums) { +% $usage->set("class$_".'_', 'Y'); +% } +% } +% } + + +% # make it easy to enumerate the pkgparts later + + +% # template row + + +% foreach (qw(shared rollover)) { + +% } + + +% foreach (@usage_class) { +% my $classnum = 'class' . $_->classnum . '_'; + +% } + + <& /elements/auto-table.html, + table => "pkgpart$pkgpart", + template_row => "pkgpart$pkgpart".'_template', + data => \@part_pkg_usage, + &> +% } +
    MinutesSharedRolloverDescriptionPriority<% $class->classname %>
    ><% $part_pkg->pkg_comment %>
    + + + + + + + + + + +
    +
    + +
    +<& /elements/footer.html &> +<%init> +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" + unless $curuser->access_right( + ['Edit package definitions', 'Edit global package definitions'] + ); + +my @where = ("(plan = 'voip_cdr' OR plan = 'voip_inbound')", + "freq != '0'", + "disabled IS NULL"); +push @where, FS::part_pkg->curuser_pkgs_sql + unless $curuser->access_right('Edit global package definitions'); +my $extra_sql = ' WHERE '.join(' AND ', @where); +my @part_pkg = qsearch({ + 'table' => 'part_pkg', + 'extra_sql' => $extra_sql, + 'order_by' => ' ORDER BY pkgpart', +}); + +my @usage_class = sort { $a->weight <=> $b->weight } + qsearch('usage_class', { disabled => '' }); + +my $n_usage_classes = scalar(@usage_class); +my $n_cols = $n_usage_classes + 5; # minutes, shared, rollover, desc, prio + diff --git a/httemplate/edit/process/part_pkg_usage.html b/httemplate/edit/process/part_pkg_usage.html new file mode 100644 index 000000000..eb6c37b82 --- /dev/null +++ b/httemplate/edit/process/part_pkg_usage.html @@ -0,0 +1,67 @@ +% if ( $is_error ) { +% $cgi->param('error' => \%part_pkg_usage); +% # internal redirect, because it's a lot of state to pass through +<& /browse/part_pkg_usage.html &> +% } else { +% # uh, not quite sure... +<% $cgi->redirect($fsurl.'browse/part_pkg.cgi') %> +% } +<%init> +my %vars = $cgi->Vars; +my %part_pkg_usage; +my $is_error; +foreach my $pkgpart ($cgi->param('pkgpart')) { + next unless $pkgpart =~ /^\d+$/; + my $part_pkg = FS::part_pkg->by_key($pkgpart) + or die "unknown pkgpart $pkgpart"; + my %old = map { $_->pkgusagepart => $_ } $part_pkg->part_pkg_usage; + $part_pkg_usage{$pkgpart} ||= []; + my @rows; + foreach (grep /^pkgpart$pkgpart/, keys %vars) { + /^pkgpart\d+_(\w+\D)(\d+)$/ or die "misspelled field name '$_'"; + my $value = delete $vars{$_}; + my $field = $1; + my $row = $2; + $rows[$row] ||= {}; + $rows[$row]->{$field} = $value; + } + + foreach my $row (@rows) { + next if !defined($row); + my $error; + my %classes; + foreach my $class (grep /^class/, keys %$row) { + $class =~ /^class(\d+)_$/; + my $classnum = $1; + $classes{$classnum} = delete $row->{$class}; + } + my $usage = FS::part_pkg_usage->new($row); + $usage->set('pkgpart', $pkgpart); + if ( $usage->pkgusagepart and $row->{minutes} > 0 ) { + $error = $usage->replace(\%classes); + # and don't delete the existing one + delete($old{$usage->pkgusagepart}); + } elsif ( $row->{minutes} > 0 ) { + $error = $usage->insert(\%classes); + } else { + next; + } + if ( $error ) { + $usage->set('error', $error); + $is_error = 1; + } + push @{ $part_pkg_usage{$pkgpart} }, $usage; + } + + foreach my $usage (values %old) { + # all of these were not sent back by the client, so delete them + my $error = $usage->delete; + if ( $error ) { + $usage->set('error', $error); + $is_error = 1; + unshift @{ $part_pkg_usage{$pkgpart} }, $usage; + } + } + +} + diff --git a/httemplate/elements/auto-table.html b/httemplate/elements/auto-table.html index 9aff94e67..3a3bd405d 100644 --- a/httemplate/elements/auto-table.html +++ b/httemplate/elements/auto-table.html @@ -70,8 +70,8 @@ function <%$pre%>set_rownum(obj, rownum) { if ( obj.id ) { obj.id = obj.id + rownum; } - if ( obj.name ) { - obj.name = obj.name + rownum; + if ( obj.getAttribute('name') ) { + obj.setAttribute('name', obj.getAttribute('name') + rownum); // also, in this case it's a form field that will be part of the record // so set up an onchange handler obj.onchange = <%$pre%>possiblyAddRow_factory(obj); @@ -96,17 +96,32 @@ function <%$pre%>addRow(data) { <%$pre%>set_rownum(row, this_rownum); if(data instanceof Array) { for (i = 0; i < data.length && i < <%$pre%>fieldorder.length; i++) { - var el = document.getElementsByName(<%$pre%>fieldorder[i] + this_rownum)[0]; + var el = document.getElementsByName(<%$pre |js_string%> + + <%$pre%>fieldorder[i] + + this_rownum)[0]; if (el) { - el.value = data[i]; + if ( el.tagName.toLowerCase() == 'span' ) { + el.innerHTML = data[i]; + } else if ( el.type == 'checkbox' ) { + el.checked = (el.value == data[i]); + } else { + el.value = data[i]; + } } } } else if (data instanceof Object) { for (var field in data) { - var el = document.getElementsByName(field + this_rownum)[0]; + var el = document.getElementsByName(<%$pre |js_string%> + + field + + this_rownum)[0]; if (el) { - el.value = data[field]; -% # doesn't work for checkbox + if ( el.tagName.toLowerCase() == 'span' ) { + el.innerHTML = data[field]; + } else if ( el.type == 'checkbox' ) { + el.checked = (el.value == data[field]); + } else { + el.value = data[field]; + } } } } // else nothing @@ -123,6 +138,20 @@ function <%$pre%>deleteRow(rownum) { <%$pre%>tbody.removeChild(r); } +function <%$pre%>set_prefix(obj) { + if ( obj.id ) { + obj.id = <%$pre |js_string%> + obj.id; + } + if ( obj.getAttribute('name') ) { + obj.setAttribute('name', <%$pre |js_string%> + obj.getAttribute('name')); + } + for (var i = 0; i < obj.children.length; i++) { + if ( obj.children[i] instanceof Node ) { + <%$pre%>set_prefix(obj.children[i]); + } + } +} + function <%$pre%>init() { <%$pre%>template = document.getElementById(<% $template_row |js_string%>); <%$pre%>tbody = document.getElementById('<%$pre%>autotable'); @@ -131,8 +160,10 @@ function <%$pre%>init() { var table = <%$pre%>template.parentNode; table.removeChild(<%$pre%>template); // give it an id - <%$pre%>template.id = <%$pre |js_string%> + 'row'; - // and a magic identifier so we know it's been submitted + <%$pre%>template.id = 'row'; + // prefix the ids and names of the TR object and all its descendants + <%$pre%>set_prefix(<%$pre%>template); + // add a magic identifier so we know it's been submitted var magic = document.createElement('INPUT'); magic.setAttribute('type', 'hidden'); magic.setAttribute('name', '<%$pre%>magic'); @@ -140,14 +171,22 @@ function <%$pre%>init() { // and a delete button %# should this be enclosed in an actual

    -- cgit v1.2.1 From 6a42226f7f1779974316111cb178a3c6a6d74931 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 26 Mar 2013 17:01:10 -0700 Subject: UI to change package quantities, #18330 --- FS/FS/cust_pkg.pm | 18 +++++++++ httemplate/edit/cust_pkg_quantity.html | 49 +++++++++++++++++++++++++ httemplate/edit/process/cust_pkg_quantity.html | 33 +++++++++++++++++ httemplate/view/cust_main/packages/package.html | 33 ++++++++++++++--- 4 files changed, 127 insertions(+), 6 deletions(-) create mode 100755 httemplate/edit/cust_pkg_quantity.html create mode 100644 httemplate/edit/process/cust_pkg_quantity.html diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 87acf0e52..374cf7a12 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1931,6 +1931,24 @@ sub change { } +=item set_quantity QUANTITY + +Change the package's quantity field. This is the one package property +that can safely be changed without canceling and reordering the package +(because it doesn't affect tax eligibility). Returns an error or an +empty string. + +=cut + +sub set_quantity { + my $self = shift; + $self = $self->replace_old; # just to make sure + my $qty = shift; + ($qty =~ /^\d+$/ and $qty > 0) or return "bad package quantity $qty"; + $self->set('quantity' => $qty); + $self->replace; +} + use Storable 'thaw'; use MIME::Base64; sub process_bulk_cust_pkg { diff --git a/httemplate/edit/cust_pkg_quantity.html b/httemplate/edit/cust_pkg_quantity.html new file mode 100755 index 000000000..ec47ed6cb --- /dev/null +++ b/httemplate/edit/cust_pkg_quantity.html @@ -0,0 +1,49 @@ +<& /elements/header-popup.html, "Change Quantity" &> +<& /elements/error.html &> + +
    + +<& /elements/table-grid.html, 'bgcolor' => '#cccccc', 'cellpadding' => 2 &> + + + Current package  + + <% $curuser->option('show_pkgnum') ? $cust_pkg->pkgnum.': ' : '' %><% $part_pkg->pkg |h %> - <% $part_pkg->comment |h %> + + + +<& /elements/tr-input-text.html, + 'field' => 'quantity', + 'curr_value' => $cust_pkg->quantity, + 'label' => emt('Quantity') +&> + + + +
    + + +
    + + + +<%init> + +#some false laziness w/misc/change_pkg.cgi + +my $conf = new FS::Conf; + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Change customer package'); + +my $pkgnum = scalar($cgi->param('pkgnum')); +$pkgnum =~ /^(\d+)$/ or die "illegal pkgnum $pkgnum"; +$pkgnum = $1; + +my $cust_pkg = FS::cust_pkg->by_key($pkgnum) or die "unknown pkgnum $pkgnum"; + +my $part_pkg = $cust_pkg->part_pkg; + + diff --git a/httemplate/edit/process/cust_pkg_quantity.html b/httemplate/edit/process/cust_pkg_quantity.html new file mode 100644 index 000000000..fb2657252 --- /dev/null +++ b/httemplate/edit/process/cust_pkg_quantity.html @@ -0,0 +1,33 @@ +% if ($error) { +% $cgi->param('error', $error); +% $cgi->redirect(popurl(3). 'edit/cust_pkg_quantity.html?'. $cgi->query_string ); +% } else { + + <& /elements/header-popup.html, "Quantity changed" &> + + + + +% } +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Change customer package'); + +my $cust_pkg = qsearchs({ + 'table' => 'cust_pkg', + 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', + 'hashref' => { 'pkgnum' => scalar($cgi->param('pkgnum')), }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, +}); +die 'unknown pkgnum' unless $cust_pkg; + +$cgi->param('quantity') =~ /^(\d+)$/; +my $quantity = $1; +my $error = $cust_pkg->set_quantity($1); + + diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html index d0fc182cb..0b72d195e 100644 --- a/httemplate/view/cust_main/packages/package.html +++ b/httemplate/view/cust_main/packages/package.html @@ -24,16 +24,19 @@ -% unless ( $cust_pkg->get('cancel') ) { +% unless ( $cust_pkg->get('cancel') ) { % -% if ( $supplemental ) { -% # then only show "Edit dates", "Add invoice details", and "Add -% # comments". +% if ( $supplemental or $part_pkg->freq eq '0' ) { +% # Supplemental packages can't be changed independently. +% # One-time charges don't need to be changed. +% # For both of those, we only show "Edit dates", "Add comments", +% # and "Add invoice details". % if ( $curuser->access_right('Edit customer package dates') ) { ( <%pkg_dates_link($cust_pkg)%> ) % } % } else { -% # the usual case +% # the usual case: links to change package definition, +% # discount, and customization % my $br = 0; % if ( $curuser->access_right('Change customer package') ) { % $br=1; @@ -181,11 +184,18 @@ % if ( $curuser->access_right('Change customer package') and % !$cust_pkg->get('cancel') and % !$supplemental and -% !$opt{'show_location'}) { +% $part_pkg->freq ne '0' ) { +% if ( !$opt{'show_location'} ) { ( <% pkg_change_location_link($cust_pkg) %> ) +% } +% if ( FS::Conf->new->exists('invoice-unitprice') ) { + + ( <% pkg_change_quantity_link($cust_pkg) %> ) + +% } % } % } @@ -274,6 +284,17 @@ sub pkg_change_location_link { ); } +sub pkg_change_quantity_link { + include( '/elements/popup_link-cust_pkg.html', + 'action' => $p. 'edit/cust_pkg_quantity.html?', + 'label' => emt('Change quantity'), + 'actionlabel' => emt('Change'), + 'cust_pkg' => shift, + 'width' => 390, + 'height' => 220, + ); +} + sub pkg_dates_link { pkg_link('edit/REAL_cust_pkg', emt('Edit dates'), @_ ); } sub pkg_discount_link { -- cgit v1.2.1 From 8a6bdb6425eac988c19822f301a5849468f85f2e Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 26 Mar 2013 19:00:27 -0700 Subject: fix RADIUS report fallout from adding closed session option, RT#22169, RT#21483 --- FS/FS/part_export/sqlradius.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/FS/FS/part_export/sqlradius.pm b/FS/FS/part_export/sqlradius.pm index db66c39c0..833dd9a1d 100644 --- a/FS/FS/part_export/sqlradius.pm +++ b/FS/FS/part_export/sqlradius.pm @@ -741,8 +741,11 @@ sub usage_sessions { } } if ( $opt->{session_status} ne 'closed' ) { - $acctstoptime = "( $acctstoptime ) OR " if $acctstoptime; - $acctstoptime .= 'AcctStopTime IS NULL'; + if ( $acctstoptime ) { + $acctstoptime = "( ( $acctstoptime ) OR AcctStopTime IS NULL )"; + } else { + $acctstoptime = 'AcctStopTime IS NULL'; + } } push @where, $acctstoptime; -- cgit v1.2.1 From c81080957a5d09a7a7679a4eed4a7b702dd3d56e Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 26 Mar 2013 19:49:08 -0700 Subject: fix for batch payment application, #22147 --- httemplate/misc/batch-cust_pay.html | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/httemplate/misc/batch-cust_pay.html b/httemplate/misc/batch-cust_pay.html index 887b92489..ef06441c8 100644 --- a/httemplate/misc/batch-cust_pay.html +++ b/httemplate/misc/batch-cust_pay.html @@ -32,6 +32,13 @@ function custnum_update_callback(rownum, prefix) { % } } +function invnum_update_callback(rownum, prefix) { + custnum_update_callback(rownum, prefix); + var enable = document.getElementById('enable_app'+rownum); + enable.checked = true; + toggle_application_row.call(enable); +} + function select_discount_term(row, prefix) { var custnum_obj = document.getElementById('custnum'+prefix+row); var select_obj = document.getElementById('discount_term'+prefix+row); @@ -198,7 +205,6 @@ function change_app_amount() { && amount_unapplied(rownum) > 0 ) { create_application_row(rownum, parseInt(appnum) + 1); - } } @@ -352,6 +358,7 @@ function preload() { footer_align => \@footer_align, onchange => \@onchange, custnum_update_callback => 'custnum_update_callback', + invnum_update_callback => 'invnum_update_callback', add_row_callback => 'add_row_callback', &> -- cgit v1.2.1 From d234df9a0d62763d341508038dafd0df711de079 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 26 Mar 2013 22:32:01 -0700 Subject: add tax items to oneline invoice export format, RT#21712 --- FS/FS/cust_bill.pm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 41124bc36..9bab4938c 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -2130,10 +2130,13 @@ sub print_csv { $previous_balance = sprintf('%.2f', $previous_balance); my $totaldue = sprintf('%.2f', $self->owed + $previous_balance); my @items = map { - ($_->{pkgnum} || ''), - $_->{description}, - $_->{amount} - } $self->_items_pkg; + $_->{pkgnum}, + $_->{description}, + $_->{amount} + } + $self->_items_pkg, #_items_nontax? no sections or anything + # with this format + $self->_items_tax; $csv->combine( $cust_main->agentnum, -- cgit v1.2.1 From 24dee535417570307d82c5f5302c116dec9cf21f Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 27 Mar 2013 02:56:33 -0700 Subject: start of auth plugin work --- FS/FS/Conf.pm | 8 ++++++++ FS/FS/access_user/internal.pm | 15 +++++++++++++++ FS/FS/access_user/legacy.pm | 15 +++++++++++++++ eg/access_user-external_auth.pm | 27 +++++++++++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 FS/FS/access_user/internal.pm create mode 100644 FS/FS/access_user/legacy.pm create mode 100644 eg/access_user-external_auth.pm diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index e8b3333de..869ce1e73 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -5423,6 +5423,14 @@ and customer address. Include units.', 'type' => 'checkbox', }, + { + 'key' => 'authentication_module', + 'section' => 'UI', + 'description' => '"Internal" is the default , which authenticates against the internal database. "Legacy" is similar, but matches passwords against a legacy htpasswd file.', + 'type' => 'select', + 'select_enum' => [qw( Internal Legacy )], + }, + { key => "apacheroot", section => "deprecated", description => "DEPRECATED", type => "text" }, { key => "apachemachine", section => "deprecated", description => "DEPRECATED", type => "text" }, { key => "apachemachines", section => "deprecated", description => "DEPRECATED", type => "text" }, diff --git a/FS/FS/access_user/internal.pm b/FS/FS/access_user/internal.pm new file mode 100644 index 000000000..94f932dee --- /dev/null +++ b/FS/FS/access_user/internal.pm @@ -0,0 +1,15 @@ +package FS::access_user::internal; +use base qw( FS::access_user ); + +use strict; + +sub authenticate { + my( $username, $check_password ) = @_; + + +} + +sub change_password { +} + +1; diff --git a/FS/FS/access_user/legacy.pm b/FS/FS/access_user/legacy.pm new file mode 100644 index 000000000..f8dcdc015 --- /dev/null +++ b/FS/FS/access_user/legacy.pm @@ -0,0 +1,15 @@ +package FS::access_user::legacy; +use base qw( FS::access_user ); #::internal ? + +use strict; + +sub authenticate { + my( $username, $check_password ) = @_; + + +} + +sub change_password { +} + +1; diff --git a/eg/access_user-external_auth.pm b/eg/access_user-external_auth.pm new file mode 100644 index 000000000..2cea1d3ca --- /dev/null +++ b/eg/access_user-external_auth.pm @@ -0,0 +1,27 @@ +package FS::access_user::external_auth; +use base qw( FS::access_user ); + +use strict; + +sub authenticate { + my( $username, $check_password ) = @_; + + #magic happens here + + if ( $auth_good ) { #verbose for clarity + return 1; + } else { + return 0; + } + +} + +#omitting these subroutines will eliminate + +#sub create_user { +# + +#sub change_password { +#} + +1; -- cgit v1.2.1 From b70a4b7f41c84aefd7f273974db59e5c37fc368b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 27 Mar 2013 02:58:15 -0700 Subject: comment --- eg/access_user-external_auth.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eg/access_user-external_auth.pm b/eg/access_user-external_auth.pm index 2cea1d3ca..47fa7d9fe 100644 --- a/eg/access_user-external_auth.pm +++ b/eg/access_user-external_auth.pm @@ -16,7 +16,7 @@ sub authenticate { } -#omitting these subroutines will eliminate +#omitting these subroutines will eliminate those options from the UI #sub create_user { # -- cgit v1.2.1 From 546fd20829df7ab53dd60b6f7589058789acd77f Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 27 Mar 2013 03:38:25 -0700 Subject: add part_pkg_msgcat, RT#19906 --- FS/FS.pm | 2 + FS/FS/Schema.pm | 13 +++++ FS/FS/part_pkg.pm | 17 ++++++ FS/FS/part_pkg_msgcat.pm | 138 +++++++++++++++++++++++++++++++++++++++++++++++ FS/MANIFEST | 2 + FS/t/part_pkg_msgcat.t | 5 ++ 6 files changed, 177 insertions(+) create mode 100644 FS/FS/part_pkg_msgcat.pm create mode 100644 FS/t/part_pkg_msgcat.t diff --git a/FS/FS.pm b/FS/FS.pm index 2517c1fd6..a62dd0b4c 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -231,6 +231,8 @@ L - Package class class L - Package definition class +L - Package definition localization class + L - Package definition link class L - Tax class class diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index cd42e4e9c..924d0d999 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2011,6 +2011,19 @@ sub tables_hashref { ], }, + 'part_pkg_msgcat' => { + 'columns' => [ + 'pkgpartmsgnum', 'serial', '', '', '', '', + 'pkgpart', 'int', '', '', '', '', + 'locale', 'varchar', '', 16, '', '', + 'pkg', 'varchar', '', $char_d, '', '', #longer/no limit? + 'comment', 'varchar', 'NULL', 2*$char_d, '', '', #longer/no limit? + ], + 'primary_key' => 'pkgpartmsgnum', + 'unique' => [ [ 'pkgpart', 'locale' ] ], + 'index' => [], + }, + 'part_pkg_link' => { 'columns' => [ 'pkglinknum', 'serial', '', '', '', '', diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 856a693dd..efb1b59ab 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -16,6 +16,7 @@ use FS::type_pkgs; use FS::part_pkg_option; use FS::pkg_class; use FS::agent; +use FS::part_pkg_msgcat; use FS::part_pkg_taxrate; use FS::part_pkg_taxoverride; use FS::part_pkg_taxproduct; @@ -715,6 +716,22 @@ sub propagate { join("\n", @error); } +=item pkg_locale LOCALE + +Returns a customer-viewable string representing this package for the given +locale, from the part_pkg_msgcat table. If no localized string is found, +returns the base pkg field. + +=cut + +sub pkg_locale { + my( $self, $locale ) = @_; + my $part_pkg_msgcat = qsearchs( 'part_pkg_msgcat', { pkgpart=>$self->pkgpart, + locale =>$locale }) + or return $self->pkg; + $part_pkg_msgcat->pkg; +} + =item pkg_comment [ OPTION => VALUE... ] Returns an (internal) string representing this package. Currently, diff --git a/FS/FS/part_pkg_msgcat.pm b/FS/FS/part_pkg_msgcat.pm new file mode 100644 index 000000000..7c00c26ac --- /dev/null +++ b/FS/FS/part_pkg_msgcat.pm @@ -0,0 +1,138 @@ +package FS::part_pkg_msgcat; + +use strict; +use base qw( FS::Record ); +use FS::Locales; +#use FS::Record qw( qsearch qsearchs ); +use FS::part_pkg; + +=head1 NAME + +FS::part_pkg_msgcat - Object methods for part_pkg_msgcat records + +=head1 SYNOPSIS + + use FS::part_pkg_msgcat; + + $record = new FS::part_pkg_msgcat \%hash; + $record = new FS::part_pkg_msgcat { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::part_pkg_msgcat object represents localized labels of a package +definition. FS::part_pkg_msgcat inherits from FS::Record. The following +fields are currently supported: + +=over 4 + +=item pkgpartmsgnum + +primary key + +=item pkgpart + +Package definition + +=item locale + +locale + +=item pkg + +Localized package name (customer-viewable) + +=item comment + +Localized package comment (non-customer-viewable), optional + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new record. To add the record to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'part_pkg_msgcat'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid record. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +# the check method should currently be supplied - FS::Record contains some +# data checking routines + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('pkgpartmsgnum') + || $self->ut_foreign_key('pkgpart', 'part_pkg', 'pkgpart') + || $self->ut_enum('locale', [ FS::Locales->locales ] ) + || $self->ut_text('pkg') + || $self->ut_textn('comment') + ; + return $error if $error; + + $self->SUPER::check; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 95b11f8e5..da4832d41 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -686,3 +686,5 @@ FS/part_pkg_usage.pm t/part_pkg_usage.t FS/cdr_cust_pkg_usage.pm t/cdr_cust_pkg_usage.t +FS/part_pkg_msgcat.pm +t/part_pkg_msgcat.t diff --git a/FS/t/part_pkg_msgcat.t b/FS/t/part_pkg_msgcat.t new file mode 100644 index 000000000..541c16799 --- /dev/null +++ b/FS/t/part_pkg_msgcat.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_pkg_msgcat; +$loaded=1; +print "ok 1\n"; -- cgit v1.2.1 From 3ee7348febaf61d9662b463aad3053210593b06b Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 27 Mar 2013 11:54:03 -0700 Subject: keep waive_setup flag when changing package, #613 --- FS/FS/cust_pkg.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 374cf7a12..9e188afe8 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1781,6 +1781,12 @@ sub change { # (i.e. customer default location) $opt->{'locationnum'} = $self->locationnum if !exists($opt->{'locationnum'}); + # usually this doesn't matter. the two cases where it does are: + # 1. unused_credit_change + pkgpart change + setup fee on the new package + # and + # 2. (more importantly) changing a package before it's billed + $hash{'waive_setup'} = $self->waive_setup; + # Create the new package. my $cust_pkg = new FS::cust_pkg { custnum => $self->custnum, -- cgit v1.2.1 From c5310e027f5d7264b22640f72c3f1744148045ff Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 27 Mar 2013 12:34:22 -0700 Subject: cust_bill_owed_percent condition, #611 --- .../part_event/Condition/cust_bill_owed_percent.pm | 50 ++++++++++++++++++++++ httemplate/elements/selectlayers.html | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 FS/FS/part_event/Condition/cust_bill_owed_percent.pm diff --git a/FS/FS/part_event/Condition/cust_bill_owed_percent.pm b/FS/FS/part_event/Condition/cust_bill_owed_percent.pm new file mode 100644 index 000000000..e06b511ef --- /dev/null +++ b/FS/FS/part_event/Condition/cust_bill_owed_percent.pm @@ -0,0 +1,50 @@ +package FS::part_event::Condition::cust_bill_owed_percent; + +use strict; +use FS::cust_bill; + +use base qw( FS::part_event::Condition ); + +sub description { + 'Percentage owed on specific invoice'; +} + +sub eventtable_hashref { + { 'cust_main' => 0, + 'cust_bill' => 1, + 'cust_pkg' => 0, + }; +} + +sub option_fields { + ( + 'owed' => { 'label' => 'Percentage of invoice owed over', + 'type' => 'percentage', + 'value' => '0', #default + }, + ); +} + +sub condition { + #my($self, $cust_bill, %opt) = @_; + my($self, $cust_bill) = @_; + + my $percent = $self->option('owed') || 0; + my $over = sprintf('%.2f', + $cust_bill->charged * $percent / 100); + + $cust_bill->owed > $over; +} + +sub condition_sql { + my( $class, $table ) = @_; + + # forces the option to be an integer--do we care? + my $percent = $class->condition_sql_option_integer('owed'); + + my $owed_sql = FS::cust_bill->owed_sql; + + "$owed_sql > CAST( cust_bill.charged * $percent / 100 AS DECIMAL(10,2) )"; +} + +1; diff --git a/httemplate/elements/selectlayers.html b/httemplate/elements/selectlayers.html index 01fd590ca..cb1d2d619 100644 --- a/httemplate/elements/selectlayers.html +++ b/httemplate/elements/selectlayers.html @@ -236,7 +236,7 @@ sub layer_callback { $date_noinit = 1; } else { - $include = "input-$include" if $include =~ /^(text|money)$/; + $include = "input-$include" if $include =~ /^(text|money|percentage)$/; $include = "tr-$include" unless $include eq 'hidden'; $html .= include( "/elements/$include.html", %$lf, -- cgit v1.2.1 From 6b93f13c012ee4d15216c51136794d8a38726ed6 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 27 Mar 2013 13:26:46 -0700 Subject: fix non-grouped display of package locations, #22207 --- httemplate/view/cust_main/packages/location.html | 11 +++++++---- httemplate/view/cust_main/packages/section.html | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/httemplate/view/cust_main/packages/location.html b/httemplate/view/cust_main/packages/location.html index 34e3a64c3..aa3fabf8e 100644 --- a/httemplate/view/cust_main/packages/location.html +++ b/httemplate/view/cust_main/packages/location.html @@ -1,7 +1,8 @@ -% unless ( $cust_pkg->locationnum ) { - (<% mt('default service address') |h %>)
    +% if ( $default ) { +
    + (<% emt('default service address') %>)
    % } <% $loc->location_label( 'join_string' => '
    ', @@ -24,8 +25,8 @@
    % } -% unless ( $cust_pkg->locationnum ) { -
    +% if ( $default ) { +
    % } % if ( ! $cust_pkg->get('cancel') @@ -54,6 +55,8 @@ my $statedefault = $opt{'statedefault'} || ($countrydefault eq 'US' ? 'CA' : ''); my $loc = $cust_pkg->cust_location_or_main; +# dubious--they should all have a location now +my $default = $cust_pkg->locationnum == $opt{'cust_main'}->ship_locationnum; sub pkg_change_location_link { my $cust_pkg = shift; diff --git a/httemplate/view/cust_main/packages/section.html b/httemplate/view/cust_main/packages/section.html index 52246192f..909798e4b 100755 --- a/httemplate/view/cust_main/packages/section.html +++ b/httemplate/view/cust_main/packages/section.html @@ -84,10 +84,11 @@ my %conf_opt = ( 'manage_link_loc' => scalar($conf->config('svc_broadband-manage_link_loc')), 'manage_link-new_window' => $conf->exists('svc_broadband-manage_link-new_window'), 'maestro-status_test' => $conf->exists('maestro-status_test'), - 'cust_pkg-large_pkg_size' => $conf->config('cust_pkg-large_pkg_size'), + 'cust_pkg-large_pkg_size' => scalar($conf->config('cust_pkg-large_pkg_size')), # for packages.html Change location link 'show_location' => $show_location, ); +warn Dumper \%conf_opt; -- cgit v1.2.1 From d947cdfd70c0bbc6d6a97d4f967fc06dfde6b862 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 27 Mar 2013 13:42:00 -0700 Subject: debug --- httemplate/view/cust_main/packages/section.html | 1 - 1 file changed, 1 deletion(-) diff --git a/httemplate/view/cust_main/packages/section.html b/httemplate/view/cust_main/packages/section.html index 909798e4b..8ea7a7d5f 100755 --- a/httemplate/view/cust_main/packages/section.html +++ b/httemplate/view/cust_main/packages/section.html @@ -89,6 +89,5 @@ my %conf_opt = ( # for packages.html Change location link 'show_location' => $show_location, ); -warn Dumper \%conf_opt; -- cgit v1.2.1 From 7db25915018db59d1337142606e225810d188239 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 27 Mar 2013 15:08:27 -0700 Subject: Excel download of Agent Commission report, #22090 --- httemplate/search/agent_commission.html | 100 ++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 6 deletions(-) diff --git a/httemplate/search/agent_commission.html b/httemplate/search/agent_commission.html index b8fbe200f..b94ae9f6e 100644 --- a/httemplate/search/agent_commission.html +++ b/httemplate/search/agent_commission.html @@ -1,6 +1,12 @@ %# still not a good way to do rows grouped by some field in a search.html %# report +% if ( $type eq 'xls' ) { +<% $data %>\ +% } else { <& /elements/header.html, $title &> +

    +Download full results
    +as Excel spreadsheet


    + @@ -38,8 +46,11 @@ % if ( $type eq 'xml' ) { <<% 'Part_IA_'. chr(65 + $tech) %>> % } -<& "477part${part}_summary.html", 'tech_code' => $tech, 'url' => $url &> -<& "477part${part}_detail.html", 'tech_code' => $tech, 'url' => $url &> +<& "477part${part}.html", + 'tech_code' => $tech, + 'url' => $url, + 'type' => $type +&> % if ( $type eq 'xml' ) { > % } diff --git a/httemplate/search/477partIA.html b/httemplate/search/477partIA.html new file mode 100755 index 000000000..1cd0b70e0 --- /dev/null +++ b/httemplate/search/477partIA.html @@ -0,0 +1,165 @@ +% if ( $opt{'type'} eq 'xml' ) { +%# container element is in 477.html +% my $col = 'a'; +% foreach ( @summary_row ) { +% my $el = $xml_prefix . $col . '1'; # PartIA_Aa1, PartIA_Ab1, etc. + <<% $el %>><% $_ %><<% "/$el" %>> +% $col++; +% } +% foreach my $col_data ( @data ) { +% my $row = 1; +% foreach my $cell ( @$col_data ) { +% my $el = $xml_prefix . $col . $row; # PartIA_Af1, PartIA_Af2... + <<% $el %>><% $cell->[0] %><<% "/$el" %>> +% if ( $percentages ) { +% $el = $xml_percent . $col . $row; # Part_p_IA_Af1, ... + <<% $el %>><% $cell->[1] %><<% "/$el" %>> +% } +% $row++; +% } # foreach $cell +% $col++; +% } # foreach $col_data +% } else { # not XML + +

    <% $title %> totals

    +<& /elements/table-grid.html &> +
    +% foreach ( 'Total Connections', +% '% owned loop', +% '% billed to end users', +% '% residential', +% '% residential > 200 kbps') { + +% } + + +% foreach ( @summary_row ) { + +% } + +
    <% $_ |h %>
    <% $_ %>
    +

    <% $title %> breakdown by speed

    + + + +% for (my $col = 0; $col < scalar(@download_option); $col++) { + +% } + +% for (my $row = 0; $row < scalar(@upload_option); $row++) { + + +% for (my $col = 0; $col < scalar(@download_option); $col++) { + +% } # for $col + +% } # for $row +
    + <% $FS::Report::FCC_477::download[$col] |h %> +
    +% if ( $asymmetric ) { + <% $FS::Report::FCC_477::upload[$row] |h %> +% } + + <% $data[$col][$row][0] %> +% if ( $percentages ) { +
    <% $data[$col][$row][1] %> +% } +
    +% } +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('List packages'); + +my %opt = @_; +my %search_hash; + +for ( qw(agentnum state) ) { + $search_hash{$_} = $cgi->param($_) if $cgi->param($_); +} +$search_hash{'status'} = 'active'; +$search_hash{'country'} = 'US'; +$search_hash{'classnum'} = [ $cgi->param('classnum') ]; + +# arrays of report_option_ numbers, running parallel to +# the download and upload speed arrays +my @download_option = $cgi->param('part1_column_option'); +my @upload_option = $cgi->param('part1_row_option'); + +my @technology_option = &FS::Report::FCC_477::parse_technology_option($cgi); + +my $total_count = 0; +my $total_residential = 0; +my $above_200 = 0; +my $tech_code = $opt{tech_code}; +my $technology = $FS::Report::FCC_477::technology[$tech_code] || 'unknown'; +my $title = "Part IA $technology"; +my $xml_prefix = 'PartIA_'. chr(65 + $tech_code); +my $xml_percent = 'Part_p_IA_'. chr(65 + $tech_code); # yes, seriously + +# whether to show the results as a matrix (upload speeds in rows) or a single +# row +my $asymmetric = 1; +if ( $technology eq 'Symmetric xDSL' or $technology eq 'Other Wireline' ) { + $asymmetric = 0; + @upload_option = ( undef ); +} +# whether to show residential percentages in each cell of the matrix +my $percentages = ($technology eq 'Terrestrial Mobile Wireless'); + +my $query = FS::cust_pkg->search(\%search_hash); +my $count_query = $query->{'count_query'}; + +my $is_residential = " AND COALESCE(cust_main.company, '') = ''"; +my $has_option = sub { + my $optionnum = shift; + $optionnum =~ /^\d+$/ ? + " AND EXISTS( + SELECT 1 FROM part_pkg_option + WHERE part_pkg_option.pkgpart = part_pkg.pkgpart + AND optionname = 'report_option_$optionnum' + AND optionvalue = '1' + )" : ''; +}; + +# limit to those that have technology option $tech_code +$count_query .= $has_option->($technology_option[$tech_code]); + +my @data; +for ( my $row = 0; $row < scalar @upload_option; $row++ ) { + for ( my $col = 0; $col < scalar @download_option; $col++ ) { + + my $this_count_query = $count_query . + $has_option->($upload_option[$row]) . + $has_option->($download_option[$col]); + + my $count = FS::Record->scalar_sql($this_count_query); + my $residential = FS::Record->scalar_sql($this_count_query . $is_residential); + + my $percent = sprintf('%.2f', $count ? 100 * $residential / $count : 0); + $data[$col][$row] = [ $count, $percent ]; + + $total_count += $count; + $total_residential += $residential; + $above_200 += $residential if $row > 0 or !$asymmetric; + } +} + +my $total_percentage = + sprintf("%.2f", $total_count ? 100*$total_residential/$total_count : 0); + +my $above_200_percentage = + sprintf("%.2f", $total_count ? 100*$above_200/$total_count : 0); + +my @summary_row = ( + $total_count, + 100.00, # own local loop--consistent with previous practice, but probably wrong + 100.00, # billed to end user--also wrong + $total_percentage, # residential percentage + $above_200_percentage, +); + + diff --git a/httemplate/search/477partIA_detail.html b/httemplate/search/477partIA_detail.html deleted file mode 100755 index 666032d0c..000000000 --- a/httemplate/search/477partIA_detail.html +++ /dev/null @@ -1,129 +0,0 @@ -<& elements/search.html, - 'html_init' => $html_init, - 'name' => 'lines', - 'query' => $query, - 'count_query' => $count_query, - 'really_disable_download' => 1, - 'disable_download' => 1, - 'nohtmlheader' => 1, - 'disable_total' => 1, - 'header' => [ '', @column_option_name ], - 'xml_elements' => [ @xml_elements ], - 'xml_omit_empty' => 1, - 'fields' => [ @fields ], - -&> -<%init> - -my $curuser = $FS::CurrentUser::CurrentUser; - -die "access denied" - unless $curuser->access_right('List packages'); - -my %opt = @_; -my %search_hash = (); - -for ( qw(agentnum magic state) ) { - $search_hash{$_} = $cgi->param($_) if $cgi->param($_); -} -$search_hash{'country'} = 'US'; - -$search_hash{'classnum'} = [ $cgi->param('classnum') ]; - -my @column_option = grep { /^\d+/ } $cgi->param('part1_column_option') - if $cgi->param('part1_column_option'); - -my @row_option = grep { /^\d+/ } $cgi->param('part1_row_option') - if $cgi->param('part1_row_option'); - -my @technology_option = &FS::Report::FCC_477::parse_technology_option($cgi); - -my @column_option_name = scalar(@column_option) - ? ( map { my $part_pkg_report_option = - qsearchs({ 'table' => 'part_pkg_report_option', - 'hashref' => { num => $_ }, - }); - $part_pkg_report_option ? $part_pkg_report_option->name - : 'no such report option'; - } @column_option - ) - : ( 'all packages' ); - -my $where = join(' OR ', map { "num = $_" } @row_option ); -my %row_option_name = $where ? - ( map { $_->num => $_->name } - qsearch({ 'table' => 'part_pkg_report_option', - 'hashref' => {}, - 'extra_sql' => "WHERE $where", - }) - ) : - (); - -my $tech_code = $opt{tech_code}; -my $technology = $FS::Report::FCC_477::technology[$tech_code] || 'unknown'; -my $html_init = "

    Part IA $technology breakdown by speeds

    "; -my $xml_prefix = 'PartIA_'. chr(65 + $tech_code); - -if ($cgi->param('_type') eq 'xml') { - #rotate data pi/2 - my @temp = @column_option; - @column_option = @row_option; - @row_option = @temp; -} - -my $query = 'SELECT '. join(' UNION ALL SELECT ',@row_option); -my $count_query = 'SELECT '. scalar(@row_option); - -my $xml_element = 'OOPS, I was never set'; -my $rowchar = 101; # 'e' -- rows are columns! (pi/2) - -my $value = sub { - my ($rowref, $column) = (shift, shift); - my $row = $rowref->[0]; - - if ($column eq 'name') { - return $row_option_name{$row} || 'no such report option'; - } elsif ( $column =~ /^(\d+)$/ ) { - my @report_option = ( $row || '', - $column_option[$column] || '', - $technology_option[$tech_code] || '', - ); - - my ( $count, $residential ) = FS::cust_pkg->fcc_477_count( - { %search_hash, 'report_option' => join(',', @report_option) } - ); - - my $percentage = sprintf('%.2f', $count ? 100 * $residential / $count : 0); - my $return = $count; - - if ($cgi->param('_type') eq 'xml') { - $rowchar++ if $column == 0; - $xml_element = $xml_prefix. chr($rowchar). ($column+1); - $return = '' if $count == 0 and $cgi->param('_type') eq 'xml'; - } else { - $return .= "
    $percentage% residential"; - } - - return $return; - } else { - return 'Bad call to column_value'; - } -}; - -my @fields = map { my $ci = $_; sub { &{$value}(shift, $ci); } } - ( 'name', (0 .. $#column_option) ); -shift @fields if $cgi->param('_type') eq 'xml'; - -my @xml_elements = ( # -- columns are rows! (pi/2) - sub { return $xml_element; }, - sub { return $xml_element; }, - sub { return $xml_element; }, - sub { return $xml_element; }, - sub { return $xml_element; }, - sub { return $xml_element; }, - sub { return $xml_element; }, - sub { return $xml_element; }, - sub { return $xml_element; }, -); - - diff --git a/httemplate/search/477partIA_summary.html b/httemplate/search/477partIA_summary.html deleted file mode 100755 index ebf081c71..000000000 --- a/httemplate/search/477partIA_summary.html +++ /dev/null @@ -1,89 +0,0 @@ -<& elements/search.html, - 'html_init' => $html_init, - 'name' => 'lines', - 'query' => 'SELECT 1', - 'count_query' => 'SELECT 1', - 'really_disable_download' => 1, - 'disable_download' => 1, - 'nohtmlheader' => 1, - 'disable_total' => 1, - 'header' => [ - 'Total Connections', - '% owned loop', - '% billed to end users', - '% residential', - '% residential > 200kbps', - ], - 'xml_elements' => [ - $xml_prefix. 'a1', - $xml_prefix. 'b1', - $xml_prefix. 'c1', - $xml_prefix. 'd1', - $xml_prefix. 'e1', - ], - 'fields' => [ - sub { $total_count }, - sub { '100.00' }, - sub { '100.00' }, - sub { $total_percentage }, - sub { $above_200_percentage }, - ], - -&> -<%init> - -my $curuser = $FS::CurrentUser::CurrentUser; - -die "access denied" - unless $curuser->access_right('List packages'); - -my %opt = @_; -my %search_hash = (); - -for ( qw(agentnum magic state) ) { - $search_hash{$_} = $cgi->param($_) if $cgi->param($_); -} -$search_hash{'country'} = 'US'; -$search_hash{'classnum'} = [ $cgi->param('classnum') ]; - -my @column_option = grep { /^\d+$/ } $cgi->param('part1_column_option') - if $cgi->param('part1_column_option'); - -my @row_option = grep { /^\d+$/ } $cgi->param('part1_row_option') - if $cgi->param('part1_row_option'); - -my @technology_option = &FS::Report::FCC_477::parse_technology_option($cgi); - -my $total_count = 0; -my $total_residential = 0; -my $above_200 = 0; -my $tech_code = $opt{tech_code}; -my $technology = $FS::Report::FCC_477::technology[$tech_code] || 'unknown'; -my $html_init = "

    Part IA $technology totals

    "; -my $xml_prefix = 'PartIA_'. chr(65 + $tech_code); - -my $not_first_row = 0; # ugh; -foreach my $row ( @row_option ) { - foreach my $column ( @column_option ) { - - my @report_option = ( $row || '-1', $column || '-1', $technology_option[$tech_code] ); - - my ( $count, $residential ) = FS::cust_pkg->fcc_477_count( - { %search_hash, 'report_option' => join(',', @report_option) } - ); - - $total_count += $count; - $total_residential += $residential; - $above_200 += $residential if $not_first_row; - } - $not_first_row++; -} - -my $total_percentage = - sprintf("%.2f", $total_count ? 100*$total_residential/$total_count : 0); - -my $above_200_percentage = - sprintf("%.2f", $total_count ? 100*$above_200/$total_count : 0); - - - diff --git a/httemplate/search/477partIIA.html b/httemplate/search/477partIIA.html index 6a532299b..95c00a3e0 100755 --- a/httemplate/search/477partIIA.html +++ b/httemplate/search/477partIIA.html @@ -1,17 +1,44 @@ -<& elements/search.html, - 'html_init' => $html_init, - 'name' => 'lines', - 'query' => $query, - 'count_query' => 'SELECT 11', - 'really_disable_download' => 1, - 'disable_download' => 1, - 'nohtmlheader' => 1, - 'disable_total' => 1, - 'header' => [ @headers ], - 'xml_elements' => [ @xml_elements ], - 'fields' => [ @fields ], - -&> +% if ( $cgi->param('_type') eq 'xml' ) { +% my @cols = qw(a b c d); +% for ( my $row = 0; $row < scalar(@rows); $row++ ) { +% for my $col (0..3) { +% if ( exists($data[$col][$row]) and $data[$col][$row] > 0 ) { +<% $cols[$col] %>>\ +<% $data[$col][$row] %>\ +<% $cols[$col] %>> +% } +% } #for $col +% } #for $row +% } else { # HTML mode +% # fake up the search-html.html header +

    Part IIA

    + + + +

    + + +% foreach (@row1_headers) { + +% } + +% my $row = 0; +% foreach my $rowhead (@rows) { + + +% for my $col (0..3) { + +% } # for $col + +% $row++; +% } #for $rowhead +
    <% $_ %>
    <% $rowhead %> +% if ( exists($data[$col][$row]) ) { + <% $data[$col][$row] %> +% } +
    +
    +% } #XML/HTML <%init> my $curuser = $FS::CurrentUser::CurrentUser; @@ -19,83 +46,76 @@ my $curuser = $FS::CurrentUser::CurrentUser; die "access denied" unless $curuser->access_right('List packages'); -my $html_init = '

    Part IIA

    '; my %search_hash = (); - -for ( qw(agentnum magic state) ) { - $search_hash{$_} = $cgi->param($_) if $cgi->param($_); -} -$search_hash{'country'} = 'US'; -$search_hash{'classnum'} = [ $cgi->param('classnum') ]; - -my @row_option = grep { /^\d+$/ } $cgi->param('part2a_row_option') - if $cgi->param('part2a_row_option'); - -# fudge in two rows of LD carrier -unshift @row_option, $row_option[0]; - -# fudge in the first pair of rows -unshift @row_option, ''; -unshift @row_option, ''; - -my $query = 'SELECT '. join(' UNION SELECT ', 1..11); -my $total_count = 0; -my $column_value = sub { - my $row = shift; - - my @report_option = ( $row_option[$row - 1] || '' ); - - my $sql_query = FS::cust_pkg->search( - { %search_hash, 'report_option' => join(',', @report_option) } - ); - - my $count_sql = delete($sql_query->{'count_query'}); - if ( $row == 2 || $row == 4 ) { - $count_sql =~ s/COUNT\(\*\) FROM/sum(COALESCE(CASE WHEN cust_main.company IS NULL OR cust_main.company = '' THEN CASE WHEN part_pkg.fcc_ds0s IS NOT NULL AND part_pkg.fcc_ds0s > 0 THEN part_pkg.fcc_ds0s WHEN pkg_class.fcc_ds0s IS NOT NULL AND pkg_class.fcc_ds0s > 0 THEN pkg_class.fcc_ds0s ELSE 0 END ELSE 0 END, 0) ) FROM/ - or die "couldn't parse count_sql"; - } else { - $count_sql =~ s/COUNT\(\*\) FROM/sum(COALESCE(CASE WHEN part_pkg.fcc_ds0s IS NOT NULL AND part_pkg.fcc_ds0s > 0 THEN part_pkg.fcc_ds0s WHEN pkg_class.fcc_ds0s IS NOT NULL AND pkg_class.fcc_ds0s > 0 THEN pkg_class.fcc_ds0s ELSE 0 END, 0)) FROM/ - or die "couldn't parse count_sql"; - } - - my $count_sth = dbh->prepare($count_sql) - or die "Error preparing $count_sql: ". dbh->errstr; - $count_sth->execute - or die "Error executing $count_sql: ". $count_sth->errstr; - my $count_arrayref = $count_sth->fetchrow_arrayref; - my $count = $count_arrayref->[0]; +$search_hash{'agentnum'} = $cgi->param('agentnum'); +$search_hash{'state'} = $cgi->param('state'); +$search_hash{'classnum'} = [ $cgi->param('classnum') ]; +$search_hash{'status'} = 'active'; - $total_count = $count if $row == 1; - $count = sprintf('%.2f', $total_count ? 100*$count/$total_count : 0) - if $row != 1; +my @row_option; +foreach ($cgi->param('part2a_row_option')) { + push @row_option, (/^\d+$/ ? $_ : undef); +} - return "$count"; +my $is_residential = "AND COALESCE(cust_main.company, '') = ''"; +my $has_report_option = sub { + map { + defined($row_option[$_]) ? + " AND EXISTS( + SELECT 1 FROM part_pkg_option + WHERE part_pkg_option.pkgpart = part_pkg.pkgpart + AND optionname = 'report_option_" . $row_option[$_]."' + AND optionvalue = '1' + )" : ' AND FALSE' + } @_ }; -my @headers = ( - '', - 'End user lines', - 'UNE-P replacement', - 'UNE (unswitched)', - 'UNE-P', +# an arrayref for each column +my @data; +# get the skeleton of the query +my $sql_query = FS::cust_pkg->search(\%search_hash); +my $from_where = $sql_query->{'count_query'}; +$from_where =~ s/^SELECT COUNT\(\*\) //; + +# for row 1 +my $query_ds0 = "SELECT SUM(COALESCE(part_pkg.fcc_ds0s, pkg_class.fcc_ds0s, 0)) + $from_where AND fcc_voip_class = '4'"; # 4 = Local Exchange + +my $total_lines = FS::Record->scalar_sql($query_ds0); +# always return zero for the number of resold lines, until an actual ILEC +# starts using this report + +@data = ( + [ $total_lines ], + [ 0 ], + [ 0 ], + [ 0 ], ); -my @xml_elements = ( - sub { my $row = shift; my $rownum = $row->[0] + 1; "PartII_${rownum}a" }, - sub { my $row = shift; my $rownum = $row->[0] + 1; "PartII_${rownum}b" }, - sub { my $row = shift; my $rownum = $row->[0] + 1; "PartII_${rownum}c" }, - sub { my $row = shift; my $rownum = $row->[0] + 1; "PartII_${rownum}d" }, +my @row_conds = ( + $is_residential, + $has_report_option->(0), # LD carrier + ($has_report_option->(0))[0] . $is_residential, + $has_report_option->(1..7), ); +if ( $total_lines > 0 ) { + foreach (@row_conds) { + my $sql = $query_ds0 . $_; + my $lines = FS::Record->scalar_sql($sql); + my $percent = sprintf('%.2f', 100 * $lines / $total_lines); + push @{ $data[0] }, $percent; + } +} my @rows = ( 'lines', '% residential', '% LD carrier', - '% residential and LD carrier', - '% own loops', - '% obtained unswitched UNE loops', + '% residential and LD', + '% owned loops', + '% unswitched UNE', '% UNE-P', '% UNE-P replacement', '% FTTP', @@ -103,13 +123,12 @@ my @rows = ( '% wireless', ); -my @fields = ( - sub { my $row = shift; $rows[$row->[0] - 1]; }, - sub { my $row = shift; &{$column_value}($row->[0]); }, - sub { 0; }, - sub { 0; }, - sub { 0; }, +my @row1_headers = ( + '', + 'End user lines', + 'UNE-P replacement', + 'unswitched UNE', + 'UNE-P', ); -shift @fields if $cgi->param('_type') eq 'xml'; diff --git a/httemplate/search/477partIIB.html b/httemplate/search/477partIIB.html index 714f15aca..5b9b30769 100755 --- a/httemplate/search/477partIIB.html +++ b/httemplate/search/477partIIB.html @@ -3,9 +3,9 @@ % for ( my $row = 0; $row < scalar(@rows); $row++ ) { % for my $col (0..2) { % if ( exists($data[$col][$row]) ) { -<% $cols[$col] %>>\ +<% $cols[$col] %>>\ <% $data[$col][$row] %>\ -<% $cols[$col] %>> +<% $cols[$col] %>> % } % } #for $col % } #for $row @@ -15,19 +15,18 @@ % if (@$packages) { -<& packages/section.html, 'packages' => $packages &> +<& packages/section.html, 'packages' => $packages, 'cust_main' => $cust_main &> % }

    - +
    % foreach (@headers) { - + % } -% my @bgcolor = ('eeeeee','ffffff'); % my $row = 0; % foreach my $rowhead (@rows) { - - + + % for my $col (0..2) { - - + + + + + + % } % if ( $conf->exists('enable_taxclasses') ) { -- cgit v1.2.1 From 596122cdd01c725d2832b352902e1f3609c04ed9 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 23 Apr 2013 23:59:59 -0700 Subject: huawei MSC / SoftX3000 format, RT#20763 --- FS/FS/Record.pm | 2 + FS/FS/cdr/gsm_tap3_12.pm | 1 + FS/FS/cdr/huawei_softx3000.pm | 2689 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2692 insertions(+) create mode 100644 FS/FS/cdr/huawei_softx3000.pm diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 3d4bfae9c..bdf3bcf3a 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -1794,6 +1794,8 @@ sub batch_import { last unless scalar(@buffer); my $row = shift @buffer; + &{ $asn_format->{row_callback} }( $row, $asn_header_buffer ) + if $asn_format->{row_callback}; foreach my $key ( keys %{ $asn_format->{map} } ) { $hash{$key} = &{ $asn_format->{map}{$key} }( $row, $asn_header_buffer ); } diff --git a/FS/FS/cdr/gsm_tap3_12.pm b/FS/FS/cdr/gsm_tap3_12.pm index b1496ac92..275e7b35c 100644 --- a/FS/FS/cdr/gsm_tap3_12.pm +++ b/FS/FS/cdr/gsm_tap3_12.pm @@ -6,6 +6,7 @@ use vars qw( %info %TZ ); use Time::Local; #use Data::Dumper; +#false laziness w/huawei_softx3000.pm %TZ = ( '+0000' => 'XXX-0', '+0100' => 'XXX-1', diff --git a/FS/FS/cdr/huawei_softx3000.pm b/FS/FS/cdr/huawei_softx3000.pm new file mode 100644 index 000000000..e66af43a9 --- /dev/null +++ b/FS/FS/cdr/huawei_softx3000.pm @@ -0,0 +1,2689 @@ +package FS::cdr::huawei_softx3000; +use base qw( FS::cdr ); + +use strict; +use vars qw( %info %TZ ); +use subs qw( ts24008_number TimeStamp ); +use Time::Local; +use FS::Record qw( qsearch ); +use FS::cdr_calltype; + +#false laziness w/gsm_tap3_12.pm +%TZ = ( + '+0000' => 'XXX-0', + '+0100' => 'XXX-1', + '+0200' => 'XXX-2', + '+0300' => 'XXX-3', + '+0400' => 'XXX-4', + '+0500' => 'XXX-5', + '+0600' => 'XXX-6', + '+0700' => 'XXX-7', + '+0800' => 'XXX-8', + '+0900' => 'XXX-9', + '+1000' => 'XXX-10', + '+1100' => 'XXX-11', + '+1200' => 'XXX-12', + '-0000' => 'XXX+0', + '-0100' => 'XXX+1', + '-0200' => 'XXX+2', + '-0300' => 'XXX+3', + '-0400' => 'XXX+4', + '-0500' => 'XXX+5', + '-0600' => 'XXX+6', + '-0700' => 'XXX+7', + '-0800' => 'XXX+8', + '-0900' => 'XXX+9', + '-1000' => 'XXX+10', + '-1100' => 'XXX+11', + '-1200' => 'XXX+12', +); + +%info = ( + 'name' => 'Huawei SoftX3000', #V100R006C05 ? + 'weight' => 160, + 'type' => 'asn.1', + 'import_fields' => [], + 'asn_format' => { + 'spec' => _asn_spec(), + 'macro' => 'CallEventDataFile', + 'header_buffer' => sub { + #my $CallEventDataFile = shift; + + my %cdr_calltype = ( map { $_->calltypename => $_->calltypenum } + qsearch('cdr_calltype', {}) + ); + + { cdr_calltype => \%cdr_calltype, + }; + + }, + 'arrayref' => sub { shift->{'callEventRecords'} }, + 'row_callback' => sub { + my( $row, $buffer ) = @_; + my @keys = keys %$row; + $buffer->{'key'} = $keys[0]; + }, + 'map' => { + 'src' => huawei_field('callingNumber', ts24008_number, ), + + 'dst' => huawei_field('calledNumber', ts24008_number, ), + + 'startdate' => huawei_field(['answerTime','deliveryTime'], TimeStamp), + 'answerdate' => huawei_field(['answerTime','deliveryTime'], TimeStamp), + 'enddate' => huawei_field('releaseTime', TimeStamp), + 'duration' => huawei_field('callDuration'), + 'billsec' => huawei_field('callDuration'), + #'disposition' => #diagnostics? + #'accountcode' + #'charged_party' => # 0 or 1, do something with this? + 'calltypenum' => sub { + my($rec, $buf) = @_; + my $key = $buf->{key}; + $buf->{'cdr_calltype'}{ $key }; + }, + #'carrierid' => + }, + + }, +); + +sub huawei_field { + my $field = shift; + my $decode = $_[0] ? shift : ''; + return sub { + my($rec, $buf) = @_; + + my $key = $buf->{key}; + + $field = ref($field) ? $field : [ $field ]; + my $value = ''; + foreach my $f (@$field) { + $value = $rec->{$key}{$f} and last; + } + + $decode + ? &{ $decode }( $value ) + : $value; + + }; +} + +sub ts24008_number { + # This type contains the binary coded decimal representation of + # a directory number e.g. calling/called/connected/translated number. + # The encoding of the octet string is in accordance with the + # the elements "Calling party BCD number", "Called party BCD number" + # and "Connected number" defined in TS 24.008. + # This encoding includes type of number and number plan information + # together with a BCD encoded digit string. + # It may also contain both a presentation and screening indicator + # (octet 3a). + # For the avoidance of doubt, this field does not include + # octets 1 and 2, the element name and length, as this would be + # redundant. + # + #type id (per TS 24.008 page 490): + # low nybble: "numbering plan identification" + # high nybble: "type of number" + # 0 unknown + # 1 international + # 2 national + # 3 network specific + # 4 dedicated access, short code + # 5 reserved + # 6 reserved + # 7 reserved for extension + # (bit 8 "extension") + return sub { + my( $type_id, $value ) = unpack 'Ch*', shift; + $value =~ s/f$//; # If the called party BCD number contains an odd number + # of digits, bits 5 to 8 of the last octet shall be + # filled with an end mark coded as "1111". + $value; + }; +} + +sub TimeStamp { + # The contents of this field are a compact form of the UTCTime format + # containing local time plus an offset to universal time. Binary coded + # decimal encoding is employed for the digits to reduce the storage and + # transmission overhead + # e.g. YYMMDDhhmmssShhmm + # where + # YY = Year 00 to 99 BCD encoded + # MM = Month 01 to 12 BCD encoded + # DD = Day 01 to 31 BCD encoded + # hh = hour 00 to 23 BCD encoded + # mm = minute 00 to 59 BCD encoded + # ss = second 00 to 59 BCD encoded + # S = Sign 0 = "+", "-" ASCII encoded + # hh = hour 00 to 23 BCD encoded + # mm = minute 00 to 59 BCD encoded + return sub { + my($year, $mon, $day, $hour, $min, $sec, $tz_sign, $tz_hour, $tz_min, $dst)= + unpack 'H2H2H2H2H2H2AH2H2C', shift; + #warn "$year/$mon/$day $hour:$min:$sec $tz_sign$tz_hour$tz_min $dst\n"; + return 0 unless $year; #y2100 bug + local($ENV{TZ}) = $TZ{ "$tz_sign$tz_hour$tz_min" }; + timelocal($sec, $min, $hour, $day, $mon-1, $year); + }; +} + +sub _asn_spec { + <<'END'; + +--DEFINITIONS IMPLICIT TAGS ::= + +--BEGIN + +-------------------------------------------------------------------------------- +-- +-- CALL AND EVENT RECORDS +-- +------------------------------------------------------------------------------ +--Font: verdana 8 + +CallEventRecord ::= CHOICE +{ + moCallRecord [0] MOCallRecord, + mtCallRecord [1] MTCallRecord, + roamingRecord [2] RoamingRecord, + incGatewayRecord [3] IncGatewayRecord, + outGatewayRecord [4] OutGatewayRecord, + transitRecord [5] TransitCallRecord, + moSMSRecord [6] MOSMSRecord, + mtSMSRecord [7] MTSMSRecord, + ssActionRecord [10] SSActionRecord, + hlrIntRecord [11] HLRIntRecord, + commonEquipRecord [14] CommonEquipRecord, + recTypeExtensions [15] ManagementExtensions, + termCAMELRecord [16] TermCAMELRecord, + mtLCSRecord [17] MTLCSRecord, + moLCSRecord [18] MOLCSRecord, + niLCSRecord [19] NILCSRecord, + forwardCallRecord [100] MOCallRecord +} + +MOCallRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + servedIMSI [1] IMSI OPTIONAL, + servedIMEI [2] IMEI OPTIONAL, + servedMSISDN [3] MSISDN OPTIONAL, + callingNumber [4] CallingNumber OPTIONAL, + calledNumber [5] CalledNumber OPTIONAL, + translatedNumber [6] TranslatedNumber OPTIONAL, + connectedNumber [7] ConnectedNumber OPTIONAL, + roamingNumber [8] RoamingNumber OPTIONAL, + recordingEntity [9] RecordingEntity OPTIONAL, + mscIncomingROUTE [10] ROUTE OPTIONAL, + mscOutgoingROUTE [11] ROUTE OPTIONAL, + location [12] LocationAreaAndCell OPTIONAL, + changeOfLocation [13] SEQUENCE OF LocationChange OPTIONAL, + basicService [14] BasicServiceCode OPTIONAL, + transparencyIndicator [15] TransparencyInd OPTIONAL, + changeOfService [16] SEQUENCE OF ChangeOfService OPTIONAL, + supplServicesUsed [17] SEQUENCE OF SuppServiceUsed OPTIONAL, + aocParameters [18] AOCParameters OPTIONAL, + changeOfAOCParms [19] SEQUENCE OF AOCParmChange OPTIONAL, + msClassmark [20] Classmark OPTIONAL, + changeOfClassmark [21] ChangeOfClassmark OPTIONAL, + seizureTime [22] TimeStamp OPTIONAL, + answerTime [23] TimeStamp OPTIONAL, + releaseTime [24] TimeStamp OPTIONAL, + callDuration [25] CallDuration OPTIONAL, + radioChanRequested [27] RadioChanRequested OPTIONAL, + radioChanUsed [28] TrafficChannel OPTIONAL, + changeOfRadioChan [29] ChangeOfRadioChannel OPTIONAL, + causeForTerm [30] CauseForTerm OPTIONAL, + diagnostics [31] Diagnostics OPTIONAL, + callReference [32] CallReference OPTIONAL, + sequenceNumber [33] SequenceNumber OPTIONAL, + additionalChgInfo [34] AdditionalChgInfo OPTIONAL, + recordExtensions [35] ManagementExtensions OPTIONAL, + gsm-SCFAddress [36] Gsm-SCFAddress OPTIONAL, + serviceKey [37] ServiceKey OPTIONAL, + networkCallReference [38] NetworkCallReference OPTIONAL, + mSCAddress [39] MSCAddress OPTIONAL, + cAMELInitCFIndicator [40] CAMELInitCFIndicator OPTIONAL, + defaultCallHandling [41] DefaultCallHandling OPTIONAL, + fnur [45] Fnur OPTIONAL, + aiurRequested [46] AiurRequested OPTIONAL, + speechVersionSupported [49] SpeechVersionIdentifier OPTIONAL, + speechVersionUsed [50] SpeechVersionIdentifier OPTIONAL, + numberOfDPEncountered [51] INTEGER OPTIONAL, + levelOfCAMELService [52] LevelOfCAMELService OPTIONAL, + freeFormatData [53] FreeFormatData OPTIONAL, + cAMELCallLegInformation [54] SEQUENCE OF CAMELInformation OPTIONAL, + freeFormatDataAppend [55] BOOLEAN OPTIONAL, + defaultCallHandling-2 [56] DefaultCallHandling OPTIONAL, + gsm-SCFAddress-2 [57] Gsm-SCFAddress OPTIONAL, + serviceKey-2 [58] ServiceKey OPTIONAL, + freeFormatData-2 [59] FreeFormatData OPTIONAL, + freeFormatDataAppend-2 [60] BOOLEAN OPTIONAL, + systemType [61] SystemType OPTIONAL, + rateIndication [62] RateIndication OPTIONAL, + partialRecordType [69] PartialRecordType OPTIONAL, + guaranteedBitRate [70] GuaranteedBitRate OPTIONAL, + maximumBitRate [71] MaximumBitRate OPTIONAL, + modemType [139] ModemType OPTIONAL, + classmark3 [140] Classmark3 OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + originalCalledNumber [142] OriginalCalledNumber OPTIONAL, + callingChargeAreaCode [145] ChargeAreaCode OPTIONAL, + calledChargeAreaCode [146] ChargeAreaCode OPTIONAL, + mscOutgoingCircuit [166] MSCCIC OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + callEmlppPriority [170] EmlppPriority OPTIONAL, + callerDefaultEmlppPriority [171] EmlppPriority OPTIONAL, + eaSubscriberInfo [174] EASubscriberInfo OPTIONAL, + selectedCIC [175] SelectedCIC OPTIONAL, + optimalRoutingFlag [177] NULL OPTIONAL, + optimalRoutingLateForwardFlag [178] NULL OPTIONAL, + optimalRoutingEarlyForwardFlag [179] NULL OPTIONAL, + portedflag [180] PortedFlag OPTIONAL, + calledIMSI [181] IMSI OPTIONAL, + globalAreaID [188] GAI OPTIONAL, + changeOfglobalAreaID [189] SEQUENCE OF ChangeOfglobalAreaID OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + firstmccmnc [192] MCCMNC OPTIONAL, + intermediatemccmnc [193] MCCMNC OPTIONAL, + lastmccmnc [194] MCCMNC OPTIONAL, + cUGOutgoingAccessIndicator [195] CUGOutgoingAccessIndicator OPTIONAL, + cUGInterlockCode [196] CUGInterlockCode OPTIONAL, + cUGOutgoingAccessUsed [197] CUGOutgoingAccessUsed OPTIONAL, + cUGIndex [198] CUGIndex OPTIONAL, + interactionWithIP [199] InteractionWithIP OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL, + setupTime [201] TimeStamp OPTIONAL, + alertingTime [202] TimeStamp OPTIONAL, + voiceIndicator [203] VoiceIndicator OPTIONAL, + bCategory [204] BCategory OPTIONAL, + callType [205] CallType OPTIONAL +} + +--at moc callingNumber is the same as served msisdn except basic msisdn != calling number such as MSP service + +MTCallRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + servedIMSI [1] IMSI OPTIONAL, + servedIMEI [2] IMEI OPTIONAL, + servedMSISDN [3] CalledNumber OPTIONAL, + callingNumber [4] CallingNumber OPTIONAL, + connectedNumber [5] ConnectedNumber OPTIONAL, + recordingEntity [6] RecordingEntity OPTIONAL, + mscIncomingROUTE [7] ROUTE OPTIONAL, + mscOutgoingROUTE [8] ROUTE OPTIONAL, + location [9] LocationAreaAndCell OPTIONAL, + changeOfLocation [10] SEQUENCE OF LocationChange OPTIONAL, + basicService [11] BasicServiceCode OPTIONAL, + transparencyIndicator [12] TransparencyInd OPTIONAL, + changeOfService [13] SEQUENCE OF ChangeOfService OPTIONAL, + supplServicesUsed [14] SEQUENCE OF SuppServiceUsed OPTIONAL, + aocParameters [15] AOCParameters OPTIONAL, + changeOfAOCParms [16] SEQUENCE OF AOCParmChange OPTIONAL, + msClassmark [17] Classmark OPTIONAL, + changeOfClassmark [18] ChangeOfClassmark OPTIONAL, + seizureTime [19] TimeStamp OPTIONAL, + answerTime [20] TimeStamp OPTIONAL, + releaseTime [21] TimeStamp OPTIONAL, + callDuration [22] CallDuration OPTIONAL, + radioChanRequested [24] RadioChanRequested OPTIONAL, + radioChanUsed [25] TrafficChannel OPTIONAL, + changeOfRadioChan [26] ChangeOfRadioChannel OPTIONAL, + causeForTerm [27] CauseForTerm OPTIONAL, + diagnostics [28] Diagnostics OPTIONAL, + callReference [29] CallReference OPTIONAL, + sequenceNumber [30] SequenceNumber OPTIONAL, + additionalChgInfo [31] AdditionalChgInfo OPTIONAL, + recordExtensions [32] ManagementExtensions OPTIONAL, + networkCallReference [33] NetworkCallReference OPTIONAL, + mSCAddress [34] MSCAddress OPTIONAL, + fnur [38] Fnur OPTIONAL, + aiurRequested [39] AiurRequested OPTIONAL, + speechVersionSupported [42] SpeechVersionIdentifier OPTIONAL, + speechVersionUsed [43] SpeechVersionIdentifier OPTIONAL, + gsm-SCFAddress [44] Gsm-SCFAddress OPTIONAL, + serviceKey [45] ServiceKey OPTIONAL, + systemType [46] SystemType OPTIONAL, + rateIndication [47] RateIndication OPTIONAL, + partialRecordType [54] PartialRecordType OPTIONAL, + guaranteedBitRate [55] GuaranteedBitRate OPTIONAL, + maximumBitRate [56] MaximumBitRate OPTIONAL, + initialCallAttemptFlag [137] NULL OPTIONAL, + ussdCallBackFlag [138] NULL OPTIONAL, + modemType [139] ModemType OPTIONAL, + classmark3 [140] Classmark3 OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + originalCalledNumber [142] OriginalCalledNumber OPTIONAL, + callingChargeAreaCode [145]ChargeAreaCode OPTIONAL, + calledChargeAreaCode [146]ChargeAreaCode OPTIONAL, + defaultCallHandling [150] DefaultCallHandling OPTIONAL, + freeFormatData [151] FreeFormatData OPTIONAL, + freeFormatDataAppend [152] BOOLEAN OPTIONAL, + numberOfDPEncountered [153] INTEGER OPTIONAL, + levelOfCAMELService [154] LevelOfCAMELService OPTIONAL, + roamingNumber [160] RoamingNumber OPTIONAL, + mscIncomingCircuit [166] MSCCIC OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + callEmlppPriority [170] EmlppPriority OPTIONAL, + calledDefaultEmlppPriority [171] EmlppPriority OPTIONAL, + eaSubscriberInfo [174] EASubscriberInfo OPTIONAL, + selectedCIC [175] SelectedCIC OPTIONAL, + optimalRoutingFlag [177] NULL OPTIONAL, + portedflag [180] PortedFlag OPTIONAL, + globalAreaID [188] GAI OPTIONAL, + changeOfglobalAreaID [189] SEQUENCE OF ChangeOfglobalAreaID OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + firstmccmnc [192] MCCMNC OPTIONAL, + intermediatemccmnc [193] MCCMNC OPTIONAL, + lastmccmnc [194] MCCMNC OPTIONAL, + cUGOutgoingAccessIndicator [195] CUGOutgoingAccessIndicator OPTIONAL, + cUGInterlockCode [196] CUGInterlockCode OPTIONAL, + cUGIncomingAccessUsed [197] CUGIncomingAccessUsed OPTIONAL, + cUGIndex [198] CUGIndex OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL, + redirectingnumber [201] RedirectingNumber OPTIONAL, + redirectingcounter [202] RedirectingCounter OPTIONAL, + setupTime [203] TimeStamp OPTIONAL, + alertingTime [204] TimeStamp OPTIONAL, + calledNumber [205] CalledNumber OPTIONAL, + voiceIndicator [206] VoiceIndicator OPTIONAL, + bCategory [207] BCategory OPTIONAL, + callType [208] CallType OPTIONAL +} + +RoamingRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + servedIMSI [1] IMSI OPTIONAL, + servedMSISDN [2] MSISDN OPTIONAL, + callingNumber [3] CallingNumber OPTIONAL, + roamingNumber [4] RoamingNumber OPTIONAL, + recordingEntity [5] RecordingEntity OPTIONAL, + mscIncomingROUTE [6] ROUTE OPTIONAL, + mscOutgoingROUTE [7] ROUTE OPTIONAL, + basicService [8] BasicServiceCode OPTIONAL, + transparencyIndicator [9] TransparencyInd OPTIONAL, + changeOfService [10] SEQUENCE OF ChangeOfService OPTIONAL, + supplServicesUsed [11] SEQUENCE OF SuppServiceUsed OPTIONAL, + seizureTime [12] TimeStamp OPTIONAL, + answerTime [13] TimeStamp OPTIONAL, + releaseTime [14] TimeStamp OPTIONAL, + callDuration [15] CallDuration OPTIONAL, + causeForTerm [17] CauseForTerm OPTIONAL, + diagnostics [18] Diagnostics OPTIONAL, + callReference [19] CallReference OPTIONAL, + sequenceNumber [20] SequenceNumber OPTIONAL, + recordExtensions [21] ManagementExtensions OPTIONAL, + networkCallReference [22] NetworkCallReference OPTIONAL, + mSCAddress [23] MSCAddress OPTIONAL, + partialRecordType [30] PartialRecordType OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + originalCalledNumber [142] OriginalCalledNumber OPTIONAL, + callingChargeAreaCode [145] ChargeAreaCode OPTIONAL, + calledChargeAreaCode [146] ChargeAreaCode OPTIONAL, + mscOutgoingCircuit [166] MSCCIC OPTIONAL, + mscIncomingCircuit [167] MSCCIC OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + callEmlppPriority [170] EmlppPriority OPTIONAL, + eaSubscriberInfo [174] EASubscriberInfo OPTIONAL, + selectedCIC [175] SelectedCIC OPTIONAL, + optimalRoutingFlag [177] NULL OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + cUGOutgoingAccessIndicator [195] CUGOutgoingAccessIndicator OPTIONAL, + cUGInterlockCode [196] CUGInterlockCode OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL +} + +TermCAMELRecord ::= SET +{ + recordtype [0] CallEventRecordType OPTIONAL, + servedIMSI [1] IMSI OPTIONAL, + servedMSISDN [2] MSISDN OPTIONAL, + recordingEntity [3] RecordingEntity OPTIONAL, + interrogationTime [4] TimeStamp OPTIONAL, + destinationRoutingAddress [5] DestinationRoutingAddress OPTIONAL, + gsm-SCFAddress [6] Gsm-SCFAddress OPTIONAL, + serviceKey [7] ServiceKey OPTIONAL, + networkCallReference [8] NetworkCallReference OPTIONAL, + mSCAddress [9] MSCAddress OPTIONAL, + defaultCallHandling [10] DefaultCallHandling OPTIONAL, + recordExtensions [11] ManagementExtensions OPTIONAL, + calledNumber [12] CalledNumber OPTIONAL, + callingNumber [13] CallingNumber OPTIONAL, + mscIncomingROUTE [14] ROUTE OPTIONAL, + mscOutgoingROUTE [15] ROUTE OPTIONAL, + seizureTime [16] TimeStamp OPTIONAL, + answerTime [17] TimeStamp OPTIONAL, + releaseTime [18] TimeStamp OPTIONAL, + callDuration [19] CallDuration OPTIONAL, + causeForTerm [21] CauseForTerm OPTIONAL, + diagnostics [22] Diagnostics OPTIONAL, + callReference [23] CallReference OPTIONAL, + sequenceNumber [24] SequenceNumber OPTIONAL, + numberOfDPEncountered [25] INTEGER OPTIONAL, + levelOfCAMELService [26] LevelOfCAMELService OPTIONAL, + freeFormatData [27] FreeFormatData OPTIONAL, + cAMELCallLegInformation [28] SEQUENCE OF CAMELInformation OPTIONAL, + freeFormatDataAppend [29] BOOLEAN OPTIONAL, + mscServerIndication [30] BOOLEAN OPTIONAL, + defaultCallHandling-2 [31] DefaultCallHandling OPTIONAL, + gsm-SCFAddress-2 [32] Gsm-SCFAddress OPTIONAL, + serviceKey-2 [33] ServiceKey OPTIONAL, + freeFormatData-2 [34] FreeFormatData OPTIONAL, + freeFormatDataAppend-2 [35] BOOLEAN OPTIONAL, + partialRecordType [42] PartialRecordType OPTIONAL, + basicService [130] BasicServiceCode OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + originalCalledNumber [142] OriginalCalledNumber OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL +} + +IncGatewayRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + callingNumber [1] CallingNumber OPTIONAL, + calledNumber [2] CalledNumber OPTIONAL, + recordingEntity [3] RecordingEntity OPTIONAL, + mscIncomingROUTE [4] ROUTE OPTIONAL, + mscOutgoingROUTE [5] ROUTE OPTIONAL, + seizureTime [6] TimeStamp OPTIONAL, + answerTime [7] TimeStamp OPTIONAL, + releaseTime [8] TimeStamp OPTIONAL, + callDuration [9] CallDuration OPTIONAL, + causeForTerm [11] CauseForTerm OPTIONAL, + diagnostics [12] Diagnostics OPTIONAL, + callReference [13] CallReference OPTIONAL, + sequenceNumber [14] SequenceNumber OPTIONAL, + recordExtensions [15] ManagementExtensions OPTIONAL, + partialRecordType [22] PartialRecordType OPTIONAL, + iSDN-BC [23] ISDN-BC OPTIONAL, + lLC [24] LLC OPTIONAL, + hLC [25] HLC OPTIONAL, + basicService [130] BasicServiceCode OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + originalCalledNumber [142] OriginalCalledNumber OPTIONAL, + rateIndication [159] RateIndication OPTIONAL, + roamingNumber [160] RoamingNumber OPTIONAL, + mscIncomingCircuit [167] MSCCIC OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + callEmlppPriority [170] EmlppPriority OPTIONAL, + eaSubscriberInfo [174] EASubscriberInfo OPTIONAL, + selectedCIC [175] SelectedCIC OPTIONAL, + cUGOutgoingAccessIndicator [195] CUGOutgoingAccessIndicator OPTIONAL, + cUGInterlockCode [196] CUGInterlockCode OPTIONAL, + cUGIncomingAccessUsed [197] CUGIncomingAccessUsed OPTIONAL, + mscIncomingRouteAttribute [198] RouteAttribute OPTIONAL, + mscOutgoingRouteAttribute [199] RouteAttribute OPTIONAL, + networkCallReference [200] NetworkCallReference OPTIONAL, + setupTime [201] TimeStamp OPTIONAL, + alertingTime [202] TimeStamp OPTIONAL, + voiceIndicator [203] VoiceIndicator OPTIONAL, + bCategory [204] BCategory OPTIONAL, + callType [205] CallType OPTIONAL +} + +OutGatewayRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + callingNumber [1] CallingNumber OPTIONAL, + calledNumber [2] CalledNumber OPTIONAL, + recordingEntity [3] RecordingEntity OPTIONAL, + mscIncomingROUTE [4] ROUTE OPTIONAL, + mscOutgoingROUTE [5] ROUTE OPTIONAL, + seizureTime [6] TimeStamp OPTIONAL, + answerTime [7] TimeStamp OPTIONAL, + releaseTime [8] TimeStamp OPTIONAL, + callDuration [9] CallDuration OPTIONAL, + causeForTerm [11] CauseForTerm OPTIONAL, + diagnostics [12] Diagnostics OPTIONAL, + callReference [13] CallReference OPTIONAL, + sequenceNumber [14] SequenceNumber OPTIONAL, + recordExtensions [15] ManagementExtensions OPTIONAL, + partialRecordType [22] PartialRecordType OPTIONAL, + basicService [130] BasicServiceCode OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + originalCalledNumber [142] OriginalCalledNumber OPTIONAL, + rateIndication [159] RateIndication OPTIONAL, + roamingNumber [160] RoamingNumber OPTIONAL, + mscOutgoingCircuit [166] MSCCIC OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + eaSubscriberInfo [174] EASubscriberInfo OPTIONAL, + selectedCIC [175] SelectedCIC OPTIONAL, + callEmlppPriority [170] EmlppPriority OPTIONAL, + cUGOutgoingAccessIndicator [195] CUGOutgoingAccessIndicator OPTIONAL, + cUGInterlockCode [196] CUGInterlockCode OPTIONAL, + cUGIncomingAccessUsed [197] CUGIncomingAccessUsed OPTIONAL, + mscIncomingRouteAttribute [198] RouteAttribute OPTIONAL, + mscOutgoingRouteAttribute [199] RouteAttribute OPTIONAL, + networkCallReference [200] NetworkCallReference OPTIONAL, + setupTime [201] TimeStamp OPTIONAL, + alertingTime [202] TimeStamp OPTIONAL, + voiceIndicator [203] VoiceIndicator OPTIONAL, + bCategory [204] BCategory OPTIONAL, + callType [205] CallType OPTIONAL +} + +TransitCallRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + recordingEntity [1] RecordingEntity OPTIONAL, + mscIncomingROUTE [2] ROUTE OPTIONAL, + mscOutgoingROUTE [3] ROUTE OPTIONAL, + callingNumber [4] CallingNumber OPTIONAL, + calledNumber [5] CalledNumber OPTIONAL, + isdnBasicService [6] BasicService OPTIONAL, + seizureTime [7] TimeStamp OPTIONAL, + answerTime [8] TimeStamp OPTIONAL, + releaseTime [9] TimeStamp OPTIONAL, + callDuration [10] CallDuration OPTIONAL, + causeForTerm [12] CauseForTerm OPTIONAL, + diagnostics [13] Diagnostics OPTIONAL, + callReference [14] CallReference OPTIONAL, + sequenceNumber [15] SequenceNumber OPTIONAL, + recordExtensions [16] ManagementExtensions OPTIONAL, + partialRecordType [23] PartialRecordType OPTIONAL, + basicService [130] BasicServiceCode OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + originalCalledNumber [142] OriginalCalledNumber OPTIONAL, + rateIndication [159] RateIndication OPTIONAL, + mscOutgoingCircuit [166] MSCCIC OPTIONAL, + mscIncomingCircuit [167] MSCCIC OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + callEmlppPriority [170] EmlppPriority OPTIONAL, + eaSubscriberInfo [174] EASubscriberInfo OPTIONAL, + selectedCIC [175] SelectedCIC OPTIONAL, + cUGOutgoingAccessIndicator [195] CUGOutgoingAccessIndicator OPTIONAL, + cUGInterlockCode [196] CUGInterlockCode OPTIONAL, + cUGIncomingAccessUsed [197] CUGIncomingAccessUsed OPTIONAL, + mscIncomingRouteAttribute [198] RouteAttribute OPTIONAL, + mscOutgoingRouteAttribute [199] RouteAttribute OPTIONAL, + networkCallReference [200] NetworkCallReference OPTIONAL, + setupTime [201] TimeStamp OPTIONAL, + alertingTime [202] TimeStamp OPTIONAL, + voiceIndicator [203] VoiceIndicator OPTIONAL, + bCategory [204] BCategory OPTIONAL, + callType [205] CallType OPTIONAL +} + +MOSMSRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + servedIMSI [1] IMSI OPTIONAL, + servedIMEI [2] IMEI OPTIONAL, + servedMSISDN [3] MSISDN OPTIONAL, + msClassmark [4] Classmark OPTIONAL, + serviceCentre [5] AddressString OPTIONAL, + recordingEntity [6] RecordingEntity OPTIONAL, + location [7] LocationAreaAndCell OPTIONAL, + messageReference [8] MessageReference OPTIONAL, + originationTime [9] TimeStamp OPTIONAL, + smsResult [10] SMSResult OPTIONAL, + recordExtensions [11] ManagementExtensions OPTIONAL, + destinationNumber [12] SmsTpDestinationNumber OPTIONAL, + cAMELSMSInformation [13] CAMELSMSInformation OPTIONAL, + systemType [14] SystemType OPTIONAL, + basicService [130] BasicServiceCode OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + classmark3 [140] Classmark3 OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + globalAreaID [188] GAI OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + firstmccmnc [192] MCCMNC OPTIONAL, + smsUserDataType [195] SmsUserDataType OPTIONAL, + smstext [196] SMSTEXT OPTIONAL, + maximumNumberOfSMSInTheConcatenatedSMS [197] MaximumNumberOfSMSInTheConcatenatedSMS OPTIONAL, + concatenatedSMSReferenceNumber [198] ConcatenatedSMSReferenceNumber OPTIONAL, + sequenceNumberOfTheCurrentSMS [199] SequenceNumberOfTheCurrentSMS OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL, + callReference [201] CallReference OPTIONAL +} + +MTSMSRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + serviceCentre [1] AddressString OPTIONAL, + servedIMSI [2] IMSI OPTIONAL, + servedIMEI [3] IMEI OPTIONAL, + servedMSISDN [4] MSISDN OPTIONAL, + msClassmark [5] Classmark OPTIONAL, + recordingEntity [6] RecordingEntity OPTIONAL, + location [7] LocationAreaAndCell OPTIONAL, + deliveryTime [8] TimeStamp OPTIONAL, + smsResult [9] SMSResult OPTIONAL, + recordExtensions [10] ManagementExtensions OPTIONAL, + systemType [11] SystemType OPTIONAL, + cAMELSMSInformation [12] CAMELSMSInformation OPTIONAL, + basicService [130] BasicServiceCode OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + classmark3 [140] Classmark3 OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + globalAreaID [188] GAI OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + firstmccmnc [192] MCCMNC OPTIONAL, + smsUserDataType [195] SmsUserDataType OPTIONAL, + smstext [196] SMSTEXT OPTIONAL, + maximumNumberOfSMSInTheConcatenatedSMS [197] MaximumNumberOfSMSInTheConcatenatedSMS OPTIONAL, + concatenatedSMSReferenceNumber [198] ConcatenatedSMSReferenceNumber OPTIONAL, + sequenceNumberOfTheCurrentSMS [199] SequenceNumberOfTheCurrentSMS OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL, + origination [201] CallingNumber OPTIONAL, + callReference [202] CallReference OPTIONAL +} + +HLRIntRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + servedIMSI [1] IMSI OPTIONAL, + servedMSISDN [2] MSISDN OPTIONAL, + recordingEntity [3] RecordingEntity OPTIONAL, + basicService [4] BasicServiceCode OPTIONAL, + routingNumber [5] RoutingNumber OPTIONAL, + interrogationTime [6] TimeStamp OPTIONAL, + numberOfForwarding [7] NumberOfForwarding OPTIONAL, + interrogationResult [8] HLRIntResult OPTIONAL, + recordExtensions [9] ManagementExtensions OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + callReference [169] CallReference OPTIONAL +} + +SSActionRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + servedIMSI [1] IMSI OPTIONAL, + servedIMEI [2] IMEI OPTIONAL, + servedMSISDN [3] MSISDN OPTIONAL, + msClassmark [4] Classmark OPTIONAL, + recordingEntity [5] RecordingEntity OPTIONAL, + location [6] LocationAreaAndCell OPTIONAL, + basicServices [7] BasicServices OPTIONAL, + supplService [8] SS-Code OPTIONAL, + ssAction [9] SSActionType OPTIONAL, + ssActionTime [10] TimeStamp OPTIONAL, + ssParameters [11] SSParameters OPTIONAL, + ssActionResult [12] SSActionResult OPTIONAL, + callReference [13] CallReference OPTIONAL, + recordExtensions [14] ManagementExtensions OPTIONAL, + systemType [15] SystemType OPTIONAL, + ussdCodingScheme [126] UssdCodingScheme OPTIONAL, + ussdString [127] SEQUENCE OF UssdString OPTIONAL, + ussdNotifyCounter [128] UssdNotifyCounter OPTIONAL, + ussdRequestCounter [129] UssdRequestCounter OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + classmark3 [140] Classmark3 OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + globalAreaID [188] GAI OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + firstmccmnc [192] MCCMNC OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL +} + +CommonEquipRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + equipmentType [1] EquipmentType OPTIONAL, + equipmentId [2] EquipmentId OPTIONAL, + servedIMSI [3] IMSI OPTIONAL, + servedMSISDN [4] MSISDN OPTIONAL, + recordingEntity [5] RecordingEntity OPTIONAL, + basicService [6] BasicServiceCode OPTIONAL, + changeOfService [7] SEQUENCE OF ChangeOfService OPTIONAL, + supplServicesUsed [8] SEQUENCE OF SuppServiceUsed OPTIONAL, + seizureTime [9] TimeStamp OPTIONAL, + releaseTime [10] TimeStamp OPTIONAL, + callDuration [11] CallDuration OPTIONAL, + callReference [12] CallReference OPTIONAL, + sequenceNumber [13] SequenceNumber OPTIONAL, + recordExtensions [14] ManagementExtensions OPTIONAL, + systemType [15] SystemType OPTIONAL, + rateIndication [16] RateIndication OPTIONAL, + fnur [17] Fnur OPTIONAL, + partialRecordType [18] PartialRecordType OPTIONAL, + causeForTerm [100] CauseForTerm OPTIONAL, + diagnostics [101] Diagnostics OPTIONAL, + servedIMEI [102] IMEI OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL +} + +------------------------------------------------------------------------------ +-- +-- OBSERVED IMEI TICKETS +-- +------------------------------------------------------------------------------ + +ObservedIMEITicket ::= SET +{ + servedIMEI [0] IMEI, + imeiStatus [1] IMEIStatus, + servedIMSI [2] IMSI, + servedMSISDN [3] MSISDN OPTIONAL, + recordingEntity [4] RecordingEntity, + eventTime [5] TimeStamp, + location [6] LocationAreaAndCell, + imeiCheckEvent [7] IMEICheckEvent OPTIONAL, + callReference [8] CallReference OPTIONAL, + recordExtensions [9] ManagementExtensions OPTIONAL, + orgMSCId [168] MSCId OPTIONAL +} + + + +------------------------------------------------------------------------------ +-- +-- LOCATION SERICE TICKETS +-- +------------------------------------------------------------------------------ + +MTLCSRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + recordingEntity [1] RecordingEntity OPTIONAL, + lcsClientType [2] LCSClientType OPTIONAL, + lcsClientIdentity [3] LCSClientIdentity OPTIONAL, + servedIMSI [4] IMSI OPTIONAL, + servedMSISDN [5] MSISDN OPTIONAL, + locationType [6] LocationType OPTIONAL, + lcsQos [7] LCSQoSInfo OPTIONAL, + lcsPriority [8] LCS-Priority OPTIONAL, + mlc-Number [9] ISDN-AddressString OPTIONAL, + eventTimeStamp [10] TimeStamp OPTIONAL, + measureDuration [11] CallDuration OPTIONAL, + notificationToMSUser [12] NotificationToMSUser OPTIONAL, + privacyOverride [13] NULL OPTIONAL, + location [14] LocationAreaAndCell OPTIONAL, + locationEstimate [15] Ext-GeographicalInformation OPTIONAL, + positioningData [16] PositioningData OPTIONAL, + lcsCause [17] LCSCause OPTIONAL, + diagnostics [18] Diagnostics OPTIONAL, + systemType [19] SystemType OPTIONAL, + recordExtensions [20] ManagementExtensions OPTIONAL, + causeForTerm [21] CauseForTerm OPTIONAL, + lcsReferenceNumber [101] CallReferenceNumber OPTIONAL, + servedIMEI [102] IMEI OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + globalAreaID [188] GAI OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + firstmccmnc [192] MCCMNC OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL, + callReference [201] CallReference OPTIONAL +} + +MOLCSRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + recordingEntity [1] RecordingEntity OPTIONAL, + lcsClientType [2] LCSClientType OPTIONAL, + lcsClientIdentity [3] LCSClientIdentity OPTIONAL, + servedIMSI [4] IMSI OPTIONAL, + servedMSISDN [5] MSISDN OPTIONAL, + molr-Type [6] MOLR-Type OPTIONAL, + lcsQos [7] LCSQoSInfo OPTIONAL, + lcsPriority [8] LCS-Priority OPTIONAL, + mlc-Number [9] ISDN-AddressString OPTIONAL, + eventTimeStamp [10] TimeStamp OPTIONAL, + measureDuration [11] CallDuration OPTIONAL, + location [12] LocationAreaAndCell OPTIONAL, + locationEstimate [13] Ext-GeographicalInformation OPTIONAL, + positioningData [14] PositioningData OPTIONAL, + lcsCause [15] LCSCause OPTIONAL, + diagnostics [16] Diagnostics OPTIONAL, + systemType [17] SystemType OPTIONAL, + recordExtensions [18] ManagementExtensions OPTIONAL, + causeForTerm [19] CauseForTerm OPTIONAL, + lcsReferenceNumber [101] CallReferenceNumber OPTIONAL, + servedIMEI [102] IMEI OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + globalAreaID [188] GAI OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + firstmccmnc [192] MCCMNC OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL, + callReference [201] CallReference OPTIONAL +} + +NILCSRecord ::= SET +{ + recordType [0] CallEventRecordType OPTIONAL, + recordingEntity [1] RecordingEntity OPTIONAL, + lcsClientType [2] LCSClientType OPTIONAL, + lcsClientIdentity [3] LCSClientIdentity OPTIONAL, + servedIMSI [4] IMSI OPTIONAL, + servedMSISDN [5] MSISDN OPTIONAL, + servedIMEI [6] IMEI OPTIONAL, + emsDigits [7] ISDN-AddressString OPTIONAL, + emsKey [8] ISDN-AddressString OPTIONAL, + lcsQos [9] LCSQoSInfo OPTIONAL, + lcsPriority [10] LCS-Priority OPTIONAL, + mlc-Number [11] ISDN-AddressString OPTIONAL, + eventTimeStamp [12] TimeStamp OPTIONAL, + measureDuration [13] CallDuration OPTIONAL, + location [14] LocationAreaAndCell OPTIONAL, + locationEstimate [15] Ext-GeographicalInformation OPTIONAL, + positioningData [16] PositioningData OPTIONAL, + lcsCause [17] LCSCause OPTIONAL, + diagnostics [18] Diagnostics OPTIONAL, + systemType [19] SystemType OPTIONAL, + recordExtensions [20] ManagementExtensions OPTIONAL, + causeForTerm [21] CauseForTerm OPTIONAL, + lcsReferenceNumber [101] CallReferenceNumber OPTIONAL, + additionalChgInfo [133] AdditionalChgInfo OPTIONAL, + chargedParty [141] ChargedParty OPTIONAL, + orgRNCorBSCId [167] RNCorBSCId OPTIONAL, + orgMSCId [168] MSCId OPTIONAL, + globalAreaID [188] GAI OPTIONAL, + subscriberCategory [190] SubscriberCategory OPTIONAL, + firstmccmnc [192] MCCMNC OPTIONAL, + hotBillingTag [200] HotBillingTag OPTIONAL, + callReference [201] CallReference OPTIONAL +} + + +------------------------------------------------------------------------------ +-- +-- FTAM / FTP / TFTP FILE CONTENTS +-- +------------------------------------------------------------------------------ + +CallEventDataFile ::= SEQUENCE +{ + headerRecord [0] HeaderRecord, + callEventRecords [1] SEQUENCE OF CallEventRecord, + trailerRecord [2] TrailerRecord, + extensions [3] ManagementExtensions +} + +ObservedIMEITicketFile ::= SEQUENCE +{ + productionDateTime [0] TimeStamp, + observedIMEITickets [1] SEQUENCE OF ObservedIMEITicket, + noOfRecords [2] INTEGER, + extensions [3] ManagementExtensions +} + +HeaderRecord ::= SEQUENCE +{ + productionDateTime [0] TimeStamp, + recordingEntity [1] RecordingEntity, + extensions [2] ManagementExtensions +} + +TrailerRecord ::= SEQUENCE +{ + productionDateTime [0] TimeStamp, + recordingEntity [1] RecordingEntity, + firstCallDateTime [2] TimeStamp, + lastCallDateTime [3] TimeStamp, + noOfRecords [4] INTEGER, + extensions [5] ManagementExtensions +} + + +------------------------------------------------------------------------------ +-- +-- COMMON DATA TYPES +-- +------------------------------------------------------------------------------ + +AdditionalChgInfo ::= SEQUENCE +{ + chargeIndicator [0] ChargeIndicator OPTIONAL, + chargeParameters [1] OCTET STRING OPTIONAL +} + +AddressString ::= OCTET STRING -- (SIZE (1..maxAddressLength)) + -- This type is used to represent a number for addressing + -- purposes. It is composed of + -- a) one octet for nature of address, and numbering plan + -- indicator. + -- b) digits of an address encoded as TBCD-String. + + -- a) The first octet includes a one bit extension indicator, a + -- 3 bits nature of address indicator and a 4 bits numbering + -- plan indicator, encoded as follows: + + -- bit 8: 1 (no extension) + + -- bits 765: nature of address indicator + -- 000 unknown + -- 001 international number + -- 010 national significant number + -- 011 network specific number + -- 100 subscriber number + -- 101 reserved + -- 110 abbreviated number + -- 111 reserved for extension + + -- bits 4321: numbering plan indicator + -- 0000 unknown + -- 0001 ISDN/Telephony Numbering Plan (Rec CCITT E.164) + -- 0010 spare + -- 0011 data numbering plan (CCITT Rec X.121) + -- 0100 telex numbering plan (CCITT Rec F.69) + -- 0101 spare + -- 0110 land mobile numbering plan (CCITT Rec E.212) + -- 0111 spare + -- 1000 national numbering plan + -- 1001 private numbering plan + -- 1111 reserved for extension + + -- all other values are reserved. + + -- b) The following octets representing digits of an address + -- encoded as a TBCD-STRING. + +-- maxAddressLength INTEGER ::= 20 + +AiurRequested ::= ENUMERATED +{ + -- + -- See Bearer Capability TS 24.008 + -- (note that value "4" is intentionally missing + -- because it is not used in TS 24.008) + -- + + aiur09600BitsPerSecond (1), + aiur14400BitsPerSecond (2), + aiur19200BitsPerSecond (3), + aiur28800BitsPerSecond (5), + aiur38400BitsPerSecond (6), + aiur43200BitsPerSecond (7), + aiur57600BitsPerSecond (8), + aiur38400BitsPerSecond1 (9), + aiur38400BitsPerSecond2 (10), + aiur38400BitsPerSecond3 (11), + aiur38400BitsPerSecond4 (12) +} + +AOCParameters ::= SEQUENCE +{ + -- + -- See TS 22.024. + -- + e1 [1] EParameter OPTIONAL, + e2 [2] EParameter OPTIONAL, + e3 [3] EParameter OPTIONAL, + e4 [4] EParameter OPTIONAL, + e5 [5] EParameter OPTIONAL, + e6 [6] EParameter OPTIONAL, + e7 [7] EParameter OPTIONAL +} + +AOCParmChange ::= SEQUENCE +{ + changeTime [0] TimeStamp, + newParameters [1] AOCParameters +} + +BasicService ::= OCTET STRING -- (SIZE(1)) + +--This parameter identifies the ISDN Basic service as defined in ETSI specification ETS 300 196. +-- allServices '00'h +-- speech '01'h +-- unrestricteDigtalInfo '02'h +-- audio3k1HZ '03'h +-- unrestricteDigtalInfowithtoneandannoucement '04'h +-- telephony3k1HZ '20'h +-- teletext '21'h +-- telefaxGroup4Class1 '22'h +-- videotextSyntaxBased '23'h +-- videotelephony '24'h +-- telefaxGroup2-3 '25'h +-- telephony7kHZ '26'h + + + +BasicServices ::= SET OF BasicServiceCode + +BasicServiceCode ::= CHOICE +{ + bearerService [2] BearerServiceCode, + teleservice [3] TeleserviceCode +} + + +TeleserviceCode ::= OCTET STRING -- (SIZE (1)) + -- This type is used to represent the code identifying a single + -- teleservice, a group of teleservices, or all teleservices. The + -- services are defined in TS GSM 02.03. + -- The internal structure is defined as follows: + + -- bits 87654321: group (bits 8765) and specific service + -- (bits 4321) + +-- allTeleservices (0x00), +-- allSpeechTransmissionServices (0x10), +-- telephony (0x11), +-- emergencyCalls (0x12), +-- +-- allShortMessageServices (0x20), +-- shortMessageMT-PP (0x21), +-- shortMessageMO-PP (0x22), +-- +-- allFacsimileTransmissionServices (0x60), +-- facsimileGroup3AndAlterSpeech (0x61), +-- automaticFacsimileGroup3 (0x62), +-- facsimileGroup4 (0x63), +-- +-- The following non-hierarchical Compound Teleservice Groups +-- are defined in TS GSM 02.30: +-- allDataTeleservices (0x70), +-- covers Teleservice Groups 'allFacsimileTransmissionServices' +-- and 'allShortMessageServices' +-- allTeleservices-ExeptSMS (0x80), +-- covers Teleservice Groups 'allSpeechTransmissionServices' and +-- 'allFacsimileTransmissionServices' +-- +-- Compound Teleservice Group Codes are only used in call +-- independent supplementary service operations, i.e. they +-- are not used in InsertSubscriberData or in +-- DeleteSubscriberData messages. +-- +-- allVoiceGroupCallServices (0x90), +-- voiceGroupCall (0x91), +-- voiceBroadcastCall (0x92), +-- +-- allPLMN-specificTS (0xd0), +-- plmn-specificTS-1 (0xd1), +-- plmn-specificTS-2 (0xd2), +-- plmn-specificTS-3 (0xd3), +-- plmn-specificTS-4 (0xd4), +-- plmn-specificTS-5 (0xd5), +-- plmn-specificTS-6 (0xd6), +-- plmn-specificTS-7 (0xd7), +-- plmn-specificTS-8 (0xd8), +-- plmn-specificTS-9 (0xd9), +-- plmn-specificTS-A (0xda), +-- plmn-specificTS-B (0xdb), +-- plmn-specificTS-C (0xdc), +-- plmn-specificTS-D (0xdd), +-- plmn-specificTS-E (0xde), +-- plmn-specificTS-F (0xdf) + + +BearerServiceCode ::= OCTET STRING -- (SIZE (1)) + -- This type is used to represent the code identifying a single + -- bearer service, a group of bearer services, or all bearer + -- services. The services are defined in TS 3GPP TS 22.002 [3]. + -- The internal structure is defined as follows: + -- + -- plmn-specific bearer services: + -- bits 87654321: defined by the HPLMN operator + + -- rest of bearer services: + -- bit 8: 0 (unused) + -- bits 7654321: group (bits 7654), and rate, if applicable + -- (bits 321) + +-- allBearerServices (0x00), +-- allDataCDA-Services (0x10), +-- dataCDA-300bps (0x11), +-- dataCDA-1200bps (0x12), +-- dataCDA-1200-75bps (0x13), +-- dataCDA-2400bps (0x14), +-- dataCDA-4800bps (0x15), +-- dataCDA-9600bps (0x16), +-- general-dataCDA (0x17), +-- +-- allDataCDS-Services (0x18), +-- dataCDS-1200bps (0x1a), +-- dataCDS-2400bps (0x1c), +-- dataCDS-4800bps (0x1d), +-- dataCDS-9600bps (0x1e), +-- general-dataCDS (0x1f), +-- +-- allPadAccessCA-Services (0x20), +-- padAccessCA-300bps (0x21), +-- padAccessCA-1200bps (0x22), +-- padAccessCA-1200-75bps (0x23), +-- padAccessCA-2400bps (0x24), +-- padAccessCA-4800bps (0x25), +-- padAccessCA-9600bps (0x26), +-- general-padAccessCA (0x27), +-- +-- allDataPDS-Services (0x28), +-- dataPDS-2400bps (0x2c), +-- dataPDS-4800bps (0x2d), +-- dataPDS-9600bps (0x2e), +-- general-dataPDS (0x2f), +-- +-- allAlternateSpeech-DataCDA (0x30), +-- +-- allAlternateSpeech-DataCDS (0x38), +-- +-- allSpeechFollowedByDataCDA (0x40), +-- +-- allSpeechFollowedByDataCDS (0x48), +-- +-- The following non-hierarchical Compound Bearer Service +-- Groups are defined in TS GSM 02.30: +-- allDataCircuitAsynchronous (0x50), +-- covers "allDataCDA-Services", "allAlternateSpeech-DataCDA" and +-- "allSpeechFollowedByDataCDA" +-- allDataCircuitSynchronous (0x58), +-- covers "allDataCDS-Services", "allAlternateSpeech-DataCDS" and +-- "allSpeechFollowedByDataCDS" +-- allAsynchronousServices (0x60), +-- covers "allDataCDA-Services", "allAlternateSpeech-DataCDA", +-- "allSpeechFollowedByDataCDA" and "allPadAccessCDA-Services" +-- allSynchronousServices (0x68), +-- covers "allDataCDS-Services", "allAlternateSpeech-DataCDS", +-- "allSpeechFollowedByDataCDS" and "allDataPDS-Services" +-- +-- Compound Bearer Service Group Codes are only used in call +-- independent supplementary service operations, i.e. they +-- are not used in InsertSubscriberData or in +-- DeleteSubscriberData messages. +-- +-- allPLMN-specificBS (0xd0), +-- plmn-specificBS-1 (0xd1), +-- plmn-specificBS-2 (0xd2), +-- plmn-specificBS-3 (0xd3), +-- plmn-specificBS-4 (0xd4), +-- plmn-specificBS-5 (0xd5), +-- plmn-specificBS-6 (0xd6), +-- plmn-specificBS-7 (0xd7), +-- plmn-specificBS-8 (0xd8), +-- plmn-specificBS-9 (0xd9), +-- plmn-specificBS-A (0xda), +-- plmn-specificBS-B (0xdb), +-- plmn-specificBS-C (0xdc), +-- plmn-specificBS-D (0xdd), +-- plmn-specificBS-E (0xde), +-- plmn-specificBS-F (0xdf) + + +BCDDirectoryNumber ::= OCTET STRING + -- This type contains the binary coded decimal representation of + -- a directory number e.g. calling/called/connected/translated number. + -- The encoding of the octet string is in accordance with the + -- the elements "Calling party BCD number", "Called party BCD number" + -- and "Connected number" defined in TS 24.008. + -- This encoding includes type of number and number plan information + -- together with a BCD encoded digit string. + -- It may also contain both a presentation and screening indicator + -- (octet 3a). + -- For the avoidance of doubt, this field does not include + -- octets 1 and 2, the element name and length, as this would be + -- redundant. + +CallDuration ::= INTEGER + -- + -- The call duration in seconds. + -- For successful calls this is the chargeable duration. + -- For call attempts this is the call holding time. + -- + +CallEventRecordType ::= ENUMERATED -- INTEGER +{ + moCallRecord (0), + mtCallRecord (1), + roamingRecord (2), + incGatewayRecord (3), + outGatewayRecord (4), + transitCallRecord (5), + moSMSRecord (6), + mtSMSRecord (7), + ssActionRecord (10), + hlrIntRecord (11), + commonEquipRecord (14), + moTraceRecord (15), + mtTraceRecord (16), + termCAMELRecord (17), + mtLCSRecord (23), + moLCSRecord (24), + niLCSRecord (25), + forwardCallRecord (100) +} + +CalledNumber ::= BCDDirectoryNumber + +CallingNumber ::= BCDDirectoryNumber + +CallingPartyCategory ::= Category + +CallReference ::= OCTET STRING -- (SIZE (1..8)) + +CallReferenceNumber ::= OCTET STRING -- (SIZE (1..8)) + +CAMELDestinationNumber ::= DestinationRoutingAddress + +CAMELInformation ::= SET +{ + cAMELDestinationNumber [1] CAMELDestinationNumber OPTIONAL, + connectedNumber [2] ConnectedNumber OPTIONAL, + roamingNumber [3] RoamingNumber OPTIONAL, + mscOutgoingROUTE [4] ROUTE OPTIONAL, + seizureTime [5] TimeStamp OPTIONAL, + answerTime [6] TimeStamp OPTIONAL, + releaseTime [7] TimeStamp OPTIONAL, + callDuration [8] CallDuration OPTIONAL, + dataVolume [9] DataVolume OPTIONAL, + cAMELInitCFIndicator [10] CAMELInitCFIndicator OPTIONAL, + causeForTerm [11] CauseForTerm OPTIONAL, + cAMELModification [12] ChangedParameters OPTIONAL, + freeFormatData [13] FreeFormatData OPTIONAL, + diagnostics [14] Diagnostics OPTIONAL, + freeFormatDataAppend [15] BOOLEAN OPTIONAL, + freeFormatData-2 [16] FreeFormatData OPTIONAL, + freeFormatDataAppend-2 [17] BOOLEAN OPTIONAL +} + +CAMELSMSInformation ::= SET +{ + gsm-SCFAddress [1] Gsm-SCFAddress OPTIONAL, + serviceKey [2] ServiceKey OPTIONAL, + defaultSMSHandling [3] DefaultSMS-Handling OPTIONAL, + freeFormatData [4] FreeFormatData OPTIONAL, + callingPartyNumber [5] CallingNumber OPTIONAL, + destinationSubscriberNumber [6] CalledNumber OPTIONAL, + cAMELSMSCAddress [7] AddressString OPTIONAL, + smsReferenceNumber [8] CallReferenceNumber OPTIONAL +} + +CAMELInitCFIndicator ::= ENUMERATED +{ + noCAMELCallForwarding (0), + cAMELCallForwarding (1) +} + +CAMELModificationParameters ::= SET + -- + -- The list contains only parameters changed due to CAMEL call + -- handling. + -- +{ + callingPartyNumber [0] CallingNumber OPTIONAL, + callingPartyCategory [1] CallingPartyCategory OPTIONAL, + originalCalledPartyNumber [2] OriginalCalledNumber OPTIONAL, + genericNumbers [3] GenericNumbers OPTIONAL, + redirectingPartyNumber [4] RedirectingNumber OPTIONAL, + redirectionCounter [5] NumberOfForwarding OPTIONAL +} + + +Category ::= OCTET STRING -- (SIZE(1)) + -- + -- The internal structure is defined in ITU-T Rec Q.763. + --see subscribe category + +CauseForTerm ::= ENUMERATED -- INTEGER + -- + -- Cause codes from 16 up to 31 are defined in TS 32.015 as 'CauseForRecClosing' + -- (cause for record closing). + -- There is no direct correlation between these two types. + -- LCS related causes belong to the MAP error causes acc. TS 29.002. + -- +{ + normalRelease (0), + partialRecord (1), + partialRecordCallReestablishment (2), + unsuccessfulCallAttempt (3), + stableCallAbnormalTermination (4), + cAMELInitCallRelease (5), + unauthorizedRequestingNetwork (52), + unauthorizedLCSClient (53), + positionMethodFailure (54), + unknownOrUnreachableLCSClient (58) +} + +CellId ::= OCTET STRING -- (SIZE(2)) + -- + -- Coded according to TS 24.008 + -- + +ChangedParameters ::= SET +{ + changeFlags [0] ChangeFlags, + changeList [1] CAMELModificationParameters OPTIONAL +} + +ChangeFlags ::= BIT STRING +-- { +-- callingPartyNumberModified (0), +-- callingPartyCategoryModified (1), +-- originalCalledPartyNumberModified (2), +-- genericNumbersModified (3), +-- redirectingPartyNumberModified (4), +-- redirectionCounterModified (5) +-- } + +ChangeOfClassmark ::= SEQUENCE +{ + classmark [0] Classmark, + changeTime [1] TimeStamp +} + +ChangeOfRadioChannel ::= SEQUENCE +{ + radioChannel [0] TrafficChannel, + changeTime [1] TimeStamp, + speechVersionUsed [2] SpeechVersionIdentifier OPTIONAL +} + +ChangeOfService ::= SEQUENCE +{ + basicService [0] BasicServiceCode, + transparencyInd [1] TransparencyInd OPTIONAL, + changeTime [2] TimeStamp, + rateIndication [3] RateIndication OPTIONAL, + fnur [4] Fnur OPTIONAL +} + +ChannelCoding ::= ENUMERATED +{ + tchF4800 (1), + tchF9600 (2), + tchF14400 (3) +} + +ChargeIndicator ::= ENUMERATED -- INTEGER +{ + noIndication (0), + noCharge (1), + charge (2) +} + +Classmark ::= OCTET STRING + -- + -- See Mobile station classmark 2 or 3 TS 24.008 + -- + +ConnectedNumber ::= BCDDirectoryNumber + +DataVolume ::= INTEGER + -- + -- The volume of data transferred in segments of 64 octets. + -- + +Day ::= INTEGER -- (1..31) + +--DayClass ::= ObjectInstance + +--DayClasses ::= SET OF DayClass + +--DayDefinition ::= SEQUENCE +--{ +-- day [0] DayOfTheWeek, +-- dayClass [1] ObjectInstance +--} + +--DayDefinitions ::= SET OF DayDefinition + +--DateDefinition ::= SEQUENCE +--{ +-- month [0] Month, +-- day [1] Day, +-- dayClass [2] ObjectInstance +--} + +--DateDefinitions ::= SET OF DateDefinition + +--DayOfTheWeek ::= ENUMERATED +--{ +-- allDays (0), +-- sunday (1), +-- monday (2), +-- tuesday (3), +-- wednesday (4), +-- thursday (5), +-- friday (6), +-- saturday (7) +--} + +DestinationRoutingAddress ::= BCDDirectoryNumber + +DefaultCallHandling ::= ENUMERATED +{ + continueCall (0), + releaseCall (1) +} + -- exception handling: + -- reception of values in range 2-31 shall be treated as "continueCall" + -- reception of values greater than 31 shall be treated as "releaseCall" + +DeferredLocationEventType ::= BIT STRING +-- { +-- msAvailable (0) +-- } (SIZE (1..16)) + + -- exception handling + -- a ProvideSubscriberLocation-Arg containing other values than listed above in + -- DeferredLocationEventType shall be rejected by the receiver with a return error cause of + -- unexpected data value. + +Diagnostics ::= CHOICE +{ + gsm0408Cause [0] INTEGER, + -- See TS 24.008 + gsm0902MapErrorValue [1] INTEGER, + -- Note: The value to be stored here corresponds to + -- the local values defined in the MAP-Errors and + -- MAP-DialogueInformation modules, for full details + -- see TS 29.002. + ccittQ767Cause [2] INTEGER, + -- See ITU-T Q.767 + networkSpecificCause [3] ManagementExtension, + -- To be defined by network operator + manufacturerSpecificCause [4] ManagementExtension + -- To be defined by manufacturer +} + +DefaultSMS-Handling ::= ENUMERATED +{ + continueTransaction (0) , + releaseTransaction (1) +} +-- exception handling: +-- reception of values in range 2-31 shall be treated as "continueTransaction" +-- reception of values greater than 31 shall be treated as "releaseTransaction" + +--Destinations ::= SET OF AE-title + +EmergencyCallIndEnable ::= BOOLEAN + +EmergencyCallIndication ::= SEQUENCE +{ + cellId [0] CellId, + callerId [1] IMSIorIMEI +} + +EParameter ::= INTEGER -- (0..1023) + -- + -- Coded according to TS 22.024 and TS 24.080 + -- + +EquipmentId ::= INTEGER + +Ext-GeographicalInformation ::= OCTET STRING -- (SIZE (1..maxExt-GeographicalInformation)) + -- Refers to geographical Information defined in 3G TS 23.032. + -- This is composed of 1 or more octets with an internal structure according to + -- 3G TS 23.032 + -- Octet 1: Type of shape, only the following shapes in 3G TS 23.032 are allowed: + -- (a) Ellipsoid point with uncertainty circle + -- (b) Ellipsoid point with uncertainty ellipse + -- (c) Ellipsoid point with altitude and uncertainty ellipsoid + -- (d) Ellipsoid Arc + -- (e) Ellipsoid Point + -- Any other value in octet 1 shall be treated as invalid + -- Octets 2 to 8 for case (a) - Ellipsoid point with uncertainty circle + -- Degrees of Latitude 3 octets + -- Degrees of Longitude 3 octets + -- Uncertainty code 1 octet + -- Octets 2 to 11 for case (b) - Ellipsoid point with uncertainty ellipse: + -- Degrees of Latitude 3 octets + -- Degrees of Longitude 3 octets + -- Uncertainty semi-major axis 1 octet + -- Uncertainty semi-minor axis 1 octet + -- Angle of major axis 1 octet + -- Confidence 1 octet + -- Octets 2 to 14 for case (c) - Ellipsoid point with altitude and uncertainty ellipsoid + -- Degrees of Latitude 3 octets + -- Degrees of Longitude 3 octets + -- Altitude 2 octets + -- Uncertainty semi-major axis 1 octet + -- Uncertainty semi-minor axis 1 octet + -- Angle of major axis 1 octet + -- Uncertainty altitude 1 octet + -- Confidence 1 octet + -- Octets 2 to 13 for case (d) - Ellipsoid Arc + -- Degrees of Latitude 3 octets + -- Degrees of Longitude 3 octets + -- Inner radius 2 octets + -- Uncertainty radius 1 octet + -- Offset angle 1 octet + -- Included angle 1 octet + -- Confidence 1 octet + -- Octets 2 to 7 for case (e) - Ellipsoid Point + -- Degrees of Latitude 3 octets + -- Degrees of Longitude 3 octets + -- + -- An Ext-GeographicalInformation parameter comprising more than one octet and + -- containing any other shape or an incorrect number of octets or coding according + -- to 3G TS 23.032 shall be treated as invalid data by a receiver. + -- + -- An Ext-GeographicalInformation parameter comprising one octet shall be discarded + -- by the receiver if an Add-GeographicalInformation parameter is received + -- in the same message. + -- + -- An Ext-GeographicalInformation parameter comprising one octet shall be treated as + -- invalid data by the receiver if an Add-GeographicalInformation parameter is not + -- received in the same message. + +-- maxExt-GeographicalInformation INTEGER ::= 20 + -- the maximum length allows for further shapes in 3G TS 23.032 to be included in later + -- versions of 3G TS 29.002 + +EquipmentType ::= ENUMERATED -- INTEGER +{ + conferenceBridge (0) +} + +FileType ::= ENUMERATED -- INTEGER +{ + callRecords (1), + traceRecords (9), + observedIMEITicket (14) +} + +Fnur ::= ENUMERATED +{ + -- + -- See Bearer Capability TS 24.008 + -- + fnurNotApplicable (0), + fnur9600-BitsPerSecond (1), + fnur14400BitsPerSecond (2), + fnur19200BitsPerSecond (3), + fnur28800BitsPerSecond (4), + fnur38400BitsPerSecond (5), + fnur48000BitsPerSecond (6), + fnur56000BitsPerSecond (7), + fnur64000BitsPerSecond (8), + fnur33600BitsPerSecond (9), + fnur32000BitsPerSecond (10), + fnur31200BitsPerSecond (11) +} + +ForwardToNumber ::= AddressString + +FreeFormatData ::= OCTET STRING -- (SIZE(1..160)) + -- + -- Free formated data as sent in the FCI message + -- See TS 29.078 + -- + +GenericNumber ::= BCDDirectoryNumber + +GenericNumbers ::= SET OF GenericNumber + +Gsm-SCFAddress ::= ISDNAddressString + -- + -- See TS 29.002 + -- + +HLRIntResult ::= Diagnostics + +Horizontal-Accuracy ::= OCTET STRING -- (SIZE (1)) + -- bit 8 = 0 + -- bits 7-1 = 7 bit Uncertainty Code defined in 3G TS 23.032. The horizontal location + -- error should be less than the error indicated by the uncertainty code with 67% + -- confidence. + +HotBillingTag ::= ENUMERATED --INTEGER +{ + noHotBilling (0), + hotBilling (1) +} + +HSCSDParmsChange ::= SEQUENCE +{ + changeTime [0] TimeStamp, + hSCSDChanAllocated [1] NumOfHSCSDChanAllocated, + initiatingParty [2] InitiatingParty OPTIONAL, + aiurRequested [3] AiurRequested OPTIONAL, + chanCodingUsed [4] ChannelCoding, + hSCSDChanRequested [5] NumOfHSCSDChanRequested OPTIONAL +} + + +IMEI ::= TBCD-STRING -- (SIZE (8)) + -- Refers to International Mobile Station Equipment Identity + -- and Software Version Number (SVN) defined in TS GSM 03.03. + -- If the SVN is not present the last octet shall contain the + -- digit 0 and a filler. + -- If present the SVN shall be included in the last octet. + +IMSI ::= TBCD-STRING -- (SIZE (3..8)) + -- digits of MCC, MNC, MSIN are concatenated in this order. + +IMEICheckEvent ::= ENUMERATED -- INTEGER +{ + mobileOriginatedCall (0), + mobileTerminatedCall (1), + smsMobileOriginating (2), + smsMobileTerminating (3), + ssAction (4), + locationUpdate (5) +} + +IMEIStatus ::= ENUMERATED +{ + greyListedMobileEquipment (0), + blackListedMobileEquipment (1), + nonWhiteListedMobileEquipment (2) +} + +IMSIorIMEI ::= CHOICE +{ + imsi [0] IMSI, + imei [1] IMEI +} + +InitiatingParty ::= ENUMERATED +{ + network (0), + subscriber (1) +} + +ISDN-AddressString ::= AddressString -- (SIZE (1..maxISDN-AddressLength)) + -- This type is used to represent ISDN numbers. + +-- maxISDN-AddressLength INTEGER ::= 9 + +LCSCause ::= OCTET STRING -- (SIZE(1)) + -- + -- See LCS Cause Value, 3GPP TS 49.031 + -- + +LCS-Priority ::= OCTET STRING -- (SIZE (1)) + -- 0 = highest priority + -- 1 = normal priority + -- all other values treated as 1 + +LCSClientIdentity ::= SEQUENCE +{ + lcsClientExternalID [0] LCSClientExternalID OPTIONAL, + lcsClientDialedByMS [1] AddressString OPTIONAL, + lcsClientInternalID [2] LCSClientInternalID OPTIONAL +} + +LCSClientExternalID ::= SEQUENCE +{ + externalAddress [0] AddressString OPTIONAL +-- extensionContainer [1] ExtensionContainer OPTIONAL +} + +LCSClientInternalID ::= ENUMERATED +{ + broadcastService (0), + o-andM-HPLMN (1), + o-andM-VPLMN (2), + anonymousLocation (3), + targetMSsubscribedService (4) +} + -- for a CAMEL phase 3 PLMN operator client, the value targetMSsubscribedService shall be used + +LCSClientType ::= ENUMERATED +{ + emergencyServices (0), + valueAddedServices (1), + plmnOperatorServices (2), + lawfulInterceptServices (3) +} + -- exception handling: + -- unrecognized values may be ignored if the LCS client uses the privacy override + -- otherwise, an unrecognized value shall be treated as unexpected data by a receiver + -- a return error shall then be returned if received in a MAP invoke + +LCSQoSInfo ::= SEQUENCE +{ + horizontal-accuracy [0] Horizontal-Accuracy OPTIONAL, + verticalCoordinateRequest [1] NULL OPTIONAL, + vertical-accuracy [2] Vertical-Accuracy OPTIONAL, + responseTime [3] ResponseTime OPTIONAL +} + +LevelOfCAMELService ::= BIT STRING +-- { +-- basic (0), +-- callDurationSupervision (1), +-- onlineCharging (2) +-- } + +LocationAreaAndCell ::= SEQUENCE +{ + locationAreaCode [0] LocationAreaCode, + cellIdentifier [1] CellId +-- +-- For 2G the content of the Cell Identifier is defined by the Cell Id +-- refer TS 24.008 and for 3G by the Service Area Code refer TS 25.413. +-- + +} + +LocationAreaCode ::= OCTET STRING -- (SIZE(2)) + -- + -- See TS 24.008 + -- + +LocationChange ::= SEQUENCE +{ + location [0] LocationAreaAndCell, + changeTime [1] TimeStamp +} + +Location-info ::= SEQUENCE +{ + mscNumber [1] MscNo OPTIONAL, + location-area [2] LocationAreaCode, + cell-identification [3] CellId OPTIONAL +} + +LocationType ::= SEQUENCE +{ +locationEstimateType [0] LocationEstimateType, + deferredLocationEventType [1] DeferredLocationEventType OPTIONAL +} + +LocationEstimateType ::= ENUMERATED +{ + currentLocation (0), + currentOrLastKnownLocation (1), + initialLocation (2), + activateDeferredLocation (3), + cancelDeferredLocation (4) +} + -- exception handling: + -- a ProvideSubscriberLocation-Arg containing an unrecognized LocationEstimateType + -- shall be rejected by the receiver with a return error cause of unexpected data value + +LocUpdResult ::= Diagnostics + +ManagementExtensions ::= SET OF ManagementExtension + +ManagementExtension ::= SEQUENCE +{ + identifier OBJECT IDENTIFIER, + significance [1] BOOLEAN , -- DEFAULT FALSE, + information [2] OCTET STRING +} + + +MCCMNC ::= OCTET STRING -- (SIZE(3)) + -- + -- This type contains the mobile country code (MCC) and the mobile + -- network code (MNC) of a PLMN. + -- + +RateIndication ::= OCTET STRING -- (SIZE(1)) + +--0 no rate adaption +--1 V.110, I.460/X.30 +--2 ITU-T X.31 flag stuffing +--3 V.120 +--7 H.223 & H.245 +--11 PIAFS + + +MessageReference ::= OCTET STRING + +Month ::= INTEGER -- (1..12) + +MOLR-Type ::= INTEGER +--0 locationEstimate +--1 assistanceData +--2 deCipheringKeys + +MSCAddress ::= AddressString + +MscNo ::= ISDN-AddressString + -- + -- See TS 23.003 + -- + +MSISDN ::= ISDN-AddressString + -- + -- See TS 23.003 + -- + +MSPowerClasses ::= SET OF RFPowerCapability + +NetworkCallReference ::= CallReferenceNumber + -- See TS 29.002 + -- + +NetworkSpecificCode ::= INTEGER + -- + -- To be defined by network operator + -- + +NetworkSpecificServices ::= SET OF NetworkSpecificCode + +NotificationToMSUser ::= ENUMERATED +{ + notifyLocationAllowed (0), + notifyAndVerify-LocationAllowedIfNoResponse (1), + notifyAndVerify-LocationNotAllowedIfNoResponse (2), + locationNotAllowed (3) +} + -- exception handling: + -- At reception of any other value than the ones listed the receiver shall ignore + -- NotificationToMSUser. + +NumberOfForwarding ::= INTEGER -- (1..5) + +NumOfHSCSDChanRequested ::= INTEGER + +NumOfHSCSDChanAllocated ::= INTEGER + +ObservedIMEITicketEnable ::= BOOLEAN + +OriginalCalledNumber ::= BCDDirectoryNumber + +OriginDestCombinations ::= SET OF OriginDestCombination + +OriginDestCombination ::= SEQUENCE +{ + origin [0] INTEGER OPTIONAL, + destination [1] INTEGER OPTIONAL + -- + -- Note that these values correspond to the contents + -- of the attributes originId and destinationId + -- respectively. At least one of the two must be present. + -- +} + +PartialRecordTimer ::= INTEGER + +PartialRecordType ::= ENUMERATED +{ + timeLimit (0), + serviceChange (1), + locationChange (2), + classmarkChange (3), + aocParmChange (4), + radioChannelChange (5), + hSCSDParmChange (6), + changeOfCAMELDestination (7), + firstHotBill (20), + severalSSOperationBill (21) +} + +PartialRecordTypes ::= SET OF PartialRecordType + +PositioningData ::= OCTET STRING -- (SIZE(1..33)) + -- + -- See Positioning Data IE (octet 3..n), 3GPP TS 49.031 + -- + +RadioChannelsRequested ::= SET OF RadioChanRequested + +RadioChanRequested ::= ENUMERATED +{ + -- + -- See Bearer Capability TS 24.008 + -- + halfRateChannel (0), + fullRateChannel (1), + dualHalfRatePreferred (2), + dualFullRatePreferred (3) +} + +--RecordClassDestination ::= CHOICE +--{ +-- osApplication [0] AE-title, +-- fileType [1] FileType +--} + +--RecordClassDestinations ::= SET OF RecordClassDestination + +RecordingEntity ::= AddressString + +RecordingMethod ::= ENUMERATED +{ + inCallRecord (0), + inSSRecord (1) +} + +RedirectingNumber ::= BCDDirectoryNumber + +RedirectingCounter ::= INTEGER + +ResponseTime ::= SEQUENCE +{ + responseTimeCategory ResponseTimeCategory +} + -- note: an expandable SEQUENCE simplifies later addition of a numeric response time. + +ResponseTimeCategory ::= ENUMERATED +{ + lowdelay (0), + delaytolerant (1) +} + -- exception handling: + -- an unrecognized value shall be treated the same as value 1 (delaytolerant) + +RFPowerCapability ::= INTEGER + -- + -- This field contains the RF power capability of the Mobile station + -- classmark 1 and 2 of TS 24.008 expressed as an integer. + -- + +RoamingNumber ::= ISDN-AddressString + -- + -- See TS 23.003 + -- + +RoutingNumber ::= CHOICE +{ + roaming [1] RoamingNumber, + forwarded [2] ForwardToNumber +} + +Service ::= CHOICE +{ + teleservice [1] TeleserviceCode, + bearerService [2] BearerServiceCode, + supplementaryService [3] SS-Code, + networkSpecificService [4] NetworkSpecificCode +} + +ServiceDistanceDependencies ::= SET OF ServiceDistanceDependency + +ServiceDistanceDependency ::= SEQUENCE +{ + aocService [0] INTEGER, + chargingZone [1] INTEGER OPTIONAL + -- + -- Note that these values correspond to the contents + -- of the attributes aocServiceId and zoneId + -- respectively. + -- +} + +ServiceKey ::= INTEGER -- (0..2147483647) + +SimpleIntegerName ::= INTEGER + +SimpleStringName ::= GraphicString + +SMSResult ::= Diagnostics + +SmsTpDestinationNumber ::= OCTET STRING + -- + -- This type contains the binary coded decimal representation of + -- the SMS address field the encoding of the octet string is in + -- accordance with the definition of address fields in TS 23.040. + -- This encoding includes type of number and numbering plan indication + -- together with the address value range. + -- + +SpeechVersionIdentifier ::= OCTET STRING -- (SIZE(1)) +-- see GSM 08.08 + +-- 000 0001 GSM speech full rate version 1 +-- 001 0001 GSM speech full rate version 2 used for enhanced full rate +-- 010 0001 GSM speech full rate version 3 for future use +-- 000 0101 GSM speech half rate version 1 +-- 001 0101 GSM speech half rate version 2 for future use +-- 010 0101 GSM speech half rate version 3 for future use + +SSActionResult ::= Diagnostics + +SSActionType ::= ENUMERATED +{ + registration (0), + erasure (1), + activation (2), + deactivation (3), + interrogation (4), + invocation (5), + passwordRegistration (6), + ussdInvocation (7) +} + +-- ussdInvocation (7) include ussd phase 1,phase 2 + +--SS Request = SSActionType + +SS-Code ::= OCTET STRING -- (SIZE (1)) + -- This type is used to represent the code identifying a single + -- supplementary service, a group of supplementary services, or + -- all supplementary services. The services and abbreviations + -- used are defined in TS 3GPP TS 22.004 [5]. The internal structure is + -- defined as follows: + -- + -- bits 87654321: group (bits 8765), and specific service + -- (bits 4321) ussd = ff + +-- allSS (0x00), +-- reserved for possible future use +-- all SS +-- +-- allLineIdentificationSS (0x10), +-- reserved for possible future use +-- all line identification SS +-- +-- calling-line-identification-presentation (0x11), +-- calling line identification presentation +-- calling-line-identification-restriction (0x12), +-- calling line identification restriction +-- connected-line-identification-presentation (0x13), +-- connected line identification presentation +-- connected-line-identification-restriction (0x14), +-- connected line identification restriction +-- malicious-call-identification (0x15), +-- reserved for possible future use +-- malicious call identification +-- +-- allNameIdentificationSS (0x18), +-- all name identification SS +-- calling-name-presentation (0x19), +-- calling name presentation +-- +-- SS-Codes '00011010'B, to '00011111'B, are reserved for future +-- NameIdentification Supplementary Service use. +-- +-- allForwardingSS (0x20), +-- all forwarding SS +-- call-forwarding-unconditional (0x21), +-- call forwarding unconditional +-- call-deflection (0x24), +-- call deflection +-- allCondForwardingSS (0x28), +-- all conditional forwarding SS +-- call-forwarding-on-mobile-subscriber-busy (0x29), +-- call forwarding on mobile subscriber busy +-- call-forwarding-on-no-reply (0x2a), +-- call forwarding on no reply +-- call-forwarding-on-mobile-subscriber-not-reachable (0x2b), +-- call forwarding on mobile subscriber not reachable +-- +-- allCallOfferingSS (0x30), +-- reserved for possible future use +-- all call offering SS includes also all forwarding SS +-- +-- explicit-call-transfer (0x31), +-- explicit call transfer +-- mobile-access-hunting (0x32), +-- reserved for possible future use +-- mobile access hunting +-- +-- allCallCompletionSS (0x40), +-- reserved for possible future use +-- all Call completion SS +-- +-- call-waiting (0x41), +-- call waiting +-- call-hold (0x42), +-- call hold +-- completion-of-call-to-busy-subscribers-originating-side (0x43), +-- completion of call to busy subscribers, originating side +-- completion-of-call-to-busy-subscribers-destination-side (0x44), +-- completion of call to busy subscribers, destination side +-- this SS-Code is used only in InsertSubscriberData and DeleteSubscriberData +-- +-- multicall (0x45), +-- multicall +-- +-- allMultiPartySS (0x50), +-- reserved for possible future use +-- all multiparty SS +-- +-- multiPTY (0x51), +-- multiparty +-- +-- allCommunityOfInterest-SS (0x60), +-- reserved for possible future use +-- all community of interest SS +-- closed-user-group (0x61), +-- closed user group +-- +-- allChargingSS (0x70), +-- reserved for possible future use +-- all charging SS +-- advice-of-charge-information (0x71), +-- advice of charge information +-- advice-of-charge-charging (0x72), +-- advice of charge charging +-- +-- allAdditionalInfoTransferSS (0x80), +-- reserved for possible future use +-- all additional information transfer SS +-- uUS1-user-to-user-signalling (0x81), +-- UUS1 user-to-user signalling +-- uUS2-user-to-user-signalling (0x82), +-- UUS2 user-to-user signalling +-- uUS3-user-to-user-signalling (0x83), +-- UUS3 user-to-user signalling +-- +-- allBarringSS (0x90), +-- all barring SS +-- barringOfOutgoingCalls (0x91), +-- barring of outgoing calls +-- barring-of-all-outgoing-calls (0x92), +-- barring of all outgoing calls +-- barring-of-outgoing-international-calls (0x93), +-- barring of outgoing international calls +-- boicExHC (0x94), +-- barring of outgoing international calls except those directed +-- to the home PLMN +-- barringOfIncomingCalls (0x99), +-- barring of incoming calls +-- barring-of-all-incoming-calls (0x9a), +-- barring of all incoming calls +-- barring-of-incoming-calls-when-roaming-outside-home-PLMN-Country (0x9b), +-- barring of incoming calls when roaming outside home PLMN +-- Country +-- +-- allCallPrioritySS (0xa0), +-- reserved for possible future use +-- all call priority SS +-- enhanced-Multilevel-Precedence-Pre-emption-EMLPP-service (0xa1), +-- enhanced Multilevel Precedence Pre-emption 'EMLPP) service +-- +-- allLCSPrivacyException (0xb0), +-- all LCS Privacy Exception Classes +-- universal (0xb1), +-- allow location by any LCS client +-- callrelated (0xb2), +-- allow location by any value added LCS client to which a call +-- is established from the target MS +-- callunrelated (0xb3), +-- allow location by designated external value added LCS clients +-- plmnoperator (0xb4), +-- allow location by designated PLMN operator LCS clients +-- +-- allMOLR-SS (0xc0), +-- all Mobile Originating Location Request Classes +-- basicSelfLocation (0xc1), +-- allow an MS to request its own location +-- autonomousSelfLocation (0xc2), +-- allow an MS to perform self location without interaction +-- with the PLMN for a predetermined period of time +-- transferToThirdParty (0xc3), +-- allow an MS to request transfer of its location to another LCS client +-- +-- allPLMN-specificSS (0xf0), +-- plmn-specificSS-1 (0xf1), +-- plmn-specificSS-2 (0xf2), +-- plmn-specificSS-3 (0xf3), +-- plmn-specificSS-4 (0xf4), +-- plmn-specificSS-5 (0xf5), +-- plmn-specificSS-6 (0xf6), +-- plmn-specificSS-7 (0xf7), +-- plmn-specificSS-8 (0xf8), +-- plmn-specificSS-9 (0xf9), +-- plmn-specificSS-A (0xfa), +-- plmn-specificSS-B (0xfb), +-- plmn-specificSS-C (0xfc), +-- plmn-specificSS-D (0xfd), +-- plmn-specificSS-E (0xfe), +-- ussd (0xff) + + +SSParameters ::= CHOICE +{ + forwardedToNumber [0] ForwardToNumber, + unstructuredData [1] OCTET STRING +} + +SupplServices ::= SET OF SS-Code + +SuppServiceUsed ::= SEQUENCE +{ + ssCode [0] SS-Code OPTIONAL, + ssTime [1] TimeStamp OPTIONAL +} + +SwitchoverTime ::= SEQUENCE +{ + hour INTEGER , -- (0..23), + minute INTEGER , -- (0..59), + second INTEGER -- (0..59) +} + +SystemType ::= ENUMERATED + -- "unknown" is not to be used in PS domain. +{ + unknown (0), + iuUTRAN (1), + gERAN (2) +} + +TBCD-STRING ::= OCTET STRING + -- This type (Telephony Binary Coded Decimal String) is used to + -- represent several digits from 0 through 9, *, #, a, b, c, two + -- digits per octet, each digit encoded 0000 to 1001 (0 to 9), + -- 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used + -- as filler when there is an odd number of digits. + + -- bits 8765 of octet n encoding digit 2n + -- bits 4321 of octet n encoding digit 2(n-1) +1 + +TariffId ::= INTEGER + +TariffPeriod ::= SEQUENCE +{ + switchoverTime [0] SwitchoverTime, + tariffId [1] INTEGER + -- Note that the value of tariffId corresponds + -- to the attribute tariffId. +} + +TariffPeriods ::= SET OF TariffPeriod + +TariffSystemStatus ::= ENUMERATED +{ + available (0), -- available for modification + checked (1), -- "frozen" and checked + standby (2), -- "frozen" awaiting activation + active (3) -- "frozen" and active +} + + +TimeStamp ::= OCTET STRING -- (SIZE(9)) + -- + -- The contents of this field are a compact form of the UTCTime format + -- containing local time plus an offset to universal time. Binary coded + -- decimal encoding is employed for the digits to reduce the storage and + -- transmission overhead + -- e.g. YYMMDDhhmmssShhmm + -- where + -- YY = Year 00 to 99 BCD encoded + -- MM = Month 01 to 12 BCD encoded + -- DD = Day 01 to 31 BCD encoded + -- hh = hour 00 to 23 BCD encoded + -- mm = minute 00 to 59 BCD encoded + -- ss = second 00 to 59 BCD encoded + -- S = Sign 0 = "+", "-" ASCII encoded + -- hh = hour 00 to 23 BCD encoded + -- mm = minute 00 to 59 BCD encoded + -- + +TrafficChannel ::= ENUMERATED +{ + fullRate (0), + halfRate (1) +} + +TranslatedNumber ::= BCDDirectoryNumber + +TransparencyInd ::= ENUMERATED +{ + transparent (0), + nonTransparent (1) +} + +ROUTE ::= CHOICE +{ + rOUTENumber [0] INTEGER, + rOUTEName [1] GraphicString +} + +--rOUTEName 1 10 octet + +TSChangeover ::= SEQUENCE +{ + newActiveTS [0] INTEGER, + newStandbyTS [1] INTEGER, +-- changeoverTime [2] GeneralizedTime OPTIONAL, + authkey [3] OCTET STRING OPTIONAL, + checksum [4] OCTET STRING OPTIONAL, + versionNumber [5] OCTET STRING OPTIONAL + -- Note that if the changeover time is not + -- specified then the change is immediate. +} + +TSCheckError ::= SEQUENCE +{ + errorId [0] TSCheckErrorId + --fail [1] ANY DEFINED BY errorId OPTIONAL +} + +TSCheckErrorId ::= CHOICE +{ + globalForm [0] OBJECT IDENTIFIER, + localForm [1] INTEGER +} + +TSCheckResult ::= CHOICE +{ + success [0] NULL, + fail [1] SET OF TSCheckError +} + +TSCopyTariffSystem ::= SEQUENCE +{ + oldTS [0] INTEGER, + newTS [1] INTEGER +} + +TSNextChange ::= CHOICE +{ + noChangeover [0] NULL, + tsChangeover [1] TSChangeover +} + +TypeOfSubscribers ::= ENUMERATED +{ + home (0), -- HPLMN subscribers + visiting (1), -- roaming subscribers + all (2) +} + +TypeOfTransaction ::= ENUMERATED +{ + successful (0), + unsuccessful (1), + all (2) +} + +Vertical-Accuracy ::= OCTET STRING -- (SIZE (1)) + -- bit 8 = 0 + -- bits 7-1 = 7 bit Vertical Uncertainty Code defined in 3G TS 23.032. + -- The vertical location error should be less than the error indicated + -- by the uncertainty code with 67% confidence. + +ISDNAddressString ::= AddressString + +EmlppPriority ::= OCTET STRING -- (SIZE (1)) + +--priorityLevelA EMLPP-Priority ::= 6 +--priorityLevelB EMLPP-Priority ::= 5 +--priorityLevel0 EMLPP-Priority ::= 0 +--priorityLevel1 EMLPP-Priority ::= 1 +--priorityLevel2 EMLPP-Priority ::= 2 +--priorityLevel3 EMLPP-Priority ::= 3 +--priorityLevel4 EMLPP-Priority ::= 4 +--See 29.002 + + +EASubscriberInfo ::= OCTET STRING -- (SIZE (3)) + -- The internal structure is defined by the Carrier Identification + -- parameter in ANSI T1.113.3. Carrier codes between "000" and "999" may + -- be encoded as 3 digits using "000" to "999" or as 4 digits using + -- "0000" to "0999". Carrier codes between "1000" and "9999" are encoded + -- using 4 digits. + +SelectedCIC ::= OCTET STRING -- (SIZE (3)) + +PortedFlag ::= ENUMERATED +{ + numberNotPorted (0), + numberPorted (1) +} + +SubscriberCategory ::= OCTET STRING -- (SIZE (1)) +-- unknownuser = 0x00, +-- frenchuser = 0x01, +-- englishuser = 0x02, +-- germanuser = 0x03, +-- russianuser = 0x04, +-- spanishuser = 0x05, +-- specialuser = 0x06, +-- reserveuser = 0x09, +-- commonuser = 0x0a, +-- superioruser = 0x0b, +-- datacalluser = 0x0c, +-- testcalluser = 0x0d, +-- spareuser = 0x0e, +-- payphoneuser = 0x0f, +-- coinuser = 0x20, +-- isup224 = 0xe0 + + +CUGOutgoingAccessIndicator ::= ENUMERATED +{ + notCUGCall (0), + cUGCall (1) +} + +CUGInterlockCode ::= OCTET STRING -- (SIZE (4)) + +-- + +CUGOutgoingAccessUsed ::= ENUMERATED +{ + callInTheSameCUGGroup (0), + callNotInTheSameCUGGroup (1) +} + +SMSTEXT ::= OCTET STRING + +MSCCIC ::= INTEGER -- (0..65535) + +RNCorBSCId ::= OCTET STRING -- (SIZE (3)) +--octet order is the same as RANAP/BSSAP signaling +--if spc is coded as 14bit, then OCTET STRING1 will filled with 00 ,for example rnc id = 123 will be coded as 00 01 23 +--OCTET STRING1 +--OCTET STRING2 +--OCTET STRING3 + +MSCId ::= OCTET STRING -- (SIZE (3)) +--National network format , octet order is the same as ISUP signaling +--if spc is coded as 14bit, then OCTET STRING1 will filled with 00,,for example rnc id = 123 will be coded as 00 01 23 +--OCTET STRING1 +--OCTET STRING2 +--OCTET STRING3 + +EmergencyCallFlag ::= ENUMERATED +{ + notEmergencyCall (0), + emergencyCall (1) +} + +CUGIncomingAccessUsed ::= ENUMERATED +{ + callInTheSameCUGGroup (0), + callNotInTheSameCUGGroup (1) +} + +SmsUserDataType ::= OCTET STRING -- (SIZE (1)) +-- +--00 concatenated-short-messages-8-bit-reference-number +--01 special-sms-message-indication +--02 reserved +--03 Value not used to avoid misinterpretation as +--04 characterapplication-port-addressing-scheme-8-bit-address +--05 application-port-addressing-scheme-16-bit-address +--06 smsc-control-parameters +--07 udh-source-indicator +--08 concatenated-short-message-16-bit-reference-number +--09 wireless-control-message-protocol +--0A text-formatting +--0B predefined-sound +--0C user-defined-sound-imelody-max-128-bytes +--0D predefined-animation +--0E large-animation-16-16-times-4-32-4-128-bytes +--0F small-animation-8-8-times-4-8-4-32-bytes +--10 large-picture-32-32-128-bytes +--11 small-picture-16-16-32-bytes +--12 variable-picture +--13 User prompt indicator +--14 Extended Object +--15 Reused Extended Object +--16 Compression Control +--17 Object Distribution Indicator +--18 Standard WVG object +--19 Character Size WVG object +--1A Extended Object Data Request Command +--1B-1F Reserved for future EMS features (see subclause 3.10) +--20 RFC 822 E-Mail Header +--21 Hyperlink format element +--22 Reply Address Element +--23 - 6F Reserved for future use +--70 - 7F (U)SIM Toolkit Security Headers +--80 - 9F SME to SME specific use +--A0 - BF Reserved for future use +--C0 - DF SC specific use +--E0 - FE Reserved for future use +--FF normal SMS + +ConcatenatedSMSReferenceNumber ::= INTEGER -- (0..65535) + +MaximumNumberOfSMSInTheConcatenatedSMS ::= INTEGER -- (0..255) + +SequenceNumberOfTheCurrentSMS ::= INTEGER -- (0..255) + +SequenceNumber ::= INTEGER + +--(1... ) +-- + +DisconnectParty ::= ENUMERATED +{ + callingPartyRelease (0), + calledPartyRelease (1), + networkRelease (2) +} + +ChargedParty ::= ENUMERATED +{ + callingParty (0), + calledParty (1) +} + +ChargeAreaCode ::= OCTET STRING -- (SIZE (1..3)) + +CUGIndex ::= OCTET STRING -- (SIZE (2)) + +GuaranteedBitRate ::= ENUMERATED +{ + gBR14400BitsPerSecond (1), -- BS20 non-transparent + gBR28800BitsPerSecond (2), -- BS20 non-transparent and transparent, + -- BS30 transparent and multimedia + gBR32000BitsPerSecond (3), -- BS30 multimedia + gBR33600BitsPerSecond (4), -- BS30 multimedia + gBR56000BitsPerSecond (5), -- BS30 transparent and multimedia + gBR57600BitsPerSecond (6), -- BS20 non-transparent + gBR64000BitsPerSecond (7), -- BS30 transparent and multimedia + + gBR12200BitsPerSecond (106), -- AMR speech + gBR10200BitsPerSecond (107), -- AMR speech + gBR7950BitsPerSecond (108), -- AMR speech + gBR7400BitsPerSecond (109), -- AMR speech + gBR6700BitsPerSecond (110), -- AMR speech + gBR5900BitsPerSecond (111), -- AMR speech + gBR5150BitsPerSecond (112), -- AMR speech + gBR4750BitsPerSecond (113) -- AMR speech +} + +MaximumBitRate ::= ENUMERATED +{ + mBR14400BitsPerSecond (1), -- BS20 non-transparent + mBR28800BitsPerSecond (2), -- BS20 non-transparent and transparent, + -- BS30 transparent and multimedia + mBR32000BitsPerSecond (3), -- BS30 multimedia + mBR33600BitsPerSecond (4), -- BS30 multimedia + mBR56000BitsPerSecond (5), -- BS30 transparent and multimedia + mBR57600BitsPerSecond (6), -- BS20 non-transparent + mBR64000BitsPerSecond (7), -- BS30 transparent and multimedia + + mBR12200BitsPerSecond (106), -- AMR speech + mBR10200BitsPerSecond (107), -- AMR speech + mBR7950BitsPerSecond (108), -- AMR speech + mBR7400BitsPerSecond (109), -- AMR speech + mBR6700BitsPerSecond (110), -- AMR speech + mBR5900BitsPerSecond (111), -- AMR speech + mBR5150BitsPerSecond (112), -- AMR speech + mBR4750BitsPerSecond (113) -- AMR speech +} + + +HLC ::= OCTET STRING + +-- this parameter is a 1:1 copy of the contents (i.e. starting with octet 3) of the "high layer compatibility" parameter of ITU-T Q.931 [35]. + +LLC ::= OCTET STRING + +-- this parameter is a 1:1 copy of the contents (i.e. starting with octet 3) of the "low layer compatibility" parameter of ITU-T Q.931 [35]. + + +ISDN-BC ::= OCTET STRING + +-- this parameter is a 1:1 copy of the contents (i.e. starting with octet 3) of the "bearer capability" parameter of ITU-T Q.931 [35]. + +ModemType ::= ENUMERATED +{ + none-modem (0), + modem-v21 (1), + modem-v22 (2), + modem-v22-bis (3), + modem-v23 (4), + modem-v26-ter (5), + modem-v32 (6), + modem-undef-interface (7), + modem-autobauding1 (8), + no-other-modem-type (31), + modem-v34 (33) +} + +UssdCodingScheme ::= OCTET STRING + +UssdString ::= OCTET STRING + +UssdNotifyCounter ::= INTEGER -- (0..255) + +UssdRequestCounter ::= INTEGER -- (0..255) + +Classmark3 ::= OCTET STRING -- (SIZE(2)) + +OptimalRoutingDestAddress ::= BCDDirectoryNumber + +GAI ::= OCTET STRING -- (SIZE(7)) +--such as 64 F0 00 00 ABCD 1234 + +ChangeOfglobalAreaID ::= SEQUENCE +{ + location [0] GAI, + changeTime [1] TimeStamp +} + +InteractionWithIP ::= NULL + +RouteAttribute ::= ENUMERATED +{ + cas (0), + tup (1), + isup (2), + pra (3), + bicc (4), + sip (5), + others (255) +} + +VoiceIndicator ::= ENUMERATED +{ + sendToneByLocalMsc (0) , + sendToneByOtherMsc (1), + voiceNoIndication (3) +} + +BCategory ::= ENUMERATED +{ + subscriberFree (0), + subscriberBusy (1), + subscriberNoIndication (3) +} + +CallType ::= ENUMERATED +{ + unknown (0), + internal (1), + incoming (2), + outgoing (3), + tandem (4) +} + +-- END +END +} + +1; + -- cgit v1.2.1 From f6d64a9f735b666e876cf1a42e5ca16169ba7870 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 24 Apr 2013 13:54:59 -0700 Subject: add options to bill or not based on cdr_calltype, like the ones on cdr_type --- FS/FS/part_pkg/voip_cdr.pm | 22 ++++++++- FS/FS/part_pkg/voip_inbound.pm | 102 ++++++++++++++++++++--------------------- FS/FS/svc_pbx.pm | 7 ++- FS/FS/svc_phone.pm | 7 ++- 4 files changed, 82 insertions(+), 56 deletions(-) diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 1c891b157..21c6a8a2c 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -157,10 +157,16 @@ tie my %detail_formats, 'Tie::IxHash', 'use_carrierid' => { 'name' => 'Only charge for CDRs where the Carrier ID is set to any of these (comma-separated) values: ', }, - 'use_cdrtypenum' => { 'name' => 'Only charge for CDRs where the CDR Type is set to: ', + 'use_cdrtypenum' => { 'name' => 'Only charge for CDRs where the CDR Type is set to this cdrtypenum: ', }, - 'ignore_cdrtypenum' => { 'name' => 'Do not charge for CDRs where the CDR Type is set to: ', + 'ignore_cdrtypenum' => { 'name' => 'Do not charge for CDRs where the CDR Type is set to this cdrtypenum: ', + }, + + 'use_calltypenum' => { 'name' => 'Only charge for CDRs where the CDR Call Type is set to this calltypenum: ', + }, + + 'ignore_calltypenum' => { 'name' => 'Do not charge for CDRs where the CDR Call Type is set to this calltypenum: ', }, 'ignore_disposition' => { 'name' => 'Do not charge for CDRs where the Disposition is set to any of these (comma-separated) values: ', @@ -309,6 +315,7 @@ tie my %detail_formats, 'Tie::IxHash', use_amaflags use_carrierid use_cdrtypenum ignore_cdrtypenum + use_calltypenum ignore_calltypenum ignore_disposition disposition_in skip_dcontext skip_dst_prefix skip_dstchannel_prefix skip_src_length_more @@ -420,6 +427,7 @@ sub calc_usage { 'disable_src' => $self->option('disable_src'), 'default_prefix' => $self->option('default_prefix'), 'cdrtypenum' => $self->option('use_cdrtypenum'), + 'calltypenum' => $self->option('use_calltypenum'), 'status' => '', 'for_update' => 1, ); # $last_bill, $$sdate ) @@ -487,6 +495,7 @@ sub calc_usage { } #returns a reason why not to rate this CDR, or false if the CDR is chargeable +# lots of false laziness w/voip_inbound sub check_chargable { my( $self, $cdr, %flags ) = @_; @@ -520,6 +529,15 @@ sub check_chargable { if length($self->option_cacheable('ignore_cdrtypenum')) && $cdr->cdrtypenum eq $self->option_cacheable('ignore_cdrtypenum'); #eq otherwise 0 matches '' + # unlike everything else, use_calltypenum is applied in FS::svc_x::get_cdrs. + return "calltypenum != ". $self->option_cacheable('use_calltypenum') + if length($self->option_cacheable('use_calltypenum')) + && $cdr->calltypenum ne $self->option_cacheable('use_calltypenum'); #ne otherwise 0 matches '' + + return "calltypenum == ". $self->option_cacheable('ignore_calltypenum') + if length($self->option_cacheable('ignore_calltypenum')) + && $cdr->calltypenum eq $self->option_cacheable('ignore_calltypenum'); #eq otherwise 0 matches '' + return "dcontext IN ( ". $self->option_cacheable('skip_dcontext'). " )" if $self->option_cacheable('skip_dcontext') =~ /\S/ && grep { $cdr->dcontext eq $_ } split(/\s*,\s*/, $self->option_cacheable('skip_dcontext')); diff --git a/FS/FS/part_pkg/voip_inbound.pm b/FS/FS/part_pkg/voip_inbound.pm index 9054f7b99..525db804d 100644 --- a/FS/FS/part_pkg/voip_inbound.pm +++ b/FS/FS/part_pkg/voip_inbound.pm @@ -60,15 +60,21 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities(); 'type' => 'checkbox', }, - 'use_carrierid' => { 'name' => 'Only charge for CDRs where the Carrier ID is set to: ', + 'use_carrierid' => { 'name' => 'Only charge for CDRs where the Carrier ID is set to any of these (comma-separated) values: ', }, - 'use_cdrtypenum' => { 'name' => 'Only charge for CDRs where the CDR Type is set to: ', + 'use_cdrtypenum' => { 'name' => 'Only charge for CDRs where the CDR Type is set to this cdrtypenum: ', }, - 'ignore_cdrtypenum' => { 'name' => 'Do not charge for CDRs where the CDR Type is set to: ', + 'ignore_cdrtypenum' => { 'name' => 'Do not charge for CDRs where the CDR Type is set to this cdrtypenum: ', }, + 'use_calltypenum' => { 'name' => 'Only charge for CDRs where the CDR Call Type is set to this cdrtypenum: ', + }, + + 'ignore_calltypenum' => { 'name' => 'Do not charge for CDRs where the CDR Call Type is set to this cdrtypenum: ', + }, + 'ignore_disposition' => { 'name' => 'Do not charge for CDRs where the Disposition is set to any of these (comma-separated) values: ', }, @@ -147,6 +153,7 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities(); use_amaflags use_carrierid use_cdrtypenum ignore_cdrtypenum + use_calltypenum ignore_calltypenum ignore_disposition disposition_in skip_dcontext skip_dstchannel_prefix skip_dst_length_less skip_lastapp @@ -329,67 +336,58 @@ sub calc_usage { } #returns a reason why not to rate this CDR, or false if the CDR is chargeable +# lots of false laziness w/voip_cdr... sub check_chargable { my( $self, $cdr, %flags ) = @_; - #should have some better way of checking these options from a hash - #or something - - my @opt = qw( - use_amaflags - use_carrierid - use_cdrtypenum - ignore_cdrtypenum - disposition_in - ignore_disposition - skip_dcontext - skip_dstchannel_prefix - skip_dst_length_less - skip_lastapp - ); - foreach my $opt (grep !exists($flags{option_cache}->{$_}), @opt ) { - $flags{option_cache}->{$opt} = $self->option($opt, 1); - } - my %opt = %{ $flags{option_cache} }; - return 'amaflags != 2' - if $opt{'use_amaflags'} && $cdr->amaflags != 2; - - return "disposition NOT IN ( $opt{'disposition_in'} )" - if $opt{'disposition_in'} =~ /\S/ - && !grep { $cdr->disposition eq $_ } split(/\s*,\s*/, $opt{'disposition_in'}); - - return "disposition IN ( $opt{'ignore_disposition'} )" - if $opt{'ignore_disposition'} =~ /\S/ - && grep { $cdr->disposition eq $_ } split(/\s*,\s*/, $opt{'ignore_disposition'}); - - return "carrierid != $opt{'use_carrierid'}" - if length($opt{'use_carrierid'}) - && $cdr->carrierid ne $opt{'use_carrierid'}; #ne otherwise 0 matches '' + if $self->option_cacheable('use_amaflags') && $cdr->amaflags != 2; - return "cdrtypenum != $opt{'use_cdrtypenum'}" - if length($opt{'use_cdrtypenum'}) - && $cdr->cdrtypenum ne $opt{'use_cdrtypenum'}; #ne otherwise 0 matches '' - - return "cdrtypenum == $opt{'ignore_cdrtypenum'}" - if length($opt{'ignore_cdrtypenum'}) - && $cdr->cdrtypenum eq $opt{'ignore_cdrtypenum'}; #eq otherwise 0 matches '' + return "disposition NOT IN ( ". $self->option_cacheable('disposition_in')." )" + if $self->option_cacheable('disposition_in') =~ /\S/ + && !grep { $cdr->disposition eq $_ } split(/\s*,\s*/, $self->option_cacheable('disposition_in')); + + return "disposition IN ( ". $self->option_cacheable('ignore_disposition')." )" + if $self->option_cacheable('ignore_disposition') =~ /\S/ + && grep { $cdr->disposition eq $_ } split(/\s*,\s*/, $self->option_cacheable('ignore_disposition')); + + return "carrierid NOT IN ( ". $self->option_cacheable('use_carrierid'). " )" + if $self->option_cacheable('use_carrierid') =~ /\S/ + && !grep { $cdr->carrierid eq $_ } split(/\s*,\s*/, $self->option_cacheable('use_carrierid')); #eq otherwise 0 matches '' + + # unlike everything else, use_cdrtypenum is applied in FS::svc_x::get_cdrs. + return "cdrtypenum != ". $self->option_cacheable('use_cdrtypenum') + if length($self->option_cacheable('use_cdrtypenum')) + && $cdr->cdrtypenum ne $self->option_cacheable('use_cdrtypenum'); #ne otherwise 0 matches '' + + return "cdrtypenum == ". $self->option_cacheable('ignore_cdrtypenum') + if length($self->option_cacheable('ignore_cdrtypenum')) + && $cdr->cdrtypenum eq $self->option_cacheable('ignore_cdrtypenum'); #eq otherwise 0 matches '' + + # unlike everything else, use_calltypenum is applied in FS::svc_x::get_cdrs. + return "calltypenum != ". $self->option_cacheable('use_calltypenum') + if length($self->option_cacheable('use_calltypenum')) + && $cdr->calltypenum ne $self->option_cacheable('use_calltypenum'); #ne otherwise 0 matches '' + + return "calltypenum == ". $self->option_cacheable('ignore_calltypenum') + if length($self->option_cacheable('ignore_calltypenum')) + && $cdr->calltypenum eq $self->option_cacheable('ignore_calltypenum'); #eq otherwise 0 matches '' - return "dcontext IN ( $opt{'skip_dcontext'} )" - if $opt{'skip_dcontext'} =~ /\S/ - && grep { $cdr->dcontext eq $_ } split(/\s*,\s*/, $opt{'skip_dcontext'}); + return "dcontext IN ( ". $self->option_cacheable('skip_dcontext'). " )" + if $self->option_cacheable('skip_dcontext') =~ /\S/ + && grep { $cdr->dcontext eq $_ } split(/\s*,\s*/, $self->option_cacheable('skip_dcontext')); - my $len_prefix = length($opt{'skip_dstchannel_prefix'}); - return "dstchannel starts with $opt{'skip_dstchannel_prefix'}" + my $len_prefix = length($self->option_cacheable('skip_dstchannel_prefix')); + return "dstchannel starts with ". $self->option_cacheable('skip_dstchannel_prefix') if $len_prefix - && substr($cdr->dstchannel,0,$len_prefix) eq $opt{'skip_dstchannel_prefix'}; + && substr($cdr->dstchannel,0,$len_prefix) eq $self->option_cacheable('skip_dstchannel_prefix'); - my $dst_length = $opt{'skip_dst_length_less'}; + my $dst_length = $self->option_cacheable('skip_dst_length_less'); return "destination less than $dst_length digits" if $dst_length && length($cdr->dst) < $dst_length; - return "lastapp is $opt{'skip_lastapp'}" - if length($opt{'skip_lastapp'}) && $cdr->lastapp eq $opt{'skip_lastapp'}; + return "lastapp is ". $self->option_cacheable('skip_lastapp') + if length($self->option_cacheable('skip_lastapp')) && $cdr->lastapp eq $self->option_cacheable('skip_lastapp'); #all right then, rate it ''; diff --git a/FS/FS/svc_pbx.pm b/FS/FS/svc_pbx.pm index 4182a1315..66e51da71 100644 --- a/FS/FS/svc_pbx.pm +++ b/FS/FS/svc_pbx.pm @@ -292,7 +292,9 @@ to allow title to indicate a range of IP addresses. =item begin, end: Start and end of date range, as unix timestamp. -=item cdrtypenum: Only return CDRs with this type number. +=item cdrtypenum: Only return CDRs with this type. + +=item calltypenum: Only return CDRs with this call type. =back @@ -310,6 +312,9 @@ sub psearch_cdrs { if ($options{'cdrtypenum'}) { $hash{'cdrtypenum'} = $options{'cdrtypenum'}; } + if ($options{'calltypenum'}) { + $hash{'calltypenum'} = $options{'calltypenum'}; + } my $for_update = $options{'for_update'} ? 'FOR UPDATE' : ''; diff --git a/FS/FS/svc_phone.pm b/FS/FS/svc_phone.pm index f28002cc4..3cc1adc66 100644 --- a/FS/FS/svc_phone.pm +++ b/FS/FS/svc_phone.pm @@ -684,7 +684,9 @@ with the chosen prefix. =item begin, end: Start and end of a date range, as unix timestamp. -=item cdrtypenum: Only return CDRs with this type number. +=item cdrtypenum: Only return CDRs with this type. + +=item calltypenum: Only return CDRs with this call type. =item disable_src => 1: Only match on "charged_party", not "src". @@ -735,6 +737,9 @@ sub psearch_cdrs { if ($options{'cdrtypenum'}) { $hash{'cdrtypenum'} = $options{'cdrtypenum'}; } + if ($options{'calltypenum'}) { + $hash{'calltypenum'} = $options{'calltypenum'}; + } my $for_update = $options{'for_update'} ? 'FOR UPDATE' : ''; -- cgit v1.2.1 From 85ce0596ef3f057adf3e768e1dd339bd5d86f1da Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 25 Apr 2013 01:29:55 -0700 Subject: add company to self-service editable fields, RT#17617 --- FS/FS/ClientAPI/MyAccount.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 8ccacc5b9..01e0ebc33 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -50,7 +50,7 @@ $me = '[FS::ClientAPI::MyAccount]'; use vars qw( @cust_main_editable_fields @location_editable_fields ); @cust_main_editable_fields = qw( - first last daytime night fax mobile + first last company daytime night fax mobile locale payby payinfo payname paystart_month paystart_year payissue payip ss paytype paystate stateid stateid_state -- cgit v1.2.1 From d295c1176370d42a4754c26debfed390e0829f15 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 25 Apr 2013 04:09:31 -0700 Subject: fix XSS --- fs_selfservice/FS-SelfService/cgi/small_custview.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs_selfservice/FS-SelfService/cgi/small_custview.html b/fs_selfservice/FS-SelfService/cgi/small_custview.html index 8d6e07368..470fe7151 100644 --- a/fs_selfservice/FS-SelfService/cgi/small_custview.html +++ b/fs_selfservice/FS-SelfService/cgi/small_custview.html @@ -10,10 +10,10 @@ Customer #<%= $custnum %> ? 'Billing Address
    ' : '' %> - <%= $first %> <%= $last %>
    - <%= $company ? $company.'
    ' : '' %> - <%= $address1 %>
    - <%= $address2 ? $address2.'
    ' : '' %> + <%= encode_entities($first) %> <%= encode_entities($last) %>
    + <%= $company ? encode_entities($company).'
    ' : '' %> + <%= encode_entities($address1) %>
    + <%= $address2 ? encode_entities($address2).'
    ' : '' %> <%= $city %>, <%= $state %> <%= $zip %>
    <%= $country && $country ne ($countrydefault||'US') ? $country.'
    ' -- cgit v1.2.1 From a1a0800de7c69fe5ee414b79e408ceacd4a1c2c3 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Thu, 25 Apr 2013 14:45:49 -0700 Subject: changes to support PayPal, #22395 --- FS/FS/ClientAPI/Signup.pm | 28 ++-- FS/FS/Conf.pm | 6 +- FS/FS/Schema.pm | 3 +- FS/FS/agent.pm | 20 +-- FS/FS/cust_main.pm | 5 +- FS/FS/cust_main/Billing_Realtime.pm | 4 +- FS/FS/payby.pm | 1 + FS/FS/payinfo_Mixin.pm | 18 +-- FS/FS/payment_gateway.pm | 15 ++- .../cgi/make_thirdparty_payment.html | 2 +- fs_selfservice/FS-SelfService/cgi/myaccount.html | 7 +- .../FS-SelfService/cgi/myaccount_menu.html | 35 +++-- fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 5 +- fs_selfservice/FS-SelfService/cgi/verify.cgi | 17 ++- httemplate/edit/agent_payment_gateway.html | 1 + httemplate/edit/payment_gateway.html | 141 +++++++++++---------- httemplate/edit/process/payment_gateway.html | 1 + 17 files changed, 180 insertions(+), 129 deletions(-) diff --git a/FS/FS/ClientAPI/Signup.pm b/FS/FS/ClientAPI/Signup.pm index 1dbb20bc7..c3beb69ff 100644 --- a/FS/FS/ClientAPI/Signup.pm +++ b/FS/FS/ClientAPI/Signup.pm @@ -946,15 +946,27 @@ sub capture_payment { } my $cust_main = $cust_pay_pending->cust_main; - my $bill_error = - $cust_main->realtime_botpp_capture( $cust_pay_pending, - %{$packet->{data}}, - apply => 1, - ); + if ( $packet->{cancel} ) { + # the user has chosen not to make this payment + # (probably should be a separate API call, but I don't want to duplicate + # all of the above...which should eventually go away) + my $error = $cust_pay_pending->delete; + # don't show any errors related to this; they're not meaningful + warn "error canceling pending payment $paypendingnum: $error\n" if $error; + return { 'error' => '_cancel', + 'session_id' => $cust_pay_pending->session_id }; + } else { + # create the payment + my $bill_error = + $cust_main->realtime_botpp_capture( $cust_pay_pending, + %{$packet->{data}}, + apply => 1, + ); - return { 'error' => ( $bill_error->{bill_error} ? '_decline' : '' ), - %$bill_error, - }; + return { 'error' => ( $bill_error->{bill_error} ? '_decline' : '' ), + %$bill_error, + }; + } } diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 6a19ff475..8dbc070a0 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -2098,7 +2098,7 @@ and customer address. Include units.', 'section' => 'self-service', 'description' => 'Acceptable payment types for the signup server', 'type' => 'selectmultiple', - 'select_enum' => [ qw(CARD DCRD CHEK DCHK LECB PREPAY BILL COMP) ], + 'select_enum' => [ qw(CARD DCRD CHEK DCHK LECB PREPAY PPAL BILL COMP) ], }, { @@ -2472,7 +2472,7 @@ and customer address. Include units.', 'section' => 'billing', 'description' => 'Available payment types.', 'type' => 'selectmultiple', - 'select_enum' => [ qw(CARD DCRD CHEK DCHK LECB BILL CASH WEST MCRD COMP) ], + 'select_enum' => [ qw(CARD DCRD CHEK DCHK LECB BILL CASH WEST MCRD PPAL COMP) ], }, { @@ -2480,7 +2480,7 @@ and customer address. Include units.', 'section' => 'UI', 'description' => 'Default payment type. HIDE disables display of billing information and sets customers to BILL.', 'type' => 'select', - 'select_enum' => [ '', qw(CARD DCRD CHEK DCHK LECB BILL CASH WEST MCRD COMP HIDE) ], + 'select_enum' => [ '', qw(CARD DCRD CHEK DCHK LECB BILL CASH WEST MCRD PPAL COMP HIDE) ], }, { diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index eb73ccbc8..4f395f285 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3267,7 +3267,8 @@ sub tables_hashref { 'gateway_username', 'varchar', 'NULL', $char_d, '', '', 'gateway_password', 'varchar', 'NULL', $char_d, '', '', 'gateway_action', 'varchar', 'NULL', $char_d, '', '', - 'gateway_callback_url', 'varchar', 'NULL', $char_d, '', '', + 'gateway_callback_url', 'varchar', 'NULL', 255, '', '', + 'gateway_cancel_url', 'varchar', 'NULL', 255, '', '', 'disabled', 'char', 'NULL', 1, '', '', ], 'primary_key' => 'gatewaynum', diff --git a/FS/FS/agent.pm b/FS/FS/agent.pm index 3794d3f1d..9b322093b 100644 --- a/FS/FS/agent.pm +++ b/FS/FS/agent.pm @@ -216,7 +216,7 @@ an attempt will be made to select a gateway suited for the taxes paid on the invoice. The I and I options can be used to influence the choice -as well. Presently only 'CC' and 'ECHECK' methods are meaningful. +as well. Presently only 'CC', 'ECHECK', and 'PAYPAL' methods are meaningful. When the I is 'CC' then the card number in I can direct this routine to route to a gateway suited for that type of card. @@ -246,13 +246,17 @@ sub payment_gateway { } #look for an agent gateway override first - my $cardtype; - if ( $options{method} && $options{method} eq 'CC' && $options{payinfo} ) { - $cardtype = cardtype($options{payinfo}); - } elsif ( $options{method} && $options{method} eq 'ECHECK' ) { - $cardtype = 'ACH'; - } else { - $cardtype = $options{method} || ''; + my $cardtype = ''; + if ( $options{method} ) { + if ( $options{method} eq 'CC' && $options{payinfo} ) { + $cardtype = cardtype($options{payinfo}); + } elsif ( $options{method} eq 'ECHECK' ) { + $cardtype = 'ACH'; + } elsif ( $options{method} eq 'PAYPAL' ) { + $cardtype = 'PayPal'; + } else { + $cardtype = $options{method} + } } my $override = diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 2a4602e19..1cf036551 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -390,7 +390,7 @@ sub insert { $payby = 'PREP' if $amount; - } elsif ( $self->payby =~ /^(CASH|WEST|MCRD)$/ ) { + } elsif ( $self->payby =~ /^(CASH|WEST|MCRD|PPAL)$/ ) { $payby = $1; $self->payby('BILL'); @@ -2021,7 +2021,8 @@ sub check { if ( $self->paydate eq '' || $self->paydate eq '-' ) { return "Expiration date required" - unless $self->payby =~ /^(BILL|PREPAY|CHEK|DCHK|LECB|CASH|WEST|MCRD)$/; + # shouldn't payinfo_check do this? + unless $self->payby =~ /^(BILL|PREPAY|CHEK|DCHK|LECB|CASH|WEST|MCRD|PPAL)$/; $self->paydate(''); } else { my( $m, $y ); diff --git a/FS/FS/cust_main/Billing_Realtime.pm b/FS/FS/cust_main/Billing_Realtime.pm index 804969b16..1caa3e5af 100644 --- a/FS/FS/cust_main/Billing_Realtime.pm +++ b/FS/FS/cust_main/Billing_Realtime.pm @@ -111,7 +111,7 @@ L for supported gateways. Required arguments in the hashref are I, and I -Available methods are: I, I and I +Available methods are: I, I, I, and I Available optional arguments are: I, I, I, I, I, I, I @@ -317,6 +317,7 @@ my %bop_method2payby = ( 'CC' => 'CARD', 'ECHECK' => 'CHEK', 'LEC' => 'LECB', + 'PAYPAL' => 'PPAL', ); sub realtime_bop { @@ -612,6 +613,7 @@ sub realtime_bop { %$bop_content, 'reference' => $cust_pay_pending->paypendingnum, #for now 'callback_url' => $payment_gateway->gateway_callback_url, + 'cancel_url' => $payment_gateway->gateway_cancel_url, 'email' => $email, %content, #after ); diff --git a/FS/FS/payby.pm b/FS/FS/payby.pm index d1961a58d..e223a050f 100644 --- a/FS/FS/payby.pm +++ b/FS/FS/payby.pm @@ -208,6 +208,7 @@ sub longname { 'CARD' => 'CC', 'CHEK' => 'ECHECK', 'MCRD' => 'CC', + 'PPAL' => 'PAYPAL', ); sub payby2bop { diff --git a/FS/FS/payinfo_Mixin.pm b/FS/FS/payinfo_Mixin.pm index 9879a3abd..82632526d 100644 --- a/FS/FS/payinfo_Mixin.pm +++ b/FS/FS/payinfo_Mixin.pm @@ -44,26 +44,18 @@ For Refunds (cust_refund): For Payments (cust_pay): 'CARD' (credit cards), 'CHEK' (electronic check/ACH), 'LECB' (phone bill billing), 'BILL' (billing), 'PREP' (prepaid card), -'CASH' (cash), 'WEST' (Western Union), or 'MCRD' (Manual credit card) +'CASH' (cash), 'WEST' (Western Union), 'MCRD' (Manual credit card), +'PPAL' (PayPal) 'COMP' (free) is depricated as a payment type in cust_pay =cut -# was this supposed to do something? - -#sub payby { -# my($self,$payby) = @_; -# if ( defined($payby) ) { -# $self->setfield('payby', $payby); -# } -# return $self->getfield('payby') -#} - =item payinfo Payment information (payinfo) can be one of the following types: -Card Number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L) +Card Number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) +prepayment identifier (see L), PayPal transaction ID =cut @@ -267,6 +259,8 @@ sub payby_payinfo_pretty { 'Western Union'; #. $self->payinfo; } elsif ( $self->payby eq 'MCRD' ) { 'Manual credit card'; #. $self->payinfo; + } elsif ( $self->payby eq 'PPAL' ) { + 'PayPal transaction#' . $self->order_number; } else { $self->payby. ' '. $self->payinfo; } diff --git a/FS/FS/payment_gateway.pm b/FS/FS/payment_gateway.pm index 4a7585e24..e94a62cf4 100644 --- a/FS/FS/payment_gateway.pm +++ b/FS/FS/payment_gateway.pm @@ -41,7 +41,7 @@ currently supported: =item gateway_namespace - Business::OnlinePayment, Business::OnlineThirdPartyPayment, or Business::BatchPayment -=item gateway_module - Business::OnlinePayment:: module name +=item gateway_module - Business::OnlinePayment:: (or other) module name =item gateway_username - payment gateway username @@ -51,6 +51,14 @@ currently supported: =item disabled - Disabled flag, empty or 'Y' +=item gateway_callback_url - For ThirdPartyPayment only, set to the URL that +the user should be redirected to on a successful payment. This will be sent +as a transaction parameter (named "callback_url"). + +=item gateway_cancel_url - For ThirdPartyPayment only, set to the URL that +the user should be redirected to if they cancel the transaction. PayPal +requires this; other gateways ignore it. + =item auto_resolve_status - For BatchPayment only, set to 'approve' to auto-approve unresolved payments after some number of days, 'reject' to auto-decline them, or null to do nothing. @@ -128,6 +136,7 @@ sub check { || $self->ut_textn('gateway_username') || $self->ut_anything('gateway_password') || $self->ut_textn('gateway_callback_url') # a bit too permissive + || $self->ut_textn('gateway_cancel_url') || $self->ut_enum('disabled', [ '', 'Y' ] ) || $self->ut_enum('auto_resolve_status', [ '', 'approve', 'reject' ]) || $self->ut_numbern('auto_resolve_days') @@ -152,8 +161,8 @@ sub check { } # this little kludge mimics FS::CGI::popurl - $self->gateway_callback_url($self->gateway_callback_url. '/') - if ( $self->gateway_callback_url && $self->gateway_callback_url !~ /\/$/ ); + #$self->gateway_callback_url($self->gateway_callback_url. '/') + # if ( $self->gateway_callback_url && $self->gateway_callback_url !~ /\/$/ ); $self->SUPER::check; } diff --git a/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html b/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html index b5b9eea1f..59ee93b00 100755 --- a/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html @@ -8,7 +8,7 @@ onSubmit="document.OneTrueForm.process.disabled=true">
    <% $_ %><% $_ %>
    <% $rowhead %>
    <% $rowhead %> + % if ( exists($data[$col][$row]) ) { <% $data[$col][$row] %> % } diff --git a/httemplate/search/477partV.html b/httemplate/search/477partV.html index 2106a44d6..b2dd9ca95 100755 --- a/httemplate/search/477partV.html +++ b/httemplate/search/477partV.html @@ -1,3 +1,6 @@ +% if ( $cgi->param('_type') =~ /^xml$/ ) { + +% } <& elements/search.html, 'html_init' => $html_init, 'name' => 'zip code', @@ -14,6 +17,9 @@ &> +% if ( $cgi->param('_type') =~ /^xml$/ ) { + +% } <%init> my $curuser = $FS::CurrentUser::CurrentUser; diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html index 68c488837..d44b45465 100644 --- a/httemplate/search/elements/search.html +++ b/httemplate/search/elements/search.html @@ -353,7 +353,7 @@ if ( $opt{'disableable'} ) { my $limit = ''; my($confmax, $maxrecords, $offset ); -unless ( $type =~ /^(csv|\w*.xls)$/) { +unless ( $type =~ /^(csv|xml|\w*.xls)$/) { # html mode unless (exists($opt{count_query}) && length($opt{count_query})) { ( $opt{count_query} = $opt{query} ) =~ -- cgit v1.2.1 From 942d6c9ed24ac236abd050773cc38a9a6694357f Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 10 Apr 2013 13:01:39 -0700 Subject: snarfs are used by commuigate pro RPOP --- FS/FS/svc_acct.pm | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 6b4838401..26d6e5b72 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -1895,22 +1895,22 @@ sub email { $self->username. '@'. $self->domain(@_); } -# snarfs are unused at this point? -# -# =item acct_snarf -# -# Returns an array of FS::acct_snarf records associated with the account. -# -# =cut -# -# sub acct_snarf { -# my $self = shift; -# qsearch({ -# 'table' => 'acct_snarf', -# 'hashref' => { 'svcnum' => $self->svcnum }, -# #'order_by' => 'ORDER BY priority ASC', -# }); -# } + +=item acct_snarf + +Returns an array of FS::acct_snarf records associated with the account. + +=cut + +# unused as originally intended, but now by Communigate Pro "RPOP" +sub acct_snarf { + my $self = shift; + qsearch({ + 'table' => 'acct_snarf', + 'hashref' => { 'svcnum' => $self->svcnum }, + #'order_by' => 'ORDER BY priority ASC', + }); +} =item cgp_rpop_hashref -- cgit v1.2.1 From e00603c86cd6cc39ca3362defdada07ab8a8faf1 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 11 Apr 2013 11:21:27 -0700 Subject: fix advanced invoice reports: agent and payment selection, calendar styling, RT#22258 --- httemplate/search/report_cust_bill.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/search/report_cust_bill.html b/httemplate/search/report_cust_bill.html index 51618fb24..b339c80e0 100644 --- a/httemplate/search/report_cust_bill.html +++ b/httemplate/search/report_cust_bill.html @@ -4,7 +4,7 @@ - % unless ( $custnum ) { <& /elements/tr-select-agent.html, -- cgit v1.2.1 From d8addd6e9eed2c3fe8d88a8fcccc7b81354c40f8 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 11 Apr 2013 12:22:38 -0700 Subject: load h_cust_main for change history --- FS/FS/Mason.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 376fedcc0..d277c282f 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -160,6 +160,7 @@ if ( -e $addl_handler_use_file ) { use FS::cust_credit; use FS::cust_credit_bill; use FS::cust_main; + use FS::h_cust_main; use FS::cust_main::Search qw(smart_search); use FS::cust_main::Import; use FS::cust_main_county; -- cgit v1.2.1 From d4fce7ee523103141cb0f47eeda9f4df2fc81fd9 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 11 Apr 2013 13:55:32 -0700 Subject: fix intermittent error using new password change functionality, RT#22059 --- httemplate/view/svc_acct.cgi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/httemplate/view/svc_acct.cgi b/httemplate/view/svc_acct.cgi index 76631baad..858ccbe67 100755 --- a/httemplate/view/svc_acct.cgi +++ b/httemplate/view/svc_acct.cgi @@ -22,6 +22,7 @@ % } + <& svc_acct/radius_usage.html, 'svc_acct' => $svc_acct, 'part_svc' => $part_svc, @@ -29,6 +30,7 @@ %gopt, &> + <& svc_acct/change_svc_form.html, 'part_svc' => \@part_svc, 'svcnum' => $svcnum, @@ -43,6 +45,9 @@ %gopt, &> + + + <& svc_acct/basics.html, 'svc_acct' => $svc_acct, 'part_svc' => $part_svc, -- cgit v1.2.1 From b8f936e5ec4cf32922e18bdfd7a47ec8ca29e4cf Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 10 Apr 2013 17:04:58 -0700 Subject: improve deferred prorate billing with period > 1 month, #22311 --- FS/FS/part_pkg/prorate_Mixin.pm | 57 ++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/FS/FS/part_pkg/prorate_Mixin.pm b/FS/FS/part_pkg/prorate_Mixin.pm index 153ed56cd..9efc7e89d 100644 --- a/FS/FS/part_pkg/prorate_Mixin.pm +++ b/FS/FS/part_pkg/prorate_Mixin.pm @@ -67,11 +67,11 @@ the base price per billing cycle. Options: - add_full_period: Bill for the time up to the prorate day plus one full -billing period after that. + billing period after that. - prorate_round_day: Round the current time to the nearest full day, -instead of using the exact time. + instead of using the exact time. - prorate_defer_bill: Don't bill the prorate interval until the prorate -day arrives. + day arrives. - prorate_verbose: Generate details to explain the prorate calculations. =cut @@ -104,7 +104,7 @@ sub calc_prorate { $add_period = 1; } - # if the customer alreqady has a billing day-of-month established, + # if the customer already has a billing day-of-month established, # and it's a valid cutoff day, try to respect it my $next_bill_day; if ( my $next_bill = $cust_pkg->cust_main->next_bill_date ) { @@ -123,31 +123,46 @@ sub calc_prorate { my $permonth = $charge / $self->freq; my $months = ( ( $self->freq - 1 ) + ($mend-$mnow) / ($mend-$mstart) ); - - if ( $self->option('prorate_verbose',1) - and $months > 0 and $months < $self->freq ) { - push @$details, - 'Prorated (' . time2str('%b %d', $mnow) . - ' - ' . time2str('%b %d', $mend) . '): ' . $money_char . - sprintf('%.2f', $permonth * $months + 0.00000001 ); - } + # after this, $self->freq - 1 < $months <= $self->freq # add a full period if currently billing for a partial period # or periods up to freq_override if billing for an override interval if ( ($param->{'freq_override'} || 0) > 1 ) { $months += $param->{'freq_override'} - 1; - } - elsif ( $add_period && $months < $self->freq) { + # freq_override - 1 correct here? + # (probably only if freq == 1, yes?) + } elsif ( $add_period && $months < $self->freq ) { + + # 'add_period' is a misnomer. + # we add enough to make the total at least a full period + $months++; + $$sdate = $self->add_freq($mstart, 1); + # now $self->freq <= $months <= $self->freq + 1 + # (note that this only happens if $months < $self->freq to begin with) - if ( $self->option('prorate_verbose',1) ) { - # calculate the prorated and add'l period charges + } + + if ( $self->option('prorate_verbose',1) and $months > 0 ) { + if ( $months < $self->freq ) { + # we are billing a fractional period only + # # (though maybe not a fractional month) + my $period_end = $self->add_freq($mstart); + push @$details, + 'Prorated (' . time2str('%b %d', $mnow) . + ' - ' . time2str('%b %d', $period_end) . '): ' . $money_char . + sprintf('%.2f', $permonth * $months + 0.00000001 ); + + } elsif ( $months > $self->freq ) { + # we are billing MORE than a full period push @$details, - 'First full month: ' . $money_char . - sprintf('%.2f', $permonth); - } - $months += $self->freq; - $$sdate = $self->add_freq($mstart); + 'Prorated (' . time2str('%b %d', $mnow) . + ' - ' . time2str('%b %d', $mend) . '): ' . $money_char . + sprintf('%.2f', $permonth * ($months - $self->freq + 0.0000001)), + + 'First full period: ' . $money_char . + sprintf('%.2f', $permonth * $self->freq); + } # else $months == $self->freq, and no prorating has happened } $param->{'months'} = $months; -- cgit v1.2.1 From 194da40d2ffbaa8a2604c75a74b650a730c3a000 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 11 Apr 2013 15:09:02 -0700 Subject: fix (old-style RT) spreadsheet links in RTx::Statistics reports, RT#22455 --- htetc/freeside-rt.conf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/htetc/freeside-rt.conf b/htetc/freeside-rt.conf index 5586e1229..71ebfbd0b 100644 --- a/htetc/freeside-rt.conf +++ b/htetc/freeside-rt.conf @@ -77,3 +77,10 @@ PerlHandler HTML::Mason SetHandler perl-script PerlHandler HTML::Mason + + + + SetHandler perl-script + PerlHandler HTML::Mason + + -- cgit v1.2.1 From 194d0e29f4587669032da09c3bf814c3531898a2 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 11 Apr 2013 18:05:07 -0700 Subject: fix "add package columns" in customer report, RT#22525 --- FS/FS/cust_main/Search.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FS/FS/cust_main/Search.pm b/FS/FS/cust_main/Search.pm index d8f620f90..9ec40cdd3 100644 --- a/FS/FS/cust_main/Search.pm +++ b/FS/FS/cust_main/Search.pm @@ -857,7 +857,8 @@ sub search { if ($params->{'flattened_pkgs'}) { #my $pkg_join = ''; - $addl_from .= ' LEFT JOIN cust_pkg USING ( custnum ) '; + $addl_from .= + ' LEFT JOIN cust_pkg ON ( cust_main.custnum = cust_pkg.custnum ) '; if ($dbh->{Driver}->{Name} eq 'Pg') { -- cgit v1.2.1 From 602d22bbe08490648362a571672d89e7f944f6bd Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 11 Apr 2013 18:10:11 -0700 Subject: fix XSS --- FS/FS/UI/Web.pm | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/FS/FS/UI/Web.pm b/FS/FS/UI/Web.pm index 792680876..3fd61efd8 100644 --- a/FS/FS/UI/Web.pm +++ b/FS/FS/UI/Web.pm @@ -472,23 +472,26 @@ sub cust_fields_subs { my $unlinked_warn = 0; return map { my $f = $_; - if( $unlinked_warn++ ) { + if ( $unlinked_warn++ ) { + sub { my $record = shift; - if( $record->custnum ) { - $record->$f(@_); - } - else { + if ( $record->custnum ) { + encode_entities( $record->$f(@_) ); + } else { '(unlinked)' }; - } - } - else { + }; + + } else { + sub { my $record = shift; - $record->$f(@_) if $record->custnum; - } + $record->custnum ? encode_entities( $record->$f(@_) ) : ''; + }; + } + } @cust_fields; } -- cgit v1.2.1 From d37fb0b5f49c46e0df95212ae8660a8423809305 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 12 Apr 2013 16:39:02 -0700 Subject: show discounts in change history, #18340 --- httemplate/view/cust_main/change_history.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/httemplate/view/cust_main/change_history.html b/httemplate/view/cust_main/change_history.html index ea84b8f75..bf32a49f9 100644 --- a/httemplate/view/cust_main/change_history.html +++ b/httemplate/view/cust_main/change_history.html @@ -43,10 +43,12 @@ tie my %tables, 'Tie::IxHash', 'svc_external' => 'External service', 'svc_phone' => 'Phone', 'phone_device' => 'Phone device', + 'cust_pkg_discount' => 'Discount', #? it gets provisioned anyway 'phone_avail' => 'Phone', ; -my $svc_join = 'JOIN cust_svc USING ( svcnum ) JOIN cust_pkg USING ( pkgnum )'; +my $pkg_join = "JOIN cust_pkg USING ( pkgnum )"; +my $svc_join = "JOIN cust_svc USING ( svcnum ) $pkg_join"; my %table_join = ( 'svc_acct' => $svc_join, @@ -58,6 +60,7 @@ my %table_join = ( 'svc_external' => $svc_join, 'svc_phone' => $svc_join, 'phone_device' => $svc_join, + 'cust_pkg_discount'=> $pkg_join, ); @@ -104,7 +107,7 @@ my $conf = new FS::Conf; my $curuser = $FS::CurrentUser::CurrentUser; -die "access deined" +die "access denied" unless $curuser->access_right('View customer history'); # find out the beginning of this customer history, if possible -- cgit v1.2.1 From a9f4e76c1d2392514c4172dd869fd101e3a9c6ec Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 14 Apr 2013 12:16:53 -0700 Subject: add customer class to A/R report, fix "(none)" selection in other reports, RT#22540 --- httemplate/search/cust_bill.html | 2 +- httemplate/search/cust_bill_pay.html | 9 ++++++--- httemplate/search/cust_bill_pkg.cgi | 11 +++++++---- httemplate/search/cust_bill_pkg_referral.html | 10 +++++++--- httemplate/search/cust_credit.html | 10 +++++++--- httemplate/search/cust_credit_refund.html | 9 ++++++--- httemplate/search/customer_accounting_summary.html | 4 +--- httemplate/search/elements/cust_main_dayranges.html | 9 +++++++++ httemplate/search/elements/cust_pay_or_refund.html | 9 ++++++--- httemplate/search/prepaid_income.html | 9 ++++++--- httemplate/search/report_receivables.html | 10 +++++++++- httemplate/search/unearned_detail.html | 13 ++++++------- 12 files changed, 71 insertions(+), 34 deletions(-) diff --git a/httemplate/search/cust_bill.html b/httemplate/search/cust_bill.html index 88cdaf5ab..473aed311 100755 --- a/httemplate/search/cust_bill.html +++ b/httemplate/search/cust_bill.html @@ -97,7 +97,7 @@ if ( $cgi->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/ ) { $search{'refnum'} = $1; } - if ( $cgi->param('cust_classnum') ) { +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { $search{'cust_classnum'} = [ $cgi->param('cust_classnum') ]; } diff --git a/httemplate/search/cust_bill_pay.html b/httemplate/search/cust_bill_pay.html index 0b64e650f..ff20458d8 100644 --- a/httemplate/search/cust_bill_pay.html +++ b/httemplate/search/cust_bill_pay.html @@ -99,9 +99,12 @@ if ( $cgi->param('refnum') && $cgi->param('refnum') =~ /^(\d+)$/ ) { $title = $part_referral->referral. " $title"; } -if ( $cgi->param('cust_classnum') ) { - my @classnums = grep /^\d+$/, $cgi->param('cust_classnum'); - push @search, 'cust_main.classnum IN('.join(',',@classnums).')' +# cust_classnum (false laziness w/ elements/cust_main_dayranges.html, prepaid_income.html, cust_bill_pkg.html, cust_bill_pkg_referral.html, unearned_detail.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql) +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); + push @search, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' if @classnums; } diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi index 0f51d9481..3a3b0feb9 100644 --- a/httemplate/search/cust_bill_pkg.cgi +++ b/httemplate/search/cust_bill_pkg.cgi @@ -260,13 +260,16 @@ if ( $cgi->param('refnum') =~ /^(\d+)$/ ) { push @where, "cust_main.refnum = $1"; } -# cust_classnum -if ( $cgi->param('cust_classnum') ) { - my @classnums = grep /^\d+$/, $cgi->param('cust_classnum'); - push @where, 'cust_main.classnum IN('.join(',',@classnums).')' +# cust_classnum (false laziness w/ elements/cust_main_dayranges.html, elements/cust_pay_or_refund.html, prepaid_income.html, cust_bill_pay.html, cust_bill_pkg_referral.html, unearned_detail.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql) +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); + push @where, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' if @classnums; } + # custnum if ( $cgi->param('custnum') =~ /^(\d+)$/ ) { push @where, "cust_main.custnum = $1"; diff --git a/httemplate/search/cust_bill_pkg_referral.html b/httemplate/search/cust_bill_pkg_referral.html index 1289ff7ee..c4dde32a0 100644 --- a/httemplate/search/cust_bill_pkg_referral.html +++ b/httemplate/search/cust_bill_pkg_referral.html @@ -156,9 +156,13 @@ if ( @refnum ) { push @where, 'cust_main.refnum IN ('.join(',', @refnum).')'; } -my @cust_classnums = grep /^\d+$/, $cgi->param('cust_classnum'); -if ( @cust_classnums ) { - push @where, 'cust_main.classnum IN ('.join(',', @cust_classnums).')'; +# cust_classnum (false laziness w/ elements/cust_main_dayranges.html, elements/cust_pay_or_refund.html, prepaid_income.html, cust_bill_pay.html, cust_bill_pkg.html, unearned_detail.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql) +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); + push @where, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' + if @classnums; } if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { diff --git a/httemplate/search/cust_credit.html b/httemplate/search/cust_credit.html index d1f41df00..cabf8c002 100755 --- a/httemplate/search/cust_credit.html +++ b/httemplate/search/cust_credit.html @@ -103,9 +103,13 @@ if ( $cgi->param('refnum') && $cgi->param('refnum') =~ /^(\d+)$/ ) { $title = $part_referral->referral. " $title"; } -if ( $cgi->param('cust_classnum') ) { - my @classnums = grep /^\d+$/, $cgi->param('cust_classnum'); - push @search, 'cust_main.classnum IN('.join(',',@classnums).')' + +# cust_classnum (false laziness w/ elements/cust_main_dayranges.html, elements/cust_pay_or_refund.html, prepaid_income.html, cust_bill_pay.html, cust_bill_pkg.html, cust_bill_pkg_referral.html, unearned_detail.html, cust_credit_refund.html, cust_main::Search::search_sql) +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); + push @search, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' if @classnums; } diff --git a/httemplate/search/cust_credit_refund.html b/httemplate/search/cust_credit_refund.html index 1504f0fbe..817420054 100644 --- a/httemplate/search/cust_credit_refund.html +++ b/httemplate/search/cust_credit_refund.html @@ -85,9 +85,12 @@ if ( $cgi->param('refnum') && $cgi->param('refnum') =~ /^(\d+)$/ ) { $title = $part_referral->referral. " $title"; } -if ( $cgi->param('cust_classnum') ) { - my @classnums = grep /^\d+$/, $cgi->param('cust_classnum'); - push @search, 'cust_main.classnum IN('.join(',',@classnums).')' +# cust_classnum (false laziness w/ elements/cust_main_dayranges.html, elements/cust_pay_or_refund.html, prepaid_income.html, cust_bill_pay.html, cust_bill_pkg.html, cust_bill_pkg_referral.html, unearned_detail.html, cust_credit.html, cust_main::Search::search_sql) +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); + push @search, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' if @classnums; } diff --git a/httemplate/search/customer_accounting_summary.html b/httemplate/search/customer_accounting_summary.html index 12c896276..b48ff21e3 100644 --- a/httemplate/search/customer_accounting_summary.html +++ b/httemplate/search/customer_accounting_summary.html @@ -142,8 +142,6 @@ $title .= $sel_part_referral->referral.' ' $title .= 'Customer Accounting Summary Report'; -my @cust_classnums = grep /^\d+$/, $cgi->param('cust_classnum'); - my @items = ('netsales', 'cashflow'); my @params = ( [], [] ); my $setuprecur = ''; @@ -173,7 +171,7 @@ foreach (qw(agentnum refnum status)) { } } $search_hash{'classnum'} = [ $cgi->param('cust_classnum') ] - if $cgi->param('cust_classnum'); + if grep { $_ eq 'cust_classnum' } $cgi->param; my $query = FS::cust_main::Search->search(\%search_hash); my @custs = qsearch($query); diff --git a/httemplate/search/elements/cust_main_dayranges.html b/httemplate/search/elements/cust_main_dayranges.html index c9c71f274..cf2d495b1 100644 --- a/httemplate/search/elements/cust_main_dayranges.html +++ b/httemplate/search/elements/cust_main_dayranges.html @@ -162,6 +162,15 @@ if ( grep { $cgi->param('status') eq $_ } FS::cust_main->statuses() ) { push @where, FS::cust_main->$method(); } +# cust_classnum (false laziness w/prepaid_income.html, elements/cust_pay_or_refund.html, cust_bill_pay.html, cust_bill_pkg.html, cust_bill_pkg_referral.html, unearned_detail.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql) +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); + push @where, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' + if @classnums; +} + #here is the agent virtualization push @where, $FS::CurrentUser::CurrentUser->agentnums_sql; diff --git a/httemplate/search/elements/cust_pay_or_refund.html b/httemplate/search/elements/cust_pay_or_refund.html index 3e5d504c6..81a012e01 100755 --- a/httemplate/search/elements/cust_pay_or_refund.html +++ b/httemplate/search/elements/cust_pay_or_refund.html @@ -252,9 +252,12 @@ if ( $cgi->param('magic') ) { $title = $part_referral->referral. " $title"; } - if ( $cgi->param('cust_classnum') ) { - my @classnums = grep /^\d+$/, $cgi->param('cust_classnum'); - push @search, 'cust_main.classnum IN('.join(',',@classnums).')' + # cust_classnum (false laziness w/ elements/cust_main_dayranges.html, prepaid_income.html, cust_bill_pay.html, cust_bill_pkg.html cust_bill_pkg_referral.html, unearned_detail.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql) + if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); + push @where, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' if @classnums; } diff --git a/httemplate/search/prepaid_income.html b/httemplate/search/prepaid_income.html index 03d121d70..cb58a666d 100644 --- a/httemplate/search/prepaid_income.html +++ b/httemplate/search/prepaid_income.html @@ -129,10 +129,13 @@ if ( $cgi->param('status') =~ /^([a-z]+)$/ ) { push @where, FS::cust_main->cust_status_sql . " = '$status'"; } -if ( $cgi->param('cust_classnum') ) { - my @classnums = grep /^\d+$/, $cgi->param('cust_classnum'); +# cust_classnum (false laziness w/ elements/cust_main_dayranges.html, elements/cust_pay_or_refund.html, cust_bill_pay.html, cust_bill_pkg.html, cust_bill_pkg_referral.html, unearned_detail.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql) +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); $link .= ";cust_classnum=$_" foreach @classnums; - push @where, 'cust_main.classnum IN('.join(',',@classnums).')' + push @where, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' if @classnums; } diff --git a/httemplate/search/report_receivables.html b/httemplate/search/report_receivables.html index 5cff0f4fc..854b24a00 100755 --- a/httemplate/search/report_receivables.html +++ b/httemplate/search/report_receivables.html @@ -15,7 +15,15 @@ <& /elements/tr-select-cust_main-status.html, 'label' => emt('Customer Status'), &> - + + <& /elements/tr-select-cust_class.html, + 'label' => emt('Customer class'), + 'field' => 'cust_classnum', + 'multiple' => 1, + 'pre_options' => [ '' => emt('(none)') ], + 'all_selected' => 1, + &> + +<%init> + +my $conf = new FS::Conf; +my %opt = @_; + +my $cust_pkg = $opt{'cust_pkg'}; + +my $contact = $cust_pkg->contact; + +sub pkg_change_contact_link { + my $cust_pkg = shift; + my $pkgpart = $cust_pkg->pkgpart; + include( '/elements/popup_link-cust_pkg.html', +#XXX + 'action' => $p. "misc/change_pkg.cgi?contactnum=-1", + 'label' => emt('Change contact'), + 'actionlabel' => emt('Change'), + 'cust_pkg' => $cust_pkg, + ); +} + +sub edit_contact_link { + my $contactnum = shift; + include( '/elements/popup_link.html', + 'action' => $p. "edit/cust_contact.cgi?contactnum=$contactnum", + 'label' => emt('Edit contact'), + 'actionlabel' => emt('Edit'), + ); +} + + diff --git a/httemplate/view/cust_main/packages/location.html b/httemplate/view/cust_main/packages/location.html index 95694850e..f2d379841 100644 --- a/httemplate/view/cust_main/packages/location.html +++ b/httemplate/view/cust_main/packages/location.html @@ -1,5 +1,3 @@ - <%init> my $conf = new FS::Conf; my %opt = @_; -my $bgcolor = $opt{'bgcolor'}; my $cust_pkg = $opt{'cust_pkg'}; my $countrydefault = $opt{'countrydefault'} || 'US'; my $statedefault = $opt{'statedefault'} diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html index 0b72d195e..520305a9a 100644 --- a/httemplate/view/cust_main/packages/package.html +++ b/httemplate/view/cust_main/packages/package.html @@ -186,11 +186,6 @@ % !$supplemental and % $part_pkg->freq ne '0' ) { -% if ( !$opt{'show_location'} ) { - -% } % if ( FS::Conf->new->exists('invoice-unitprice') ) { -% if ( $show_location ) { - -% } + @@ -13,6 +11,7 @@ % foreach my $cust_pkg (@$packages) { <& .packagerow, $cust_pkg, 'cust_main' => $opt{'cust_main'}, + 'bgcolor' => $opt{'bgcolor'}, %conf_opt &> % } @@ -27,10 +26,11 @@ <& package.html, %iopt &> - <& status.html, %iopt &> -% if ( $iopt{'show_location'} ) { - <& location.html, %iopt &> -% } + <& status.html, %iopt &> + <& services.html, %iopt &> % $row++; @@ -51,7 +51,6 @@ my $conf = new FS::Conf; my $curuser = $FS::CurrentUser::CurrentUser; my $packages = $opt{'packages'}; -my $show_location = $opt{'show_location'}; # Sort order is hardcoded for now, can change this if needed. @$packages = sort { @@ -86,8 +85,6 @@ my %conf_opt = ( 'maestro-status_test' => $conf->exists('maestro-status_test'), 'cust_pkg-large_pkg_size' => scalar($conf->config('cust_pkg-large_pkg_size')), - # for packages.html Change location link - 'show_location' => $show_location, ); diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html index 6be0296a3..9d5a88e0f 100644 --- a/httemplate/view/cust_main/packages/status.html +++ b/httemplate/view/cust_main/packages/status.html @@ -1,4 +1,4 @@ - <%init> my $conf = new FS::Conf; -- cgit v1.2.1 From 7ce77a80cf98d1b97e8bcd942d03905902b9d653 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 16 Apr 2013 22:46:33 -0700 Subject: fix method name conflict --- FS/FS/cust_pkg.pm | 7 ++++++- httemplate/view/cust_main/packages/contact.html | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index bb1b4e37a..801228871 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -227,7 +227,7 @@ Create a new billing item. To add the item to the database, see L<"insert">. =cut sub table { 'cust_pkg'; } -sub cust_linked { $_[0]->cust_main_custnum; } +sub cust_linked { $_[0]->cust_main_custnum || $_[0]->custnum } sub cust_unlinked_msg { my $self = shift; "WARNING: can't find cust_main.custnum ". $self->custnum. @@ -3569,6 +3569,11 @@ sub main_pkg { return; } +# workaround for name conflict +sub pkg_contact { + FS::contact_Mixin::contact(@_); +} + =back =head1 CLASS METHODS diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index 87a7b02bd..bb9453470 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -20,7 +20,7 @@ my %opt = @_; my $cust_pkg = $opt{'cust_pkg'}; -my $contact = $cust_pkg->contact; +my $contact = $cust_pkg->pkg_contact; sub pkg_change_contact_link { my $cust_pkg = shift; -- cgit v1.2.1 From de2d2fc7243b193e037e971c096a5030d71ff0c6 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 17 Apr 2013 09:41:30 -0700 Subject: fix fallout from #22185 (#22601, #22600) --- FS/FS/contact_Mixin.pm | 4 ++-- httemplate/elements/tr-select-contact.html | 2 +- httemplate/view/cust_main/packages/contact.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FS/FS/contact_Mixin.pm b/FS/FS/contact_Mixin.pm index 33cd3509a..6e8f315b9 100644 --- a/FS/FS/contact_Mixin.pm +++ b/FS/FS/contact_Mixin.pm @@ -4,13 +4,13 @@ use strict; use FS::Record qw( qsearchs ); use FS::contact; -=item contact +=item contact_obj Returns the contact object, if any (see L). =cut -sub contact { +sub contact_obj { my $self = shift; return '' unless $self->contactnum; qsearchs( 'contact', { 'contactnum' => $self->contactnum } ); diff --git a/httemplate/elements/tr-select-contact.html b/httemplate/elements/tr-select-contact.html index 579117808..d6bc67f36 100644 --- a/httemplate/elements/tr-select-contact.html +++ b/httemplate/elements/tr-select-contact.html @@ -162,7 +162,7 @@ if ( $contactnum && $contactnum > 0 ) { if ( $contactnum == -1 ) { $contact->$_( $cgi->param($_) ) foreach @contact_fields; #XXX } elsif ( $cust_pkg && $cust_pkg->contactnum ) { - my $pkg_contact = $cust_pkg->contact; + my $pkg_contact = $cust_pkg->contact_obj; $contact->$_( $pkg_contact->$_ ) foreach @contact_fields; #XXX why are we making a new one gagain?? $opt{'empty_label'} ||= 'package contact: '.$pkg_contact->line; } elsif ( $cust_main ) { diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index a6f8a4273..f47705c3d 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -22,7 +22,7 @@ my %opt = @_; my $cust_pkg = $opt{'cust_pkg'}; -my $contact = $cust_pkg->contact; +my $contact = $cust_pkg->contact_obj; sub pkg_change_contact_link { my $cust_pkg = shift; -- cgit v1.2.1 From 67065f306c08433774a1044bcd8e5d6254d752da Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 17 Apr 2013 09:45:44 -0700 Subject: fix fallout from #22185 (#22601, #22600) --- httemplate/view/cust_main/packages/contact.html | 1 - 1 file changed, 1 deletion(-) diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index f47705c3d..5f47cf706 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -14,7 +14,6 @@ % } - <%init> my $conf = new FS::Conf; -- cgit v1.2.1 From 9fbee73725ce02023c76179d573048cf4177903b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 17 Apr 2013 10:16:54 -0700 Subject: fix customer class selection in A/R report, RT#22540, RT#22604 --- httemplate/search/elements/cust_pay_or_refund.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/httemplate/search/elements/cust_pay_or_refund.html b/httemplate/search/elements/cust_pay_or_refund.html index 81a012e01..7b2a17058 100755 --- a/httemplate/search/elements/cust_pay_or_refund.html +++ b/httemplate/search/elements/cust_pay_or_refund.html @@ -255,9 +255,9 @@ if ( $cgi->param('magic') ) { # cust_classnum (false laziness w/ elements/cust_main_dayranges.html, prepaid_income.html, cust_bill_pay.html, cust_bill_pkg.html cust_bill_pkg_referral.html, unearned_detail.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql) if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); - push @where, 'COALESCE( cust_main.classnum, 0) IN ( '. - join(',', map { $_ || '0' } @classnums ). - ' )' + push @search, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' if @classnums; } -- cgit v1.2.1 From 5d2551a955964d8af6fec48ee85647567e942b0c Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 17 Apr 2013 16:21:58 -0700 Subject: dummy export module for testing --- FS/FS/part_export/test.pm | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 FS/FS/part_export/test.pm diff --git a/FS/FS/part_export/test.pm b/FS/FS/part_export/test.pm new file mode 100644 index 000000000..126897c0b --- /dev/null +++ b/FS/FS/part_export/test.pm @@ -0,0 +1,75 @@ +package FS::part_export::test; + +use strict; +use vars qw(%options %info); +use Tie::IxHash; +use base qw(FS::part_export); + +tie %options, 'Tie::IxHash', + 'result' => { label => 'Result', + type => 'select', + options => [ 'success', 'failure', 'exception' ], + default => 'success', + }, + 'errormsg'=> { label => 'Error message', + default => 'Test export' }, + 'insert' => { label => 'Insert', type => 'checkbox', default => 1, }, + 'delete' => { label => 'Delete', type => 'checkbox', default => 1, }, + 'replace' => { label => 'Replace',type => 'checkbox', default => 1, }, + 'suspend' => { label => 'Suspend',type => 'checkbox', default => 1, }, + 'unsuspend'=>{ label => 'Unsuspend', type => 'checkbox', default => 1, }, +; + +%info = ( + 'svc' => [ qw(svc_acct svc_broadband svc_phone svc_domain) ], + 'desc' => 'Test export for development', + 'options' => \%options, + 'notes' => <Test export. Do not use this in production systems.

    +

    This export either always succeeds, always fails (returning an error), +or always dies, according to the "Result" option. It does nothing else; the +purpose is purely to simulate success or failure within an export module.

    +

    The checkbox options can be used to turn the export off for certain +actions, if this is needed.

    +END +); + +sub export_insert { + my $self = shift; + $self->run(@_) if $self->option('insert'); +} + +sub export_delete { + my $self = shift; + $self->run(@_) if $self->option('delete'); +} + +sub export_replace { + my $self = shift; + $self->run(@_) if $self->option('replace'); +} + +sub export_suspend { + my $self = shift; + $self->run(@_) if $self->option('suspend'); +} + +sub export_unsuspend { + my $self = shift; + $self->run(@_) if $self->option('unsuspend'); +} + +sub run { + my $self = shift; + my $svc_x = shift; + my $result = $self->option('result'); + if ( $result eq 'failure' ) { + return $self->option('errormsg'); + } elsif ( $result eq 'exception' ) { + die $self->option('errormsg'); + } else { + return ''; + } +} + +1; -- cgit v1.2.1 From 67cb1a2d4882c8f04728f828cc13de1a543a2bb3 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 17 Apr 2013 16:22:01 -0700 Subject: fix transaction state when exiting a queue job, #22524 --- FS/bin/freeside-queued | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued index 2fd80255e..dcc6ac4ba 100644 --- a/FS/bin/freeside-queued +++ b/FS/bin/freeside-queued @@ -212,8 +212,10 @@ while (1) { # don't put @args in the log, may expose passwords $log->info('starting job ('.$ljob->job.')'); warn 'running "&'. $ljob->job. '('. join(', ', @args). ")\n" if $DEBUG; + local $FS::UID::AutoCommit = 0; # so that we can clean up failures eval $eval; #throw away return value? suppose so if ( $@ ) { + dbh->rollback; my %hash = $ljob->hash; $hash{'statustext'} = $@; if ( $hash{'statustext'} =~ /\/misc\/queued_report/ ) { #use return? @@ -225,8 +227,10 @@ while (1) { my $fjob = new FS::queue( \%hash ); my $error = $fjob->replace($ljob); die $error if $error; + dbh->commit; # for the status change only } else { $ljob->delete; + dbh->commit; # for the job itself } if ( UNIVERSAL::can(dbh, 'sprintProfile') ) { -- cgit v1.2.1 From 04bf3e2423b070d3e3e2a2e6006b678bcf11b481 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 17 Apr 2013 20:44:39 -0700 Subject: move from legacy compat JSON to_json to modern JSON::XS encode_json, RT#22630 --- FS/FS/Mason.pm | 2 +- FS/FS/UI/Web.pm | 7 ++----- httemplate/edit/payment_gateway.html | 2 +- httemplate/elements/auto-table.html | 4 ++-- httemplate/elements/dashboard-toplist.html | 3 --- httemplate/elements/select-tiered.html | 7 ------- httemplate/elements/tr-select-cust_location.html | 2 +- httemplate/misc/xmlhttp-cust_bill_pkg-calculate_taxes.html | 2 +- httemplate/misc/xmlhttp-cust_main-email_search.html | 2 +- 9 files changed, 9 insertions(+), 22 deletions(-) diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index d277c282f..1553a42df 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -77,7 +77,7 @@ if ( -e $addl_handler_use_file ) { use HTML::TableExtract qw(tree); use HTML::FormatText; use HTML::Defang; - use JSON; + use JSON::XS; # use XMLRPC::Transport::HTTP; # use XMLRPC::Lite; # for XMLRPC::Serializer use MIME::Base64; diff --git a/FS/FS/UI/Web.pm b/FS/FS/UI/Web.pm index 3fd61efd8..c8ad430b2 100644 --- a/FS/FS/UI/Web.pm +++ b/FS/FS/UI/Web.pm @@ -581,7 +581,7 @@ use vars qw($DEBUG); use Carp; use Storable qw(nfreeze); use MIME::Base64; -use JSON; +use JSON::XS; use FS::UID qw(getotaker); use FS::Record qw(qsearchs); use FS::queue; @@ -726,10 +726,7 @@ sub job_status { @return = ( 'error', $job ? $job->statustext : $jobnum ); } - #to_json(\@return); #waiting on deb 5.0 for new JSON.pm? - #silence the warning though - my $to_json = JSON->can('to_json') || JSON->can('objToJson'); - &$to_json(\@return); + encode_json \@return; } diff --git a/httemplate/edit/payment_gateway.html b/httemplate/edit/payment_gateway.html index dfe52f109..a469beb7f 100644 --- a/httemplate/edit/payment_gateway.html +++ b/httemplate/edit/payment_gateway.html @@ -19,7 +19,7 @@ +<%init> + +my( %opt ) = @_; + +my $field = $opt{'field'} || $opt{'field_name'} || 'svcnum'; + +my $value = $opt{'curr_value'} || $opt{'value'}; + +my $svc_broadband = ''; +if ( $value ) { + $svc_broadband = qsearchs({ + 'table' => 'svc_broadband', + 'hashref' => { 'svcnum' => $value }, + #have to join to cust_main for an agentnum 'extra_sql' => " AND ". $FS::CurrentUser::CurrentUser->agentnums_sql, + }); +} + + diff --git a/httemplate/elements/tr-search-svc_broadband.html b/httemplate/elements/tr-search-svc_broadband.html new file mode 100644 index 000000000..cd7c11500 --- /dev/null +++ b/httemplate/elements/tr-search-svc_broadband.html @@ -0,0 +1,15 @@ +<& tr-td-label.html, @_ &> + +
    + + + +<%init> + +my %opt = @_; + +my $cell_style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : ''; + +my $colspan = $opt{'colspan'} ? 'COLSPAN="'.$opt{'colspan'}.'"' : ''; + + diff --git a/httemplate/misc/xmlhttp-svc_broadband-search.cgi b/httemplate/misc/xmlhttp-svc_broadband-search.cgi new file mode 100644 index 000000000..578e6140e --- /dev/null +++ b/httemplate/misc/xmlhttp-svc_broadband-search.cgi @@ -0,0 +1,22 @@ +% if ( $sub eq 'smart_search' ) { +% +% my $string = $cgi->param('arg'); +% my @svc_broadband = FS::svc_broadband->smart_search( $string ); +% my $return = [ map { my $cust_pkg = $_->cust_svc->cust_pkg; +% [ $_->svcnum, +% $_->label. ( $cust_pkg +% ? ' ('. $cust_pkg->cust_main->name. ')' +% : '' +% ), +% ]; +% } +% @svc_broadband, +% ]; +% +<% encode_json($return) %>\ +% } +<%init> + +my $sub = $cgi->param('sub'); + + diff --git a/httemplate/view/svc_broadband.cgi b/httemplate/view/svc_broadband.cgi index 05b6ac56d..7d6520e57 100644 --- a/httemplate/view/svc_broadband.cgi +++ b/httemplate/view/svc_broadband.cgi @@ -36,6 +36,14 @@ my @fields = ( #'longitude', { field => 'coordinates', value_callback => \&coordinates }, 'altitude', + + 'radio_serialnum', + 'radio_location', + 'poe_location', + 'rssi', + 'suid', + { field => 'shared_svcnum', value_callback=> \&shared_svcnum, }, #value_callback => + 'vlan_profile', 'authkey', 'plan_id', @@ -112,9 +120,36 @@ sub coordinates { ); } +sub shared_svcnum { + my $svc_broadband = shift; + return '' unless $svc_broadband->shared_svcnum; + + my $shared_svc_broadband = + qsearchs('svc_broadband', { 'svcnum' => $svc_broadband->shared_svcnum, + } + #agent virt? + ) + or return ''; + my $shared_cust_pkg = $shared_svc_broadband->cust_svc->cust_pkg; + + $shared_svc_broadband->label. + ( $shared_cust_pkg + ? ' ('. $shared_cust_pkg->cust_main->name. ')' + : '' + ); +} + sub svc_callback { # trying to move to the callback style my ($cgi, $svc_x, $part_svc, $cust_pkg, $fields, $opt) = @_; + + if ( $part_svc->part_svc_column('latitude')->columnflag eq 'F' + && $part_svc->part_svc_column('longitude')->columnflag eq 'F' + ) + { + @$fields = grep { !ref($_) || $_->{field} ne 'coordinates' } @$fields; + } + # again, we assume at most one of these exports per part_svc my ($nas_export) = $part_svc->part_export('broadband_nas'); if ( $nas_export ) { -- cgit v1.2.1 From cd4196b482d216fe8a0e132d2e156134a3b56407 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 18 Apr 2013 22:49:14 -0700 Subject: uppercase company name in NACHA export format, RT#21597 --- FS/FS/pay_batch/nacha.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/pay_batch/nacha.pm b/FS/FS/pay_batch/nacha.pm index d0758f4b6..c069082c7 100644 --- a/FS/FS/pay_batch/nacha.pm +++ b/FS/FS/pay_batch/nacha.pm @@ -47,7 +47,7 @@ $DEBUG = 0; my $origin = $1; my $company = $conf->config('company_name', $pay_batch->agentnum); - $company = substr($company. (' 'x23), 0, 23); + $company = substr(uc($company). (' 'x23), 0, 23); my $now = time; -- cgit v1.2.1 From 110a9f8a594aa5cf5ac1cc9c91aee90fea67c949 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 19 Apr 2013 00:42:21 -0700 Subject: add fuzzy-fuzziness config, RT#22519 --- FS/FS/Conf.pm | 7 +++++++ FS/FS/cust_main/Search.pm | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 76f29bd59..6a19ff475 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -3823,6 +3823,13 @@ and customer address. Include units.', 'type' => 'checkbox', }, + { + 'key' => 'fuzzy-fuzziness', + 'section' => 'UI', + 'description' => 'Set the "fuzziness" of fuzzy searching (see the String::Approx manpage for details). Defaults to 10%', + 'type' => 'text', + }, + { 'key' => 'pkg_referral', 'section' => '', 'description' => 'Enable package-specific advertising sources.', diff --git a/FS/FS/cust_main/Search.pm b/FS/FS/cust_main/Search.pm index 9ec40cdd3..7dbb7a859 100644 --- a/FS/FS/cust_main/Search.pm +++ b/FS/FS/cust_main/Search.pm @@ -954,6 +954,11 @@ sub fuzzy_search { my @cust_main = (); + my @fuzzy_mod = 'i'; + my $conf = new FS::Conf; + my $fuzziness = $conf->config('fuzzy-fuzziness'); + push @fuzzy_mod, $fuzziness if $fuzziness; + check_and_rebuild_fuzzyfiles(); foreach my $field ( keys %$fuzzy ) { @@ -961,7 +966,7 @@ sub fuzzy_search { next unless scalar(@$all); my %match = (); - $match{$_}=1 foreach ( amatch( $fuzzy->{$field}, ['i'], @$all ) ); + $match{$_}=1 foreach ( amatch( $fuzzy->{$field}, \@fuzzy_mod, @$all ) ); next if !keys(%match); my $in_matches = 'IN (' . -- cgit v1.2.1 From 20aa565c8c1916a86a11726c33f087306f105164 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 19 Apr 2013 11:54:58 -0700 Subject: package contacts / "name per packages", RT#22185 --- httemplate/view/cust_main/packages/contact.html | 55 +++++++++++++++---------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index c3b161b70..dd78239ab 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -1,18 +1,15 @@ % if ( $contact ) { <% $contact->line |h %> +% if ( $show_link ) { + + ( <%pkg_change_contact_link($cust_pkg)%> ) + +% } +% } elsif ( $show_link ) { + + ( <%pkg_add_contact_link($cust_pkg)%> ) + % } - -% if ( ! $cust_pkg->get('cancel') -% && $FS::CurrentUser::CurrentUser->access_right('Change customer package') -% ) -% { - -%#XXX ( <%pkg_change_contact_link($cust_pkg)%> ) -%# % if ( $cust_pkg->contactnum ) { -%# ( <%edit_contact_link($cust_pkg->contactnum)%> ) -%# % } - -% } <%init> my $conf = new FS::Conf; @@ -20,27 +17,41 @@ my %opt = @_; my $cust_pkg = $opt{'cust_pkg'}; +my $show_link = + ! $cust_pkg->get('cancel') + && $FS::CurrentUser::CurrentUser->access_right('Change customer package'); + my $contact = $cust_pkg->contact_obj; sub pkg_change_contact_link { my $cust_pkg = shift; - my $pkgpart = $cust_pkg->pkgpart; + #my $pkgpart = $cust_pkg->pkgpart; include( '/elements/popup_link-cust_pkg.html', -#XXX - 'action' => $p. "misc/change_pkg.cgi?contactnum=-1", - 'label' => emt('Change contact'), + 'action' => $p. "misc/change_pkg_contact.html", + 'label' => emt('Change'), # contact'), 'actionlabel' => emt('Change'), 'cust_pkg' => $cust_pkg, ); } -sub edit_contact_link { - my $contactnum = shift; - include( '/elements/popup_link.html', - 'action' => $p. "edit/cust_contact.cgi?contactnum=$contactnum", - 'label' => emt('Edit contact'), - 'actionlabel' => emt('Edit'), +sub pkg_add_contact_link { + my $cust_pkg = shift; + #my $pkgpart = $cust_pkg->pkgpart; + include( '/elements/popup_link-cust_pkg.html', + 'action' => $p. "misc/change_pkg_contact.html", + 'label' => emt('Add contact'), + 'actionlabel' => emt('Change'), + 'cust_pkg' => $cust_pkg, ); } +#sub edit_contact_link { +# my $contactnum = shift; +# include( '/elements/popup_link.html', +# 'action' => $p. "edit/cust_contact.cgi?contactnum=$contactnum", +# 'label' => emt('Edit contact'), +# 'actionlabel' => emt('Edit'), +# ); +#} + -- cgit v1.2.1 From b279ca3f1c66ea5f589421196b7c5fc5f7163ec4 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 19 Apr 2013 12:35:02 -0700 Subject: avoid some redundant upgrades, #18548 --- FS/FS/cust_pay.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm index 7b01ff590..0e9e8a716 100644 --- a/FS/FS/cust_pay.pm +++ b/FS/FS/cust_pay.pm @@ -1063,6 +1063,8 @@ sub _upgrade_data { #class method warn "couldn't find paybatch history record for $table ".$object->$pkey."\n"; next; } + # if the paybatch didn't have an auth string, then it's fine + $h->paybatch =~ /:(\w+):/ or next; # set paybatch to what it was in that record $object->set('paybatch', $h->paybatch) # and then upgrade it like the old records -- cgit v1.2.1 From c0c1485222462c4df5aac8e209a865c984262d3c Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 19 Apr 2013 13:05:56 -0700 Subject: package contacts / "name per packages", RT#22185 --- httemplate/misc/change_pkg_contact.html | 70 +++++++++++++++++++++++++ httemplate/misc/process/change_pkg_contact.html | 49 +++++++++++++++++ httemplate/view/cust_main/packages/contact.html | 4 ++ 3 files changed, 123 insertions(+) create mode 100755 httemplate/misc/change_pkg_contact.html create mode 100644 httemplate/misc/process/change_pkg_contact.html diff --git a/httemplate/misc/change_pkg_contact.html b/httemplate/misc/change_pkg_contact.html new file mode 100755 index 000000000..d9da5beec --- /dev/null +++ b/httemplate/misc/change_pkg_contact.html @@ -0,0 +1,70 @@ +<& /elements/header-popup.html, mt("Change Package Contact") &> + +<& /elements/error.html &> + + + + +<% ntable('#cccccc') %> + + + + + + +% if ( $cust_pkg->contactnum ) { + + + + +% } + +<& /elements/tr-select-contact.html, + 'label' => mt('New Contact'), #XXX test + 'cgi' => $cgi, + 'cust_main' => $cust_pkg->cust_main, +&> + +
    <% mt('Customers') |h %> diff --git a/httemplate/search/unearned_detail.html b/httemplate/search/unearned_detail.html index 425aa5a4e..285fb50a7 100644 --- a/httemplate/search/unearned_detail.html +++ b/httemplate/search/unearned_detail.html @@ -114,13 +114,12 @@ if ( $cgi->param('status') =~ /^([a-z]+)$/ ) { push @where, "cust_bill._date >= $beginning", "cust_bill._date <= $ending"; -if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { - push @where, "cust_main.agentnum = $1"; -} - -if ( $cgi->param('cust_classnum') ) { - my @classnums = grep /^\d+$/, $cgi->param('cust_classnum'); - push @where, 'cust_main.classnum IN('.join(',',@classnums).')' +# cust_classnum (false laziness w/ elements/cust_main_dayranges.html, elements/cust_pay_or_refund.html, prepaid_income.html, cust_bill_pay.html, cust_bill_pkg.html, cust_bill_pkg_referral.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql) +if ( grep { $_ eq 'cust_classnum' } $cgi->param ) { + my @classnums = grep /^\d*$/, $cgi->param('cust_classnum'); + push @where, 'COALESCE( cust_main.classnum, 0) IN ( '. + join(',', map { $_ || '0' } @classnums ). + ' )' if @classnums; } -- cgit v1.2.1 From 2e761a72c380dc9d7320ccd822cfe8476534b369 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 14 Apr 2013 17:08:36 -0700 Subject: package contacts / "name per packages", RT#22185 --- FS/FS/Schema.pm | 1 + FS/FS/contact_Mixin.pm | 19 +++ FS/FS/cust_main/Packages.pm | 22 +++ FS/FS/cust_pkg.pm | 5 +- FS/MANIFEST | 2 + FS/t/contact_Mixin.t | 5 + httemplate/elements/contact.html | 6 +- httemplate/elements/tr-select-contact.html | 204 +++++++++++++++++++++++ httemplate/misc/order_pkg.html | 6 + httemplate/view/cust_main/packages.html | 7 +- httemplate/view/cust_main/packages/contact.html | 48 ++++++ httemplate/view/cust_main/packages/location.html | 4 - httemplate/view/cust_main/packages/package.html | 5 - httemplate/view/cust_main/packages/section.html | 17 +- httemplate/view/cust_main/packages/status.html | 2 +- 15 files changed, 323 insertions(+), 30 deletions(-) create mode 100644 FS/FS/contact_Mixin.pm create mode 100644 FS/t/contact_Mixin.t create mode 100644 httemplate/elements/tr-select-contact.html create mode 100644 httemplate/view/cust_main/packages/contact.html diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 924d0d999..bbf3b42fe 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1721,6 +1721,7 @@ sub tables_hashref { 'custnum', 'int', '', '', '', '', 'pkgpart', 'int', '', '', '', '', 'pkgbatch', 'varchar', 'NULL', $char_d, '', '', + 'contactnum', 'int', 'NULL', '', '', '', 'locationnum', 'int', 'NULL', '', '', '', 'otaker', 'varchar', 'NULL', 32, '', '', 'usernum', 'int', 'NULL', '', '', '', diff --git a/FS/FS/contact_Mixin.pm b/FS/FS/contact_Mixin.pm new file mode 100644 index 000000000..33cd3509a --- /dev/null +++ b/FS/FS/contact_Mixin.pm @@ -0,0 +1,19 @@ +package FS::contact_Mixin; + +use strict; +use FS::Record qw( qsearchs ); +use FS::contact; + +=item contact + +Returns the contact object, if any (see L). + +=cut + +sub contact { + my $self = shift; + return '' unless $self->contactnum; + qsearchs( 'contact', { 'contactnum' => $self->contactnum } ); +} + +1; diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm index 29e3bec13..f83bce915 100644 --- a/FS/FS/cust_main/Packages.pm +++ b/FS/FS/cust_main/Packages.pm @@ -100,6 +100,28 @@ sub order_pkg { local $FS::UID::AutoCommit = 0; my $dbh = dbh; + if ( $opt->{'contactnum'} and $opt->{'contactnum'} != -1 ) { + + $cust_pkg->contactnum($opt->{'contactnum'}); + + } elsif ( $opt->{'contact'} ) { + + if ( ! $opt->{'contact'}->contactnum ) { + # not inserted yet + my $error = $opt->{'contact'}->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "inserting contact (transaction rolled back): $error"; + } + } + $cust_pkg->contactnum($opt->{'contact'}->contactnum); + + #} else { + # + # $cust_pkg->contactnum(); + + } + if ( $opt->{'locationnum'} and $opt->{'locationnum'} != -1 ) { $cust_pkg->locationnum($opt->{'locationnum'}); diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index b2cb4139d..bb1b4e37a 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1,7 +1,8 @@ package FS::cust_pkg; use strict; -use base qw( FS::otaker_Mixin FS::cust_main_Mixin FS::location_Mixin +use base qw( FS::otaker_Mixin FS::cust_main_Mixin + FS::contact_Mixin FS::location_Mixin FS::m2m_Common FS::option_Common ); use vars qw($disable_agentcheck $DEBUG $me); use Carp qw(cluck); @@ -17,6 +18,7 @@ use FS::CurrentUser; use FS::cust_svc; use FS::part_pkg; use FS::cust_main; +use FS::contact; use FS::cust_location; use FS::pkg_svc; use FS::cust_bill_pkg; @@ -620,6 +622,7 @@ sub check { $self->ut_numbern('pkgnum') || $self->ut_foreign_key('custnum', 'cust_main', 'custnum') || $self->ut_numbern('pkgpart') + || $self->ut_foreign_keyn('contactnum', 'contact', 'contactnum' ) || $self->ut_foreign_keyn('locationnum', 'cust_location', 'locationnum') || $self->ut_numbern('start_date') || $self->ut_numbern('setup') diff --git a/FS/MANIFEST b/FS/MANIFEST index da4832d41..94232905e 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -490,6 +490,8 @@ FS/phone_type.pm t/phone_type.t FS/contact_email.pm t/contact_email.t +FS/contact_Mixin.pm +t/contact_Mixin.t FS/prospect_main.pm t/prospect_main.t FS/o2m_Common.pm diff --git a/FS/t/contact_Mixin.t b/FS/t/contact_Mixin.t new file mode 100644 index 000000000..89dcc37c5 --- /dev/null +++ b/FS/t/contact_Mixin.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::contact_Mixin; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/elements/contact.html b/httemplate/elements/contact.html index 490ba2303..3d5177612 100644 --- a/httemplate/elements/contact.html +++ b/httemplate/elements/contact.html @@ -2,9 +2,9 @@ - +
    -% if ( @contact_class ) { +% if ( @contact_class && ! $opt{name_only} ) { + <<%$th%> ALIGN="right" VALIGN="top"><% $opt{'label'} || emt('Service contact') %>> + + + + +<%init> + +#based on / kinda false laziness w/tr-select-cust_contact.html + +my $conf = new FS::Conf; + +my %opt = @_; +my $cgi = $opt{'cgi'}; +my $cust_pkg = $opt{'cust_pkg'}; +my $cust_main = $opt{'cust_main'}; +my $prospect_main = $opt{'prospect_main'}; +die "cust_main or prospect_main required" unless $cust_main or $prospect_main; + +my $contactnum = ''; +if ( $cgi->param('error') ) { + $cgi->param('contactnum') =~ /^(\-?\d*)$/ or die "illegal contactnum"; + $contactnum = $1; +} else { + if ( length($opt{'curr_value'}) ) { + $contactnum = $opt{'curr_value'}; + } elsif ($prospect_main) { + my @cust_contact = $prospect_main->cust_contact; + $contactnum = $cust_contact[0]->contactnum if scalar(@cust_contact)==1; + } else { #$cust_main + $cgi->param('contactnum') =~ /^(\-?\d*)$/ or die "illegal contactnum"; + $contactnum = $1; + } +} + +##probably could use explicit controls +#my $editable = $cust_main ? 0 : 1; #could use explicit control +my $editable = 0; +my $addnew = $cust_main ? 1 : ( $contactnum>0 ? 0 : 1 ); + +my @contact_fields = map "contactnum_$_", qw( first last ); + +my $contact; #the one that shows by default in the contact edit space +if ( $contactnum && $contactnum > 0 ) { + $contact = qsearchs('contact', { 'contactnum' => $contactnum } ) + or die "unknown contactnum"; +} else { + $contact = new FS::contact; + if ( $contactnum == -1 ) { + $contact->$_( $cgi->param($_) ) foreach @contact_fields; #XXX + } elsif ( $cust_pkg && $cust_pkg->contactnum ) { + my $pkg_contact = $cust_pkg->contact; + $contact->$_( $pkg_contact->$_ ) foreach @contact_fields; #XXX why are we making a new one gagain?? + $opt{'empty_label'} ||= 'package contact: '.$pkg_contact->line; + } elsif ( $cust_main ) { + $contact = new FS::contact; #I think + } +} + +my $contact_sort = sub { + lc($a->last) cmp lc($b->last) + or lc($a->first) cmp lc($b->first) +}; + +my @contact; +push @contact, $cust_main->cust_contact if $cust_main; +push @contact, $prospect_main->contact if $prospect_main; +push @contact, $contact + if !$cust_main && $contact && $contact->contactnum > 0 + && ! grep { $_->contactnum == $contact->contactnum } @contact; + +@contact = sort $contact_sort grep !$_->disabled, @contact; + +$contact = $contact[0] + if ( $prospect_main ) + && !$opt{'is_optional'} + && @contact; + +my $disabled = + ( $contactnum < 0 + || ( $editable && $contactnum ) + || ( $prospect_main + && !$opt{'is_optional'} && !@contact && $addnew + ) + ) + ? '' + : 'DISABLED'; + +my $th = $opt{'no_bold'} ? 'TD' : 'TH'; + + diff --git a/httemplate/misc/order_pkg.html b/httemplate/misc/order_pkg.html index 993ea366c..e09ba986d 100644 --- a/httemplate/misc/order_pkg.html +++ b/httemplate/misc/order_pkg.html @@ -93,6 +93,12 @@ &> % } +<& /elements/tr-select-contact.html, + 'cgi' => $cgi, + 'cust_main' => $cust_main, + 'prospect_main' => $prospect_main, +&> + % if ( $cgi->param('lock_locationnum') ) {
    + + +<% include('/elements/contact.html', + 'object' => $contact, + #'onchange' ? probably not + 'disabled' => $disabled, + 'name_only' => 1, + ) +%> + +
    -% if ( $conf->exists('cust_pkg-group_by_location') and $show_location ) { +% if ( $conf->exists('cust_pkg-group_by_location') ) { <& locations.html, 'cust_main' => $cust_main, 'packages' => $packages, @@ -113,7 +113,6 @@ table.usage { <& packages/section.html, 'cust_main' => $cust_main, 'packages' => $packages, - 'show_location' => $show_location, &>
    % } @@ -140,10 +139,6 @@ my $curuser = $FS::CurrentUser::CurrentUser; my( $packages, $num_old_packages ) = get_packages($cust_main, $conf); - -my $show_location = $conf->exists('cust_pkg-always_show_location') - || (grep $_->locationnum ne $cust_main->ship_locationnum, @$packages); - my $countrydefault = scalar($conf->config('countrydefault')) || 'US'; #subroutines diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html new file mode 100644 index 000000000..a6f8a4273 --- /dev/null +++ b/httemplate/view/cust_main/packages/contact.html @@ -0,0 +1,48 @@ +% if ( $contact ) { + <% $contact->line |h %> +% } + +% if ( ! $cust_pkg->get('cancel') +% && $FS::CurrentUser::CurrentUser->access_right('Change customer package') +% ) +% { + +%#XXX ( <%pkg_change_contact_link($cust_pkg)%> ) +%# % if ( $cust_pkg->contactnum ) { +%# ( <%edit_contact_link($cust_pkg->contactnum)%> ) +%# % } + +% } + +
    - % if ( $default ) {
    % } @@ -41,13 +39,11 @@ % } -
    - ( <% pkg_change_location_link($cust_pkg) %> ) - ( <% pkg_change_quantity_link($cust_pkg) %> ) diff --git a/httemplate/view/cust_main/packages/section.html b/httemplate/view/cust_main/packages/section.html index 8ea7a7d5f..5f54c0a36 100755 --- a/httemplate/view/cust_main/packages/section.html +++ b/httemplate/view/cust_main/packages/section.html @@ -3,9 +3,7 @@ % #my $width = $show_location ? 'WIDTH="25%"' : 'WIDTH="33%"'; <% mt('Package') |h %> <% mt('Status') |h %><% mt('Location') |h %><% mt('Contact/Location') |h %> <% mt('Services') |h %>
    + <& contact.html, %iopt &> + <& location.html, %iopt &> +
    + %#this should use cust_pkg->status and cust_pkg->statuscolor eventually -- cgit v1.2.1 From 6f97b139aca5de337dd8bfaa62959eda62a1607a Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sun, 14 Apr 2013 17:09:11 -0700 Subject: package contacts / "name per packages", RT#22185 --- httemplate/edit/process/quick-cust_pkg.cgi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi index 4ea4ace9e..0cc17d36b 100644 --- a/httemplate/edit/process/quick-cust_pkg.cgi +++ b/httemplate/edit/process/quick-cust_pkg.cgi @@ -70,6 +70,9 @@ my $quantity = $1 || 1; $cgi->param('refnum') =~ /^(\d*)$/ or die 'illegal refnum '. $cgi->param('refnum'); my $refnum = $1; +$cgi->param('contactnum') =~ /^(\-?\d*)$/ + or die 'illegal contactnum '. $cgi->param('contactnum'); +my $contactnum = $1; $cgi->param('locationnum') =~ /^(\-?\d*)$/ or die 'illegal locationnum '. $cgi->param('locationnum'); my $locationnum = $1; @@ -109,6 +112,7 @@ my %hash = ( : '' ), 'refnum' => $refnum, + 'contactnum' => $contactnum, 'locationnum' => $locationnum, 'discountnum' => $discountnum, #for the create a new discount case @@ -142,6 +146,14 @@ if ( $quotationnum ) { my %opt = ( 'cust_pkg' => $cust_pkg ); + if ( $contactnum == -1 ) { + my $contact = FS::contact->new({ + 'custnum' => scalar($cgi->param('custnum')), + map { $_ => scalar($cgi->param("contactnum_$_")) } qw( first last ) + }); + $opt{'contact'} = $contact; + } + if ( $locationnum == -1 ) { my $cust_location = FS::cust_location->new_or_existing({ map { $_ => scalar($cgi->param($_)) } -- cgit v1.2.1 From 458154df5fb1ebf983458007e266da130b706ef7 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 15 Apr 2013 19:18:53 -0700 Subject: add separate ACL for employee reports, RT#22516 --- FS/FS/AccessRight.pm | 2 ++ FS/FS/access_right.pm | 4 +++- httemplate/elements/menu.html | 10 ++++++---- httemplate/search/employee_audit.html | 2 +- httemplate/search/part_pkg.html | 2 +- httemplate/search/report_employee_audit.html | 2 +- httemplate/search/report_employee_commission.html | 2 +- 7 files changed, 15 insertions(+), 9 deletions(-) diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index a60d033d6..bfb39b4ad 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -305,6 +305,8 @@ tie my %rights, 'Tie::IxHash', 'Usage: Call Detail Records (CDRs)', 'Usage: Unrateable CDRs', 'Usage: Time worked', + { rightname=>'Employees: Commission Report', global=>1 }, + { rightname=>'Employees: Audit Report', global=>1 }, #{ rightname => 'List customers of all agents', global=>1 }, ], diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm index 0e8bf45a9..d370ba5d1 100644 --- a/FS/FS/access_right.pm +++ b/FS/FS/access_right.pm @@ -229,7 +229,9 @@ sub _upgrade_data { # class method 'Usage: Unrateable CDRs', ], 'Provision customer service' => [ 'Edit password' ], - + 'Financial reports' => [ 'Employees: Commission Report', + 'Employees: Audit Report', + ], ; foreach my $old_acl ( keys %onetime ) { diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 14d36c31d..5689b12d2 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -294,9 +294,11 @@ tie my %report_ticketing, 'Tie::IxHash', 'Advanced ticket reports' => [ $fsurl.'rt/Search/Build.html?NewQuery=1', 'List tickets by any criteria' ], ; -tie my %report_employees, 'Tie::IxHash', - 'Employee Commission Report' => [ $fsurl.'search/report_employee_commission.html', '' ], - 'Employee Audit Report' => [ $fsurl.'search/report_employee_audit.html', 'Employee audit report' ], +tie my %report_employees, 'Tie::IxHash'; +$report_employees{'Employee Commission Report'} = [ $fsurl.'search/report_employee_commission.html', '' ] + if $curuser->access_right('Employees: Commission Report'); +$report_employees{'Employee Audit Report'} = [ $fsurl.'search/report_employee_audit.html', 'Employee audit report' ] + if $curuser->access_right('Employees: Audit Report'); ; tie my %report_bill_event, 'Tie::IxHash', @@ -397,7 +399,7 @@ $report_menu{'Tickets'} = [ \%report_ticketing, 'Ticket reports' ] if $conf->config('ticket_system') ;#&& FS::TicketSystem->access_right(\%session, 'Something'); $report_menu{'Employees'} = [ \%report_employees, 'Employee reports' ] - if $curuser->access_right('Financial reports'); + if keys %report_employees; $report_menu{'Billing events'} = [ \%report_bill_event, 'Billing events' ] if $curuser->access_right('Billing event reports'); $report_menu{'Financial'} = [ \%report_financial, 'Financial reports' ] diff --git a/httemplate/search/employee_audit.html b/httemplate/search/employee_audit.html index 753c7bff3..2bc6ff46e 100644 --- a/httemplate/search/employee_audit.html +++ b/httemplate/search/employee_audit.html @@ -7,7 +7,7 @@ <%init> die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + unless $FS::CurrentUser::CurrentUser->access_right('Employees: Audit Report'); my %tables = ( cust_pay => 'Payments', diff --git a/httemplate/search/part_pkg.html b/httemplate/search/part_pkg.html index 2178346e2..a90f13c95 100644 --- a/httemplate/search/part_pkg.html +++ b/httemplate/search/part_pkg.html @@ -23,7 +23,7 @@ my $curuser = $FS::CurrentUser::CurrentUser; die "access denied" - unless $curuser->access_right('Financial reports'); + unless $curuser->access_right('Employees: Commission Report'); #that's all this does so far my $conf = new FS::Conf; my $money_char = $conf->config('money_char') || '$'; diff --git a/httemplate/search/report_employee_audit.html b/httemplate/search/report_employee_audit.html index 757b8232f..461849b76 100644 --- a/httemplate/search/report_employee_audit.html +++ b/httemplate/search/report_employee_audit.html @@ -23,7 +23,7 @@ <%init> die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + unless $FS::CurrentUser::CurrentUser->access_right('Employees: Audit Report'); my %tables = ( cust_pay => 'Payments', diff --git a/httemplate/search/report_employee_commission.html b/httemplate/search/report_employee_commission.html index 51afad3b5..ebfcae82d 100644 --- a/httemplate/search/report_employee_commission.html +++ b/httemplate/search/report_employee_commission.html @@ -25,6 +25,6 @@ <%init> die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + unless $FS::CurrentUser::CurrentUser->access_right('Employees: Commission Report'); -- cgit v1.2.1 From 90d53f2bfaac6b65afb211e81c1f9aa160da9e1c Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 16 Apr 2013 21:12:17 -0700 Subject: for exports with per-service machine selection, make sure there is always a machine selected, #17194, #22524 --- FS/FS/Schema.pm | 3 +- FS/FS/export_svc.pm | 50 +++++++++- FS/FS/part_export.pm | 168 ++++++++++++++++++++++++++------ FS/FS/svc_export_machine.pm | 4 + httemplate/edit/part_export.cgi | 81 ++++++++++----- httemplate/edit/process/part_export.cgi | 1 + 6 files changed, 249 insertions(+), 58 deletions(-) diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index bbf3b42fe..9f68a41de 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2729,9 +2729,10 @@ sub tables_hashref { 'columns' => [ 'exportnum', 'serial', '', '', '', '', 'exportname', 'varchar', 'NULL', $char_d, '', '', - 'machine', 'varchar', 'NULL', $char_d, '', '', + 'machine', 'varchar', 'NULL', $char_d, '', '', 'exporttype', 'varchar', '', $char_d, '', '', 'nodomain', 'char', 'NULL', 1, '', '', + 'default_machine','int', 'NULL', '', '', '', ], 'primary_key' => 'exportnum', 'unique' => [], diff --git a/FS/FS/export_svc.pm b/FS/FS/export_svc.pm index 0370f5f0b..b08f8f7c3 100644 --- a/FS/FS/export_svc.pm +++ b/FS/FS/export_svc.pm @@ -5,6 +5,7 @@ use vars qw( @ISA ); use FS::Record qw( qsearch qsearchs dbh ); use FS::part_export; use FS::part_svc; +use FS::svc_export_machine; @ISA = qw(FS::Record); @@ -209,6 +210,19 @@ sub insert { } #end of duplicate check, whew $error = $self->SUPER::insert; + + my $part_export = $self->part_export; + if ( !$error and $part_export->default_machine ) { + foreach my $cust_svc ( $self->part_svc->cust_svc ) { + my $svc_export_machine = FS::svc_export_machine->new({ + 'exportnum' => $self->exportnum, + 'svcnum' => $cust_svc->svcnum, + 'machinenum' => $part_export->default_machine, + }); + $error ||= $svc_export_machine->insert; + } + } + if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -251,7 +265,23 @@ Delete this record from the database. =cut -# the delete method can be inherited from FS::Record +sub delete { + my $self = shift; + my $dbh = dbh; + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + + my $error = $self->SUPER::delete; + foreach ($self->svc_export_machine) { + $error ||= $_->delete; + } + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; +} + =item replace OLD_RECORD @@ -307,6 +337,24 @@ sub part_svc { qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } ); } +=item svc_export_machine + +Returns all export hostname records (L) for this +combination of svcpart and exportnum. + +=cut + +sub svc_export_machine { + my $self = shift; + qsearch({ + 'table' => 'svc_export_machine', + 'select' => 'svc_export_machine.*', + 'addl_from' => 'JOIN cust_svc USING (svcnum)', + 'hashref' => { 'exportnum' => $self->exportnum }, + 'extra_sql' => ' AND cust_svc.svcpart = '.$self->svcpart, + }); +} + =back =head1 BUGS diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index 15ce9c059..28cb1419d 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -125,31 +125,14 @@ sub insert { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - my $error = $self->SUPER::insert(@_); + my $error = $self->SUPER::insert(@_) + || $self->replace; + # use replace to do all the part_export_machine and default_machine stuff if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; } - #kinda false laziness with process_m2name - my @machines = map { $_ =~ s/^\s+//; $_ =~ s/\s+$//; $_ } - grep /\S/, - split /[\n\r]{1,2}/, - $self->part_export_machine_textarea; - - foreach my $machine ( @machines ) { - - my $part_export_machine = new FS::part_export_machine { - 'exportnum' => $self->exportnum, - 'machine' => $machine, - }; - $error = $part_export_machine->insert; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } - } - $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; } @@ -217,6 +200,7 @@ or modified. sub replace { my $self = shift; + my $old = $self->replace_old; local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; @@ -228,12 +212,7 @@ sub replace { my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; - - my $error = $self->SUPER::replace(@_); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } + my $error; if ( $self->part_export_machine_textarea ) { @@ -258,6 +237,10 @@ sub replace { } } + if ( $self->default_machine_name eq $machine ) { + $self->default_machine( $part_export_machine{$machine}->machinenum ); + } + delete $part_export_machine{$machine}; #so we don't disable it below } else { @@ -272,11 +255,13 @@ sub replace { return $error; } + if ( $self->default_machine_name eq $machine ) { + $self->default_machine( $part_export_machine->machinenum ); + } } } - foreach my $part_export_machine ( values %part_export_machine ) { $part_export_machine->disabled('Y'); $error = $part_export_machine->replace; @@ -286,6 +271,48 @@ sub replace { } } + if ( $old->machine ne '_SVC_MACHINE' ) { + # then set up the default for any already-attached export_svcs + foreach my $export_svc ( $self->export_svc ) { + my @svcs = qsearch('cust_svc', { 'svcpart' => $export_svc->svcpart }); + foreach my $cust_svc ( @svcs ) { + my $svc_export_machine = FS::svc_export_machine->new({ + 'exportnum' => $self->exportnum, + 'svcnum' => $cust_svc->svcnum, + 'machinenum' => $self->default_machine, + }); + $error ||= $svc_export_machine->insert; + } + } + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } # if switching to selectable hosts + + } elsif ( $old->machine eq '_SVC_MACHINE' ) { + # then we're switching from selectable to non-selectable + foreach my $svc_export_machine ( + qsearch('svc_export_machine', { 'exportnum' => $self->exportnum }) + ) { + $error ||= $svc_export_machine->delete; + } + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + } + + $error = $self->SUPER::replace(@_); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + if ( $self->machine eq '_SVC_MACHINE' and ! $self->default_machine ) { + $dbh->rollback if $oldAutoCommit; + return "no default export host selected"; } $dbh->commit or die $dbh->errstr if $oldAutoCommit; @@ -308,6 +335,13 @@ sub check { || $self->ut_domainn('machine') || $self->ut_alpha('exporttype') ; + + if ( $self->machine eq '_SVC_MACHINE' ) { + $error ||= $self->ut_numbern('default_machine') + } else { + $self->set('default_machine', ''); + } + return $error if $error; $self->nodomain =~ /^(Y?)$/ or return "Illegal nodomain: ". $self->nodomain; @@ -471,7 +505,9 @@ sub _rebless { $self; } -=item svc_machine +=item svc_machine SVC_X + +Return the export hostname for SVC_X. =cut @@ -483,14 +519,33 @@ sub svc_machine { my $svc_export_machine = qsearchs('svc_export_machine', { 'svcnum' => $svc_x->svcnum, 'exportnum' => $self->exportnum, - }) - #would only happen if you add this export to existing services without a - #machine set then try to run exports without setting it... right? - or die "No hostname selected for ".($self->exportname || $self->exporttype); + }); + + if (!$svc_export_machine) { + warn "No hostname selected for ".($self->exportname || $self->exporttype); + return $self->default_export_machine->machine; + } return $svc_export_machine->part_export_machine->machine; } +=item default_export_machine + +Return the default export hostname for this export. + +=cut + +sub default_export_machine { + my $self = shift; + my $machinenum = $self->default_machine; + if ( $machinenum ) { + my $default_machine = FS::part_export_machine->by_key($machinenum); + return $default_machine->machine if $default_machine; + } + # this should not happen + die "no default export hostname for export ".$self->exportnum; +} + #these should probably all go away, just let the subclasses define em =item export_insert SVC_OBJECT @@ -703,6 +758,55 @@ sub _upgrade_data { #class method $error = $opt->replace; die $error if $error; } + # for exports that have selectable hostnames, make sure all services + # have a hostname selected + foreach my $part_export ( + qsearch('part_export', { 'machine' => '_SVC_MACHINE' }) + ) { + + my $exportnum = $part_export->exportnum; + my $machinenum = $part_export->default_machine; + if (!$machinenum) { + my ($first) = $part_export->part_export_machine; + if (!$first) { + # user intervention really is required. + die "Export $exportnum has no hostname options defined.\n". + "You must correct this before upgrading.\n"; + } + # warn about this, because we might not choose the right one + warn "Export $exportnum (". $part_export->exporttype. + ") has no default hostname. Setting to ".$first->machine."\n"; + $machinenum = $first->machinenum; + $part_export->set('default_machine', $machinenum); + my $error = $part_export->replace; + die $error if $error; + } + + # the service belongs to a service def that uses this export + # and there is not a hostname selected for this export for that service + my $join = ' JOIN export_svc USING ( svcpart )'. + ' LEFT JOIN svc_export_machine'. + ' ON ( cust_svc.svcnum = svc_export_machine.svcnum'. + ' AND export_svc.exportnum = svc_export_machine.exportnum )'; + + my @svcs = qsearch( { + 'select' => 'cust_svc.*', + 'table' => 'cust_svc', + 'addl_from' => $join, + 'extra_sql' => ' WHERE svcexportmachinenum IS NULL'. + ' AND export_svc.exportnum = '.$part_export->exportnum, + } ); + foreach my $cust_svc (@svcs) { + my $svc_export_machine = FS::svc_export_machine->new({ + 'exportnum' => $exportnum, + 'machinenum' => $machinenum, + 'svcnum' => $cust_svc->svcnum, + }); + my $error = $svc_export_machine->insert; + die $error if $error; + } + } + # pass downstream my %exports_in_use; $exports_in_use{ref $_} = 1 foreach qsearch('part_export', {}); diff --git a/FS/FS/svc_export_machine.pm b/FS/FS/svc_export_machine.pm index 10f7b6821..7ca20ccb6 100644 --- a/FS/FS/svc_export_machine.pm +++ b/FS/FS/svc_export_machine.pm @@ -40,6 +40,10 @@ fields are currently supported: primary key +=item exportnum + +Export definition, see L + =item svcnum Customer service, see L diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi index 4dd253be8..2897cf39d 100644 --- a/httemplate/edit/part_export.cgi +++ b/httemplate/edit/part_export.cgi @@ -2,6 +2,34 @@ <% include('/elements/error.html') %> +
    @@ -58,7 +86,6 @@ my $widget = new HTML::Widgets::SelectLayers( 'form_name' => 'dummy', 'form_action' => 'process/part_export.cgi', 'form_text' => [qw( exportnum exportname )], -# 'form_checkbox' => [qw()], 'html_between' => "
    \n", 'layer_callback' => sub { my $layer = shift; @@ -87,7 +114,8 @@ my $widget = new HTML::Widgets::SelectLayers( if ( $exports->{$layer}{svc_machine} ) { my( $N_CHK, $Y_CHK) = ( 'CHECKED', '' ); my( $machine_DISABLED, $pem_DISABLED) = ( '', 'DISABLED' ); - my $part_export_machine = ''; + my @part_export_machine; + my $default_machine = ''; if ( $cgi->param('svc_machine') eq 'Y' || $machine eq '_SVC_MACHINE' ) @@ -97,38 +125,43 @@ my $widget = new HTML::Widgets::SelectLayers( $machine_DISABLED = 'DISABLED'; $pem_DISABLED = ''; $machine = ''; - $part_export_machine = - $cgi->param('part_export_machine') - || join "\n", + @part_export_machine = $cgi->param('part_export_machine'); + if (!@part_export_machine) { + @part_export_machine = map $_->machine, grep ! $_->disabled, $part_export->part_export_machine; + } + $default_machine = + $cgi->param('default_machine_name') + || $part_export->default_export_machine; } - my $oc = qq(onChange="${layer}_svc_machine_changed(this)"); + my $oc = qq(onChange="svc_machine_changed(this, '$layer')"); $html .= qq[
    - Selected in each customer service from these choices - - - +
    + Selected in each customer service from these choices: + +
    + Default: + ' } else { $html .= qq(). ''; diff --git a/httemplate/edit/process/part_export.cgi b/httemplate/edit/process/part_export.cgi index bcb9c0df1..e0c470675 100644 --- a/httemplate/edit/process/part_export.cgi +++ b/httemplate/edit/process/part_export.cgi @@ -56,6 +56,7 @@ my $new = new FS::part_export ( { if ( $cgi->param('svc_machine') eq 'Y' ) { $new->machine('_SVC_MACHINE'); $new->part_export_machine_textarea( $cgi->param('part_export_machine') ); + $new->default_machine_name( $cgi->param('default_machine_name') ); } my $error; -- cgit v1.2.1 From b595a15e182ce891241bf710cd7dbaf84570edd4 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 16 Apr 2013 21:12:22 -0700 Subject: more useful qsearch error messages --- FS/FS/Record.pm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 42af68ca5..3d4bfae9c 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -458,7 +458,13 @@ sub qsearch { # grep defined( $record->{$_} ) && $record->{$_} ne '', @fields # ) or croak "Error executing \"$statement\": ". $sth->errstr; - $sth->execute or croak "Error executing \"$statement\": ". $sth->errstr; + my $ok = $sth->execute; + if (!$ok) { + my $error = "Error executing \"$statement\""; + $error .= ' (' . join(', ', map {"'$_'"} @value) . ')' if @value; + $error .= ': '. $sth->errstr; + croak $error; + } my $table = $stable[0]; my $pkey = ''; -- cgit v1.2.1 From 70703cceac85b646d72db2f71f82ca35f7a517dc Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 16 Apr 2013 22:27:25 -0700 Subject: fix stray /td tag --- httemplate/view/cust_main/packages/contact.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index a6f8a4273..87a7b02bd 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -13,8 +13,6 @@ %# % } % } - -
    <% $cell_style %> ID="<% $opt{input_id} || $opt{id}.'_input0' %>"><& search-svc_broadband.html, @_ &>
    <% mt('Package') |h %> + <% $curuser->option('show_pkgnum') ? $cust_pkg->pkgnum.': ' : '' %><% $part_pkg->pkg |h %> - <% $part_pkg->comment |h %> +
    <% mt('Current Contact') %> + <% $cust_pkg->contact_obj->line |h %> +
    + +
    +" +> + + + + + +<%init> + +my $conf = new FS::Conf; + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Change customer package'); + +my $pkgnum = scalar($cgi->param('pkgnum')); +$pkgnum =~ /^(\d+)$/ or die "illegal pkgnum $pkgnum"; +$pkgnum = $1; + +my $cust_pkg = + qsearchs({ + 'table' => 'cust_pkg', + 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', + 'hashref' => { 'pkgnum' => $pkgnum }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, + }) or die "unknown pkgnum $pkgnum"; + +my $cust_main = $cust_pkg->cust_main + or die "can't get cust_main record for custnum ". $cust_pkg->custnum. + " ( pkgnum ". cust_pkg->pkgnum. ")"; + +my $part_pkg = $cust_pkg->part_pkg; + + diff --git a/httemplate/misc/process/change_pkg_contact.html b/httemplate/misc/process/change_pkg_contact.html new file mode 100644 index 000000000..2795c1197 --- /dev/null +++ b/httemplate/misc/process/change_pkg_contact.html @@ -0,0 +1,49 @@ +<% header(emt("Package contact $past_method")) %> + + + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Change customer package'); + +#untaint pkgnum +my $pkgnum = $cgi->param('pkgnum'); +$pkgnum =~ /^(\d+)$/ or die "Illegal pkgnum"; +$pkgnum = $1; + +my $cust_pkg = qsearchs( 'cust_pkg', {'pkgnum'=>$pkgnum} ); #needs agent virt + +my $contactnum = $cgi->param('contactnum'); +$contactnum =~ /^(-?\d*)$/ or die "Illegal contactnum"; +$contactnum = $1; + +my $past_method = $cust_pkg->contactnum ? 'changed' : 'added'; + +my $error = ''; + +if ( $contactnum == -1 ) { + + #little false laziness w/edit/process/quick-cust_pkg.cgi, also the whole + # thing should be a single transaction + my $contact = new FS::contact { + 'custnum' => $cust_pkg->custnum, + map { $_ => scalar($cgi->param("contactnum_$_")) } qw( first last ) + }; + $error = $contact->insert; + $cust_pkg->contactnum( $contact->contactnum ); + +} else { + $cust_pkg->contactnum($contactnum); +} + +$error ||= $cust_pkg->replace; + +if ($error) { + $cgi->param('error', $error); + print $cgi->redirect(popurl(2). "change_pkg_contact.html?". $cgi->query_string ); +} + + diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index dd78239ab..93129915f 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -31,6 +31,8 @@ sub pkg_change_contact_link { 'label' => emt('Change'), # contact'), 'actionlabel' => emt('Change'), 'cust_pkg' => $cust_pkg, + 'width' => 616, + 'height' => 220, ); } @@ -42,6 +44,8 @@ sub pkg_add_contact_link { 'label' => emt('Add contact'), 'actionlabel' => emt('Change'), 'cust_pkg' => $cust_pkg, + 'width' => 616, + 'height' => 192, ); } -- cgit v1.2.1 From 8e83c67a7c8fdb375e9c48f6dac92b1fcd5b5e3a Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 19 Apr 2013 13:54:09 -0700 Subject: add "Only count paid bills" option to "Run only once for each time the package has been billed" condition, for commissions, RT#21040 --- FS/FS/part_event/Condition/once_perinv.pm | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/FS/FS/part_event/Condition/once_perinv.pm b/FS/FS/part_event/Condition/once_perinv.pm index f85a05665..1ee53b812 100644 --- a/FS/FS/part_event/Condition/once_perinv.pm +++ b/FS/FS/part_event/Condition/once_perinv.pm @@ -12,6 +12,15 @@ sub description { "Run only once for each time the package has been billed"; } # Run the event, at most, a number of times equal to the number of # distinct invoices that contain line items from this package. +sub option_fields { + ( + 'paid' => { 'label' => 'Only count paid bills', + 'type' => 'checkbox', + 'value' => 'Y', + }, + ) +} + sub eventtable_hashref { { 'cust_main' => 0, 'cust_bill' => 0, @@ -22,9 +31,15 @@ sub eventtable_hashref { sub condition { my($self, $cust_pkg, %opt) = @_; - my %invnum; - $invnum{$_->invnum} = 1 - foreach ( qsearch('cust_bill_pkg', { 'pkgnum' => $cust_pkg->pkgnum }) ); + my @cust_bill_pkg = qsearch('cust_bill_pkg', { pkgnum=>$cust_pkg->pkgnum }); + + @cust_bill_pkg = grep { ($_->owed_setup + $_->owed_recur) == 0 } + @cust_bill_pkg + if $self->option('paid'); + + my %invnum = (); + $invnum{$_->invnum} = 1 foreach @cust_bill_pkg; + my @events = qsearch( { 'table' => 'cust_event', 'hashref' => { 'eventpart' => $self->eventpart, @@ -40,6 +55,9 @@ sub condition { sub condition_sql { my( $self, $table ) = @_; + #paid flag not yet implemented here, but that's okay, a partial optimization + # is better than none + "( ( SELECT COUNT(distinct(invnum)) FROM cust_bill_pkg -- cgit v1.2.1 From d372a6b46727cd3d86f70e4c9c567a97f5f1f077 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 23 Apr 2013 11:36:54 -0700 Subject: option to show district on 3.0 tax report, #22137 --- FS/FS/cust_main_county.pm | 18 +++++++++--------- httemplate/search/report_tax.cgi | 11 +++++++---- httemplate/search/report_tax.html | 14 +++++++++++++- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/FS/FS/cust_main_county.pm b/FS/FS/cust_main_county.pm index 9a4990a9d..a61d67e11 100644 --- a/FS/FS/cust_main_county.pm +++ b/FS/FS/cust_main_county.pm @@ -147,13 +147,10 @@ If the taxname field is set, it will look like If the taxclass is set, then it will be "Anytown, Alameda County, CA, US (International)". -Currently it will not contain the district, even if the city+county+state -is not unique. - -OPTIONS may contain "no_taxclass" (hides taxclass) and/or "no_city" -(hides city). It may also contain "out", in which case, if this -region (district+city+county+state+country) contains no non-zero -taxes, the label will read "Out of taxable region(s)". +OPTIONS may contain "with_taxclass", "with_city", and "with_district" to show +those fields. It may also contain "out", in which case, if this region +(district+city+county+state+country) contains no non-zero taxes, the label +will read "Out of taxable region(s)". =cut @@ -175,12 +172,15 @@ sub label { my $label = $self->country; $label = $self->state.", $label" if $self->state; $label = $self->county." County, $label" if $self->county; - if (!$opt{no_city}) { + if ($opt{with_city}) { $label = $self->city.", $label" if $self->city; + if ($opt{with_district} and $self->district) { + $label = $self->district . ", $label"; + } } # ugly labels when taxclass and taxname are both non-null... # but this is how the tax report does it - if (!$opt{no_taxclass}) { + if ($opt{with_taxclass}) { $label = "$label (".$self->taxclass.')' if $self->taxclass; } $label = $self->taxname." ($label)" if $self->taxname; diff --git a/httemplate/search/report_tax.cgi b/httemplate/search/report_tax.cgi index 42a52d154..479b99044 100755 --- a/httemplate/search/report_tax.cgi +++ b/httemplate/search/report_tax.cgi @@ -250,8 +250,10 @@ my $conf = new FS::Conf; my $out = 'Out of taxable region(s)'; my %label_opt = ( out => 1 ); #enable 'Out of Taxable Region' label -$label_opt{no_city} = 1 unless $cgi->param('show_cities'); -$label_opt{no_taxclass} = 1 unless $cgi->param('show_taxclasses'); +$label_opt{with_city} = 1 if $cgi->param('show_cities'); +$label_opt{with_district} = 1 if $cgi->param('show_districts'); + +$label_opt{with_taxclass} = 1 if $cgi->param('show_taxclasses'); my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi); @@ -487,7 +489,8 @@ my $tot_tax = 0; my $tot_credit = 0; my @loc_params = qw(country state county); -push @loc_params, qw(city district) if $cgi->param('show_cities'); +push @loc_params, 'city' if $cgi->param('show_cities'); +push @loc_params, 'district' if $cgi->param('show_districts'); foreach my $r ( qsearch({ 'table' => 'cust_main_county', })) { my $taxnum = $r->taxnum; @@ -522,7 +525,7 @@ foreach my $r ( qsearch({ 'table' => 'cust_main_county', })) { } if ( $cgi->param('show_taxclasses') ) { - my $base_label = $r->label(%label_opt, 'no_taxclass' => 1); + my $base_label = $r->label(%label_opt, 'with_taxclass' => 0); $base_regions{$base_label} ||= { label => $base_label, diff --git a/httemplate/search/report_tax.html b/httemplate/search/report_tax.html index 2ab0e0b2e..8a207aafb 100755 --- a/httemplate/search/report_tax.html +++ b/httemplate/search/report_tax.html @@ -34,9 +34,21 @@ % if ( $city ) {
    Show cities
    Show districts
    diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html index 9ab262261..a6352e07a 100644 --- a/fs_selfservice/FS-SelfService/cgi/myaccount.html +++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html @@ -6,18 +6,13 @@ Hello <%= $name %>!

    <%= include('small_custview') %>
    -<%= unless ( $access_pkgnum ) { - $OUT .= qq!Balance: \$$balance

    !; - } - ''; -%> <%= $OUT .= qq! View All Invoices     !; %> <%= if ( $balance > 0 ) { - if (scalar(grep $_, @hide_payment_fields)) { + if (scalar(grep $_, @hide_payment_fields)) { # this sucks $OUT .= qq! Make a payment

    !; } else { $OUT .= qq! Make a payment
    !; diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html index 4a31b1258..cf719e849 100644 --- a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html +++ b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html @@ -23,37 +23,44 @@ unless ( $access_pkgnum ) { url=>'customer_order_pkg', 'indent'=>2 }; } +my %payby_mode; +@payby_mode{@cust_paybys} = @hide_payment_fields; +# $payby_mode{FOO} is true if FOO is thirdparty, false if it's B::OP, +# nonexistent if it's not supported + if ( $balance > 0 ) { #XXXFIXME "enable selfservice prepay features" flag or something, eventually per-pkg or something really fancy - #XXXFIXME still a bit sloppy for multi-gateway of differing namespace - my $i = 0; - while($i < scalar(@cust_paybys)) { last if $cust_paybys[$i] =~ /^CARD/; $i++ } - if ( $cust_paybys[$i] && $cust_paybys[$i] =~ /^CARD/ ) { + if ( exists( $payby_mode{CARD} ) ) { push @menu, { title => 'Recharge my account with a credit card', - url => $hide_payment_fields[$i] + url => $payby_mode{CARD} ? 'make_thirdparty_payment&payby_method=CC' : 'make_payment', indent => 2, } } - $i = 0; - while($i < scalar(@cust_paybys)) { last if $cust_paybys[$i] =~ /^CHEK/; $i++ } - if ( $cust_paybys[$i] && $cust_paybys[$i] =~ /^CHEK/ ) { + if ( exists( $payby_mode{CHEK} ) ) { push @menu, { title => 'Recharge my account with a check', - url => $hide_payment_fields[$i] + url => $payby_mode{CHEK} ? 'make_thirdparty_payment&payby_method=ECHECK' : 'make_ach_payment', indent => 2, } } - push @menu, { title => 'Recharge my account with a prepaid card', - url => 'recharge_prepay', - indent => 2, - } - if grep(/^PREP/, @cust_paybys); + if ( exists( $payby_mode{PREP} ) ) { + push @menu, { title => 'Recharge my account with a prepaid card', + url => 'recharge_prepay', + indent => 2, + } + } + if ( exists( $payby_mode{PPAL} ) ) { + push @menu, { title => 'Recharge my account with PayPal', + url => 'make_thirdparty_payment&payby_method=PAYPAL', + indent => 2, + } + } } push @menu, diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index f7fe308cf..40fe98af2 100755 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -667,12 +667,15 @@ sub make_thirdparty_payment { } sub post_thirdparty_payment { - $cgi->param('payby_method') =~ /^(CC|ECHECK)$/ + $cgi->param('payby_method') =~ /^(CC|ECHECK|PAYPAL)$/ or die "illegal payby method"; my $method = $1; $cgi->param('amount') =~ /^(\d+(\.\d*)?)$/ or die "illegal amount"; my $amount = $1; + # realtime_collect() returns the result from FS::cust_main->realtime_collect + # which returns realtime_bop() + # which returns a hashref of popup_url, collectitems, and reference my $result = realtime_collect( 'session_id' => $session_id, 'method' => $method, diff --git a/fs_selfservice/FS-SelfService/cgi/verify.cgi b/fs_selfservice/FS-SelfService/cgi/verify.cgi index d9346b897..ff209d2f9 100755 --- a/fs_selfservice/FS-SelfService/cgi/verify.cgi +++ b/fs_selfservice/FS-SelfService/cgi/verify.cgi @@ -87,11 +87,14 @@ my $rv = capture_payment( map { $_ => scalar($cgi->param($_)) } $cgi->param }, url => $cgi->self_url, + cancel => ($cgi->param('cancel') ? 1 : 0), ); $error = $rv->{error}; - -if ( $error eq '_decline' ) { + +if ( $error eq '_cancel' ) { + print_okay(%$rv); +} elsif ( $error eq '_decline' ) { print_decline(); } elsif ( $error ) { print_verify(); @@ -133,8 +136,14 @@ sub print_okay { $success_url .= '/signup.cgi?action=success'; } - print $cgi->header( '-expires' => 'now' ), - $success_template->fill_in( HASH => { success_url => $success_url } ); + if ( $param{error} eq '_cancel' ) { + # then the payment was canceled, so don't show a message, just redirect + # (during signup, you really need a separate landing page for this case) + print $cgi->redirect($success_url); + } else { + print $cgi->header( '-expires' => 'now' ), + $success_template->fill_in( HASH => { success_url => $success_url } ); + } } sub success_default { #html to use if you don't specify a success file diff --git a/httemplate/edit/agent_payment_gateway.html b/httemplate/edit/agent_payment_gateway.html index 4a7cedf79..41a9f3e95 100644 --- a/httemplate/edit/agent_payment_gateway.html +++ b/httemplate/edit/agent_payment_gateway.html @@ -34,6 +34,7 @@ for ' } - my $text .= qq! +ENDOUT + + $OUT .= domainselector( svcpart=>$default_svcpart, domsvc=>$default_domain ) + if $default_svcpart; + + $OUT .= < -- cgit v1.2.1 From a0b714142b349a36eee41a5de1e511758a382ffb Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 29 Apr 2013 12:31:06 -0700 Subject: add selectable domain option to signup, RT#21557 --- FS/FS/ClientAPI/Signup.pm | 4 ++-- FS/FS/Conf.pm | 4 ++-- fs_selfservice/FS-SelfService/SelfService.pm | 2 +- fs_selfservice/FS-SelfService/cgi/signup.html | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/FS/FS/ClientAPI/Signup.pm b/FS/FS/ClientAPI/Signup.pm index 895c5823e..16d6c8f3a 100644 --- a/FS/FS/ClientAPI/Signup.pm +++ b/FS/FS/ClientAPI/Signup.pm @@ -98,7 +98,7 @@ sub signup_info { my @signup_bools = qw( no_company recommend_daytime recommend_email ); - my @signup_server_scalars = qw( default_pkgpart default_svcpart default_domain ); + my @signup_server_scalars = qw( default_pkgpart default_svcpart default_domsvc ); my @selfservice_textareas = qw( head body_header body_footer ); @@ -670,7 +670,7 @@ sub new_customer { my $svc = new FS::svc_acct { 'svcpart' => $svcpart, map { $_ => $packet->{$_} } - qw( username _password sec_phrase popnum ), + qw( username _password sec_phrase popnum domsvc ), }; my @acct_snarf; diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index c93331d24..0db5d86cc 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -2164,9 +2164,9 @@ and customer address. Include units.', }, { - 'key' => 'signup_server-default_domain', + 'key' => 'signup_server-default_domsvc', 'section' => 'self-service', - 'description' => 'If specified, the default domain for signup (useful when domain is set to selectable choice).', + 'description' => 'If specified, the default domain svcpart for signup (useful when domain is set to selectable choice).', 'type' => 'text', }, diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 1fa67c2ad..d44f978a5 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -1799,7 +1799,7 @@ sub domainselector { '' } - my $text .= qq! ENDOUT - $OUT .= domainselector( svcpart=>$default_svcpart, domsvc=>$default_domain ) + $OUT .= domainselector( svcpart=>$default_svcpart, domsvc=>$default_domsvc ) if $default_svcpart; $OUT .= < Date: Mon, 29 Apr 2013 16:09:17 -0700 Subject: quote params correctly for HLR SIM export, #21514, --- FS/FS/part_export/huawei_hlr.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FS/FS/part_export/huawei_hlr.pm b/FS/FS/part_export/huawei_hlr.pm index 007981880..41cbbfb58 100644 --- a/FS/FS/part_export/huawei_hlr.pm +++ b/FS/FS/part_export/huawei_hlr.pm @@ -314,8 +314,8 @@ sub import_sim { # push IMSI/KI to the HLR my $return = $self->command($socket, @command, - 'IMSI', $imsi, - 'KIVALUE', $ki, + 'IMSI', qq{"$imsi"}, + 'KIVALUE', qq{"$ki"}, @args ); if ( $return->{success} ) { -- cgit v1.2.1 From 97c67d2bf226fbe1cea8aceef36c24c3c406b74f Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 29 Apr 2013 16:18:13 -0700 Subject: also indicate required export settings, --- FS/FS/part_export/huawei_hlr.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FS/FS/part_export/huawei_hlr.pm b/FS/FS/part_export/huawei_hlr.pm index 41cbbfb58..aa09a1c64 100644 --- a/FS/FS/part_export/huawei_hlr.pm +++ b/FS/FS/part_export/huawei_hlr.pm @@ -18,16 +18,16 @@ $DEBUG = 0; @ISA = qw(FS::part_export); tie my %options, 'Tie::IxHash', - 'opname' => { label=>'Operator login' }, - 'pwd' => { label=>'Operator password' }, + 'opname' => { label=>'Operator login (required)' }, + 'pwd' => { label=>'Operator password (required)' }, 'tplid' => { label=>'Template number' }, 'hlrsn' => { label=>'HLR serial number' }, 'k4sno' => { label=>'K4 serial number' }, - 'cardtype' => { label => 'Card type', + 'cardtype' => { label => 'Card type (required)', type => 'select', options=> ['SIM', 'USIM'] }, - 'alg' => { label => 'Authentication algorithm', + 'alg' => { label => 'Authentication algorithm (required)', type => 'select', options=> ['COMP128_1', 'COMP128_2', -- cgit v1.2.1 From 41466beaadfad0627adf5559d173e1bcc2829939 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 29 Apr 2013 18:17:03 -0700 Subject: add monthly cap to daily RADIUS usage, RT#22699 --- FS/FS/part_pkg/sqlradacct_daily.pm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/FS/FS/part_pkg/sqlradacct_daily.pm b/FS/FS/part_pkg/sqlradacct_daily.pm index d99def21b..d0d3e1006 100644 --- a/FS/FS/part_pkg/sqlradacct_daily.pm +++ b/FS/FS/part_pkg/sqlradacct_daily.pm @@ -66,8 +66,13 @@ use Date::Format; 'default' => 0, }, + 'monthly_cap' => { 'name' => 'Monthly (billing frequency) cap on all overage charges'. + ' (0 means no cap)', + 'default' => 0, + }, + }, - 'fieldorder' => [qw( recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap global_cap )], + 'fieldorder' => [qw( recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap global_cap monthly_cap )], 'weight' => 41, ); @@ -79,7 +84,7 @@ sub price_info { } #hacked-up false laziness w/sqlradacct_hour, -# but keeping it separate to start with is safer for existing folks +# but keeping it separate to start with is safer for existing folks sub calc_recur { my($self, $cust_pkg, $sdate, $details ) = @_; @@ -179,6 +184,10 @@ sub calc_recur { $day_start = $tomorrow; } + $charges = $self->option('monthly_cap') + if $self->option('monthly_cap') + && $charges > $self->option('monthly_cap'); + $self->option('recur_fee') + $charges; } -- cgit v1.2.1 From d02079cf51058085a7e62c33d747b141fe0a1c89 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 29 Apr 2013 18:52:42 -0700 Subject: allow @domain to be passed as part of a white/black-list, RT#20896 --- FS/FS/part_export/http_status.pm | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/FS/FS/part_export/http_status.pm b/FS/FS/part_export/http_status.pm index 80139e776..5c4a8d074 100644 --- a/FS/FS/part_export/http_status.pm +++ b/FS/FS/part_export/http_status.pm @@ -129,7 +129,7 @@ sub export_setstatus_listdel { } sub export_setstatus_listX { - my( $self, $svc_x, $action, $list, $address ) = @_; + my( $self, $svc_x, $action, $list, $address_item ) = @_; my $option; if ( $list =~ /^[WA]/i ) { #Whitelist/Allow @@ -139,8 +139,16 @@ sub export_setstatus_listX { } $option .= $action. '_url'; - $address = Email::Valid->address($address) - or die "address failed $Email::Valid::Details check.\n"; + my $address; + unless ( $address = Email::Valid->address($address_item) ) { + + if ( $address_item =~ /^(\@[\w\-\.]+\.\w{2,63})$/ ) { # "@domain" + $address = $1; + } else { + die "address failed $Email::Valid::Details check.\n"; + } + + } #some false laziness w/export_getstatus above my $url; -- cgit v1.2.1 From 78710489c60a996222b4d37552f78f1ff0ec138f Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 30 Apr 2013 22:35:36 -0700 Subject: fix signup with domain, RT#21557 --- fs_selfservice/FS-SelfService/cgi/signup.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs_selfservice/FS-SelfService/cgi/signup.html b/fs_selfservice/FS-SelfService/cgi/signup.html index 306e49749..a9b67592b 100755 --- a/fs_selfservice/FS-SelfService/cgi/signup.html +++ b/fs_selfservice/FS-SelfService/cgi/signup.html @@ -45,7 +45,7 @@ %> <%= - $OUT = join("\n", map { qq|| } qw / promo_code reg_code pkgpart username _password _password2 sec_phrase popnum mac_addr countrycode phonenum sip_password pin / ); + $OUT = join("\n", map { qq|| } qw / promo_code reg_code pkgpart username _password _password2 sec_phrase popnum domsvc mac_addr countrycode phonenum sip_password pin / ); %> <%= @@ -445,7 +445,7 @@ function fixup_form() { var signup_elements = new Array ( 'promo_code', 'reg_code', 'pkgpart', - 'username', '_password', '_password2', 'sec_phrase', 'popnum', + 'username', '_password', '_password2', 'sec_phrase', 'popnum', 'domsvc', 'mac_addr', 'countrycode', 'phonenum', 'sip_password', 'pin' ); -- cgit v1.2.1 From 51d26d73eb99d9f7f45591fa6a4b99c3a3429565 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 2 May 2013 01:10:45 -0700 Subject: detach a package into a new customer, RT#22185 --- FS/FS/Schema.pm | 1 + FS/FS/cust_pkg.pm | 48 +++++++++-- httemplate/edit/process/detach-cust_pkg.html | 47 +++++++++++ httemplate/misc/change_pkg_contact.html | 4 +- httemplate/misc/detach_pkg.html | 104 ++++++++++++++++++++++++ httemplate/view/cust_main/packages/contact.html | 14 ++++ httemplate/view/cust_main/packages/status.html | 36 +++++++- 7 files changed, 243 insertions(+), 11 deletions(-) create mode 100644 httemplate/edit/process/detach-cust_pkg.html create mode 100755 httemplate/misc/detach_pkg.html diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 4f395f285..bbc4f1d21 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1743,6 +1743,7 @@ sub tables_hashref { 'change_pkgnum', 'int', 'NULL', '', '', '', 'change_pkgpart', 'int', 'NULL', '', '', '', 'change_locationnum', 'int', 'NULL', '', '', '', + 'change_custnum', 'int', 'NULL', '', '', '', 'main_pkgnum', 'int', 'NULL', '', '', '', 'pkglinknum', 'int', 'NULL', '', '', '', 'manual_flag', 'char', 'NULL', 1, '', '', diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index be3acb9ee..d8b6e699e 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -862,6 +862,7 @@ sub cancel { my %hash = $self->hash; $date ? ($hash{'expire'} = $date) : ($hash{'cancel'} = $cancel_time); + $hash{'change_custnum'} = $options{'change_custnum'}; my $new = new FS::cust_pkg ( \%hash ); $error = $new->replace( $self, options => { $self->options } ); if ( $error ) { @@ -1703,6 +1704,11 @@ New locationnum, to change the location for this package. New FS::cust_location object, to create a new location and assign it to this package. +=item cust_main + +New FS::cust_main object, to create a new customer and assign the new package +to it. + =item pkgpart New pkgpart (see L). @@ -1818,12 +1824,25 @@ sub change { # 2. (more importantly) changing a package before it's billed $hash{'waive_setup'} = $self->waive_setup; + my $custnum = $self->custnum; + if ( $opt->{cust_main} ) { + my $cust_main = $opt->{cust_main}; + unless ( $cust_main->custnum) { + my $error = $cust_main->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "inserting cust_main (transaction rolled back): $error"; + } + } + $custnum = $cust_main->custnum; + } + # Create the new package. my $cust_pkg = new FS::cust_pkg { - custnum => $self->custnum, - pkgpart => ( $opt->{'pkgpart'} || $self->pkgpart ), - refnum => ( $opt->{'refnum'} || $self->refnum ), - locationnum => ( $opt->{'locationnum'} ), + custnum => $custnum, + pkgpart => ( $opt->{'pkgpart'} || $self->pkgpart ), + refnum => ( $opt->{'refnum'} || $self->refnum ), + locationnum => ( $opt->{'locationnum'} ), %hash, }; $error = $cust_pkg->insert( 'change' => 1, @@ -1919,7 +1938,7 @@ sub change { my $new = FS::cust_pkg->new({ pkgpart => $link->dst_pkgpart, pkglinknum => $link->pkglinknum, - custnum => $self->custnum, + custnum => $custnum, main_pkgnum => $cust_pkg->pkgnum, locationnum => $cust_pkg->locationnum, start_date => $cust_pkg->start_date, @@ -1960,9 +1979,10 @@ sub change { #because the new package will be billed for the same date range. #Supplemental packages are also canceled here. $error = $self->cancel( - quiet => 1, - unused_credit => $unused_credit, - nobill => $keep_dates + quiet => 1, + unused_credit => $unused_credit, + nobill => $keep_dates, + change_custnum => ( $self->custnum != $custnum ? $custnum : '' ), ); if ($error) { $dbh->rollback if $oldAutoCommit; @@ -2134,6 +2154,18 @@ sub old_cust_pkg { qsearchs('cust_pkg', { 'pkgnum' => $self->change_pkgnum } ); } +=item change_cust_main + +Returns the customter this package was detached to, if any. + +=cut + +sub change_cust_main { + my $self = shift; + return '' unless $self->change_custnum; + qsearchs('cust_main', { 'custnum' => $self->change_custnum } ); +} + =item calc_setup Calls the I of the FS::part_pkg object associated with this billing diff --git a/httemplate/edit/process/detach-cust_pkg.html b/httemplate/edit/process/detach-cust_pkg.html new file mode 100644 index 000000000..ab87eb536 --- /dev/null +++ b/httemplate/edit/process/detach-cust_pkg.html @@ -0,0 +1,47 @@ +% if ($error) { +% $cgi->param('error', $error); +% $cgi->redirect(popurl(3). 'misc/detach_pkg.html?'. $cgi->query_string ); +% } else { + + <% header(emt("Package detached")) %> + + + + +% } +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Change customer package'); + +my $cust_pkg = qsearchs({ + 'table' => 'cust_pkg', + 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', + 'hashref' => { 'pkgnum' => scalar($cgi->param('pkgnum')), }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, +}); +die 'unknown pkgnum' unless $cust_pkg; + +my $cust_location = new FS::cust_location { + map { $_ => scalar($cgi->param($_)) } FS::cust_main->location_fields +}; + +my $cust_main = new FS::cust_main { + ( map { ( $_, scalar($cgi->param($_)) ) } fields('cust_main') ), + ( map { ( "ship_$_", '' ) } FS::cust_main->location_fields ), + 'bill_location' => $cust_location, + 'ship_location' => $cust_location, +}; + +my $pkg_or_error = $cust_pkg->change( { + 'keep_dates' => 1, + 'cust_main' => $cust_main, +} ); + +my $error = ref($pkg_or_error) ? '' : $pkg_or_error; + + diff --git a/httemplate/misc/change_pkg_contact.html b/httemplate/misc/change_pkg_contact.html index d9da5beec..c88140ebf 100755 --- a/httemplate/misc/change_pkg_contact.html +++ b/httemplate/misc/change_pkg_contact.html @@ -9,7 +9,7 @@ - @@ -17,7 +17,7 @@ % if ( $cust_pkg->contactnum ) { - diff --git a/httemplate/misc/detach_pkg.html b/httemplate/misc/detach_pkg.html new file mode 100755 index 000000000..64b3e6e3f --- /dev/null +++ b/httemplate/misc/detach_pkg.html @@ -0,0 +1,104 @@ +<& /elements/header-popup.html, mt("Detach Package to New Customer") &> + + + +<& /elements/error.html &> + + + +% foreach my $f (qw( agentnum refnum )) { + +% } + +% foreach my $f (FS::cust_main->location_fields) { + +% } + +<% ntable('#cccccc') %> + + + + + + +% #always should be present for detaching, yes? #if ( $cust_pkg->contactnum ) { +% my $cust_contact = $cust_pkg->contact_obj; + + + + + + + + +% #} + + + + + + +
    <% ntable("#cccccc",2) %> @@ -127,7 +129,9 @@ function areyousure(href) { % } +% if ( $cust_svc ) { <& /elements/table-tickets.html, object => $cust_svc &> +% } <% joblisting({'svcnum'=>$svcnum}, 1) %> @@ -150,7 +154,7 @@ my $fields = $opt{'fields'} my $svcnum; if ( $cgi->param('svcnum') ) { - $cgi->param('svcnum') =~ /^(\d+)$/ or die "unparsable svcnum"; + $cgi->param('svcnum') =~ /^(\d+)$/ or die "unparseable svcnum"; $svcnum = $1; } else { my($query) = $cgi->keywords; @@ -170,19 +174,29 @@ my $svc_x = qsearchs({ }) or die "Unknown svcnum $svcnum in ". $opt{'table'}. " table\n"; my $cust_svc = $svc_x->cust_svc; -my($label, $value, $svcdb) = $cust_svc->label; +my ($label, $value, $svcdb, $part_svc ); +my $labels = $opt{labels}; #not -> here -my $part_svc = $cust_svc->part_svc; +if ( $cust_svc ) { + ($label, $value, $svcdb) = $cust_svc->label; -#false laziness w/edit/svc_Common.html -#override default labels with service-definition labels if applicable -my $labels = $opt{labels}; #not -> here -foreach my $field ( keys %$labels ) { - my $col = $part_svc->part_svc_column($field); - $labels->{$field} = $col->columnlabel if $col->columnlabel !~ /^\s*$/; + $part_svc = $cust_svc->part_svc; + + #false laziness w/edit/svc_Common.html + #override default labels with service-definition labels if applicable + foreach my $field ( keys %$labels ) { + my $col = $part_svc->part_svc_column($field); + $labels->{$field} = $col->columnlabel if $col->columnlabel !~ /^\s*$/; + } +} else { + $label = "Unlinked $table"; + $value = $svc_x->label; + $svcdb = $table; + # just to satisfy callbacks + $part_svc = FS::part_svc->new({ svcpart => 0, svcdb => $table }); } -my $pkgnum = $cust_svc->pkgnum; +my $pkgnum = $cust_svc->pkgnum if $cust_svc; my($cust_pkg, $custnum); if ($pkgnum) { diff --git a/httemplate/view/svc_Common.html b/httemplate/view/svc_Common.html index 7b46dc9c9..7e300b049 100644 --- a/httemplate/view/svc_Common.html +++ b/httemplate/view/svc_Common.html @@ -7,7 +7,7 @@ # false laziness w/edit/svc_Common.html -$cgi->param('svcdb') =~ /^(svc_\w+)$/ or die "unparsable svcdb"; +$cgi->param('svcdb') =~ /^(svc_\w+)$/ or die "unparseable svcdb"; my $table = $1; require "FS/$table.pm"; -- cgit v1.2.1 From f4ee951f84a23a683cff75ed8cfd88cf693e462c Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sat, 27 Apr 2013 15:18:40 -0700 Subject: when uncanceling services, clean up those that failed to export, from #22385 --- FS/FS/cust_pkg.pm | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 741d440fa..be3acb9ee 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1037,15 +1037,20 @@ sub uncancel { $dbh->rollback if $oldAutoCommit; return $svc_error; } else { + # if we've failed to insert the svc_x object, svc_Common->insert + # will have removed the cust_svc already. if not, then both records + # were inserted but we failed for some other reason (export, most + # likely). in that case, report the error and delete the records. push @svc_errors, $svc_error; - # is this necessary? svc_Common::insert already deletes the - # cust_svc if inserting svc_x fails. my $cust_svc = qsearchs('cust_svc', { 'svcnum' => $svc_x->svcnum }); if ( $cust_svc ) { - my $cs_error = $cust_svc->delete; - if ( $cs_error ) { + # except if export_insert failed, export_delete probably won't be + # much better + local $FS::svc_Common::noexport_hack = 1; + my $cleanup_error = $svc_x->delete; # also deletes cust_svc + if ( $cleanup_error ) { # and if THAT fails, then run away $dbh->rollback if $oldAutoCommit; - return $cs_error; + return $cleanup_error; } } } # svc_fatal -- cgit v1.2.1 From 00755aee33cc3ecdf3634bcc0f50f54814bfc400 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 29 Apr 2013 11:36:01 -0700 Subject: delete customer notes, #22296 --- httemplate/misc/delete-note.html | 11 +++++++++++ httemplate/view/cust_main/notes.html | 6 +++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 httemplate/misc/delete-note.html diff --git a/httemplate/misc/delete-note.html b/httemplate/misc/delete-note.html new file mode 100644 index 000000000..436326ff1 --- /dev/null +++ b/httemplate/misc/delete-note.html @@ -0,0 +1,11 @@ +<%init> +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Edit customer note'); + +my ($notenum) = $cgi->keywords; +$notenum =~ /^\d+$/ or die "bad notenum '$notenum'"; +my $note = FS::cust_main_note->by_key($notenum) + or die "notenum '$notenum' not found"; +$note->delete; + +<% $cgi->redirect($p.'view/cust_main.cgi?'.$note->custnum) %> diff --git a/httemplate/view/cust_main/notes.html b/httemplate/view/cust_main/notes.html index 1e9f464db..2de68ff46 100755 --- a/httemplate/view/cust_main/notes.html +++ b/httemplate/view/cust_main/notes.html @@ -63,7 +63,11 @@ % % my $edit = ''; % if ($curuser->access_right('Edit customer note') ) { -% $edit = qq! (!.emt('edit').')'; +% my $delete_url = $fsurl.'misc/delete-note.html?'.$notenum; +% $edit = qq! (!.emt('edit').')'. +% qq! !. +% '('.emt('delete').')'; % } % % if ( $last_classnum != $note->classnum && !$skipheader ) { -- cgit v1.2.1 From 7266a53154af0f0b2240d3de4f912c52670d67d0 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 29 Apr 2013 12:18:07 -0700 Subject: add selectable domain option to signup, RT#21557 --- FS/FS/ClientAPI/Signup.pm | 2 +- FS/FS/Conf.pm | 9 ++++++++- fs_selfservice/FS-SelfService/SelfService.pm | 3 ++- fs_selfservice/FS-SelfService/cgi/signup.cgi | 6 ++++-- fs_selfservice/FS-SelfService/cgi/signup.html | 6 ++++++ 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/FS/FS/ClientAPI/Signup.pm b/FS/FS/ClientAPI/Signup.pm index 1dbb20bc7..895c5823e 100644 --- a/FS/FS/ClientAPI/Signup.pm +++ b/FS/FS/ClientAPI/Signup.pm @@ -98,7 +98,7 @@ sub signup_info { my @signup_bools = qw( no_company recommend_daytime recommend_email ); - my @signup_server_scalars = qw( default_pkgpart default_svcpart ); + my @signup_server_scalars = qw( default_pkgpart default_svcpart default_domain ); my @selfservice_textareas = qw( head body_header body_footer ); diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 6a19ff475..c93331d24 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -2159,10 +2159,17 @@ and customer address. Include units.', { 'key' => 'signup_server-default_svcpart', 'section' => 'self-service', - 'description' => 'Default service definition for the signup server - only necessary for services that trigger special provisioning widgets (such as DID provisioning).', + 'description' => 'Default service definition for the signup server - only necessary for services that trigger special provisioning widgets (such as DID provisioning or domain selection).', 'type' => 'select-part_svc', }, + { + 'key' => 'signup_server-default_domain', + 'section' => 'self-service', + 'description' => 'If specified, the default domain for signup (useful when domain is set to selectable choice).', + 'type' => 'text', + }, + { 'key' => 'signup_server-mac_addr_svcparts', 'section' => 'self-service', diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 651a8f5cf..1fa67c2ad 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -1799,8 +1799,9 @@ sub domainselector { '
    Domain
    Domain
    Password
    Domain
    Domain
    <% mt('Package') |h %> + <% $curuser->option('show_pkgnum') ? $cust_pkg->pkgnum.': ' : '' %><% $part_pkg->pkg |h %> - <% $part_pkg->comment |h %>
    <% mt('Current Contact') %> + <% $cust_pkg->contact_obj->line |h %>
    <% mt('Package') |h %> + <% $curuser->option('show_pkgnum') ? $cust_pkg->pkgnum.': ' : '' %><% $part_pkg->pkg |h %> - <% $part_pkg->comment |h %> +
    <% mt('Name') %> + <% $cust_pkg->contact_obj->line |h %> +
    <% mt('Address') %> + + <% $loc->location_label( 'join_string' => '
    ', + 'double_space' => '   ', + 'escape_function' => \&encode_entities, + 'countrydefault' => $countrydefault, + ) + %> +
    + +%#XXX payment info +%#XXX should be sticky on errors... +<& /edit/cust_main/billing.html, FS::cust_main->new({}), + invoicing_list => [], + +&> + +
    +
    +" +> + +%#and a cancel button? or is the popup close sufficient? + + + + + +<%init> + +my $conf = new FS::Conf; +my $countrydefault = $conf->config('countrydefault') || 'US'; + +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" + unless $curuser->access_right('Change customer package'); + +my $pkgnum = scalar($cgi->param('pkgnum')); +$pkgnum =~ /^(\d+)$/ or die "illegal pkgnum $pkgnum"; +$pkgnum = $1; + +my $cust_pkg = + qsearchs({ + 'table' => 'cust_pkg', + 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', + 'hashref' => { 'pkgnum' => $pkgnum }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, + }) or die "unknown pkgnum $pkgnum"; + +my $loc = $cust_pkg->cust_location_or_main; + +my $cust_main = $cust_pkg->cust_main + or die "can't get cust_main record for custnum ". $cust_pkg->custnum. + " ( pkgnum ". cust_pkg->pkgnum. ")"; + +my $part_pkg = $cust_pkg->part_pkg; + + diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index 93129915f..4e0551b31 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -3,6 +3,7 @@ % if ( $show_link ) { ( <%pkg_change_contact_link($cust_pkg)%> ) + ( <%pkg_detach_link($cust_pkg)%> ) % } % } elsif ( $show_link ) { @@ -49,6 +50,19 @@ sub pkg_add_contact_link { ); } +sub pkg_detach_link { + my $cust_pkg = shift; + #my $pkgpart = $cust_pkg->pkgpart; + include( '/elements/popup_link-cust_pkg.html', + 'action' => $p. "misc/detach_pkg.html", + 'label' => emt('Detach'), + 'actionlabel' => emt('Detach'), + 'cust_pkg' => $cust_pkg, + 'width' => 616, + 'height' => 676, + ); +} + #sub edit_contact_link { # my $contactnum = shift; # include( '/elements/popup_link.html', diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html index 9d5a88e0f..24a4dfcd0 100644 --- a/httemplate/view/cust_main/packages/status.html +++ b/httemplate/view/cust_main/packages/status.html @@ -14,6 +14,8 @@ <% pkg_status_row($cust_pkg, emt('Cancelled'), 'cancel', 'color'=>'FF0000', %opt ) %> + <% pkg_status_row_detached($cust_pkg, %opt) %> + <% pkg_reason_row($cust_pkg, $cpr, color => 'ff0000', %opt) %> % unless ( $cust_pkg->get('setup') ) { @@ -29,7 +31,7 @@ % } % -% if ( $part_pkg->freq and !$supplemental ) { #? +% if ( $part_pkg->freq && !$supplemental && !$cust_pkg->change_custnum ) { #?
    > @@ -360,6 +362,38 @@ sub pkg_status_row_changed { $html; } +sub pkg_status_row_detached { + my( $cust_pkg, %opt ) = @_; + +warn $cust_pkg->pkgnum; +warn $cust_pkg->change_custnum; + + return '' unless $cust_pkg->change_custnum; + + my $html = ''; + + my $cust_main = $cust_pkg->change_cust_main; + if ( $cust_main ) { + + my $cust_link = ''. + encode_entities( $cust_main->name ). + ''; + + $html .= pkg_status_row_colspan( $cust_pkg, + emt("Detached to customer #[_1]: ", + $cust_pkg->change_custnum + ). + $cust_link, + '', + 'size' => '-1', + 'align' => 'right', + 'colspan' => 4, + ); + } + + $html; +} + sub pkg_status_row_noauto { my( $cust_pkg, %opt ) = @_; my $part_pkg = $opt{'part_pkg'}; -- cgit v1.2.1 From dfe6570a5d327350d93148633bef5eb8c1aaa9d3 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 2 May 2013 12:32:21 -0400 Subject: Fixed Rounding issue in summary --- FS/FS/pay_batch/BoM.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/pay_batch/BoM.pm b/FS/FS/pay_batch/BoM.pm index a3708d477..b609df351 100644 --- a/FS/FS/pay_batch/BoM.pm +++ b/FS/FS/pay_batch/BoM.pm @@ -59,7 +59,7 @@ $name = 'BoM'; footer => sub { my ($pay_batch, $batchcount, $batchtotal) = @_; sprintf( "YD%08u%014.0f%55s\n", $batchcount, $batchtotal*100, ""). #80 - sprintf( "Z%014u%05u%014u%05u%40s", #80 now + sprintf( "Z%014.0f%05u%014u%05u%40s", #80 now $batchtotal*100, $batchcount, "0", "0", ""); }, ); -- cgit v1.2.1 From c7f829cfde03b3a81b2bd3e642a82ee0bc845f5d Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 30 Apr 2013 15:06:32 -0700 Subject: unbreak location-grouped package display --- httemplate/view/cust_main/locations.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/view/cust_main/locations.html b/httemplate/view/cust_main/locations.html index b29d0ce4d..689c9a390 100755 --- a/httemplate/view/cust_main/locations.html +++ b/httemplate/view/cust_main/locations.html @@ -36,7 +36,7 @@ STYLE="padding-bottom: 0px; % }

    % } #foreach $locationnum -- cgit v1.2.1 From 7280c02bfea0defe3bec909e2de8a69c175ef61f Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 30 Apr 2013 21:05:49 -0700 Subject: transfer package balances on package change, #22597 --- FS/FS/cust_main/Billing.pm | 137 +++++++++++++++++++++++++++++++++++++++------ FS/FS/reason.pm | 37 ++++++++++++ 2 files changed, 156 insertions(+), 18 deletions(-) diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index 939a625c7..814802b34 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -437,6 +437,24 @@ sub bill { my @part_pkg = $cust_pkg->part_pkg->self_and_bill_linked; $options{has_hidden} = 1 if ($part_pkg[1] && $part_pkg[1]->hidden); + # if this package was changed from another package, + # and it hasn't been billed since then, + # and package balances are enabled, + if ( $cust_pkg->change_pkgnum + and $cust_pkg->change_date >= ($cust_pkg->last_bill || 0) + and $cust_pkg->change_date < $invoice_time + and $conf->exists('pkg-balances') ) + { + # _transfer_balance will also create the appropriate credit + my @transfer_items = $self->_transfer_balance($cust_pkg); + # $part_pkg[0] is the "real" part_pkg + my $pass = ($cust_pkg->no_auto || $part_pkg[0]->no_auto) ? + 'no_auto' : ''; + push @{ $cust_bill_pkg{$pass} }, @transfer_items; + # treating this as recur, just because most charges are recur... + ${$total_recur{$pass}} += $_->recur foreach @transfer_items; + } + foreach my $part_pkg ( @part_pkg ) { $cust_pkg->set($_, $hash{$_}) foreach qw ( setup last_bill bill ); @@ -1220,24 +1238,107 @@ sub _make_lines { } -# This is _handle_taxes. It's called once for each cust_bill_pkg generated -# from _make_lines, along with the part_pkg, cust_pkg, invoice time, the -# non-overridden pkgpart, a flag indicating whether the package is being -# canceled, and a partridge in a pear tree. -# -# The most important argument is 'taxlisthash'. This is shared across the -# entire invoice. It looks like this: -# { -# 'cust_main_county 1001' => [ [FS::cust_main_county], ... ], -# 'cust_main_county 1002' => [ [FS::cust_main_county], ... ], -# } -# -# 'cust_main_county' can also be 'tax_rate'. The first object in the array -# is always the cust_main_county or tax_rate identified by the key. -# -# That "..." is a list of FS::cust_bill_pkg objects that will be fed to -# the 'taxline' method to calculate the amount of the tax. This doesn't -# happen until calculate_taxes, though. +=item _transfer_balance TO_PKG [ FROM_PKGNUM ] + +Takes one argument, a cust_pkg object that is being billed. This will +be called only if the package was created by a package change, and has +not been billed since the package change, and package balance tracking +is enabled. The second argument can be an alternate package number to +transfer the balance from; this should not be used externally. + +Transfers the balance from the previous package (now canceled) to +this package, by crediting one package and creating an invoice item for +the other. Inserts the credit and returns the invoice item (so that it +can be added to an invoice that's being built). + +If the previous package was never billed, and was also created by a package +change, then this will also transfer the balance from I previous +package, and so on, until reaching a package that either has been billed +or was not created by a package change. + +=cut + +my $balance_transfer_reason; + +sub _transfer_balance { + my $self = shift; + my $cust_pkg = shift; + my $from_pkgnum = shift || $cust_pkg->change_pkgnum; + my $from_pkg = FS::cust_pkg->by_key($from_pkgnum); + + my @transfers; + + # if $from_pkg is not the first package in the chain, and it was never + # billed, walk back + if ( $from_pkg->change_pkgnum and scalar($from_pkg->cust_bill_pkg) == 0 ) { + @transfers = $self->_transfer_balance($cust_pkg, $from_pkg->change_pkgnum); + } + + my $prev_balance = $self->balance_pkgnum($from_pkgnum); + if ( $prev_balance != 0 ) { + $balance_transfer_reason ||= FS::reason->new_or_existing( + 'reason' => 'Package balance transfer', + 'type' => 'Internal adjustment', + 'class' => 'R' + ); + + my $credit = FS::cust_credit->new({ + 'custnum' => $self->custnum, + 'amount' => abs($prev_balance), + 'reasonnum' => $balance_transfer_reason->reasonnum, + '_date' => $cust_pkg->change_date, + }); + + my $cust_bill_pkg = FS::cust_bill_pkg->new({ + 'setup' => 0, + 'recur' => abs($prev_balance), + #'sdate' => $from_pkg->last_bill, # not sure about this + #'edate' => $cust_pkg->change_date, + 'itemdesc' => $self->mt('Previous Balance, [_1]', + $from_pkg->part_pkg->pkg), + }); + + if ( $prev_balance > 0 ) { + # credit the old package, charge the new one + $credit->set('pkgnum', $from_pkgnum); + $cust_bill_pkg->set('pkgnum', $cust_pkg->pkgnum); + } else { + # the reverse + $credit->set('pkgnum', $cust_pkg->pkgnum); + $cust_bill_pkg->set('pkgnum', $from_pkgnum); + } + my $error = $credit->insert; + die "error transferring package balance from #".$from_pkgnum. + " to #".$cust_pkg->pkgnum.": $error\n" if $error; + + push @transfers, $cust_bill_pkg; + } # $prev_balance != 0 + + return @transfers; +} + +=item _handle_taxes PART_PKG TAXLISTHASH CUST_BILL_PKG CUST_PKG TIME PKGPART [ OPTIONS ] + +This is _handle_taxes. It's called once for each cust_bill_pkg generated +from _make_lines, along with the part_pkg, cust_pkg, invoice time, the +non-overridden pkgpart, a flag indicating whether the package is being +canceled, and a partridge in a pear tree. + +The most important argument is 'taxlisthash'. This is shared across the +entire invoice. It looks like this: +{ + 'cust_main_county 1001' => [ [FS::cust_main_county], ... ], + 'cust_main_county 1002' => [ [FS::cust_main_county], ... ], +} + +'cust_main_county' can also be 'tax_rate'. The first object in the array +is always the cust_main_county or tax_rate identified by the key. + +That "..." is a list of FS::cust_bill_pkg objects that will be fed to +the 'taxline' method to calculate the amount of the tax. This doesn't +happen until calculate_taxes, though. + +=cut sub _handle_taxes { my $self = shift; diff --git a/FS/FS/reason.pm b/FS/FS/reason.pm index a9a7d745d..e6b20db8f 100644 --- a/FS/FS/reason.pm +++ b/FS/FS/reason.pm @@ -139,6 +139,43 @@ sub reasontype { =back +=head1 CLASS METHODS + +=over 4 + +=item new_or_existing reason => REASON, type => TYPE, class => CLASS + +Fetches the reason matching these parameters if there is one. If not, +inserts one. Will also insert the reason type if necessary. CLASS must +be one of 'C' (cancel reasons), 'R' (credit reasons), or 'S' (suspend reasons). + +This will die if anything fails. + +=cut + +sub new_or_existing { + my $class = shift; + my %opt = @_; + + my $error = ''; + my %hash = ('class' => $opt{'class'}, 'type' => $opt{'type'}); + my $reason_type = qsearchs('reason_type', \%hash) + || FS::reason_type->new(\%hash); + + $error = $reason_type->insert unless $reason_type->typenum; + die "error inserting reason type: $error\n" if $error; + + %hash = ('reason_type' => $reason_type->typenum, 'reason' => $opt{'reason'}); + my $reason = qsearchs('reason', \%hash) + || FS::reason->new(\%hash); + + $error = $reason->insert unless $reason->reasonnum; + die "error inserting reason: $error\n" if $error; + + $reason; +} + + =head1 BUGS Here by termintes. Don't use on wooden computers. -- cgit v1.2.1 From cc839bbae9c4615a5d3d2b0c7edcfb0bae58b0ec Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Thu, 2 May 2013 14:16:20 -0700 Subject: excel download fixes, #21937, #20337, etc. --- httemplate/search/cust_pay_pending.html | 5 ++--- .../search/elements/cust_main_dayranges.html | 9 +++++--- httemplate/search/elements/search-xls.html | 25 +++++++++++++++++++++- httemplate/search/h_cust_pay.html | 5 ++--- httemplate/search/unapplied_cust_pay.html | 5 ++--- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/httemplate/search/cust_pay_pending.html b/httemplate/search/cust_pay_pending.html index 2afce0ce9..54c9935ef 100755 --- a/httemplate/search/cust_pay_pending.html +++ b/httemplate/search/cust_pay_pending.html @@ -1,4 +1,4 @@ -<% include( 'elements/cust_pay_or_refund.html', +<& elements/cust_pay_or_refund.html, 'thing' => 'pay_pending', 'amount_field' => 'paid', 'name_singular' => 'pending payment', @@ -10,8 +10,7 @@ $status_sub, ], 'redirect_empty' => $redirect_empty, - ) -%> +&> <%init> my %statusaction = ( diff --git a/httemplate/search/elements/cust_main_dayranges.html b/httemplate/search/elements/cust_main_dayranges.html index cf2d495b1..493365281 100644 --- a/httemplate/search/elements/cust_main_dayranges.html +++ b/httemplate/search/elements/cust_main_dayranges.html @@ -2,10 +2,10 @@ Example: - include( 'elements/cust_main_dayranges.html', + <& elements/cust_main_dayranges.html, 'title' => 'Accounts Receivable Aging Summary', 'range_sub' => $mysub, - ) + &> my $mysub = sub { my( $start, $end ) = @_; @@ -44,7 +44,7 @@ Example: $row->{'rangecol_60_90'} ), sprintf( $money_char.'%.2f', $row->{'rangecol_90_0'} ), - sprintf( ''. $money_char.'%.2f'. '', + sprintf( ''.$money_char.'%.2f', $row->{'rangecol_0_0'} ), ('') x @pay_labels, ], @@ -81,6 +81,9 @@ Example: '', '', '', '', 'b', ( map '', @pay_labels ), ], + 'xls_format' => [ (map '', FS::UI::Web::cust_styles), + '', '', '', '', { bold => 1 }, + ], 'color' => [ FS::UI::Web::cust_colors(), '', diff --git a/httemplate/search/elements/search-xls.html b/httemplate/search/elements/search-xls.html index 26a51c4c7..bc844a579 100644 --- a/httemplate/search/elements/search-xls.html +++ b/httemplate/search/elements/search-xls.html @@ -6,6 +6,8 @@ my $header = $args{'header'}; my $rows = $args{'rows'}; my %opt = %{ $args{'opt'} }; +my $style = $opt{'style'}; + my $override = scalar(@$rows) >= 65536 ? 'XLSX' : ''; my $format = $FS::CurrentUser::CurrentUser->spreadsheet_format($override); @@ -42,6 +44,12 @@ my $header_format = $workbook->add_format( bg_color => 55, #22, bottom => 3, ); +my $footer_format = $workbook->add_format( + italic => 1, + locked => 1, + bg_color => 55, + top => 3, +); my $default_format = $workbook->add_format(locked => 0); my %money_format; @@ -50,10 +58,24 @@ my $money_char = FS::Conf->new->config('money_char') || '$'; my %date_format; xl_parse_date_init(); +my %bold_format; + my $writer = sub { # Wrapper for $worksheet->write. # Do any massaging of the value/format here. my ($r, $c, $value, $format) = @_; + #warn "writer called with format $format\n"; + + if ( $style->[$c] eq 'b' or $value =~ //i ) { # the only one in common use + $value =~ s[][]ig; + if ( !exists($bold_format{$format}) ) { + $bold_format{$format} = $workbook->add_format(); + $bold_format{$format}->copy($format); + $bold_format{$format}->set_bold(); + } + $format = $bold_format{$format}; + } + # convert HTML entities # both Spreadsheet::WriteExcel and Excel::Writer::XLSX accept UTF-8 strings $value = decode_entities($value); @@ -86,6 +108,7 @@ my $writer = sub { # String: replace line breaks with newlines $value =~ s/
    /\n/gi; } + #warn "writing with format $format\n"; $worksheet->write($r, $c, $value, $format); }; @@ -140,7 +163,7 @@ if ( $opt{'footer'} ) { if ( ref($item) eq 'CODE' ) { $item = &{$item}(); } - $writer->( $r, $c++, $item, $header_format ); + $writer->( $r, $c++, $item, $footer_format ); } } diff --git a/httemplate/search/h_cust_pay.html b/httemplate/search/h_cust_pay.html index 99330fadd..6d2dd9955 100755 --- a/httemplate/search/h_cust_pay.html +++ b/httemplate/search/h_cust_pay.html @@ -1,9 +1,8 @@ -<% include( 'elements/cust_pay_or_refund.html', +<& elements/cust_pay_or_refund.html, 'table' => 'h_cust_pay', 'amount_field' => 'paid', 'name_singular' => 'payment', 'name_verb' => 'paid', 'pre_header' => [ 'Transaction', 'By' ], 'pre_fields' => [ 'history_action', 'history_user' ], - ) -%> +&> diff --git a/httemplate/search/unapplied_cust_pay.html b/httemplate/search/unapplied_cust_pay.html index e232291fe..f5c2bf0f9 100755 --- a/httemplate/search/unapplied_cust_pay.html +++ b/httemplate/search/unapplied_cust_pay.html @@ -1,9 +1,8 @@ -<% include( 'elements/cust_main_dayranges.html', +<& elements/cust_main_dayranges.html, #'title' => 'Prepaid Balance Aging Summary', #??? 'title' => 'Unapplied Payments Aging Summary', 'range_sub' => \&unapplied_payments, - ) -%> +&> <%init> die "access denied" -- cgit v1.2.1 From 6b1b3797e7136fb617c32d467bb3281920318436 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Thu, 2 May 2013 16:21:56 -0700 Subject: "Without census tract" search should look at the service location, #22741, #940 --- FS/FS/cust_main/Search.pm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/FS/FS/cust_main/Search.pm b/FS/FS/cust_main/Search.pm index 7dbb7a859..e0c7080fe 100644 --- a/FS/FS/cust_main/Search.pm +++ b/FS/FS/cust_main/Search.pm @@ -624,14 +624,14 @@ sub search { # parse without census tract checkbox ## - push @where, "(censustract = '' or censustract is null)" + push @where, "(ship_location.censustract = '' or ship_location.censustract is null)" if $params->{'no_censustract'}; ## # parse with hardcoded tax location checkbox ## - push @where, "geocode is not null" + push @where, "ship_location.geocode is not null" if $params->{'with_geocode'}; ## @@ -841,7 +841,7 @@ sub search { 'ON (cust_main.'.$pre.'locationnum = '.$pre.'location.locationnum) '; } - my $count_query = "SELECT COUNT(*) FROM cust_main $extra_sql"; + my $count_query = "SELECT COUNT(*) FROM cust_main $addl_from $extra_sql"; my @select = ( 'cust_main.custnum', @@ -927,6 +927,8 @@ sub search { 'extra_headers' => \@extra_headers, 'extra_fields' => \@extra_fields, }; + warn Data::Dumper::Dumper($sql_query); + $sql_query; } -- cgit v1.2.1 From 4a3e900ad42a15a6a999e1d1461b816d7fac2230 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 2 May 2013 23:40:22 -0700 Subject: detach a package into a new customer, RT#22185 --- FS/FS/AccessRight.pm | 1 + FS/FS/access_right.pm | 1 + httemplate/view/cust_main/packages/contact.html | 25 ++++++++++++++++++------- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index bfb39b4ad..373617e36 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -132,6 +132,7 @@ tie my %rights, 'Tie::IxHash', 'Order customer package', 'One-time charge', 'Change customer package', + 'Detach customer package', 'Bulk change customer packages', 'Edit customer package dates', 'Discount customer package', #NEW diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm index d370ba5d1..5bcf92214 100644 --- a/FS/FS/access_right.pm +++ b/FS/FS/access_right.pm @@ -232,6 +232,7 @@ sub _upgrade_data { # class method 'Financial reports' => [ 'Employees: Commission Report', 'Employees: Audit Report', ], + 'Change customer package' => 'Detach customer package', ; foreach my $old_acl ( keys %onetime ) { diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index 4e0551b31..0c81eb39d 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -1,15 +1,18 @@ % if ( $contact ) { <% $contact->line |h %> -% if ( $show_link ) { +% if ( $show_change_link ) { ( <%pkg_change_contact_link($cust_pkg)%> ) + +% } +% if ( $show_detach_link ) { ( <%pkg_detach_link($cust_pkg)%> )
    % } -% } elsif ( $show_link ) { - - ( <%pkg_add_contact_link($cust_pkg)%> ) - +% } elsif ( $show_contact_link ) { + + ( <%pkg_add_contact_link($cust_pkg)%> ) + % } <%init> @@ -18,10 +21,18 @@ my %opt = @_; my $cust_pkg = $opt{'cust_pkg'}; -my $show_link = +my $show_change_link = ! $cust_pkg->get('cancel') && $FS::CurrentUser::CurrentUser->access_right('Change customer package'); +my $show_detach_link = + ! $cust_pkg->get('cancel') + && $FS::CurrentUser::CurrentUser->access_right('Detach customer package'); + +my $show_contact_link = + ! $cust_pkg->get('cancel') + ; #&& $FS::CurrentUser::CurrentUser->access_right('Add package contact'); #or something like that + my $contact = $cust_pkg->contact_obj; sub pkg_change_contact_link { @@ -43,7 +54,7 @@ sub pkg_add_contact_link { include( '/elements/popup_link-cust_pkg.html', 'action' => $p. "misc/change_pkg_contact.html", 'label' => emt('Add contact'), - 'actionlabel' => emt('Change'), + 'actionlabel' => emt('Add contact'), 'cust_pkg' => $cust_pkg, 'width' => 616, 'height' => 192, -- cgit v1.2.1 From e0d4d66f670371a0c8a40dc471352634f9fd6017 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 3 May 2013 00:31:07 -0700 Subject: merging is now attaching by default, with the old destructive merge operation as an option when deletecustomers is enabled, RT#22185 --- FS/FS/cust_main/Packages.pm | 76 +++++++++++++++++++++++++++++++++++- FS/FS/cust_pkg.pm | 2 +- httemplate/misc/cust_main-merge.html | 12 +++++- httemplate/misc/merge_cust.html | 42 +++++++++++++++++--- httemplate/view/cust_main.cgi | 11 ++++-- 5 files changed, 132 insertions(+), 11 deletions(-) diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm index f83bce915..e904cfd1f 100644 --- a/FS/FS/cust_main/Packages.pm +++ b/FS/FS/cust_main/Packages.pm @@ -4,7 +4,7 @@ use strict; use vars qw( $DEBUG $me ); use List::Util qw( min ); use FS::UID qw( dbh ); -use FS::Record qw( qsearch ); +use FS::Record qw( qsearch qsearchs ); use FS::cust_pkg; use FS::cust_svc; @@ -291,6 +291,80 @@ sub order_pkgs { ''; #no error } +=item attach_pkgs + +Merges this customer's package's into the target customer and then cancels them. + +=cut + +sub attach_pkgs { + my( $self, $new_custnum ) = @_; + + #mostly false laziness w/ merge + + return "Can't attach packages to self" if $self->custnum == $new_custnum; + + my $new_cust_main = qsearchs( 'cust_main', { 'custnum' => $new_custnum } ) + or return "Invalid new customer number: $new_custnum"; + + return 'Access denied: "Merge customer across agents" access right required to merge into a customer of a different agent' + if $self->agentnum != $new_cust_main->agentnum + && ! $FS::CurrentUser::CurrentUser->access_right('Merge customer across agents'); + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + if ( qsearch('agent', { 'agent_custnum' => $self->custnum } ) ) { + $dbh->rollback if $oldAutoCommit; + return "Can't merge a master agent customer"; + } + + #use FS::access_user + if ( qsearch('access_user', { 'user_custnum' => $self->custnum } ) ) { + $dbh->rollback if $oldAutoCommit; + return "Can't merge a master employee customer"; + } + + if ( qsearch('cust_pay_pending', { 'custnum' => $self->custnum, + 'status' => { op=>'!=', value=>'done' }, + } + ) + ) { + $dbh->rollback if $oldAutoCommit; + return "Can't merge a customer with pending payments"; + } + + #end of false laziness + + foreach my $cust_pkg ( $self->ncancelled_pkgs ) { + + my $pkg_or_error = $cust_pkg->change( { + 'keep_dates' => 1, + 'cust_main' => $new_cust_main, + } ); + + my $error = ref($pkg_or_error) ? '' : $pkg_or_error; + + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; #no error + +} + =item all_pkgs [ OPTION => VALUE... | EXTRA_QSEARCH_PARAMS_HASHREF ] Returns all packages (see L) for this customer. diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index d8b6e699e..df5a4dc01 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1827,7 +1827,7 @@ sub change { my $custnum = $self->custnum; if ( $opt->{cust_main} ) { my $cust_main = $opt->{cust_main}; - unless ( $cust_main->custnum) { + unless ( $cust_main->custnum ) { my $error = $cust_main->insert; if ( $error ) { $dbh->rollback if $oldAutoCommit; diff --git a/httemplate/misc/cust_main-merge.html b/httemplate/misc/cust_main-merge.html index 4decbef7a..3b4425fc8 100755 --- a/httemplate/misc/cust_main-merge.html +++ b/httemplate/misc/cust_main-merge.html @@ -31,7 +31,17 @@ if ( $cgi->param('new_custnum') =~ /^(\d+)$/ ) { } ); die "No customer # $custnum" unless $cust_main; - $error = $cust_main->merge($new_custnum); + if ( $cgi->param('merge') eq 'Y' ) { + + #old-style merge: everything + delete old customer + $error = $cust_main->merge($new_custnum); + + } else { + + #new-style attach: move packages 3.0 style, that's it + $error = $cust_main->attach_pkgs($new_custnum); + + } } else { $error = 'Select a customer to merge into'; diff --git a/httemplate/misc/merge_cust.html b/httemplate/misc/merge_cust.html index ad075be2f..9c869fa21 100644 --- a/httemplate/misc/merge_cust.html +++ b/httemplate/misc/merge_cust.html @@ -1,6 +1,6 @@ -<% include('/elements/header-popup.html', 'Merge customer' ) %> +<& /elements/header-popup.html, 'Merge customer' &> -<% include('/elements/error.html') %> +<& /elements/error.html &>
    @@ -35,13 +35,43 @@ function do_submit_merge() { - <% include('/elements/tr-search-cust_main.html', + + <& /elements/tr-search-cust_main.html, 'label' => 'Merge into: ', 'field' => 'new_custnum', 'find_button' => 1, 'curr_value' => scalar($cgi->param('new_custnum')), - ) - %> + &> + +% if ( $conf->exists('deletecustomers') ) { + +% if ( scalar($cust_main->ncancelled_pkgs) ) { + + + +% } else { +% $cgi->param('merge', 'Y'); +% } + + + + +% } +
    + <& /elements/radio.html, + 'field' => 'merge', + 'value' => '', + 'curr_value' => scalar($cgi->param('merge')), + &> + Merge packages only. +
    + <& /elements/radio.html, + 'field' => 'merge', + 'value' => 'Y', + 'curr_value' => scalar($cgi->param('merge')), + &> + Merge invoices, payments/credits, notes, tickets and delete this customer. +

    @@ -54,6 +84,8 @@ function do_submit_merge() { <%init> +my $conf = new FS::Conf; + $cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum'; my $custnum = $1; diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi index ec3191971..be0100fb3 100755 --- a/httemplate/view/cust_main.cgi +++ b/httemplate/view/cust_main.cgi @@ -91,14 +91,19 @@ function areyousure(href, message) { &> | % } -% if ( $curuser->access_right('Merge customer') ) { +% if ( $curuser->access_right('Merge customer') +% and ( scalar($cust_main->ncancelled_pkgs) +% || $conf->exists('deletecustomers') +% ) +% ) +% { <& /elements/popup_link-cust_main.html, { 'action' => $p. 'misc/merge_cust.html', 'label' => emt('Merge this customer'), 'actionlabel' => emt('Merge customer'), 'cust_main' => $cust_main, - 'width' => 480, - 'height' => 192, + 'width' => 569, + 'height' => 210, } &> | % } -- cgit v1.2.1 From 71c6403be78e91e34d4124da35c9d0d284ad197d Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 4 May 2013 00:19:30 -0700 Subject: merging is now attaching, RT#22185 --- FS/FS/cust_main/Packages.pm | 34 +++++++++++++++++++++++-- FS/FS/cust_pkg.pm | 2 ++ httemplate/view/cust_main/packages/contact.html | 3 ++- httemplate/view/cust_main/packages/section.html | 12 ++++++++- httemplate/view/cust_main/packages/status.html | 7 +++-- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm index e904cfd1f..41ef22894 100644 --- a/FS/FS/cust_main/Packages.pm +++ b/FS/FS/cust_main/Packages.pm @@ -7,6 +7,8 @@ use FS::UID qw( dbh ); use FS::Record qw( qsearch qsearchs ); use FS::cust_pkg; use FS::cust_svc; +use FS::contact; # for attach_pkgs +use FS::cust_location; # $DEBUG = 0; $me = '[FS::cust_main::Packages]'; @@ -344,11 +346,39 @@ sub attach_pkgs { #end of false laziness + #pull in contact + + my %contact_hash = ( 'first' => $self->first, + 'last' => $self->get('last'), + 'custnum' => $new_custnum, + 'disabled' => '', + ); + + my $contact = qsearchs( 'contact', \%contact_hash) + || new FS::contact \%contact_hash; + unless ( $contact->contactnum ) { + my $error = $contact->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + foreach my $cust_pkg ( $self->ncancelled_pkgs ) { + my $cust_location = $cust_pkg->cust_location || $self->ship_location; + my %loc_hash = $cust_location->hash; + $loc_hash{'locationnum'} = ''; + $loc_hash{'custnum'} = $new_custnum; + $loc_hash{'disabled'} = ''; + my $new_cust_location = qsearchs( 'cust_location', \%loc_hash) + || new FS::cust_location \%loc_hash; + my $pkg_or_error = $cust_pkg->change( { - 'keep_dates' => 1, - 'cust_main' => $new_cust_main, + 'keep_dates' => 1, + 'cust_main' => $new_cust_main, + 'contactnum' => $contact->contactnum, + 'cust_location' => $new_cust_location, } ); my $error = ref($pkg_or_error) ? '' : $pkg_or_error; diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index df5a4dc01..4464aa5a2 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1837,6 +1837,8 @@ sub change { $custnum = $cust_main->custnum; } + $hash{'contactnum'} = $opt->{'contactnum'} if $opt->{'contactnum'}; + # Create the new package. my $cust_pkg = new FS::cust_pkg { custnum => $custnum, diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html index 0c81eb39d..fe8b71534 100644 --- a/httemplate/view/cust_main/packages/contact.html +++ b/httemplate/view/cust_main/packages/contact.html @@ -6,6 +6,7 @@ % } % if ( $show_detach_link ) { + ( <%pkg_detach_link($cust_pkg)%> ) % } @@ -70,7 +71,7 @@ sub pkg_detach_link { 'actionlabel' => emt('Detach'), 'cust_pkg' => $cust_pkg, 'width' => 616, - 'height' => 676, + 'height' => 684, ); } diff --git a/httemplate/view/cust_main/packages/section.html b/httemplate/view/cust_main/packages/section.html index 5f54c0a36..391a13b5f 100755 --- a/httemplate/view/cust_main/packages/section.html +++ b/httemplate/view/cust_main/packages/section.html @@ -28,7 +28,7 @@ <& package.html, %iopt &> <& status.html, %iopt &> - <& contact.html, %iopt &> + <& contact.html, %iopt &>
    <& location.html, %iopt &> <& services.html, %iopt &> @@ -59,6 +59,15 @@ my $packages = $opt{'packages'}; ( $a->getfield('pkgnum') <=> $b->getfield('pkgnum') ) } @$packages; +my %change_custnum = map { $_->change_custnum => 1 } + grep { $_->change_custnum } + grep { $_->getfield('cancel') } + @$packages; + +my $pkg_attached = ( scalar(keys %change_custnum) == 1 + && ! grep { ! $_->getfield('cancel') } @$packages + ); + my $countrydefault = scalar($conf->config('countrydefault')) || 'US'; my %conf_opt = ( @@ -67,6 +76,7 @@ my %conf_opt = ( || $curuser->option('cust_pkg-display_times')), #for status.html 'cust_pkg-show_autosuspend' => $conf->exists('cust_pkg-show_autosuspend'), + 'pkg_attached' => $pkg_attached, #for status.html pkg-balances 'pkg-balances' => $conf->exists('pkg-balances'), 'money_char' => ( $conf->config('money_char') || '$' ), diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html index 24a4dfcd0..c0213e90b 100644 --- a/httemplate/view/cust_main/packages/status.html +++ b/httemplate/view/cust_main/packages/status.html @@ -365,9 +365,6 @@ sub pkg_status_row_changed { sub pkg_status_row_detached { my( $cust_pkg, %opt ) = @_; -warn $cust_pkg->pkgnum; -warn $cust_pkg->change_custnum; - return '' unless $cust_pkg->change_custnum; my $html = ''; @@ -379,8 +376,10 @@ warn $cust_pkg->change_custnum; encode_entities( $cust_main->name ). ''; + my $what = $opt{'pkg_attached'} ? 'Attached' : 'Detached'; + $html .= pkg_status_row_colspan( $cust_pkg, - emt("Detached to customer #[_1]: ", + emt("$what to customer #[_1]: ", $cust_pkg->change_custnum ). $cust_link, -- cgit v1.2.1 From 786d21e09d1f11c8976a8d45ef734d2d0a100ee7 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sun, 5 May 2013 16:44:26 -0700 Subject: allow certain minor location edits without moving packages, #940 --- FS/FS/cust_bill_pkg.pm | 15 ++-- FS/FS/cust_location.pm | 100 +++++++++++++++++++++------ FS/FS/cust_main.pm | 38 ++-------- FS/FS/cust_main/Packages.pm | 11 ++- FS/FS/cust_pkg.pm | 16 ++--- FS/FS/svc_phone.pm | 5 +- httemplate/edit/process/change-cust_pkg.html | 2 +- httemplate/edit/process/cust_location.cgi | 6 +- httemplate/edit/process/cust_main.cgi | 4 +- httemplate/edit/process/quick-cust_pkg.cgi | 2 +- httemplate/edit/process/svc_phone.html | 2 +- 11 files changed, 111 insertions(+), 90 deletions(-) diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index d8cbf5915..0c8c0bbbf 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -1104,15 +1104,12 @@ sub upgrade_tax_location { delete @hash{qw(censustract censusyear latitude longitude coord_auto)}; $hash{custnum} = $h_cust_main->custnum; - my $tax_loc = FS::cust_location->new_or_existing(\%hash); - if ( !$tax_loc->locationnum ) { - $tax_loc->disabled('Y'); - my $error = $tax_loc->insert; - if ( $error ) { - warn "couldn't create historical location record for cust#". - $h_cust_main->custnum.": $error\n"; - next INVOICE; - } + my $tax_loc = FS::cust_location->new(\%hash); + my $error = $tax_loc->find_or_insert || $tax_loc->disable_if_unused; + if ( $error ) { + warn "couldn't create historical location record for cust#". + $h_cust_main->custnum.": $error\n"; + next INVOICE; } my $exempt_cust = 1 if $h_cust_main->tax; diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm index b12a161db..4560716d5 100644 --- a/FS/FS/cust_location.pm +++ b/FS/FS/cust_location.pm @@ -104,33 +104,93 @@ points to. You can ask the object for a copy with the I method. sub table { 'cust_location'; } -=item new_or_existing HASHREF +=item find_or_insert -Returns an existing location matching the customer and address fields in -HASHREF, if one exists; otherwise returns a new location containing those -fields. The following fields must match: address1, address2, city, county, -state, zip, country, geocode, disabled. Other fields are only required -to match if they're specified in HASHREF. +Finds an existing location matching the customer and address values in this +location, if one exists, and sets the contents of this location equal to that +one (including its locationnum). -The new location will not be inserted; the calling code must call C -(or a method such as C) to insert it, and check for errors at that -point. +If an existing location is not found, this one I be inserted. (This is a +change from the "new_or_existing" method that this replaces.) + +The following fields are considered "essential" and I match: custnum, +address1, address2, city, county, state, zip, country, location_number, +location_type, location_kind. Disabled locations will be found only if this +location is set to disabled. + +If 'coord_auto' is null, and latitude and longitude are not null, then +latitude and longitude are also essential fields. + +All other fields are considered "non-essential". If a non-essential field is +empty in this location, it will be ignored in determining whether an existing +location matches. + +If a non-essential field is non-empty in this location, existing locations +that contain a different non-empty value for that field will not match. An +existing location in which the field is I will match, but will be +updated in-place with the value of that field. + +Returns an error string if inserting or updating a location failed. + +It is unfortunately hard to determine if this created a new location or not. =cut -sub new_or_existing { - my $class = shift; - my %hash = ref($_[0]) ? %{$_[0]} : @_; - # if coords are empty, then it doesn't matter if they're auto or not - if ( !$hash{'latitude'} and !$hash{'longitude'} ) { - delete $hash{'coord_auto'}; +sub find_or_insert { + my $self = shift; + + my @essential = (qw(custnum address1 address2 city county state zip country + location_number location_type location_kind disabled)); + + if ( !$self->coord_auto and $self->latitude and $self->longitude ) { + push @essential, qw(latitude longitude); + # but NOT coord_auto; if the latitude and longitude match the geocoded + # values then that's good enough } - foreach ( qw(address1 address2 city county state zip country geocode - disabled ) ) { - # empty fields match only empty fields - $hash{$_} = '' if !defined($hash{$_}); + + # put nonempty, nonessential fields/values into this hash + my %nonempty = map { $_ => $self->get($_) } + grep {$self->get($_)} $self->fields; + delete @nonempty{@essential}; + delete $nonempty{'locationnum'}; + + my %hash = map { $_ => $self->get($_) } @essential; + my @matches = qsearch('cust_location', \%hash); + + # consider candidate locations + MATCH: foreach my $old (@matches) { + my $reject = 0; + foreach my $field (keys %nonempty) { + my $old_value = $old->get($field); + if ( length($old_value) > 0 ) { + if ( $field eq 'latitude' or $field eq 'longitude' ) { + # special case, because these are decimals + if ( abs($old_value - $nonempty{$field}) > 0.000001 ) { + $reject = 1; + } + } elsif ( $old_value ne $nonempty{$field} ) { + $reject = 1; + } + } else { + # it's empty in $old, has a value in $self + $old->set($field, $nonempty{$field}); + } + next MATCH if $reject; + } # foreach $field + + if ( $old->modified ) { + my $error = $old->replace; + return $error if $error; + } + # set $self equal to $old + foreach ($self->fields) { + $self->set($_, $old->get($_)); + } + return ""; } - return qsearchs('cust_location', \%hash) || $class->new(\%hash); + + # didn't find a match + return $self->insert; } =item insert diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 1cf036551..f21932cf6 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -1509,43 +1509,17 @@ sub replace { my $old_loc = $old->$l; my $new_loc = $self->$l; - if ( !$new_loc->locationnum ) { - # changing location - # If the new location is all empty fields, or if it's identical to - # the old location in all fields, don't replace. - my @nonempty = grep { $new_loc->$_ } $self->location_fields; - next if !@nonempty; - my @unlike = grep { $new_loc->$_ ne $old_loc->$_ } $self->location_fields; - - if ( @unlike or $old_loc->disabled ) { - warn " changed $l fields: ".join(',',@unlike)."\n" - if $DEBUG; - $new_loc->set(custnum => $self->custnum); - - # insert it--the old location will be disabled later - my $error = $new_loc->insert; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } - - } else { - # no fields have changed and $old_loc isn't disabled, so don't change it - next; - } - - } - elsif ( $new_loc->custnum ne $self->custnum or $new_loc->prospectnum ) { + # find the existing location if there is one + $new_loc->set('custnum' => $self->custnum); + my $error = $new_loc->find_or_insert; + if ( $error ) { $dbh->rollback if $oldAutoCommit; - return "$l belongs to customer ".$new_loc->custnum; + return $error; } - # else the new location belongs to this customer so we're good - - # set the foo_locationnum now that we have one. $self->set($l.'num', $new_loc->locationnum); - } #for $l + # replace the customer record my $error = $self->SUPER::replace($old); if ( $error ) { diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm index 41ef22894..8484df50e 100644 --- a/FS/FS/cust_main/Packages.pm +++ b/FS/FS/cust_main/Packages.pm @@ -130,13 +130,10 @@ sub order_pkg { } elsif ( $opt->{'cust_location'} ) { - if ( ! $opt->{'cust_location'}->locationnum ) { - # not inserted yet - my $error = $opt->{'cust_location'}->insert; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "inserting cust_location (transaction rolled back): $error"; - } + my $error = $opt->{'cust_location'}->find_or_insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "inserting cust_location (transaction rolled back): $error"; } $cust_pkg->locationnum($opt->{'cust_location'}->locationnum); diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 4464aa5a2..c49007ce1 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1773,19 +1773,13 @@ sub change { $hash{"change_$_"} = $self->$_() foreach qw( pkgnum pkgpart locationnum ); - if ( $opt->{'cust_location'} && - ( ! $opt->{'locationnum'} || $opt->{'locationnum'} == -1 ) ) { - - if ( ! $opt->{'cust_location'}->locationnum ) { - # not inserted yet - $error = $opt->{'cust_location'}->insert; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "inserting cust_location (transaction rolled back): $error"; - } + if ( $opt->{'cust_location'} ) { + $error = $opt->{'cust_location'}->find_or_insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "inserting cust_location (transaction rolled back): $error"; } $opt->{'locationnum'} = $opt->{'cust_location'}->locationnum; - } # whether to override pkgpart checking on the new package diff --git a/FS/FS/svc_phone.pm b/FS/FS/svc_phone.pm index 3cc1adc66..bab8537bb 100644 --- a/FS/FS/svc_phone.pm +++ b/FS/FS/svc_phone.pm @@ -288,9 +288,8 @@ sub insert { #false laziness w/cust_pkg.pm... move this to location_Mixin? that would #make it more of a base class than a mixin... :) - if ( $options{'cust_location'} - && ( ! $self->locationnum || $self->locationnum == -1 ) ) { - my $error = $options{'cust_location'}->insert; + if ( $options{'cust_location'} ) { + my $error = $options{'cust_location'}->find_or_insert; if ( $error ) { $dbh->rollback if $oldAutoCommit; return "inserting cust_location (transaction rolled back): $error"; diff --git a/httemplate/edit/process/change-cust_pkg.html b/httemplate/edit/process/change-cust_pkg.html index 77f261d56..c893f13a2 100644 --- a/httemplate/edit/process/change-cust_pkg.html +++ b/httemplate/edit/process/change-cust_pkg.html @@ -32,7 +32,7 @@ my %change = map { $_ => scalar($cgi->param($_)) } $change{'keep_dates'} = 1; if ( $cgi->param('locationnum') == -1 ) { - my $cust_location = FS::cust_location->new_or_existing({ + my $cust_location = FS::cust_location->new({ 'custnum' => $cust_pkg->custnum, map { $_ => scalar($cgi->param($_)) } qw( address1 address2 city county state zip country ) diff --git a/httemplate/edit/process/cust_location.cgi b/httemplate/edit/process/cust_location.cgi index 56c3968f6..fd1b8740e 100644 --- a/httemplate/edit/process/cust_location.cgi +++ b/httemplate/edit/process/cust_location.cgi @@ -28,12 +28,12 @@ my $cust_location = qsearchs({ }); die "unknown locationnum $locationnum" unless $cust_location; -my $new = FS::cust_location->new_or_existing({ +my $new = FS::cust_location->new({ custnum => $cust_location->custnum, prospectnum => $cust_location->prospectnum, map { $_ => scalar($cgi->param($_)) } FS::cust_main->location_fields }); - -my $error = $cust_location->move_to($new); +my $error = $new->find_or_insert; +$error ||= $cust_location->move_to($new); diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi index c1f815550..d295ed317 100755 --- a/httemplate/edit/process/cust_main.cgi +++ b/httemplate/edit/process/cust_main.cgi @@ -11,7 +11,7 @@ <%once> my $me = '[edit/process/cust_main.cgi]'; -my $DEBUG = 0; +my $DEBUG = 1; <%init> @@ -83,7 +83,7 @@ for my $pre (qw(bill ship)) { } $hash{'custnum'} = $cgi->param('custnum'); warn Dumper \%hash if $DEBUG; - $locations{$pre} = FS::cust_location->new_or_existing(\%hash); + $locations{$pre} = FS::cust_location->new(\%hash); } if ( ($cgi->param('same') || '') eq 'Y' ) { diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi index 0cc17d36b..14dbda166 100644 --- a/httemplate/edit/process/quick-cust_pkg.cgi +++ b/httemplate/edit/process/quick-cust_pkg.cgi @@ -155,7 +155,7 @@ if ( $quotationnum ) { } if ( $locationnum == -1 ) { - my $cust_location = FS::cust_location->new_or_existing({ + my $cust_location = FS::cust_location->new({ map { $_ => scalar($cgi->param($_)) } ('custnum', FS::cust_main->location_fields) }); diff --git a/httemplate/edit/process/svc_phone.html b/httemplate/edit/process/svc_phone.html index 9983ea2cb..09398fdfb 100644 --- a/httemplate/edit/process/svc_phone.html +++ b/httemplate/edit/process/svc_phone.html @@ -40,7 +40,7 @@ my $args_callback = sub { my %opt = (); if ( $cgi->param('locationnum') == -1 ) { - my $cust_location = FS::cust_location->new_or_existing({ + my $cust_location = FS::cust_location->new({ map { $_ => scalar($cgi->param($_)) } qw( custnum address1 address2 city county state zip country ) }); -- cgit v1.2.1 From e62544064299324ab04abae64cc33afef12a24aa Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 6 May 2013 21:31:04 -0700 Subject: NG auth: use database session keys, RT#21563 --- FS/FS.pm | 2 + FS/FS/AuthCookieHandler.pm | 39 +++++----- FS/FS/CurrentUser.pm | 70 +++++++++++++++++- FS/FS/Schema.pm | 17 ++++- FS/FS/UID.pm | 40 ++++++++-- FS/FS/access_user_session.pm | 158 ++++++++++++++++++++++++++++++++++++++++ FS/MANIFEST | 2 + FS/t/access_user_session.t | 5 ++ httemplate/loginout/login.html | 34 +++++---- httemplate/loginout/logout.html | 11 ++- 10 files changed, 327 insertions(+), 51 deletions(-) create mode 100644 FS/FS/access_user_session.pm create mode 100644 FS/t/access_user_session.t diff --git a/FS/FS.pm b/FS/FS.pm index 2517c1fd6..741d8159f 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -87,6 +87,8 @@ L - Mixin class for records in tables that contain payinfo. L - Employees / internal users +L - Access sessions + L - Employee preferences L - Employee groups diff --git a/FS/FS/AuthCookieHandler.pm b/FS/FS/AuthCookieHandler.pm index a4a31188e..a8ee37079 100644 --- a/FS/FS/AuthCookieHandler.pm +++ b/FS/FS/AuthCookieHandler.pm @@ -2,27 +2,24 @@ package FS::AuthCookieHandler; use base qw( Apache2::AuthCookie ); use strict; -use Digest::SHA qw( sha1_hex ); -use FS::UID qw( adminsuidsetup ); - -my $secret = "XXX temporary"; #XXX move to a DB session with random number as key +use FS::UID qw( adminsuidsetup preuser_setup ); +use FS::CurrentUser; my $module = 'legacy'; #XXX i am set in a conf somehow? or a config file sub authen_cred { my( $self, $r, $username, $password ) = @_; - if ( _is_valid_user($username, $password) ) { - warn "authenticated $username from ". $r->connection->remote_ip. "\n"; - adminsuidsetup($username); - my $session_key = - $username . '::' . sha1_hex( $username, $secret ); - return $session_key; - } else { - warn "failed authentication $username from ". $r->connection->remote_ip. "\n"; + unless ( _is_valid_user($username, $password) ) { + warn "failed auth $username from ". $r->connection->remote_ip. "\n"; + return undef; } - return undef; #? + warn "authenticated $username from ". $r->connection->remote_ip. "\n"; + adminsuidsetup($username); + + FS::CurrentUser->new_session; + } sub _is_valid_user { @@ -38,18 +35,18 @@ sub _is_valid_user { } sub authen_ses_key { - my( $self, $r, $session_key ) = @_; + my( $self, $r, $sessionkey ) = @_; + + preuser_setup(); - my ($username, $mac) = split /::/, $session_key; + my $curuser = FS::CurrentUser->load_user_session( $sessionkey ); - if ( sha1_hex( $username, $secret ) eq $mac ) { - adminsuidsetup($username); - return $username; - } else { - warn "bad session $session_key from ". $r->connection->remote_ip. "\n"; + unless ( $curuser ) { + warn "bad session $sessionkey from ". $r->connection->remote_ip. "\n"; + return undef; } - return undef; + $curuser->username; } diff --git a/FS/FS/CurrentUser.pm b/FS/FS/CurrentUser.pm index bcd337d2c..7b0fe28a6 100644 --- a/FS/FS/CurrentUser.pm +++ b/FS/FS/CurrentUser.pm @@ -1,6 +1,6 @@ package FS::CurrentUser; -use vars qw($CurrentUser $upgrade_hack); +use vars qw($CurrentUser $CurrentSession $upgrade_hack); #not at compile-time, circular dependancey causes trouble #use FS::Record qw(qsearchs); @@ -10,12 +10,20 @@ $upgrade_hack = 0; =head1 NAME -FS::CurrentUser - Package representing the current user +FS::CurrentUser - Package representing the current user (and session) =head1 SYNOPSIS =head1 DESCRIPTION +=head1 CLASS METHODS + +=over 4 + +=item load_user USERNAME + +Sets the current user to the provided username + =cut sub load_user { @@ -44,9 +52,65 @@ sub load_user { $CurrentUser; } +=item new_session + +Creates a new session for the current user and returns the session key + +=cut + +use vars qw( @saltset ); +@saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '+' , '/' ); + +sub new_session { + my( $class ) = @_; + + #not the best thing in the world... + eval "use FS::access_user_session;"; + die $@ if $@; + + my $sessionkey = join('', map $saltset[int(rand(scalar @saltset))], 0..39); + + my $access_user_session = new FS::access_user_session { + 'sessionkey' => $sessionkey, + 'usernum' => $CurrentUser->usernum, + 'start_date' => time, + }; + my $error = $access_user_session->insert; + die $error if $error; + + return $sessionkey; + +} + +=item load_user_session SESSION_KEY + +Sets the current user via the provided session key + +=cut + +sub load_user_session { + my( $class, $sessionkey ) = @_; + + #not the best thing in the world... + eval "use FS::Record qw(qsearchs);"; + die $@ if $@; + eval "use FS::access_user_session;"; + die $@ if $@; + + $CurrentSession = qsearchs('access_user_session', { + 'sessionkey' => $sessionkey, + #XXX check for timed out but not-yet deleted sessions here + }) or return ''; + + $CurrentSession->touch_last_date; + + $CurrentUser = $CurrentSession->access_user; + +} + =head1 BUGS -Creepy crawlies +Minimal docs =head1 SEE ALSO diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index cd42e4e9c..923f1fd9d 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -187,9 +187,9 @@ sub dbdef_dist { my $tables_hashref_torrus = tables_hashref_torrus(); - #create history tables (false laziness w/create-history-tables) + #create history tables foreach my $table ( - grep { ! /^clientapi_session/ + grep { ! /^(clientapi|access_user)_session/ && ! /^h_/ && ! /^log(_context)?$/ && ! $tables_hashref_torrus->{$_} @@ -3569,6 +3569,19 @@ sub tables_hashref { 'index' => [], }, + 'access_user_session' => { + 'columns' => [ + 'sessionnum', 'serial', '', '', '', '', + 'sessionkey', 'varchar', '', $char_d, '', '', + 'usernum', 'int', '', '', '', '', + 'start_date', @date_type, '', '', + 'last_date', @date_type, '', '', + ], + 'primary_key' => 'sessionnum', + 'unique' => [ [ 'sessionkey' ] ], + 'index' => [], + }, + 'access_user' => { 'columns' => [ 'usernum', 'serial', '', '', '', '', diff --git a/FS/FS/UID.pm b/FS/FS/UID.pm index 44d3870cc..6596a983b 100644 --- a/FS/FS/UID.pm +++ b/FS/FS/UID.pm @@ -15,6 +15,7 @@ use FS::CurrentUser; @ISA = qw(Exporter); @EXPORT_OK = qw( checkeuid checkruid cgi setcgi adminsuidsetup forksuidsetup + preuser_setup getotaker dbh datasrc getsecrets driver_name myconnect use_confcompat ); @@ -61,7 +62,6 @@ Sets the user to USER (see config.html from the base documentation). Cleans the environment. Make sure the script is running as freeside, or setuid freeside. Opens a connection to the database. -Swaps real and effective UIDs. Runs any defined callbacks (see below). Returns the DBI database handle (usually you don't need this). @@ -86,13 +86,40 @@ sub forksuidsetup { $user = $1; } - $ENV{'PATH'} ='/usr/local/bin:/usr/bin:/usr/ucb:/bin'; + env_setup(); + + db_setup($olduser); + + callback_setup(); + + warn "$me forksuidsetup loading user\n" if $DEBUG; + FS::CurrentUser->load_user($user); + + $dbh; +} + +sub preuser_setup { + $dbh->disconnect if $dbh; + env_setup(); + db_setup(); + callback_setup(); + $dbh; +} + +sub env_setup { + + $ENV{'PATH'} ='/usr/local/bin:/usr/bin:/bin'; $ENV{'SHELL'} = '/bin/sh'; $ENV{'IFS'} = " \t\n"; $ENV{'CDPATH'} = ''; $ENV{'ENV'} = ''; $ENV{'BASH_ENV'} = ''; +} + +sub db_setup { + my $olduser = shift; + croak "Not running uid freeside (\$>=$>, \$<=$<)\n" unless checkeuid(); warn "$me forksuidsetup connecting to database\n" if $DEBUG; @@ -126,6 +153,11 @@ sub forksuidsetup { die "NO CONFIGURATION TABLE FOUND" unless $FS::Schema::setup_hack; } + +} + +sub callback_setup { + unless ( $callback_hack ) { warn "$me calling callbacks\n" if $DEBUG; foreach ( keys %callback ) { @@ -138,10 +170,6 @@ sub forksuidsetup { warn "$me skipping callbacks (callback_hack set)\n" if $DEBUG; } - warn "$me forksuidsetup loading user\n" if $DEBUG; - FS::CurrentUser->load_user($user); - - $dbh; } sub myconnect { diff --git a/FS/FS/access_user_session.pm b/FS/FS/access_user_session.pm new file mode 100644 index 000000000..df112f984 --- /dev/null +++ b/FS/FS/access_user_session.pm @@ -0,0 +1,158 @@ +package FS::access_user_session; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearchs ); # qsearch ); +use FS::access_user; + +=head1 NAME + +FS::access_user_session - Object methods for access_user_session records + +=head1 SYNOPSIS + + use FS::access_user_session; + + $record = new FS::access_user_session \%hash; + $record = new FS::access_user_session { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::access_user_session object represents a backoffice web session. +FS::access_user_session inherits from FS::Record. The following fields are +currently supported: + +=over 4 + +=item sessionnum + +Database primary key + +=item sessionkey + +Session key + +=item usernum + +Employee (see L) + +=item start_date + +Session start timestamp + +=item last_date + +Last session activity timestamp + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new session. To add the session to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'access_user_session'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=item check + +Checks all fields to make sure this is a valid session. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('sessionnum') + || $self->ut_text('sessionkey') + || $self->ut_foreign_key('usernum', 'access_user', 'usernum') + || $self->ut_number('start_date') + || $self->ut_numbern('last_date') + ; + return $error if $error; + + $self->last_date( $self->start_date ) unless $self->last_date; + + $self->SUPER::check; +} + +=item access_user + +Returns the employee (see L) for this session. + +=cut + +sub access_user { + my $self = shift; + qsearchs('access_user', { 'usernum' => $self->usernum }); +} + +=item touch_last_date + +=cut + +sub touch_last_date { + my $self = shift; + my $old_last_date = $self->last_date; + $self->last_date(time); + return if $old_last_date >= $self->last_date; + my $error = $self->replace; + die $error if $error; +} + +=item logout + +=cut + +sub logout { + my $self = shift; + my $error = $self->delete; + die $error if $error; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 43f36abf6..d2b7013a4 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -690,3 +690,5 @@ FS/part_pkg_usage.pm t/part_pkg_usage.t FS/cdr_cust_pkg_usage.pm t/cdr_cust_pkg_usage.t +FS/access_user_session.pm +t/access_user_session.t diff --git a/FS/t/access_user_session.t b/FS/t/access_user_session.t new file mode 100644 index 000000000..ab3a59acc --- /dev/null +++ b/FS/t/access_user_session.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::access_user_session; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/loginout/login.html b/httemplate/loginout/login.html index e5b45893b..a67ea4b58 100644 --- a/httemplate/loginout/login.html +++ b/httemplate/loginout/login.html @@ -39,30 +39,34 @@ my %error = ( 'no_cookie' => '', #First login, don't display an error - 'bad_cookie' => 'Bad Cookie', #timed out? server reboot? + 'bad_cookie' => 'Bad Cookie', #timed out? 'bad_credentials' => 'Incorrect username / password', - 'logout' => 'You have been logged out.', + #'logout' => 'You have been logged out.', ); -my $url_string = CGI->new->url; +my $error = # $cgi->param('logout') || + $r->prev->subprocess_env("AuthCookieReason"); -my $error = $cgi->param('logout') || $r->prev->subprocess_env("AuthCookieReason"); $error = exists($error{$error}) ? $error{$error} : $error; + +#my $url_string = CGI->new->url; +my $url_string = $cgi->url; + #fake a freeside path for /login so we get our .css. shrug $url_string =~ s/login$/freeside\/login/ unless $url_string =~ /freeside\//; #even though this is kludgy and false laziness w/CGI.pm - $url_string =~ s{ / index\.html /? $ } - {/}x; - $url_string =~ - s{ - /(login|loginout) - ([\w\-\.\/]*) - $ - } - {}ix; - - $url_string .= '/' unless $url_string =~ /\/$/; +$url_string =~ s{ / index\.html /? $ } + {/}x; +$url_string =~ + s{ + /(login|loginout) + ([\w\-\.\/]*) + $ + } + {}ix; + +$url_string .= '/' unless $url_string =~ /\/$/; diff --git a/httemplate/loginout/logout.html b/httemplate/loginout/logout.html index 33b87feb0..5626aa4a1 100644 --- a/httemplate/loginout/logout.html +++ b/httemplate/loginout/logout.html @@ -1,10 +1,13 @@ -<% $cgi->redirect($fsurl.'?logout=logout') %> +<% $cgi->redirect($redirect) %> <%init> -my $auth_type = $r->auth_type; +# Delete the server-side session +$FS::CurrentUser::CurrentSession->logout; -# Delete the cookie, etc. +# Delete the browser cookie, etc. +my $auth_type = $r->auth_type; $auth_type->logout($r); -#XXX etc: should delete the server-side session + +my $redirect = $fsurl; #.'?logout=logout'; -- cgit v1.2.1 From 5c898c621e1343f8c116a75ca3131eb78229e09b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 6 May 2013 22:20:40 -0700 Subject: fix login css for all paths, RT#21563 --- httemplate/loginout/login.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/httemplate/loginout/login.html b/httemplate/loginout/login.html index a67ea4b58..d06d0a8fc 100644 --- a/httemplate/loginout/login.html +++ b/httemplate/loginout/login.html @@ -50,8 +50,7 @@ my $error = # $cgi->param('logout') || $error = exists($error{$error}) ? $error{$error} : $error; -#my $url_string = CGI->new->url; -my $url_string = $cgi->url; +my $url_string = $r->uri; #fake a freeside path for /login so we get our .css. shrug $url_string =~ s/login$/freeside\/login/ unless $url_string =~ /freeside\//; -- cgit v1.2.1 From 9d35792778885932c09102bd011b518eb47c5131 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 6 May 2013 23:13:11 -0700 Subject: NG auth: fix new customer, remove mapsecrets support, RT#21563 --- FS/FS/Mason.pm | 2 +- FS/FS/Record.pm | 13 +- FS/FS/UI/Web.pm | 4 +- FS/FS/UID.pm | 49 ++--- FS/FS/banned_pay.pm | 1 - FS/FS/cust_credit.pm | 2 +- FS/FS/cust_credit_bill.pm | 1 - FS/FS/cust_main.pm | 2 +- FS/FS/cust_main/Status.pm | 5 +- FS/FS/cust_pay.pm | 1 - FS/FS/cust_pay_refund.pm | 1 - FS/FS/cust_pay_void.pm | 1 - FS/FS/cust_pkg.pm | 2 +- FS/FS/cust_refund.pm | 1 - FS/bin/freeside-setup | 2 +- FS/bin/freeside-upgrade | 2 +- bin/fs-migrate-svc_acct_sm | 227 ------------------------ bin/fs-radius-add-check | 8 +- bin/fs-radius-add-reply | 8 +- httemplate/edit/cust_credit.cgi | 2 - httemplate/edit/cust_main.cgi | 1 - httemplate/edit/elements/ApplicationCommon.html | 2 - httemplate/edit/svc_acct.cgi | 2 - httemplate/edit/svc_cert.cgi | 2 - httemplate/edit/svc_domain.cgi | 2 - httemplate/elements/header.html | 2 +- httemplate/index.html | 2 +- httemplate/pref/pref-process.html | 3 +- httemplate/pref/pref.html | 2 +- 29 files changed, 43 insertions(+), 309 deletions(-) delete mode 100755 bin/fs-migrate-svc_acct_sm diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index ae75539ac..43e9b0653 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -126,7 +126,7 @@ if ( -e $addl_handler_use_file ) { use LWP::UserAgent; use Storable qw( nfreeze thaw ); use FS; - use FS::UID qw( getotaker dbh datasrc driver_name ); + use FS::UID qw( dbh datasrc driver_name ); use FS::Record qw( qsearch qsearchs fields dbdef str2time_sql str2time_sql_closing midnight_sql diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 42af68ca5..a868d4892 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -18,7 +18,7 @@ use Text::CSV_XS; use File::Slurp qw( slurp ); use DBI qw(:sql_types); use DBIx::DBSchema 0.38; -use FS::UID qw(dbh getotaker datasrc driver_name); +use FS::UID qw(dbh datasrc driver_name); use FS::CurrentUser; use FS::Schema qw(dbdef); use FS::SearchCache; @@ -1901,7 +1901,11 @@ sub _h_statement { "INSERT INTO h_". $self->table. " ( ". join(', ', qw(history_date history_user history_action), @fields ). ") VALUES (". - join(', ', $time, dbh->quote(getotaker()), dbh->quote($action), @values). + join(', ', $time, + dbh->quote( $FS::CurrentUser::CurrentUser->username ), + dbh->quote($action), + @values + ). ")" ; } @@ -1932,11 +1936,6 @@ sub unique { #warn "field $field is tainted" if is_tainted($field); my($counter) = new File::CounterFile "$table.$field",0; -# hack for web demo -# getotaker() =~ /^([\w\-]{1,16})$/ or die "Illegal CGI REMOTE_USER!"; -# my($user)=$1; -# my($counter) = new File::CounterFile "$user/$table.$field",0; -# endhack my $index = $counter->inc; $index = $counter->inc while qsearchs($table, { $field=>$index } ); diff --git a/FS/FS/UI/Web.pm b/FS/FS/UI/Web.pm index 792680876..c11e6c951 100644 --- a/FS/FS/UI/Web.pm +++ b/FS/FS/UI/Web.pm @@ -579,7 +579,7 @@ use Carp; use Storable qw(nfreeze); use MIME::Base64; use JSON; -use FS::UID qw(getotaker); +use FS::CurrentUser; use FS::Record qw(qsearchs); use FS::queue; use FS::CGI qw(rooturl); @@ -653,7 +653,7 @@ sub start_job { push @{$param{$field}}, $value; } } - $param{CurrentUser} = getotaker(); + $param{CurrentUser} = $FS::CurrentUser::CurrentUser->username; $param{RootURL} = rooturl($self->{cgi}->self_url); warn "FS::UI::Web::start_job\n". join('', map { diff --git a/FS/FS/UID.pm b/FS/FS/UID.pm index 6596a983b..9c52f0883 100644 --- a/FS/FS/UID.pm +++ b/FS/FS/UID.pm @@ -2,7 +2,7 @@ package FS::UID; use strict; use vars qw( - @ISA @EXPORT_OK $DEBUG $me $cgi $freeside_uid $user $conf_dir $cache_dir + @ISA @EXPORT_OK $DEBUG $me $cgi $freeside_uid $conf_dir $cache_dir $secrets $datasrc $db_user $db_pass $schema $dbh $driver_name $AutoCommit %callback @callback $callback_hack $use_confcompat ); @@ -38,7 +38,7 @@ FS::UID - Subroutines for database login and assorted other stuff =head1 SYNOPSIS - use FS::UID qw(adminsuidsetup dbh datasrc getotaker checkeuid checkruid); + use FS::UID qw(adminsuidsetup dbh datasrc checkeuid checkruid); $dbh = adminsuidsetup $user; @@ -73,7 +73,7 @@ sub adminsuidsetup { } sub forksuidsetup { - $user = shift; + my $user = shift; my $olduser = $user; warn "$me forksuidsetup starting for $user\n" if $DEBUG; @@ -173,12 +173,12 @@ sub callback_setup { } sub myconnect { - my $handle = DBI->connect( getsecrets(@_), { 'AutoCommit' => 0, - 'ChopBlanks' => 1, - 'ShowErrorStatement' => 1, - 'pg_enable_utf8' => 1, - #'mysql_enable_utf8' => 1, - } + my $handle = DBI->connect( getsecrets(), { 'AutoCommit' => 0, + 'ChopBlanks' => 1, + 'ShowErrorStatement' => 1, + 'pg_enable_utf8' => 1, + #'mysql_enable_utf8' => 1, + } ) or die "DBI->connect error: $DBI::errstr\n"; @@ -276,12 +276,13 @@ sub suidsetup { =item getotaker -Returns the current Freeside user. +(Deprecated) Returns the current Freeside user's username. =cut sub getotaker { - $user; + carp "FS::UID::getotaker deprecated"; + $FS::CurrentUser::CurrentUser->username; } =item checkeuid @@ -305,34 +306,18 @@ sub checkruid { ( $< == $freeside_uid ); } -=item getsecrets [ USER ] +=item getsecrets -Sets the user to USER, if supplied. -Sets and returns the DBI datasource, username and password for this user from -the `/usr/local/etc/freeside/mapsecrets' file. +Sets and returns the DBI datasource, username and password from +the `/usr/local/etc/freeside/secrets' file. =cut sub getsecrets { - my($setuser) = shift; - $user = $setuser if $setuser; - - if ( -e "$conf_dir/mapsecrets" ) { - die "No user!" unless $user; - my($line) = grep /^\s*($user|\*)\s/, - map { /^(.*)$/; $1 } readline(new IO::File "$conf_dir/mapsecrets"); - confess "User $user not found in mapsecrets!" unless $line; - $line =~ /^\s*($user|\*)\s+(.*)$/; - $secrets = $2; - die "Illegal mapsecrets line for user?!" unless $secrets; - } else { - # no mapsecrets file at all, so do the default thing - $secrets = 'secrets'; - } ($datasrc, $db_user, $db_pass, $schema) = - map { /^(.*)$/; $1 } readline(new IO::File "$conf_dir/$secrets") - or die "Can't get secrets: $conf_dir/$secrets: $!\n"; + map { /^(.*)$/; $1 } readline(new IO::File "$conf_dir/secrets") + or die "Can't get secrets: $conf_dir/secrets: $!\n"; undef $driver_name; ($datasrc, $db_user, $db_pass); diff --git a/FS/FS/banned_pay.pm b/FS/FS/banned_pay.pm index b93f67bbe..713c81adf 100644 --- a/FS/FS/banned_pay.pm +++ b/FS/FS/banned_pay.pm @@ -4,7 +4,6 @@ use strict; use base qw( FS::otaker_Mixin FS::Record ); use Digest::MD5 qw(md5_base64); use FS::Record qw( qsearch qsearchs ); -use FS::UID qw( getotaker ); use FS::CurrentUser; =head1 NAME diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index ba279a26c..0376f1dc4 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -7,7 +7,7 @@ use vars qw( $conf $unsuspendauto $me $DEBUG ); use List::Util qw( min ); use Date::Format; -use FS::UID qw( dbh getotaker ); +use FS::UID qw( dbh ); use FS::Misc qw(send_email); use FS::Record qw( qsearch qsearchs dbdef ); use FS::CurrentUser; diff --git a/FS/FS/cust_credit_bill.pm b/FS/FS/cust_credit_bill.pm index 900a5c0d5..9ecb7e048 100644 --- a/FS/FS/cust_credit_bill.pm +++ b/FS/FS/cust_credit_bill.pm @@ -2,7 +2,6 @@ package FS::cust_credit_bill; use strict; use vars qw( @ISA $conf ); -use FS::UID qw( getotaker ); use FS::Record qw( qsearch qsearchs ); use FS::cust_main_Mixin; use FS::cust_bill_ApplicationCommon; diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 2a4602e19..3c0702fc1 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -32,7 +32,7 @@ use Date::Format; use File::Temp; #qw( tempfile ); use Business::CreditCard 0.28; use Locale::Country; -use FS::UID qw( getotaker dbh driver_name ); +use FS::UID qw( dbh driver_name ); use FS::Record qw( qsearchs qsearch dbdef regexp_sql ); use FS::Misc qw( generate_email send_email generate_ps do_print ); use FS::Msgcat qw(gettext); diff --git a/FS/FS/cust_main/Status.pm b/FS/FS/cust_main/Status.pm index e5803e0db..f84ff0f0e 100644 --- a/FS/FS/cust_main/Status.pm +++ b/FS/FS/cust_main/Status.pm @@ -2,13 +2,10 @@ package FS::cust_main::Status; use strict; use vars qw( $conf ); # $module ); #$DEBUG $me ); +use Tie::IxHash; use FS::UID; use FS::cust_pkg; -#use Tie::IxHash; - -use FS::UID qw( getotaker dbh driver_name ); - #$DEBUG = 0; #$me = '[FS::cust_main::Status]'; diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm index 6d09f8908..4491f780c 100644 --- a/FS/FS/cust_pay.pm +++ b/FS/FS/cust_pay.pm @@ -9,7 +9,6 @@ use vars qw( $DEBUG $me $conf @encrypted_fields use Date::Format; use Business::CreditCard; use Text::Template; -use FS::UID qw( getotaker ); use FS::Misc qw( send_email ); use FS::Record qw( dbh qsearch qsearchs ); use FS::CurrentUser; diff --git a/FS/FS/cust_pay_refund.pm b/FS/FS/cust_pay_refund.pm index cb9dbcef2..b799f69e7 100644 --- a/FS/FS/cust_pay_refund.pm +++ b/FS/FS/cust_pay_refund.pm @@ -2,7 +2,6 @@ package FS::cust_pay_refund; use strict; use vars qw( @ISA ); #$conf ); -use FS::UID qw( getotaker ); use FS::Record qw( qsearchs ); # qsearch ); use FS::cust_main; use FS::cust_pay; diff --git a/FS/FS/cust_pay_void.pm b/FS/FS/cust_pay_void.pm index 42fc2966c..92a96cb96 100644 --- a/FS/FS/cust_pay_void.pm +++ b/FS/FS/cust_pay_void.pm @@ -5,7 +5,6 @@ use base qw( FS::otaker_Mixin FS::payinfo_transaction_Mixin FS::cust_main_Mixin FS::Record ); use vars qw( @encrypted_fields $otaker_upgrade_kludge ); use Business::CreditCard; -use FS::UID qw(getotaker); use FS::Record qw(qsearch qsearchs dbh fields); use FS::CurrentUser; use FS::access_user; diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 374cf7a12..19337c4d6 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -10,7 +10,7 @@ use List::Util qw(min max); use Tie::IxHash; use Time::Local qw( timelocal timelocal_nocheck ); use MIME::Entity; -use FS::UID qw( getotaker dbh driver_name ); +use FS::UID qw( dbh driver_name ); use FS::Misc qw( send_email ); use FS::Record qw( qsearch qsearchs fields ); use FS::CurrentUser; diff --git a/FS/FS/cust_refund.pm b/FS/FS/cust_refund.pm index 45a170ba0..064992955 100644 --- a/FS/FS/cust_refund.pm +++ b/FS/FS/cust_refund.pm @@ -5,7 +5,6 @@ use base qw( FS::otaker_Mixin FS::payinfo_transaction_Mixin FS::cust_main_Mixin FS::Record ); use vars qw( @encrypted_fields ); use Business::CreditCard; -use FS::UID qw(getotaker); use FS::Record qw( qsearch qsearchs dbh ); use FS::CurrentUser; use FS::cust_credit; diff --git a/FS/bin/freeside-setup b/FS/bin/freeside-setup index 155c74aa0..07da88dea 100755 --- a/FS/bin/freeside-setup +++ b/FS/bin/freeside-setup @@ -32,7 +32,7 @@ $config_dir =~ /^([\w.:=\/]+)$/ or die "unacceptable configuration directory name"; $config_dir = $1; -getsecrets($opt_u); +getsecrets(); #needs to match FS::Record my($dbdef_file) = "%%%FREESIDE_CONF%%%/dbdef.". datasrc; diff --git a/FS/bin/freeside-upgrade b/FS/bin/freeside-upgrade index b08a8401f..399c11994 100755 --- a/FS/bin/freeside-upgrade +++ b/FS/bin/freeside-upgrade @@ -5,7 +5,7 @@ use vars qw($opt_d $opt_s $opt_q $opt_v $opt_r); use vars qw($DEBUG $DRY_RUN); use Getopt::Std; use DBIx::DBSchema 0.31; #0.39 -use FS::UID qw(adminsuidsetup checkeuid datasrc driver_name); #getsecrets); +use FS::UID qw(adminsuidsetup checkeuid datasrc driver_name); use FS::CurrentUser; use FS::Schema qw( dbdef dbdef_dist reload_dbdef ); use FS::Misc::prune qw(prune_applications); diff --git a/bin/fs-migrate-svc_acct_sm b/bin/fs-migrate-svc_acct_sm deleted file mode 100755 index 07f7b611c..000000000 --- a/bin/fs-migrate-svc_acct_sm +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/perl -Tw -# -# jeff@cmh.net 01-Jul-20 - -#to delay loading dbdef until we're ready -#BEGIN { $FS::Record::setup_hack = 1; } - -use strict; -use Term::Query qw(query); -#use DBI; -#use DBIx::DBSchema; -#use DBIx::DBSchema::Table; -#use DBIx::DBSchema::Column; -#use DBIx::DBSchema::ColGroup::Unique; -#use DBIx::DBSchema::ColGroup::Index; -use FS::Conf; -use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets); -use FS::Record qw(qsearch qsearchs); -use FS::svc_domain; -use FS::svc_forward; -use vars qw( $conf $old_default_domain %part_domain_svc %part_acct_svc %part_forward_svc $svc_acct $svc_acct_sm $error); - -die "Not running uid freeside!" unless checkeuid(); - -my $user = shift or die &usage; -getsecrets($user); - -$conf = new FS::Conf; -$old_default_domain = $conf->config('domain'); - -#needs to match FS::Record -#my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc; - -### -# This section would be the appropriate place to manipulate -# the schema & tables. -### - -## we need to add the domsvc to svc_acct -## we must add a svc_forward record.... -## I am thinking that the fields svcnum (int), destsvc (int), and -## dest (varchar (80)) are appropriate, with destsvc/dest an either/or -## much in the spirit of cust_main_invoice - -### -# massage the data -### - -my($dbh)=adminsuidsetup $user; - -$|=1; - -$FS::svc_Common::noexport_hack = 1; -$FS::svc_domain::whois_hack = 1; - -%part_domain_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_domain'}); -%part_acct_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'}); -%part_forward_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_forward'}); - -die "No services with svcdb svc_domain!\n" unless %part_domain_svc; -die "No services with svcdb svc_acct!\n" unless %part_acct_svc; -die "No services with svcdb svc_forward!\n" unless %part_forward_svc; - -my($svc_domain) = qsearchs('svc_domain', { 'domain' => $old_default_domain }); -if (! $svc_domain || $svc_domain->domain != $old_default_domain) { - print <); - chop $response; - if ($response =~ /^[yY]/) { - print "\n\n", &menu_domain_svc, "\n", < $old_default_domain, - 'svcpart' => $domain_svcpart, - 'action' => 'M', - }; -# $error=$svc_domain->insert && die "Error adding domain $old_default_domain: $error"; - $error=$svc_domain->insert; - die "Error adding domain $old_default_domain: $error" if $error; - }else{ - print <svc, sort keys %part_domain_svc ). "\n"; -} -sub menu_acct_svc { - ( join "\n", map "$_: ".$part_acct_svc{$_}->svc, sort keys %part_acct_svc ). "\n"; -} -sub menu_forward_svc { - ( join "\n", map "$_: ".$part_forward_svc{$_}->svc, sort keys %part_forward_svc ). "\n"; -} -sub getdomainpart { - $^W=0; # Term::Query isn't -w-safe - my $return = query "Enter part number:", 'irk', [ keys %part_domain_svc ]; - $^W=1; - $return; -} -sub getacctpart { - $^W=0; # Term::Query isn't -w-safe - my $return = query "Enter part number:", 'irk', [ keys %part_acct_svc ]; - $^W=1; - $return; -} -sub getforwardpart { - $^W=0; # Term::Query isn't -w-safe - my $return = query "Enter part number:", 'irk', [ keys %part_forward_svc ]; - $^W=1; - $return; -} - - -#migrate data - -my(@svc_accts) = qsearch('svc_acct', {}); -foreach $svc_acct (@svc_accts) { - my(@svc_acct_sms) = qsearch('svc_acct_sm', { - domuid => $svc_acct->getfield('uid'), - } - ); - - # Ok.. we've got the svc_acct record, and an array of svc_acct_sm's - # What do we do from here? - - # The intuitive: - # plop the svc_acct into the 'default domain' - # and then represent the svc_acct_sm's with svc_forwards - # they can be gussied up manually, later - # - # Perhaps better: - # when no svc_acct_sm exists, place svc_acct in 'default domain' - # when one svc_acct_sm exists, place svc_acct in corresponding - # domain & possibly create a svc_forward in 'default domain' - # when multiple svc_acct_sm's exists (in different domains) we'd - # better use the 'intuitive' approach. - # - # Specific way: - # as 'perhaps better,' but we may be able to guess which domain - # is correct by comparing the svcnum of domains to the username - # of the svc_acct - # - - # The intuitive way: - - my $def_acct = new FS::svc_acct ( { $svc_acct->hash } ); - $def_acct->setfield('domsvc' => $svc_domain->getfield('svcnum')); - $error = $def_acct->replace($svc_acct); - die "Error replacing svc_acct for " . $def_acct->username . " : $error" if $error; - - foreach $svc_acct_sm (@svc_acct_sms) { - - my($domrec)=qsearchs('svc_domain', { - svcnum => $svc_acct_sm->getfield('domsvc'), - }) || die "svc_acct_sm references invalid domsvc $svc_acct_sm->getfield('domsvc')\n"; - - if ($svc_acct_sm->getfield('domuser') =~ /^\*$/) { - - my($newdom) = new FS::svc_domain ( { $domrec->hash } ); - $newdom->setfield('catchall', $svc_acct->svcnum); - $newdom->setfield('action', "M"); - $error = $newdom->replace($domrec); - die "Error replacing svc_domain for (anything)@" . $domrec->domain . " : $error" if $error; - - } else { - - my($newacct) = new FS::svc_acct { - 'svcpart' => $pop_svcpart, - 'username' => $svc_acct_sm->getfield('domuser'), - 'domsvc' => $svc_acct_sm->getfield('domsvc'), - 'dir' => '/dev/null', - }; - $error = $newacct->insert; - die "Error adding svc_acct for " . $newacct->username . " : $error" if $error; - - my($newforward) = new FS::svc_forward { - 'svcpart' => $forward_svcpart, - 'srcsvc' => $newacct->getfield('svcnum'), - 'dstsvc' => $def_acct->getfield('svcnum'), - }; - $error = $newforward->insert; - die "Error adding svc_forward for " . $newacct->username ." : $error" if $error; - } - - $error = $svc_acct_sm->delete; - die "Error deleting svc_acct_sm for " . $svc_acct_sm->domuser ." : $error" if $error; - - }; - -}; - - -$dbh->commit or die $dbh->errstr; -$dbh->disconnect or die $dbh->errstr; - -print "svc_acct_sm records sucessfully migrated\n"; - -sub usage { - die "Usage:\n fs-migrate-svc_acct_sm user\n"; -} - diff --git a/bin/fs-radius-add-check b/bin/fs-radius-add-check index 4e4769e58..ee093b375 100755 --- a/bin/fs-radius-add-check +++ b/bin/fs-radius-add-check @@ -1,20 +1,18 @@ #!/usr/bin/perl -Tw # quick'n'dirty hack of fs-setup to add radius attributes +# (i'm not sure this even works in the new world of schema changes - everyone +# uses attributes via groups now) use strict; use DBI; -use FS::UID qw(adminsuidsetup checkeuid getsecrets); +use FS::UID qw(adminsuidsetup); use FS::raddb; -die "Not running uid freeside!" unless checkeuid(); - my %attrib2db = map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib; my $user = shift or die &usage; -getsecrets($user); - my $dbh = adminsuidsetup $user; ### diff --git a/bin/fs-radius-add-reply b/bin/fs-radius-add-reply index 3de01374f..c6c24e039 100755 --- a/bin/fs-radius-add-reply +++ b/bin/fs-radius-add-reply @@ -1,20 +1,18 @@ #!/usr/bin/perl -Tw # quick'n'dirty hack of fs-setup to add radius attributes +# (i'm not sure this even works in the new world of schema changes - everyone +# uses attributes via groups now) use strict; use DBI; -use FS::UID qw(adminsuidsetup checkeuid getsecrets); +use FS::UID qw(adminsuidsetup); use FS::raddb; -die "Not running uid freeside!" unless checkeuid(); - my %attrib2db = map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib; my $user = shift or die &usage; -getsecrets($user); - my $dbh = adminsuidsetup $user; ### diff --git a/httemplate/edit/cust_credit.cgi b/httemplate/edit/cust_credit.cgi index 4dba1e769..09300c629 100755 --- a/httemplate/edit/cust_credit.cgi +++ b/httemplate/edit/cust_credit.cgi @@ -8,7 +8,6 @@ - <% ntable("#cccccc", 2) %> @@ -74,7 +73,6 @@ die "access denied" my $custnum = $cgi->param('custnum'); my $amount = $cgi->param('amount'); my $_date = time; -my $otaker = getotaker; my $p1 = popurl(1); diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi index 2908848c6..d597d0bc2 100755 --- a/httemplate/edit/cust_main.cgi +++ b/httemplate/edit/cust_main.cgi @@ -299,7 +299,6 @@ if ( $cgi->param('error') ) { $cust_main = new FS::cust_main ( {} ); $cust_main->agentnum( $conf->config('default_agentnum') ) if $conf->exists('default_agentnum'); - $cust_main->otaker( &getotaker ); $cust_main->referral_custnum( $cgi->param('referral_custnum') ); @invoicing_list = (); push @invoicing_list, 'POST' diff --git a/httemplate/edit/elements/ApplicationCommon.html b/httemplate/edit/elements/ApplicationCommon.html index 7b1050ade..acc3368b8 100644 --- a/httemplate/edit/elements/ApplicationCommon.html +++ b/httemplate/edit/elements/ApplicationCommon.html @@ -441,8 +441,6 @@ if ( $cgi->param('error') ) { $dst_pkeyvalue = ''; } -my $otaker = getotaker; - my $p1 = popurl(1); my $src = qsearchs($src_table, { $src_pkey => $src_pkeyvalue } ); diff --git a/httemplate/edit/svc_acct.cgi b/httemplate/edit/svc_acct.cgi index 627791ba7..574fb51eb 100755 --- a/httemplate/edit/svc_acct.cgi +++ b/httemplate/edit/svc_acct.cgi @@ -482,8 +482,6 @@ my $action = $svcnum ? 'Edit' : 'Add'; my $svc = $part_svc->getfield('svc'); -my $otaker = getotaker; - my $username = $svc_acct->username; my $password = ''; diff --git a/httemplate/edit/svc_cert.cgi b/httemplate/edit/svc_cert.cgi index 93194228e..dc2cc3200 100644 --- a/httemplate/edit/svc_cert.cgi +++ b/httemplate/edit/svc_cert.cgi @@ -185,8 +185,6 @@ my $action = $svcnum ? 'Edit' : 'Add'; my $svc = $part_svc->getfield('svc'); -#my $otaker = getotaker; - my $p1 = popurl(1); my $link_query = "?svcnum=$svcnum;pkgnum=$pkgnum;svcpart=$svcpart"; diff --git a/httemplate/edit/svc_domain.cgi b/httemplate/edit/svc_domain.cgi index c3307fa8c..417b1b4c5 100755 --- a/httemplate/edit/svc_domain.cgi +++ b/httemplate/edit/svc_domain.cgi @@ -148,8 +148,6 @@ my $export = $exports[0]; # If we have a domain registration export, get the registrar object my $registrar = $export ? $export->registrar : ''; -my $otaker = getotaker; - my $domain = $svc_domain->domain; my $p1 = popurl(1); diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html index 4f5015e7a..7a7dc088d 100644 --- a/httemplate/elements/header.html +++ b/httemplate/elements/header.html @@ -52,7 +52,7 @@ Example: <% $company_name || 'ExampleCo' %> - Logged in as <% getotaker %>  logout
    Preferences + Logged in as <% $FS::CurrentUser::CurrentUser->username |h %>  logout
    Preferences % if ( $conf->config("ticket_system") % && FS::TicketSystem->access_right(\%session, 'ModifySelf') ) { | Ticketing preferences diff --git a/httemplate/index.html b/httemplate/index.html index bc51e6a52..d563fa0b2 100644 --- a/httemplate/index.html +++ b/httemplate/index.html @@ -21,7 +21,7 @@ % ORDER BY history_date desc" # LIMIT 10 % ) or die dbh->errstr; % -% $sth->execute( getotaker() ) or die $sth->errstr; +% $sth->execute( $FS::CurrentUser::CurrentUser->username ) or die $sth->errstr; % % my %saw = (); % my @custnums = grep { !$saw{$_}++ } map $_->[0], @{ $sth->fetchall_arrayref }; diff --git a/httemplate/pref/pref-process.html b/httemplate/pref/pref-process.html index 6b94f7175..242e12294 100644 --- a/httemplate/pref/pref-process.html +++ b/httemplate/pref/pref-process.html @@ -20,7 +20,8 @@ if ( grep { $cgi->param($_) !~ /^\s*$/ } ) { $access_user = qsearchs( 'access_user', { - 'username' => getotaker, + 'usernum' => $FS::CurrentUser::CurrentUser->usernum, + 'username' => $FS::CurrentUser::CurrentUser->username, '_password' => scalar($cgi->param('_password')), } ); diff --git a/httemplate/pref/pref.html b/httemplate/pref/pref.html index 5babb0181..9861c3f85 100644 --- a/httemplate/pref/pref.html +++ b/httemplate/pref/pref.html @@ -1,4 +1,4 @@ -<% include('/elements/header.html', 'Preferences for '. getotaker ) %> +<% include('/elements/header.html', 'Preferences for '. $FS::CurrentUser::CurrentUser->username ) %> -- cgit v1.2.1 From c6fa106e14a3bff641ca9f4f8a95c2749c53ba95 Mon Sep 17 00:00:00 2001 From: jeremyd Date: Tue, 7 May 2013 15:11:35 -0400 Subject: #22795 Add company to Oneline format --- FS/FS/cust_bill.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 8b156c642..f85bca6af 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -2144,6 +2144,7 @@ sub print_csv { $self->custnum, $cust_main->first, $cust_main->last, + $cust_main->company, $cust_main->address1, $cust_main->address2, $cust_main->city, -- cgit v1.2.1 From 0dfdc3e5dc012c1a2640ac2af22b1488cdfbd083 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 7 May 2013 15:16:11 -0700 Subject: fix smart search for all-numeric strings --- FS/FS/cust_svc.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm index cab80a871..627410729 100644 --- a/FS/FS/cust_svc.pm +++ b/FS/FS/cust_svc.pm @@ -870,7 +870,7 @@ sub smart_search_param { FS::part_svc->svc_tables; if ( $string =~ /^(\d+)$/ ) { - unshift @or, "SELECT cust_svc.svcnum, NULL FROM cust_svc WHERE agent_svcid = $1"; + unshift @or, "SELECT cust_svc.svcnum, NULL as svcdb FROM cust_svc WHERE agent_svcid = $1"; } my $addl_from = " RIGHT JOIN (\n" . join("\nUNION\n", @or) . "\n) AS svc_all ". -- cgit v1.2.1 From 85dc9f5c03d159e88d2af277749ec2c2707de3a1 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 7 May 2013 16:02:01 -0700 Subject: changes to support new invoice features, #21293 --- FS/FS/Conf.pm | 10 +++++++ FS/FS/Template_Mixin.pm | 70 ++++++++++++++++++++++++++++++++++++++++++++----- FS/FS/cust_bill.pm | 6 +++-- 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index db21563dc..d955f34ae 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1038,6 +1038,9 @@ sub reason_type_options { 'select_hash' => [ '%b %o, %Y' => 'Mon DDth, YYYY', '%e %b %Y' => 'DD Mon YYYY', + '%m/%d/%Y' => 'MM/DD/YYYY', + '%d/%m/%Y' => 'DD/MM/YYYY', + '%Y/%m/%d' => 'YYYY/MM/DD', ], }, @@ -4137,6 +4140,13 @@ and customer address. Include units.', 'type' => 'checkbox', }, + { + 'key' => 'always_show_tax', + 'section' => 'invoicing', + 'description' => 'Show a line for tax on the invoice even when the tax is zero. Optionally provide text for the tax name to show.', + 'type' => [ qw(checkbox text) ], + }, + { 'key' => 'address_standardize_method', 'section' => 'UI', #??? diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index 2e78f12f4..dd1796c7d 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -597,12 +597,54 @@ sub print_generic { # info from customer's last invoice before this one, for some # summary formats $invoice_data{'last_bill'} = {}; - my $last_bill = $pr_cust_bill[-1]; + # returns the last unpaid bill, not the last bill + #my $last_bill = $pr_cust_bill[-1]; + # THIS returns the customer's last bill before this one + my $last_bill = qsearchs({ + 'table' => 'cust_bill', + 'hashref' => { 'custnum' => $self->custnum, + 'invnum' => { op => '<', value => $self->invnum }, + }, + 'order_by' => ' ORDER BY invnum DESC LIMIT 1' + }); if ( $last_bill ) { $invoice_data{'last_bill'} = { '_date' => $last_bill->_date, #unformatted # all we need for now }; + my (@payments, @credits); + # for formats that itemize previous payments + foreach my $cust_pay ( qsearch('cust_pay', { + 'custnum' => $self->custnum, + '_date' => { op => '>=', + value => $last_bill->_date } + } ) ) + { + next if $cust_pay->_date > $self->_date; + push @payments, { + '_date' => $cust_pay->_date, + 'date' => time2str($date_format, $cust_pay->_date), + 'payinfo' => $cust_pay->payby_payinfo_pretty, + 'amount' => sprintf('%.2f', $cust_pay->paid), + }; + # not concerned about applications + } + foreach my $cust_credit ( qsearch('cust_credit', { + 'custnum' => $self->custnum, + '_date' => { op => '>=', + value => $last_bill->_date } + } ) ) + { + next if $cust_credit->_date > $self->_date; + push @credits, { + '_date' => $cust_credit->_date, + 'date' => time2str($date_format, $cust_credit->_date), + 'creditreason'=> $cust_credit->cust_credit->reason, + 'amount' => sprintf('%.2f', $cust_credit->amount), + }; + } + $invoice_data{'previous_payments'} = \@payments; + $invoice_data{'previous_credits'} = \@credits; } my $summarypage = ''; @@ -687,6 +729,11 @@ sub print_generic { my $other_money_char = $other_money_chars{$format}; $invoice_data{'dollar'} = $other_money_char; + my %minus_signs = ( 'latex' => '$-$', + 'html' => '−', + 'template' => '- ' ); + my $minus = $minus_signs{$format}; + my @detail_items = (); my @total_items = (); my @buf = (); @@ -971,7 +1018,8 @@ sub print_generic { warn "$me adding taxes\n" if $DEBUG > 1; - foreach my $tax ( $self->_items_tax ) { + my @items_tax = $self->_items_tax; + foreach my $tax ( @items_tax ) { $taxtotal += $tax->{'amount'}; @@ -1006,7 +1054,7 @@ sub print_generic { } - if ( $taxtotal ) { + if ( @items_tax ) { my $total = {}; $total->{'total_item'} = $self->mt('Sub-total'); $total->{'total_amount'} = @@ -1106,7 +1154,7 @@ sub print_generic { my $total; $total->{'total_item'} = &$escape_function($credit->{'description'}); $credittotal += $credit->{'amount'}; - $total->{'total_amount'} = '-'. $other_money_char. $credit->{'amount'}; + $total->{'total_amount'} = $minus.$other_money_char.$credit->{'amount'}; $adjusttotal += $credit->{'amount'}; if ( $multisection ) { my $money = $old_latex ? '' : $money_char; @@ -1137,7 +1185,7 @@ sub print_generic { my $total = {}; $total->{'total_item'} = &$escape_function($payment->{'description'}); $paymenttotal += $payment->{'amount'}; - $total->{'total_amount'} = '-'. $other_money_char. $payment->{'amount'}; + $total->{'total_amount'} = $minus.$other_money_char.$payment->{'amount'}; $adjusttotal += $payment->{'amount'}; if ( $multisection ) { my $money = $old_latex ? '' : $money_char; @@ -2129,7 +2177,17 @@ sub _taxsort { sub _items_tax { my $self = shift; my @cust_bill_pkg = sort _taxsort grep { ! $_->pkgnum } $self->cust_bill_pkg; - $self->_items_cust_bill_pkg(\@cust_bill_pkg, @_); + my @items = $self->_items_cust_bill_pkg(\@cust_bill_pkg, @_); + + if ( $self->conf->exists('always_show_tax') ) { + my $itemdesc = $self->conf->config('always_show_tax') || 'Tax'; + if (0 == grep { $_->{description} eq $itemdesc } @items) { + push @items, + { 'description' => $itemdesc, + 'amount' => 0.00 }; + } + } + @items; } =item _items_cust_bill_pkg CUST_BILL_PKGS OPTIONS diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index f85bca6af..fc6a7ddbe 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -110,9 +110,11 @@ Customer info at invoice generation time =over 4 -=item previous_balance +=item billing_balance - the customer's balance at the time the invoice was +generated (not including charges on this invoice) -=item billing_balance +=item previous_balance - the billing_balance of this customer's previous +invoice plus the charges on that invoice =back -- cgit v1.2.1 From bd86f39993db7511cb71a66c11ed56f5fa48be28 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 7 May 2013 18:28:37 -0700 Subject: add -s flag to skip CDR files that error out, RT#20763 --- FS/bin/freeside-cdr-sftp_and_import | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/FS/bin/freeside-cdr-sftp_and_import b/FS/bin/freeside-cdr-sftp_and_import index c37ff11d6..9aacd6753 100755 --- a/FS/bin/freeside-cdr-sftp_and_import +++ b/FS/bin/freeside-cdr-sftp_and_import @@ -12,8 +12,8 @@ use FS::cdr; # parse command line ### -use vars qw( $opt_m $opt_p $opt_r $opt_e $opt_d $opt_v $opt_P $opt_a $opt_c $opt_g ); -getopts('c:m:p:r:e:d:v:P:ag'); +use vars qw( $opt_m $opt_p $opt_r $opt_e $opt_d $opt_v $opt_P $opt_a $opt_c $opt_g $opt_s ); +getopts('c:m:p:r:e:d:v:P:ags'); $opt_e ||= 'csv'; #$opt_e = ".$opt_e" unless $opt_e =~ /^\./; @@ -192,7 +192,7 @@ freeside-cdr-sftp_and_import - Download CDR files from a remote server via SFTP cdr.sftp_and_import [ -m method ] [ -p prefix ] [ -e extension ] [ -r remotefolder ] [ -d donefolder ] [ -v level ] [ -P port ] - [ -a ] [ -c cdrtypenum ] user format [sftpuser@]servername + [ -a ] [ -g ] [ -s ] [ -c cdrtypenum ] user format [sftpuser@]servername =head1 DESCRIPTION @@ -220,6 +220,8 @@ or FTP and then import them into the database. -g: File is gzipped +-s: Warn and skip files which could not be imported rather than abort + user: freeside username format: CDR format name -- cgit v1.2.1 From e9f160b9f019b82fd5a8cc630fa92943a52af1d2 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 7 May 2013 18:28:47 -0700 Subject: add -s flag to skip CDR files that error out, RT#20763 --- FS/bin/freeside-cdr-sftp_and_import | 50 +++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/FS/bin/freeside-cdr-sftp_and_import b/FS/bin/freeside-cdr-sftp_and_import index 9aacd6753..722bf733e 100755 --- a/FS/bin/freeside-cdr-sftp_and_import +++ b/FS/bin/freeside-cdr-sftp_and_import @@ -116,31 +116,39 @@ foreach my $filename ( @$ls ) { $import_options->{'cdrtypenum'} = $opt_c if $opt_c; my $error = FS::cdr::batch_import($import_options); + if ( $error ) { - unlink "$cachedir/$filename"; - unlink "$cachedir/$ungziped" if $opt_g; - die $error; - } - if ( $opt_d ) { - if($opt_m eq 'ftp') { - my $ftp = ftp(); - $ftp->rename($filename, "$opt_d/$file_timestamp") - or do { - unlink "$cachedir/$filename"; - unlink "$cachedir/$ungziped" if $opt_g; - die "Can't move $filename to $opt_d: ".$ftp->message . "\n"; - }; + if ( $opt_s ) { + warn "$ungzipped: $error\n"; + } else { + unlink "$cachedir/$filename"; + unlink "$cachedir/$ungziped" if $opt_g; + die $error; } - else { - my $sftp = sftp(); - $sftp->rename($filename, "$opt_d/$file_timestamp") - or do { - unlink "$cachedir/$filename"; - unlink "$cachedir/$ungziped" if $opt_g; - die "can't move $filename to $opt_d: ". $sftp->error . "\n"; - }; + + } else { + + if ( $opt_d ) { + if ( $opt_m eq 'ftp') { + my $ftp = ftp(); + $ftp->rename($filename, "$opt_d/$file_timestamp") + or do { + unlink "$cachedir/$filename"; + unlink "$cachedir/$ungziped" if $opt_g; + die "Can't move $filename to $opt_d: ".$ftp->message . "\n"; + }; + } else { + my $sftp = sftp(); + $sftp->rename($filename, "$opt_d/$file_timestamp") + or do { + unlink "$cachedir/$filename"; + unlink "$cachedir/$ungziped" if $opt_g; + die "can't move $filename to $opt_d: ". $sftp->error . "\n"; + }; + } } + } unlink "$cachedir/$filename"; -- cgit v1.2.1 From 57a9a48d9a56255a3a05821c0090acac6c1f0336 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 7 May 2013 18:29:13 -0700 Subject: add -s flag to skip CDR files that error out, RT#20763 --- FS/bin/freeside-cdr-sftp_and_import | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/bin/freeside-cdr-sftp_and_import b/FS/bin/freeside-cdr-sftp_and_import index 722bf733e..a7452e87f 100755 --- a/FS/bin/freeside-cdr-sftp_and_import +++ b/FS/bin/freeside-cdr-sftp_and_import @@ -120,7 +120,7 @@ foreach my $filename ( @$ls ) { if ( $error ) { if ( $opt_s ) { - warn "$ungzipped: $error\n"; + warn "$ungziped: $error\n"; } else { unlink "$cachedir/$filename"; unlink "$cachedir/$ungziped" if $opt_g; -- cgit v1.2.1 From 92a3df0360d3df6b6ace99fee3d4cc443e6154d0 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 7 May 2013 23:55:11 -0700 Subject: NG auth: internal db auth, RT#21563 --- FS/FS/Auth.pm | 25 +++++++++++++++++++++++++ FS/FS/AuthCookieHandler.pm | 18 ++++++------------ FS/FS/Mason/Request.pm | 2 +- FS/FS/Schema.pm | 15 ++++++++------- eg/Auth-my_external_auth.pm | 27 +++++++++++++++++++++++++++ eg/access_user-external_auth.pm | 28 ---------------------------- 6 files changed, 67 insertions(+), 48 deletions(-) create mode 100644 FS/FS/Auth.pm create mode 100644 eg/Auth-my_external_auth.pm delete mode 100644 eg/access_user-external_auth.pm diff --git a/FS/FS/Auth.pm b/FS/FS/Auth.pm new file mode 100644 index 000000000..543978e8b --- /dev/null +++ b/FS/FS/Auth.pm @@ -0,0 +1,25 @@ +package FS::Auth; + +use strict; +use FS::Conf; + +sub authenticate { + my $class = shift; + + $class->auth_class->authenticate(@_); +} + +sub auth_class { + #my($class) = @_; + + my $conf = new FS::Conf; + my $module = lc($conf->config('authentication_module')) || 'internal'; + + my $auth_class = 'FS::Auth::'.$module; + eval "use $auth_class;"; + die $@ if $@; + + $auth_class; +} + +1; diff --git a/FS/FS/AuthCookieHandler.pm b/FS/FS/AuthCookieHandler.pm index a8ee37079..cd89f55af 100644 --- a/FS/FS/AuthCookieHandler.pm +++ b/FS/FS/AuthCookieHandler.pm @@ -4,34 +4,29 @@ use base qw( Apache2::AuthCookie ); use strict; use FS::UID qw( adminsuidsetup preuser_setup ); use FS::CurrentUser; - -my $module = 'legacy'; #XXX i am set in a conf somehow? or a config file +use FS::Auth; sub authen_cred { my( $self, $r, $username, $password ) = @_; + preuser_setup(); + unless ( _is_valid_user($username, $password) ) { warn "failed auth $username from ". $r->connection->remote_ip. "\n"; return undef; } warn "authenticated $username from ". $r->connection->remote_ip. "\n"; - adminsuidsetup($username); - FS::CurrentUser->new_session; + FS::CurrentUser->load_user($username); + FS::CurrentUser->new_session; } sub _is_valid_user { my( $username, $password ) = @_; - my $class = 'FS::Auth::'.$module; - - #earlier? - eval "use $class;"; - die $@ if $@; - - $class->authenticate($username, $password); + FS::Auth->authenticate($username, $password); } sub authen_ses_key { @@ -47,7 +42,6 @@ sub authen_ses_key { } $curuser->username; - } 1; diff --git a/FS/FS/Mason/Request.pm b/FS/FS/Mason/Request.pm index 1e2555a76..5d6fc4cd4 100644 --- a/FS/FS/Mason/Request.pm +++ b/FS/FS/Mason/Request.pm @@ -93,7 +93,7 @@ sub freeside_setup { $cgi = new CGI; setcgi($cgi); - #cgisuidsetup is gone, adminsuidsetup is now done in AuthCookieHandler + #cgisuidsetup is gone, equivalent is now done in AuthCookieHandler $fsurl = rooturl(); $p = popurl(2); diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 923f1fd9d..899b67b35 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3584,13 +3584,14 @@ sub tables_hashref { 'access_user' => { 'columns' => [ - 'usernum', 'serial', '', '', '', '', - 'username', 'varchar', '', $char_d, '', '', - '_password', 'varchar', '', $char_d, '', '', - 'last', 'varchar', '', $char_d, '', '', - 'first', 'varchar', '', $char_d, '', '', - 'user_custnum', 'int', 'NULL', '', '', '', - 'disabled', 'char', 'NULL', 1, '', '', + 'usernum', 'serial', '', '', '', '', + 'username', 'varchar', '', $char_d, '', '', + '_password', 'varchar', '', $char_d, '', '', + '_password_encoding', 'varchar', 'NULL', $char_d, '', '', + 'last', 'varchar', '', $char_d, '', '', + 'first', 'varchar', '', $char_d, '', '', + 'user_custnum', 'int', 'NULL', '', '', '', + 'disabled', 'char', 'NULL', 1, '', '', ], 'primary_key' => 'usernum', 'unique' => [ [ 'username' ] ], diff --git a/eg/Auth-my_external_auth.pm b/eg/Auth-my_external_auth.pm new file mode 100644 index 000000000..38f9d5bfb --- /dev/null +++ b/eg/Auth-my_external_auth.pm @@ -0,0 +1,27 @@ +package FS::Auth::my_external_auth; +use base qw( FS::Auth::external ); #need to inherit from ::external + +use strict; + +sub authenticate { + my($self, $username, $check_password ) = @_; + + #magic happens here + + if ( $auth_good ) { #verbose for clarity + return 1; + } else { + return 0; + } + +} + +#omitting these subroutines will eliminate those options from the UI + +#sub create_user { +# + +#sub change_password { +#} + +1; diff --git a/eg/access_user-external_auth.pm b/eg/access_user-external_auth.pm deleted file mode 100644 index bc6e23a2d..000000000 --- a/eg/access_user-external_auth.pm +++ /dev/null @@ -1,28 +0,0 @@ -package FS::access_user::external_auth; -use base qw( FS::access_user::external ); #inherit from ::external for - # autocreation - -use strict; - -sub authenticate { - my( $username, $check_password ) = @_; - - #magic happens here - - if ( $auth_good ) { #verbose for clarity - return 1; - } else { - return 0; - } - -} - -#omitting these subroutines will eliminate those options from the UI - -#sub create_user { -# - -#sub change_password { -#} - -1; -- cgit v1.2.1 From 199450cf528a5ac6b4fe739c38f9adf99a913712 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 7 May 2013 23:55:36 -0700 Subject: NG auth: internal db auth, RT#21563 --- FS/FS/Auth/internal.pm | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/FS/FS/Auth/internal.pm b/FS/FS/Auth/internal.pm index 86fddd237..5d9170e23 100644 --- a/FS/FS/Auth/internal.pm +++ b/FS/FS/Auth/internal.pm @@ -2,14 +2,44 @@ package FS::Auth::internal; #use base qw( FS::Auth ); use strict; +use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash); +use FS::Record qw( qsearchs ); +use FS::access_user; sub authenticate { - my( $username, $check_password ) = @_; + my($self, $username, $check_password ) = @_; + my $access_user = qsearchs('access_user', { 'username' => $username, + 'disabled' => '', + } + ) + or return 0; -} + if ( $access_user->_password_encoding eq 'bcrypt' ) { + + my( $cost, $salt, $hash ) = split(',', $access_user->_password); + + my $check_hash = bcrypt_hash( { key_nul => 1, + cost => $cost, + salt => $salt, + }, + $check_password + ); + + $hash eq $check_hash; + + } else { + + return 0 if $access_user->_password eq 'notyet' + || $access_user->_password eq ''; + + $access_user->_password eq $check_password; + + } -sub change_password { } +#sub change_password { +#} + 1; -- cgit v1.2.1 From d139a46390d127753877e8e55766e864df788d0b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 02:11:01 -0700 Subject: fix CCH update adding a TAXCAT, RT#21687 --- FS/FS/tax_class.pm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index bfec2c06c..eeb8993ee 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -259,13 +259,15 @@ sub batch_import { 'description' => $type->[1].':'.$cat->[1], } ); my $error = $tax_class->insert; - return $error if $error; + return "can't insert tax_class for old TAXTYPE $type and new TAXCAT $cat: $error" if $error; $imported++; } } + my %cats = map { $_=>1 } ( @old_cats, @{$data->{'taxcat'}} ); + foreach my $type (@{$data->{'taxtype'}}) { - foreach my $cat (@old_cats, @{$data->{'taxcat'}}) { + foreach my $cat (keys %cats) { if ( $job ) { # progress bar if ( time - $min_sec > $last ) { @@ -283,7 +285,7 @@ sub batch_import { 'description' => $type->[1].':'.$cat->[1], } ); my $error = $tax_class->insert; - return $error if $error; + return "can't insert tax_class for new TAXTYPE $type and TAXCAT $cat: $error" if $error; $imported++; } } @@ -363,7 +365,7 @@ sub batch_import { my $error = &{$endhook}(); if ( $error ) { $dbh->rollback if $oldAutoCommit; - return "can't insert tax_class for $line: $error"; + return "can't run end hook: $error"; } $dbh->commit or die $dbh->errstr if $oldAutoCommit; -- cgit v1.2.1 From 9732b34df2fad5f09751766378c05eacd671e4fb Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 02:55:51 -0700 Subject: fix CCH update adding a TAXCAT, RT#21687 --- FS/FS/tax_class.pm | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index eeb8993ee..15f9a42a6 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -253,21 +253,28 @@ sub batch_import { } } - my $tax_class = - new FS::tax_class( { 'data_vendor' => 'cch', - 'taxclass' => $type->[0].':'.$cat->[0], - 'description' => $type->[1].':'.$cat->[1], - } ); - my $error = $tax_class->insert; - return "can't insert tax_class for old TAXTYPE $type and new TAXCAT $cat: $error" if $error; + my %hash = ( 'data_vendor' => 'cch', + 'taxclass' => $type->[0].':'.$cat->[0], + 'description' => $type->[1].':'.$cat->[1], + ); + unless ( qsearchs('tax_class', \%hash) ) { + my $tax_class = new FS::tax_class \%hash; + my $error = $tax_class->insert; + + return "can't insert tax_class for ". + " old TAXTYPE ". $type->[0].':'.$type->[1]. + " and new TAXCAT ". $cat->[0].':'. $cat->[1]. + " : $error" + if $error; + } + $imported++; + } } - my %cats = map { $_=>1 } ( @old_cats, @{$data->{'taxcat'}} ); - foreach my $type (@{$data->{'taxtype'}}) { - foreach my $cat (keys %cats) { + foreach my $cat (@old_cats, @{$data->{'taxcat'}}) { if ( $job ) { # progress bar if ( time - $min_sec > $last ) { -- cgit v1.2.1 From 56094325213b403e787bbfce7f3db7870b707173 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 03:31:32 -0700 Subject: debug CCH update replacing a TAXCAT, RT#21687 --- FS/FS/tax_class.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index 15f9a42a6..376a1ad40 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -169,7 +169,7 @@ sub batch_import { $hook = sub { my $hash = shift; - +warn Dumper($hash); if ($hash->{'table'} eq 'DETAIL') { push @{$data->{'taxcat'}}, [ $hash->{'value'}, $hash->{'description'} ] if ($hash->{'name'} eq 'TAXCAT' && @@ -194,6 +194,7 @@ sub batch_import { ($name eq 'TAXCAT' ? $value : '%')."'", ); foreach (@tax_class) { +warn "deleting ". $_->taxclass. ' '. $_->description. "\n"; my $error = $_->delete; return $error if $error; } -- cgit v1.2.1 From f744f757a01e1750afa55072c7208714f16d1d13 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 03:46:41 -0700 Subject: debug CCH update replacing a TAXCAT, RT#21687 --- FS/FS/tax_class.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index 376a1ad40..c8fe88968 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -169,6 +169,7 @@ sub batch_import { $hook = sub { my $hash = shift; +use Data::Dumper; warn Dumper($hash); if ($hash->{'table'} eq 'DETAIL') { push @{$data->{'taxcat'}}, [ $hash->{'value'}, $hash->{'description'} ] -- cgit v1.2.1 From d8843f184a7f6ee87eec99724f2d6430c1df34ea Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 03:51:33 -0700 Subject: revert changes checked into this branch by accident --- FS/FS/tax_class.pm | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index c8fe88968..bfec2c06c 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -169,8 +169,7 @@ sub batch_import { $hook = sub { my $hash = shift; -use Data::Dumper; -warn Dumper($hash); + if ($hash->{'table'} eq 'DETAIL') { push @{$data->{'taxcat'}}, [ $hash->{'value'}, $hash->{'description'} ] if ($hash->{'name'} eq 'TAXCAT' && @@ -195,7 +194,6 @@ warn Dumper($hash); ($name eq 'TAXCAT' ? $value : '%')."'", ); foreach (@tax_class) { -warn "deleting ". $_->taxclass. ' '. $_->description. "\n"; my $error = $_->delete; return $error if $error; } @@ -255,23 +253,14 @@ warn "deleting ". $_->taxclass. ' '. $_->description. "\n"; } } - my %hash = ( 'data_vendor' => 'cch', - 'taxclass' => $type->[0].':'.$cat->[0], - 'description' => $type->[1].':'.$cat->[1], - ); - unless ( qsearchs('tax_class', \%hash) ) { - my $tax_class = new FS::tax_class \%hash; - my $error = $tax_class->insert; - - return "can't insert tax_class for ". - " old TAXTYPE ". $type->[0].':'.$type->[1]. - " and new TAXCAT ". $cat->[0].':'. $cat->[1]. - " : $error" - if $error; - } - + my $tax_class = + new FS::tax_class( { 'data_vendor' => 'cch', + 'taxclass' => $type->[0].':'.$cat->[0], + 'description' => $type->[1].':'.$cat->[1], + } ); + my $error = $tax_class->insert; + return $error if $error; $imported++; - } } @@ -294,7 +283,7 @@ warn "deleting ". $_->taxclass. ' '. $_->description. "\n"; 'description' => $type->[1].':'.$cat->[1], } ); my $error = $tax_class->insert; - return "can't insert tax_class for new TAXTYPE $type and TAXCAT $cat: $error" if $error; + return $error if $error; $imported++; } } @@ -374,7 +363,7 @@ warn "deleting ". $_->taxclass. ' '. $_->description. "\n"; my $error = &{$endhook}(); if ( $error ) { $dbh->rollback if $oldAutoCommit; - return "can't run end hook: $error"; + return "can't insert tax_class for $line: $error"; } $dbh->commit or die $dbh->errstr if $oldAutoCommit; -- cgit v1.2.1 From bee0671782e7a40961cf406cd7a10675fed6b3ba Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 03:52:42 -0700 Subject: debug CCH update adding a tax class, RT#21687 --- FS/FS/tax_class.pm | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index bfec2c06c..c8fe88968 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -169,7 +169,8 @@ sub batch_import { $hook = sub { my $hash = shift; - +use Data::Dumper; +warn Dumper($hash); if ($hash->{'table'} eq 'DETAIL') { push @{$data->{'taxcat'}}, [ $hash->{'value'}, $hash->{'description'} ] if ($hash->{'name'} eq 'TAXCAT' && @@ -194,6 +195,7 @@ sub batch_import { ($name eq 'TAXCAT' ? $value : '%')."'", ); foreach (@tax_class) { +warn "deleting ". $_->taxclass. ' '. $_->description. "\n"; my $error = $_->delete; return $error if $error; } @@ -253,14 +255,23 @@ sub batch_import { } } - my $tax_class = - new FS::tax_class( { 'data_vendor' => 'cch', - 'taxclass' => $type->[0].':'.$cat->[0], - 'description' => $type->[1].':'.$cat->[1], - } ); - my $error = $tax_class->insert; - return $error if $error; + my %hash = ( 'data_vendor' => 'cch', + 'taxclass' => $type->[0].':'.$cat->[0], + 'description' => $type->[1].':'.$cat->[1], + ); + unless ( qsearchs('tax_class', \%hash) ) { + my $tax_class = new FS::tax_class \%hash; + my $error = $tax_class->insert; + + return "can't insert tax_class for ". + " old TAXTYPE ". $type->[0].':'.$type->[1]. + " and new TAXCAT ". $cat->[0].':'. $cat->[1]. + " : $error" + if $error; + } + $imported++; + } } @@ -283,7 +294,7 @@ sub batch_import { 'description' => $type->[1].':'.$cat->[1], } ); my $error = $tax_class->insert; - return $error if $error; + return "can't insert tax_class for new TAXTYPE $type and TAXCAT $cat: $error" if $error; $imported++; } } @@ -363,7 +374,7 @@ sub batch_import { my $error = &{$endhook}(); if ( $error ) { $dbh->rollback if $oldAutoCommit; - return "can't insert tax_class for $line: $error"; + return "can't run end hook: $error"; } $dbh->commit or die $dbh->errstr if $oldAutoCommit; -- cgit v1.2.1 From 7685d697180f48048b8a98de84718a26d8fb58b7 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 04:10:46 -0700 Subject: proceed with a CCH update even if some GEOCODE/tax_rate_location deletions can't be found, RT#21687 --- FS/FS/tax_rate_location.pm | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/FS/FS/tax_rate_location.pm b/FS/FS/tax_rate_location.pm index b4be8b90e..aeb14d31a 100644 --- a/FS/FS/tax_rate_location.pm +++ b/FS/FS/tax_rate_location.pm @@ -234,13 +234,14 @@ sub batch_import { $hash->{disabled} = ''; my $tax_rate_location = qsearchs('tax_rate_location', $hash); - return "Can't find tax_rate_location to delete: ". - join(" ", map { "$_ => ". $hash->{$_} } @fields) - unless $tax_rate_location; - - $tax_rate_location->disabled('Y'); - my $error = $tax_rate_location->replace; - return $error if $error; + if ( $tax_rate_location ) { + $tax_rate_location->disabled('Y'); + my $error = $tax_rate_location->replace; + return $error if $error; + } else { + warn "WARNING: Can't find tax_rate_location to delete, continuing update anyway: ". + join(" ", map { "$_ => ". $hash->{$_} } @fields); + } delete($hash->{$_}) foreach (keys %$hash); } -- cgit v1.2.1 From fc8def113cc11ef4572b45100c37ff2b37bb7a3d Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 04:35:35 -0700 Subject: revert: proceed with a CCH update even if some GEOCODE/tax_rate_location deletions can't be found, RT#21687 --- FS/FS/tax_rate_location.pm | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/FS/FS/tax_rate_location.pm b/FS/FS/tax_rate_location.pm index aeb14d31a..b4be8b90e 100644 --- a/FS/FS/tax_rate_location.pm +++ b/FS/FS/tax_rate_location.pm @@ -234,14 +234,13 @@ sub batch_import { $hash->{disabled} = ''; my $tax_rate_location = qsearchs('tax_rate_location', $hash); - if ( $tax_rate_location ) { - $tax_rate_location->disabled('Y'); - my $error = $tax_rate_location->replace; - return $error if $error; - } else { - warn "WARNING: Can't find tax_rate_location to delete, continuing update anyway: ". - join(" ", map { "$_ => ". $hash->{$_} } @fields); - } + return "Can't find tax_rate_location to delete: ". + join(" ", map { "$_ => ". $hash->{$_} } @fields) + unless $tax_rate_location; + + $tax_rate_location->disabled('Y'); + my $error = $tax_rate_location->replace; + return $error if $error; delete($hash->{$_}) foreach (keys %$hash); } -- cgit v1.2.1 From 4c19a4409480f6ba71e79757c723a307ac485347 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 05:00:07 -0700 Subject: fix cch update adding a TAXCAT, RT#21687 --- FS/FS/tax_rate.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/tax_rate.pm b/FS/FS/tax_rate.pm index a5a623d94..e146bd6a9 100644 --- a/FS/FS/tax_rate.pm +++ b/FS/FS/tax_rate.pm @@ -978,7 +978,7 @@ sub _perform_batch_import { unlink $filename or warn "Can't delete $filename: $!" unless $keep_cch_files; push @insert_list, $name, $insertname, $import_sub, $format; - if ( $name eq 'GEOCODE' ) { #handle this whole ordering issue better + if ( $name eq 'GEOCODE' || $name eq 'CODE' ) { #handle this whole ordering issue better unshift @predelete_list, $name, $deletename, $import_sub, $format; } else { unshift @delete_list, $name, $deletename, $import_sub, $format; -- cgit v1.2.1 From 5cc16936f50d1ab2ea4b3f7b209405731b3ac014 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 05:06:54 -0700 Subject: fix cch update adding a TAXCAT, RT#21687 --- FS/FS/tax_class.pm | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index c8fe88968..79bb24836 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -83,9 +83,6 @@ Delete this record from the database. sub delete { my $self = shift; - return "Can't delete a tax class which has tax rates!" - if qsearch( 'tax_rate', { 'taxclassnum' => $self->taxclassnum } ); - return "Can't delete a tax class which has package tax rates!" if qsearch( 'part_pkg_taxrate', { 'taxclassnum' => $self->taxclassnum } ); @@ -95,8 +92,37 @@ sub delete { return "Can't delete a tax class which has package tax overrides!" if qsearch( 'part_pkg_taxoverride', { 'taxclassnum' => $self->taxclassnum } ); - $self->SUPER::delete(@_); - + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + foreach my $tax_rate ( + qsearch( 'tax_rate', { taxclassnum=>$self->taxclassnum } ) + ) { + my $error = $tax_rate->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + my $error = $self->SUPER::delete(@_); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + } =item replace OLD_RECORD @@ -169,8 +195,7 @@ sub batch_import { $hook = sub { my $hash = shift; -use Data::Dumper; -warn Dumper($hash); + if ($hash->{'table'} eq 'DETAIL') { push @{$data->{'taxcat'}}, [ $hash->{'value'}, $hash->{'description'} ] if ($hash->{'name'} eq 'TAXCAT' && @@ -195,7 +220,6 @@ warn Dumper($hash); ($name eq 'TAXCAT' ? $value : '%')."'", ); foreach (@tax_class) { -warn "deleting ". $_->taxclass. ' '. $_->description. "\n"; my $error = $_->delete; return $error if $error; } @@ -389,9 +413,6 @@ warn "deleting ". $_->taxclass. ' '. $_->description. "\n"; =head1 BUGS - batch_import does not handle mixed I and D records in the same file for - format cch-update - =head1 SEE ALSO L, schema.html from the base documentation. -- cgit v1.2.1 From 5c7c467af6e6880b05df8bd04a6744e72d8d0577 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 05:09:37 -0700 Subject: fix cch update adding a TAXCAT, RT#21687 --- FS/FS/tax_class.pm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index 79bb24836..7fe102385 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -83,9 +83,6 @@ Delete this record from the database. sub delete { my $self = shift; - return "Can't delete a tax class which has package tax rates!" - if qsearch( 'part_pkg_taxrate', { 'taxclassnum' => $self->taxclassnum } ); - return "Can't delete a tax class which has package tax rates!" if qsearch( 'part_pkg_taxrate', { 'taxclassnumtaxed' => $self->taxclassnum } ); @@ -113,6 +110,16 @@ sub delete { } } + foreach my $part_pkg_taxrate ( + qsearch( 'part_pkg_taxrate', { taxclassnum=>$self->taxclassnum } ) + ) { + my $error = $part_pkg_taxrate->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + my $error = $self->SUPER::delete(@_); if ( $error ) { $dbh->rollback if $oldAutoCommit; -- cgit v1.2.1 From fe5b1c30b591e50abc6f5496853f24f79a84e1c1 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 11:48:09 -0700 Subject: fix cch update removing a TAXCAT, RT#21687 --- FS/FS/tax_rate.pm | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/FS/FS/tax_rate.pm b/FS/FS/tax_rate.pm index e146bd6a9..721d5f583 100644 --- a/FS/FS/tax_rate.pm +++ b/FS/FS/tax_rate.pm @@ -785,7 +785,8 @@ sub batch_import { } - for (grep { !exists($delete{$_}) } keys %insert) { + my @replace = grep { exists($delete{$_}) } keys %insert; + for (@replace) { if ( $job ) { # progress bar if ( time - $min_sec > $last ) { my $error = $job->update_statustext( @@ -799,20 +800,35 @@ sub batch_import { } } - my $tax_rate = new FS::tax_rate( $insert{$_} ); - my $error = $tax_rate->insert; + my $old = qsearchs( 'tax_rate', $delete{$_} ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - my $hashref = $insert{$_}; - $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) ); - return "can't insert tax_rate for $line: $error"; + if ( $old ) { + + my $new = new FS::tax_rate({ $old->hash, %{$insert{$_}}, 'manual' => '' }); + $new->taxnum($old->taxnum); + my $error = $new->replace($old); + + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + my $hashref = $insert{$_}; + $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) ); + return "can't replace tax_rate for $line: $error"; + } + + $imported++; + + } else { + + $old = delete $delete{$_}; + warn "WARNING: can't find tax_rate to replace (inserting instead and continuing) for: ". + #join(" ", map { "$_ => ". $old->{$_} } @fields); + join(" ", map { "$_ => ". $old->{$_} } keys(%$old) ); } $imported++; } - for (grep { exists($delete{$_}) } keys %insert) { + for (grep { !exists($delete{$_}) } keys %insert) { if ( $job ) { # progress bar if ( time - $min_sec > $last ) { my $error = $job->update_statustext( @@ -826,27 +842,17 @@ sub batch_import { } } - my $old = qsearchs( 'tax_rate', $delete{$_} ); - unless ($old) { - $dbh->rollback if $oldAutoCommit; - $old = $delete{$_}; - return "can't find tax_rate to replace for: ". - #join(" ", map { "$_ => ". $old->{$_} } @fields); - join(" ", map { "$_ => ". $old->{$_} } keys(%$old) ); - } - my $new = new FS::tax_rate({ $old->hash, %{$insert{$_}}, 'manual' => '' }); - $new->taxnum($old->taxnum); - my $error = $new->replace($old); + my $tax_rate = new FS::tax_rate( $insert{$_} ); + my $error = $tax_rate->insert; if ( $error ) { $dbh->rollback if $oldAutoCommit; my $hashref = $insert{$_}; $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) ); - return "can't replace tax_rate for $line: $error"; + return "can't insert tax_rate for $line: $error"; } $imported++; - $imported++; } for (grep { !exists($insert{$_}) } keys %delete) { -- cgit v1.2.1 From 66720bf1f5bae4b1d4022eabff456c247447fbc1 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 13:33:24 -0700 Subject: fix cch update removal of PLUS4/ZIP and TXMATRIX, RT#21687 --- FS/FS/cust_tax_location.pm | 10 ++++++---- FS/FS/part_pkg_taxrate.pm | 13 +++++++------ FS/FS/tax_rate.pm | 18 +++++++++++++++--- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/FS/FS/cust_tax_location.pm b/FS/FS/cust_tax_location.pm index 1a9bf5a41..aec941045 100644 --- a/FS/FS/cust_tax_location.pm +++ b/FS/FS/cust_tax_location.pm @@ -234,13 +234,15 @@ sub batch_import { if (exists($hash->{actionflag}) && $hash->{actionflag} eq 'D') { delete($hash->{actionflag}); - my $cust_tax_location = qsearchs('cust_tax_location', $hash); + my @cust_tax_location = qsearch('cust_tax_location', $hash); return "Can't find cust_tax_location to delete: ". join(" ", map { "$_ => ". $hash->{$_} } @fields) - unless $cust_tax_location; + unless scalar(@cust_tax_location) || $param->{'delete_only'} ; - my $error = $cust_tax_location->delete; - return $error if $error; + foreach my $cust_tax_location (@cust_tax_location) { + my $error = $cust_tax_location->delete; + return $error if $error; + } delete($hash->{$_}) foreach (keys %$hash); } diff --git a/FS/FS/part_pkg_taxrate.pm b/FS/FS/part_pkg_taxrate.pm index c83f700d9..a73272040 100644 --- a/FS/FS/part_pkg_taxrate.pm +++ b/FS/FS/part_pkg_taxrate.pm @@ -5,8 +5,7 @@ use vars qw( @ISA ); use Date::Parse; use DateTime; use DateTime::Format::Strptime; -use FS::UID qw(dbh); -use FS::Record qw( qsearch qsearchs ); +use FS::Record qw( qsearch qsearchs dbh ); use FS::part_pkg_taxproduct; use FS::Misc qw(csv_from_fixed); @@ -310,8 +309,8 @@ sub batch_import { } } - my $part_pkg_taxrate = qsearchs('part_pkg_taxrate', $hash); - unless ( $part_pkg_taxrate ) { + my @part_pkg_taxrate = qsearch('part_pkg_taxrate', $hash); + unless ( scalar(@part_pkg_taxrate) || $param->{'delete_only'} ) { if ( $hash->{taxproductnum} ) { my $taxproduct = qsearchs( 'part_pkg_taxproduct', @@ -324,8 +323,10 @@ sub batch_import { join(" ", map { "$_ => *". $hash->{$_}. '*' } keys(%$hash) ); } - my $error = $part_pkg_taxrate->delete; - return $error if $error; + foreach my $part_pkg_taxrate (@part_pkg_taxrate) { + my $error = $part_pkg_taxrate->delete; + return $error if $error; + } delete($hash->{$_}) foreach (keys %$hash); } diff --git a/FS/FS/tax_rate.pm b/FS/FS/tax_rate.pm index 721d5f583..265383398 100644 --- a/FS/FS/tax_rate.pm +++ b/FS/FS/tax_rate.pm @@ -967,7 +967,7 @@ sub _perform_batch_import { my $file = lc($name). 'file'; unless ($files{$file}) { - $error = "No $name supplied"; + #$error = "No $name supplied"; next; } next if $name eq 'DETAIL' && $format =~ /update/; @@ -1002,10 +1002,17 @@ sub _perform_batch_import { 'DETAIL', "$dir/".$files{detailfile}, \&FS::tax_rate::batch_import, $format if $format =~ /update/; + my %addl_param = (); + if ( $param->{'delete_only'} ) { + $addl_param{'delete_only'} = $param->{'delete_only'}; + @insert_list = () + } + $error ||= _perform_cch_tax_import( $job, [ @predelete_list ], [ @insert_list ], [ @delete_list ], + \%addl_param, ); @@ -1030,7 +1037,8 @@ sub _perform_batch_import { sub _perform_cch_tax_import { - my ( $job, $predelete_list, $insert_list, $delete_list ) = @_; + my ( $job, $predelete_list, $insert_list, $delete_list, $addl_param ) = @_; + $addl_param ||= {}; my $error = ''; foreach my $list ($predelete_list, $insert_list, $delete_list) { @@ -1039,7 +1047,11 @@ sub _perform_cch_tax_import { my $fmt = "$format-update"; $fmt = $format. ( lc($name) eq 'zip' ? '-zip' : '' ); open my $fh, "< $file" or $error ||= "Can't open $name file $file: $!"; - $error ||= &{$method}({ 'filehandle' => $fh, 'format' => $fmt }, $job); + my $param = { 'filehandle' => $fh, + 'format' => $fmt, + %$addl_param, + }; + $error ||= &{$method}($param, $job); close $fh; } } -- cgit v1.2.1 From d2714607b1002c73a7e5c624de985c7b60d20338 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 13:38:38 -0700 Subject: fix cch update removal of PLUS4/ZIP and TXMATRIX, RT#21687 --- FS/FS/cust_tax_location.pm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/FS/FS/cust_tax_location.pm b/FS/FS/cust_tax_location.pm index aec941045..4293b2c90 100644 --- a/FS/FS/cust_tax_location.pm +++ b/FS/FS/cust_tax_location.pm @@ -199,13 +199,15 @@ sub batch_import { if (exists($hash->{actionflag}) && $hash->{actionflag} eq 'D') { delete($hash->{actionflag}); - my $cust_tax_location = qsearchs('cust_tax_location', $hash); + my @cust_tax_location = qsearch('cust_tax_location', $hash); return "Can't find cust_tax_location to delete: ". join(" ", map { "$_ => ". $hash->{$_} } @fields) - unless $cust_tax_location; + unless scalar(@cust_tax_location) || $param->{'delete_only'} ; - my $error = $cust_tax_location->delete; - return $error if $error; + foreach my $cust_tax_location (@cust_tax_location) { + my $error = $cust_tax_location->delete; + return $error if $error; + } delete($hash->{$_}) foreach (keys %$hash); } -- cgit v1.2.1 From 04a9b5d2558b495f23508f3efc25fb51edae88e4 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 13:53:17 -0700 Subject: use tables that are searched --- FS/FS/tax_class.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FS/FS/tax_class.pm b/FS/FS/tax_class.pm index 7fe102385..d68e7e30c 100644 --- a/FS/FS/tax_class.pm +++ b/FS/FS/tax_class.pm @@ -5,6 +5,8 @@ use vars qw( @ISA ); use FS::UID qw(dbh); use FS::Record qw( qsearch qsearchs ); use FS::Misc qw( csv_from_fixed ); +use FS::part_pkg_taxrate; +use FS::part_pkg_taxoverride; @ISA = qw(FS::Record); -- cgit v1.2.1 From 580d1080593d3b2583d6e164c1efeff86cde6f89 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 13:54:06 -0700 Subject: cch tools --- bin/cch.finish_failed | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ bin/cch.redelete | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 bin/cch.finish_failed create mode 100644 bin/cch.redelete diff --git a/bin/cch.finish_failed b/bin/cch.finish_failed new file mode 100644 index 000000000..cb2533044 --- /dev/null +++ b/bin/cch.finish_failed @@ -0,0 +1,51 @@ +#!/usr/bin/perl -w + +use strict; +use Storable qw( thaw nfreeze ); +use MIME::Base64; +use FS::UID qw( adminsuidsetup ); +use FS::tax_rate; + +adminsuidsetup(shift); + +#my @namelist = qw( code detail geocode plus4 txmatrix zip ); +my @namelist = qw( code detail plus4 txmatrix zip ); + +my $cache_dir = '/usr/local/etc/freeside/cache.'. $FS::UID::datasrc. '/'; +my $dir = $cache_dir.'taxdata/cch'; + +my @list = (); +foreach my $name ( @namelist ) { + my $difffile = "$dir.new/$name.txt"; + if (1) { # ($update) { + #my $error = $job->update_statustext( "0,Comparing to previous $name" ); + #die $error if $error; + warn "processing $dir.new/$name.txt\n"; # if $DEBUG; + #my $olddir = $update ? "$dir.1" : ""; + my $olddir = "$dir.1"; + $difffile = FS::tax_rate::_perform_cch_diff( $name, "$dir.new", $olddir ); + } + $difffile =~ s/^$cache_dir//; + push @list, "${name}file:$difffile"; +} + +# perform the import +local $FS::tax_rate::keep_cch_files = 1; +my $param = { + 'format' => 'cch-update', + 'uploaded_files' => join( ',', @list ), +}; +my $error = + #_perform_batch_import( $job, encode_base64( nfreeze( $param ) ) ); + FS::tax_rate::_perform_batch_import( '', encode_base64( nfreeze( $param ) ) ); + +if ( $error ) { + warn "ERROR: $error\n"; +} else { + warn "success!\n"; +} + +#XXX do this manually +#rename "$dir.new", "$dir" +# or die "cch tax update processed, but can't rename $dir.new: $!\n"; + diff --git a/bin/cch.redelete b/bin/cch.redelete new file mode 100644 index 000000000..2cff389ad --- /dev/null +++ b/bin/cch.redelete @@ -0,0 +1,52 @@ +#!/usr/bin/perl -w + +use strict; +use Storable qw( thaw nfreeze ); +use MIME::Base64; +use FS::UID qw( adminsuidsetup ); +use FS::tax_rate; + +adminsuidsetup(shift); + +#my @namelist = qw( code detail geocode plus4 txmatrix zip ); +my @namelist = qw( plus4 txmatrix zip ); + +my $cache_dir = '/usr/local/etc/freeside/cache.'. $FS::UID::datasrc. '/'; +my $dir = $cache_dir.'taxdata/cch'; + +my @list = (); +foreach my $name ( @namelist ) { + my $difffile = "$dir.new/$name.txt"; + if (1) { # ($update) { + #my $error = $job->update_statustext( "0,Comparing to previous $name" ); + #die $error if $error; + warn "processing $dir.new/$name.txt\n"; # if $DEBUG; + #my $olddir = $update ? "$dir.1" : ""; + my $olddir = "$dir.1"; + $difffile = FS::tax_rate::_perform_cch_diff( $name, "$dir.new", $olddir ); + } + $difffile =~ s/^$cache_dir//; + push @list, "${name}file:$difffile"; +} + +# perform the import +local $FS::tax_rate::keep_cch_files = 1; +my $param = { + 'format' => 'cch-update', + 'uploaded_files' => join( ',', @list ), + 'delete_only' => 1, +}; +my $error = + #_perform_batch_import( $job, encode_base64( nfreeze( $param ) ) ); + FS::tax_rate::_perform_batch_import( '', encode_base64( nfreeze( $param ) ) ); + +if ( $error ) { + warn "ERROR: $error\n"; +} else { + warn "success!\n"; +} + +#XXX do this manually +#rename "$dir.new", "$dir" +# or die "cch tax update processed, but can't rename $dir.new: $!\n"; + -- cgit v1.2.1 From 2c323723445c1301057078c3f312b15d00734a66 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 14:01:52 -0700 Subject: $YEAR --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index a2babf317..e68c06ffc 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ Freeside is a billing and administration package for Internet Service Providers, VoIP providers and other online businesses. -Copyright (C) 2005-2011 Freeside Internet Services, Inc. +Copyright (C) 2005-2013 Freeside Internet Services, Inc. Copyright (C) 2000-2005 Ivan Kohler Copyright (C) 1999 Silicon Interactive Software Design Additional copyright holders may be found in the docs/license.html file. -- cgit v1.2.1 From 51a7e60b5c7dc157bd2bbe701201d3808aa36f58 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 8 May 2013 14:23:27 -0700 Subject: handle CCH maxtype = 1 taxes, RT#19150 --- FS/FS/tax_rate.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FS/FS/tax_rate.pm b/FS/FS/tax_rate.pm index 265383398..342c7cb0b 100644 --- a/FS/FS/tax_rate.pm +++ b/FS/FS/tax_rate.pm @@ -413,7 +413,7 @@ sub taxline { } my $maxtype = $self->maxtype || 0; - if ($maxtype != 0 && $maxtype != 9) { + if ($maxtype != 0 && $maxtype != 1 && $maxtype != 9) { return $self->_fatal_or_null( 'tax with "'. $self->maxtype_name. '" threshold' ); @@ -476,12 +476,12 @@ sub taxline { } - # - # XXX insert exemption handling here + # XXX handle excessrate (use_excessrate) / excessfee / + # taxbase/feebase / taxmax/feemax + # and eventually exemptions # # the tax or fee is applied to taxbase or feebase and then # the excessrate or excess fee is applied to taxmax or feemax - # $amount += $taxable_charged * $self->tax; $amount += $taxable_units * $self->fee; -- cgit v1.2.1 From 120718856665ca90ad852535d1155f8ea8ecb6b6 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 9 May 2013 01:42:39 -0700 Subject: NG auth: pw changes, RT#21563 --- FS/FS/Auth/internal.pm | 57 +++++++++++++++++++++------ FS/FS/access_user.pm | 23 ++++++++++- httemplate/edit/access_user.html | 10 ++++- httemplate/edit/process/access_user.html | 28 +++++++++---- httemplate/edit/process/elements/process.html | 7 ++++ httemplate/pref/pref-process.html | 36 ++++++++--------- httemplate/pref/pref.html | 34 ++++++++-------- 7 files changed, 138 insertions(+), 57 deletions(-) diff --git a/FS/FS/Auth/internal.pm b/FS/FS/Auth/internal.pm index 5d9170e23..bb116ce75 100644 --- a/FS/FS/Auth/internal.pm +++ b/FS/FS/Auth/internal.pm @@ -2,29 +2,32 @@ package FS::Auth::internal; #use base qw( FS::Auth ); use strict; -use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash); +use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash en_base64 de_base64); use FS::Record qw( qsearchs ); use FS::access_user; sub authenticate { my($self, $username, $check_password ) = @_; - my $access_user = qsearchs('access_user', { 'username' => $username, - 'disabled' => '', - } - ) + my $access_user = + ref($username) ? $username + : qsearchs('access_user', { 'username' => $username, + 'disabled' => '', + } + ) or return 0; if ( $access_user->_password_encoding eq 'bcrypt' ) { my( $cost, $salt, $hash ) = split(',', $access_user->_password); - my $check_hash = bcrypt_hash( { key_nul => 1, - cost => $cost, - salt => $salt, - }, - $check_password - ); + my $check_hash = en_base64( bcrypt_hash( { key_nul => 1, + cost => $cost, + salt => de_base64($salt), + }, + $check_password + ) + ); $hash eq $check_hash; @@ -39,7 +42,35 @@ sub authenticate { } -#sub change_password { -#} +sub change_password { + my($self, $access_user, $new_password) = @_; + + $self->change_password_fields( $access_user, $new_password ); + + $access_user->replace; + +} + +sub change_password_fields { + my($self, $access_user, $new_password) = @_; + + $access_user->_password_encoding('bcrypt'); + + my $cost = 8; + + my $salt = pack( 'C*', map int(rand(256)), 1..16 ); + + my $hash = bcrypt_hash( { key_nul => 1, + cost => $cost, + salt => $salt, + }, + $new_password, + ); + + $access_user->_password( + join(',', $cost, en_base64($salt), en_base64($hash) ) + ); + +} 1; diff --git a/FS/FS/access_user.pm b/FS/FS/access_user.pm index 509cc0950..cdee3773b 100644 --- a/FS/FS/access_user.pm +++ b/FS/FS/access_user.pm @@ -4,6 +4,7 @@ use strict; use base qw( FS::m2m_Common FS::option_Common ); use vars qw( $DEBUG $me $conf $htpasswd_file ); use FS::UID; +use FS::Auth; use FS::Conf; use FS::Record qw( qsearch qsearchs dbh ); use FS::access_user_pref; @@ -563,7 +564,27 @@ sub is_system_user { fs_signup fs_bootstrap fs_selfserv -) ); + ) ); +} + +=item change_password NEW_PASSWORD + +=cut + +sub change_password { + #my( $self, $password ) = @_; + #FS::Auth->auth_class->change_password( $self, $password ); + FS::Auth->auth_class->change_password( @_ ); +} + +=item change_password_fields NEW_PASSWORD + +=cut + +sub change_password_fields { + #my( $self, $password ) = @_; + #FS::Auth->auth_class->change_password_fields( $self, $password ); + FS::Auth->auth_class->change_password_fields( @_ ); } =back diff --git a/httemplate/edit/access_user.html b/httemplate/edit/access_user.html index 86ce25374..b087943c2 100644 --- a/httemplate/edit/access_user.html +++ b/httemplate/edit/access_user.html @@ -3,8 +3,7 @@ 'table' => 'access_user', 'fields' => [ 'username', - { field=>'_password', type=>'password' }, - { field=>'_password2', type=>'password' }, + @pw_fields, 'last', 'first', { field=>'user_custnum', type=>'search-cust_main', }, @@ -50,6 +49,13 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); +my @pw_fields = + FS::Auth->auth_class->can('change_password') + ? ( { field=>'_password', type=>'password' }, + { field=>'_password2', type=>'password' }, + ) + : (); + my $check_user_custnum_search = < function check_user_custnum_search(what) { diff --git a/httemplate/edit/process/access_user.html b/httemplate/edit/process/access_user.html index 8e7e70a06..7fc7c25e1 100644 --- a/httemplate/edit/process/access_user.html +++ b/httemplate/edit/process/access_user.html @@ -3,14 +3,15 @@ % print $cgi->redirect(popurl(2) . "access_user.html?" . $cgi->query_string); % } else { <% include( 'elements/process.html', - 'table' => 'access_user', - 'viewall_dir' => 'browse', - 'copy_on_empty' => [ '_password' ], + 'table' => 'access_user', + 'viewall_dir' => 'browse', + 'copy_on_empty' => [ '_password', '_password_encoding' ], 'clear_on_error' => [ '_password', '_password2' ], - 'process_m2m' => { 'link_table' => 'access_usergroup', - 'target_table' => 'access_group', - }, - 'precheck_callback'=> \&precheck_callback, + 'process_m2m' => { 'link_table' => 'access_usergroup', + 'target_table' => 'access_group', + }, + 'precheck_callback' => \&precheck_callback, + 'post_new_object_callback' => \&post_new_object_callback, ) %> % } @@ -26,11 +27,24 @@ if ( FS::Conf->new->exists('disable_acl_changes') ) { sub precheck_callback { my $cgi = shift; + my $o = FS::access_user->new({username => $cgi->param('username')}); if( $o->is_system_user and !$cgi->param('usernum') ) { $cgi->param('username',''); return "username '".$o->username."' reserved for system account." } + return ''; } + +sub post_new_object_callback { + my( $cgi, $access_user ) = @_; + + if ( length($cgi->param('_password')) ) { + my $password = scalar($cgi->param('_password')); + $access_user->change_password_fields($password); + } + +} + diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html index fb1ee7a27..2afbdd082 100644 --- a/httemplate/edit/process/elements/process.html +++ b/httemplate/edit/process/elements/process.html @@ -70,6 +70,9 @@ Example: #return an error string or empty for no error 'precheck_callback' => sub { my( $cgi ) = @_; }, + #after the new object is created + 'post_new_object_callback' => sub { my( $cgi, $object ) = @_; }, + #after everything's inserted 'noerror_callback' => sub { my( $cgi, $object ) = @_; }, @@ -226,6 +229,10 @@ foreach my $value ( @values ) { } } + if ( $opt{'post_new_object_callback'} ) { + &{ $opt{'post_new_object_callback'} }( $cgi, $new ); + } + if ( $opt{'agent_virt'} ) { if ( ! $new->agentnum diff --git a/httemplate/pref/pref-process.html b/httemplate/pref/pref-process.html index 242e12294..962ee51b6 100644 --- a/httemplate/pref/pref-process.html +++ b/httemplate/pref/pref-process.html @@ -13,35 +13,35 @@ if ( FS::Conf->new->exists('disable_acl_changes') ) { } my $error = ''; -my $access_user = ''; -if ( grep { $cgi->param($_) !~ /^\s*$/ } - qw(_password new_password new_password2) +if ( FS::Auth->auth_class->can('change_password') + && grep { $cgi->param($_) !~ /^\s*$/ } + qw(_password new_password new_password2) ) { - $access_user = qsearchs( 'access_user', { - 'usernum' => $FS::CurrentUser::CurrentUser->usernum, - 'username' => $FS::CurrentUser::CurrentUser->username, - '_password' => scalar($cgi->param('_password')), - } ); + if ( $cgi->param('new_password') ne $cgi->param('new_password2') ) { + $error = "New passwords don't match"; - $error = 'Current password incorrect; password not changed' - unless $access_user; + } elsif ( ! length($cgi->param('new_password')) ) { + $error = 'No new password entered'; - $error ||= "New passwords don't match" - unless $cgi->param('new_password') eq $cgi->param('new_password2'); + } elsif ( ! FS::Auth->authenticate( $FS::CurrentUser::CurrentUser, + scalar($cgi->param('_password')) ) + ) { + $error = 'Current password incorrect; password not changed'; - $error ||= "No new password entered" - unless length($cgi->param('new_password')); + } else { - $access_user->_password($cgi->param('new_password')) unless $error; + $error = $FS::CurrentUser::CurrentUser->change_password( + scalar($cgi->param('new_password')) + ); -} else { - - $access_user = $FS::CurrentUser::CurrentUser; + } } +my $access_user = $FS::CurrentUser::CurrentUser; + #well, if you got your password change wrong, you don't get anything else #changed right now. but it should be sticky on the form unless ( $error ) { # if ($access_user) { diff --git a/httemplate/pref/pref.html b/httemplate/pref/pref.html index 9861c3f85..dc44db0b0 100644 --- a/httemplate/pref/pref.html +++ b/httemplate/pref/pref.html @@ -4,28 +4,30 @@ <% include('/elements/error.html') %> +% if ( FS::Auth->auth_class->can('change_password') ) { -<% mt('Change password (leave blank for no change)') |h %> -<% ntable("#cccccc",2) %> + <% mt('Change password (leave blank for no change)') |h %> + <% ntable("#cccccc",2) %> - - Current password: - - + + Current password: + + - - New password: - - + + New password: + + - - Re-enter new password: - - + + Re-enter new password: + + - -
    + +
    +% } Interface <% ntable("#cccccc",2) %> -- cgit v1.2.1 From 076ddfe0b0e764636e8389edebaedddef0fbf003 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 9 May 2013 01:44:00 -0700 Subject: NG auth: pw changes, RT#21563 --- httemplate/edit/process/elements/process.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html index 2afbdd082..0439d4e9c 100644 --- a/httemplate/edit/process/elements/process.html +++ b/httemplate/edit/process/elements/process.html @@ -204,7 +204,7 @@ my %hash = my @values = ( 1 ); if ( $bfield ) { @values = $cgi->param($bfield); - warn join(',', @values); + #warn join(',', @values); } my $new; -- cgit v1.2.1 From 19eef2ec0e68587304cd597fc5b2f8e1f151e424 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 9 May 2013 02:09:09 -0700 Subject: NG auth: pw changes, RT#21563 --- FS/FS/access_user.pm | 58 ++++++++-------------------------------------------- 1 file changed, 8 insertions(+), 50 deletions(-) diff --git a/FS/FS/access_user.pm b/FS/FS/access_user.pm index cdee3773b..79e863bde 100644 --- a/FS/FS/access_user.pm +++ b/FS/FS/access_user.pm @@ -2,7 +2,7 @@ package FS::access_user; use strict; use base qw( FS::m2m_Common FS::option_Common ); -use vars qw( $DEBUG $me $conf $htpasswd_file ); +use vars qw( $DEBUG $me $conf ); use FS::UID; use FS::Auth; use FS::Conf; @@ -15,12 +15,6 @@ use FS::cust_main; $DEBUG = 0; $me = '[FS::access_user]'; -#kludge htpasswd for now (i hope this bootstraps okay) -FS::UID->install_callback( sub { - $conf = new FS::Conf; - $htpasswd_file = $conf->base_dir. '/htpasswd'; -} ); - =head1 NAME FS::access_user - Object methods for access_user records @@ -106,7 +100,6 @@ sub insert { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - $error = $self->htpasswd_kludge(); if ( $error ) { $dbh->rollback or die $dbh->errstr if $oldAutoCommit; return $error; @@ -116,14 +109,7 @@ sub insert { if ( $error ) { $dbh->rollback or die $dbh->errstr if $oldAutoCommit; - - #make sure it isn't a dup username? or you could nuke people's passwords - #blah. really just should do our own login w/cookies - #and auth out of the db in the first place - #my $hterror = $self->htpasswd_kludge('-D'); - #$error .= " - additionally received error cleaning up htpasswd file: $hterror" return $error; - } else { $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; @@ -131,26 +117,6 @@ sub insert { } -sub htpasswd_kludge { - my $self = shift; - - return '' if $self->is_system_user; - - unshift @_, '-c' unless -e $htpasswd_file; - if ( - system('htpasswd', '-b', @_, - $htpasswd_file, - $self->username, - $self->_password, - ) == 0 - ) - { - return ''; - } else { - return 'htpasswd exited unsucessfully'; - } -} - =item delete Delete this record from the database. @@ -171,10 +137,7 @@ sub delete { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - my $error = - $self->SUPER::delete(@_) - || $self->htpasswd_kludge('-D') - ; + my $error = $self->SUPER::delete(@_); if ( $error ) { $dbh->rollback or die $dbh->errstr if $oldAutoCommit; @@ -211,16 +174,11 @@ sub replace { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - if ( $new->_password ne $old->_password ) { - my $error = $new->htpasswd_kludge(); - if ( $error ) { - $dbh->rollback or die $dbh->errstr if $oldAutoCommit; - return $error; - } - } elsif ( $old->disabled && !$new->disabled - && $new->_password =~ /changeme/i ) { - return "Must change password when enabling this account"; - } + return "Must change password when enabling this account" + if $old->disabled && !$new->disabled + && ( $new->_password =~ /changeme/i + || $new->_password eq 'notyet' + ); my $error = $new->SUPER::replace($old, @_); @@ -551,7 +509,7 @@ sub spreadsheet_format { =item is_system_user Returns true if this user has the name of a known system account. These -users will not appear in the htpasswd file and can't have passwords set. +users cannot log into the web interface and can't have passwords set. =cut -- cgit v1.2.1 From 2272361a3302113bb43cbf4581e7187db25f3a58 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Thu, 9 May 2013 15:06:23 -0700 Subject: billing events for reconciling inactive accounts, #19873 --- FS/FS/part_event/Action/fee.pm | 18 ++++++++++-- FS/FS/part_event/Condition/inactive_age.pm | 46 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 FS/FS/part_event/Condition/inactive_age.pm diff --git a/FS/FS/part_event/Action/fee.pm b/FS/FS/part_event/Action/fee.pm index 68288d090..cd9e200c8 100644 --- a/FS/FS/part_event/Action/fee.pm +++ b/FS/FS/part_event/Action/fee.pm @@ -17,14 +17,25 @@ sub option_fields { type=>'checkbox', value=>'Y' }, 'nextbill' => { label=>'Hold late fee until next invoice', type=>'checkbox', value=>'Y' }, + 'limit_to_credit'=> + { label=>"Charge no more than the customer's credit balance", + type=>'checkbox', value=>'Y' }, ); } sub default_weight { 10; } sub _calc_fee { - #my( $self, $cust_object ) = @_; - my $self = shift; + my( $self, $cust_object ) = @_; + if ( $self->option('limit_to_credit') ) { + my $balance = $cust_object->cust_main->balance; + if ( $balance >= 0 ) { + return 0; + } elsif ( (-1 * $balance) < $self->option('charge') ) { + return -1 * $balance; + } + } + $self->option('charge'); } @@ -44,6 +55,9 @@ sub do_action { 'setuptax' => $self->option('setuptax'), ); + # amazingly, FS::cust_main::charge will allow a charge of zero + return '' if $charge{'amount'} == 0; + #unless its more than N months away? $charge{'start_date'} = $cust_main->next_bill_date if $self->option('nextbill'); diff --git a/FS/FS/part_event/Condition/inactive_age.pm b/FS/FS/part_event/Condition/inactive_age.pm new file mode 100644 index 000000000..8918a1a3c --- /dev/null +++ b/FS/FS/part_event/Condition/inactive_age.pm @@ -0,0 +1,46 @@ +package FS::part_event::Condition::inactive_age; + +use strict; +use base qw( FS::part_event::Condition ); +use FS::Record qw( qsearch ); + +sub description { 'Days without billing activity' } + +sub option_fields { + ( + 'age' => { 'label' => 'No activity within', + 'type' => 'freq', + }, + # flags to select kinds of activity, + # like if you just want "no payments since"? + # not relevant yet + ); +} + +sub condition { + my( $self, $obj, %opt ) = @_; + my $custnum = $obj->custnum; + my $age = $self->option_age_from('age', $opt{'time'} ); + + foreach my $t (qw(cust_bill cust_pay cust_credit cust_refund)) { + my $class = "FS::$t"; + return 0 if $class->count("custnum = $custnum AND _date >= $age"); + } + 1; +} + +sub condition_sql { + my( $class, $table, %opt ) = @_; + my $age = $class->condition_sql_option_age_from('age', $opt{'time'}); + my @sql; + for my $t (qw(cust_bill cust_pay cust_credit cust_refund)) { + push @sql, + "NOT EXISTS( SELECT 1 FROM $t ". + "WHERE $t.custnum = cust_main.custnum AND $t._date >= $age". + ")"; + } + join(' AND ', @sql); +} + +1; + -- cgit v1.2.1 From 56f9dffcd409d2a10e7a2cbe4c15b397f6f3abe1 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 9 May 2013 21:42:37 -0700 Subject: NG auth: autocreate records for external users, RT#21563 --- FS/FS/Auth/external.pm | 13 ++--------- FS/FS/Auth/internal.pm | 2 ++ FS/FS/Auth/legacy.pm | 2 ++ FS/FS/AuthCookieHandler.pm | 15 ++++++------- FS/FS/CurrentUser.pm | 55 ++++++++++++++++++++++++++++++++++++++------- FS/FS/Schema.pm | 6 ++--- FS/FS/access_user.pm | 9 ++++---- eg/Auth-my_external_auth.pm | 23 ++++++++++--------- 8 files changed, 80 insertions(+), 45 deletions(-) diff --git a/FS/FS/Auth/external.pm b/FS/FS/Auth/external.pm index d2bc74600..51f1f0496 100644 --- a/FS/FS/Auth/external.pm +++ b/FS/FS/Auth/external.pm @@ -1,18 +1,9 @@ -packages FS::Auth::external; +package FS::Auth::external; #use base qw( FS::Auth ); use strict; -sub autocreate { - my $username = shift; - my $access_user = new FS::access_user { - 'username' => $username, - #'_password' => #XXX something random so a switch to internal auth doesn't - #let people on? - }; - my $error = $access_user->insert; - #die $error if $error; -} +sub autocreate { 1; } 1; diff --git a/FS/FS/Auth/internal.pm b/FS/FS/Auth/internal.pm index bb116ce75..f6d1a0086 100644 --- a/FS/FS/Auth/internal.pm +++ b/FS/FS/Auth/internal.pm @@ -42,6 +42,8 @@ sub authenticate { } +sub autocreate { 0; } + sub change_password { my($self, $access_user, $new_password) = @_; diff --git a/FS/FS/Auth/legacy.pm b/FS/FS/Auth/legacy.pm index 72122029e..1133197bc 100644 --- a/FS/FS/Auth/legacy.pm +++ b/FS/FS/Auth/legacy.pm @@ -16,6 +16,8 @@ sub authenticate { )->htCheckPassword($username, $check_password); } +sub autocreate { 0; } + #don't support this in legacy? change in both htpasswd and database like 3.x # for easier transitioning? hoping its really only me+employees that have a # mismatch in htpasswd vs access_user, so maybe that's not necessary diff --git a/FS/FS/AuthCookieHandler.pm b/FS/FS/AuthCookieHandler.pm index cd89f55af..b571e4705 100644 --- a/FS/FS/AuthCookieHandler.pm +++ b/FS/FS/AuthCookieHandler.pm @@ -11,24 +11,23 @@ sub authen_cred { preuser_setup(); - unless ( _is_valid_user($username, $password) ) { + my $info = {}; + + unless ( FS::Auth->authenticate($username, $password, $info) ) { warn "failed auth $username from ". $r->connection->remote_ip. "\n"; return undef; } warn "authenticated $username from ". $r->connection->remote_ip. "\n"; - FS::CurrentUser->load_user($username); + FS::CurrentUser->load_user( $username, + 'autocreate' => FS::Auth->auth_class->autocreate, + %$info, + ); FS::CurrentUser->new_session; } -sub _is_valid_user { - my( $username, $password ) = @_; - - FS::Auth->authenticate($username, $password); -} - sub authen_ses_key { my( $self, $r, $sessionkey ) = @_; diff --git a/FS/FS/CurrentUser.pm b/FS/FS/CurrentUser.pm index 7b0fe28a6..d272066e0 100644 --- a/FS/FS/CurrentUser.pm +++ b/FS/FS/CurrentUser.pm @@ -27,13 +27,13 @@ Sets the current user to the provided username =cut sub load_user { - my( $class, $user ) = @_; #, $pass + my( $class, $username, %opt ) = @_; if ( $upgrade_hack ) { return $CurrentUser = new FS::CurrentUser::BootstrapUser; } - #return "" if $user =~ /^fs_(queue|selfservice)$/; + #return "" if $username =~ /^fs_(queue|selfservice)$/; #not the best thing in the world... eval "use FS::Record qw(qsearchs);"; @@ -41,13 +41,52 @@ sub load_user { eval "use FS::access_user;"; die $@ if $@; - $CurrentUser = qsearchs('access_user', { - 'username' => $user, - #'_password' => - 'disabled' => '', - } ); + my %hash = ( 'username' => $username, + 'disabled' => '', + ); - die "unknown user: $user" unless $CurrentUser; # or bad password + $CurrentUser = qsearchs('access_user', \%hash) and return $CurrentUser; + + die "unknown user: $username" unless $opt{'autocreate'}; + + $CurrentUser = new FS::access_user \%hash; + $CurrentUser->set($_, $opt{$_}) foreach qw( first last ); + my $error = $CurrentUser->insert; + die $error if $error; #better way to handle this error? + + my $template_user = + $opt{'template_user'} + || FS::Conf->new->config('external_auth-access_group-template_user'); + + if ( $template_user ) { + + my $tmpl_access_user = + qsearchs('access_user', { 'username' => $template_user } ); + + if ( $tmpl_access_user ) { + eval "use FS::access_usergroup;"; + die $@ if $@; + + foreach my $tmpl_access_usergroup + ($tmpl_access_user->access_usergroup) { + my $access_usergroup = new FS::access_usergroup { + 'usernum' => $CurrentUser->usernum, + 'groupnum' => $tmpl_access_usergroup->groupnum, + }; + my $error = $access_usergroup->insert; + if ( $error ) { + #shouldn't happen, but seems better to proceed than to die + warn "error inserting access_usergroup: $error"; + }; + } + + } else { + warn "template username $template_user not found\n"; + } + + } else { + warn "no access template user for autocreated user $username\n"; + } $CurrentUser; } diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 899b67b35..633e59cb6 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3586,10 +3586,10 @@ sub tables_hashref { 'columns' => [ 'usernum', 'serial', '', '', '', '', 'username', 'varchar', '', $char_d, '', '', - '_password', 'varchar', '', $char_d, '', '', + '_password', 'varchar', 'NULL', $char_d, '', '', '_password_encoding', 'varchar', 'NULL', $char_d, '', '', - 'last', 'varchar', '', $char_d, '', '', - 'first', 'varchar', '', $char_d, '', '', + 'last', 'varchar', 'NULL', $char_d, '', '', + 'first', 'varchar', 'NULL', $char_d, '', '', 'user_custnum', 'int', 'NULL', '', '', '', 'disabled', 'char', 'NULL', 1, '', '', ], diff --git a/FS/FS/access_user.pm b/FS/FS/access_user.pm index 79e863bde..7c25acbe3 100644 --- a/FS/FS/access_user.pm +++ b/FS/FS/access_user.pm @@ -209,9 +209,9 @@ sub check { my $error = $self->ut_numbern('usernum') || $self->ut_alpha_lower('username') - || $self->ut_text('_password') - || $self->ut_text('last') - || $self->ut_text('first') + || $self->ut_textn('_password') + || $self->ut_textn('last') + || $self->ut_textn('first') || $self->ut_foreign_keyn('user_custnum', 'cust_main', 'custnum') || $self->ut_enum('disabled', [ '', 'Y' ] ) ; @@ -229,7 +229,8 @@ Returns a name string for this user: "Last, First". sub name { my $self = shift; return $self->username - if $self->get('last') eq 'Lastname' && $self->first eq 'Firstname'; + if $self->get('last') eq 'Lastname' && $self->first eq 'Firstname' + or $self->get('last') eq '' && $self->first eq ''; return $self->get('last'). ', '. $self->first; } diff --git a/eg/Auth-my_external_auth.pm b/eg/Auth-my_external_auth.pm index 38f9d5bfb..8eda462f8 100644 --- a/eg/Auth-my_external_auth.pm +++ b/eg/Auth-my_external_auth.pm @@ -4,24 +4,25 @@ use base qw( FS::Auth::external ); #need to inherit from ::external use strict; sub authenticate { - my($self, $username, $check_password ) = @_; + my($self, $username, $check_password, $info ) = @_; - #magic happens here + #your magic happens here + + if ( $auth_good ) { + + #optionally return a real name + #$info->{'first'} = "Jean"; + #$info->{'last'} = "D'eau"; + + #optionally return a template username to copy access groups from that user + #$info->{'template_user'} = 'username'; - if ( $auth_good ) { #verbose for clarity return 1; + } else { return 0; } } -#omitting these subroutines will eliminate those options from the UI - -#sub create_user { -# - -#sub change_password { -#} - 1; -- cgit v1.2.1 From 0832972047a36d19ffcf7d1462abc48de7045d3d Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 9 May 2013 21:42:51 -0700 Subject: NG auth: autocreate records for external users, RT#21563 --- FS/FS/Conf.pm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 869ce1e73..831ffe2a3 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -5431,6 +5431,13 @@ and customer address. Include units.', 'select_enum' => [qw( Internal Legacy )], }, + { + 'key' => 'external_auth-access_group-template_user', + 'section' => 'UI', + 'description' => 'When using an external authentication module, specifies the default access groups for autocreated users, via a template user.', + 'type' => 'text', + }, + { key => "apacheroot", section => "deprecated", description => "DEPRECATED", type => "text" }, { key => "apachemachine", section => "deprecated", description => "DEPRECATED", type => "text" }, { key => "apachemachines", section => "deprecated", description => "DEPRECATED", type => "text" }, -- cgit v1.2.1 From a40c575ed229d24706a3dd491ea9fda14f7dea81 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 10 May 2013 00:46:53 -0700 Subject: 3add --- bin/3commit | 26 ++++++++++++++++++++++++++ bin/3diff | 13 +++++++++++++ 2 files changed, 39 insertions(+) create mode 100755 bin/3commit create mode 100755 bin/3diff diff --git a/bin/3commit b/bin/3commit new file mode 100755 index 000000000..cd1db2174 --- /dev/null +++ b/bin/3commit @@ -0,0 +1,26 @@ +#!/usr/bin/perl + +# usage: 23commit 'log message' filename filename ... + +use Cwd; +use String::ShellQuote; + +my $USER = $ENV{USER}; + +my $dir = getcwd; +( my $prefix = $dir ) =~ s(^/home/$USER/freeside/?)() or die $dir; #eventually from anywhere + +my $desc = shell_quote(shift @ARGV); # -m + +die "no files!" unless @ARGV; + +#warn "$prefix"; + +#print < Date: Fri, 10 May 2013 00:47:12 -0700 Subject: my silly multi-branch tools --- bin/3add | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 bin/3add diff --git a/bin/3add b/bin/3add new file mode 100755 index 000000000..8bc034d9c --- /dev/null +++ b/bin/3add @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +use Cwd; +use String::ShellQuote; + +my $USER = $ENV{USER}; + +my $dir = getcwd; +( my $prefix = $dir ) =~ s(^/home/$USER/freeside/?)() or die $dir; #eventually from anywhere + +system join('', + "git add @ARGV ; ", + "( for file in @ARGV; do ", + "cp -i \$file /home/$USER/freeside3/$prefix/`dirname \$file`;", + "done ) && ", + "cd /home/$USER/freeside3/$prefix/ && ", + "git add @ARGV" +); + -- cgit v1.2.1 From 7b5a266236857fbb4bbf8d4ac3031c3fec75cac2 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 10 May 2013 01:05:04 -0700 Subject: master will be 4.0 --- FS/FS.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS.pm b/FS/FS.pm index d8bc33347..77dd4ff20 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -3,7 +3,7 @@ package FS; use strict; use vars qw($VERSION); -$VERSION = '3.1git'; +$VERSION = '4.0git'; #find missing entries in this file with: # for a in `ls *pm | cut -d. -f1`; do grep 'L' ../FS.pm >/dev/null || echo "missing $a" ; done -- cgit v1.2.1 From 5fc7d59d743f5efedcdcc28594cfb2d67602158e Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 10 May 2013 13:02:36 -0700 Subject: remove obsolete docs --- httemplate/docs/session.html | 59 -------------------------------------------- httemplate/docs/signup.html | 54 ---------------------------------------- 2 files changed, 113 deletions(-) delete mode 100644 httemplate/docs/session.html delete mode 100644 httemplate/docs/signup.html diff --git a/httemplate/docs/session.html b/httemplate/docs/session.html deleted file mode 100644 index 72e16424e..000000000 --- a/httemplate/docs/session.html +++ /dev/null @@ -1,59 +0,0 @@ - - Session monitor - - -

    Session monitor

    -

    Installation

    -For security reasons, the client portion of the session montior may run on one -or more external public machine(s). On these machines, install: -
      -
    • Perl (at l -east 5.004_05 for the 5.004 series or 5.005_03 for the 5.005 series. Don't enable experimental features like threads or the PerlIO abstraction layer.) -
    • FS::SessionClient (copy the fs_session/FS-SessionClient directory to the external machine, then: perl Makefile.PL; make; make install) -
    -Then: -
      -
    • Add the user `freeside' to the the external machine. -
    • Create the /usr/local/freeside directory on the external machine (owned by the freeside user). -
    • touch /usr/local/freeside/fs_sessiond_socket; chown freeside /usr/local/freeside/fs_sessiond_socket; chmod 600 /usr/local/freeside/fs_sessiond_socket -
    • Append the identity.pub from the freeside user on your freeside machine to the authorized_keys file of the newly created freeside user on the external machine(s). -
    • Run
      fs_session_server user machine
      on the Freeside machine. -
        -
      • user is a user from the mapsecrets file. -
      • machine is the name of the external machine. -
      -
    -

    Usage

    -
      -
    • Web -
        -
      • Copy FS-SessionClient/cgi/login.cgi and logout.cgi to your web - server's document space. -
      • Use suEXEC or setuid (see install.html for details) to run login.cgi and logout.cgi as the freeside user. -
      -
    • Command-line -
      freeside-login username ( portnum | ip | nasnum nasport )
      -freeside-logout username ( portnum | ip | nasnum nasport )
      -
        -
      • username is a customer username from the svc_acct table -
      • portnum, ip or nasport and nasnum uniquely identify a port in the port database table. -
      -
    • RADIUS - One of: -
        -
      • Run the freeside-sqlradius-radacctd daemon to import radacct - records from all configured sqlradius exports: - freeside-sqlradius-radacctd username -
      • Configure your RADIUS server's login and logout callbacks to use the command-line freeside-login and freeside-logout utilites. -
      • (incomplete)Use the fs_radlog/fs_radlogd tool to - import records from a text radacct file. -
      -
    -

    Callbacks

    -
      -
    • Sesstion start - The command(s) specified in the session-start configuration file are executed on the Freeside machine. The contents of the file are treated as a double-quoted perl string, with the following variables available: $ip, $nasip and $nasfqdn, which are the IP address of the starting session, and the IP address and fully-qualified domain name of the NAS this session is on. -
    • Session end - The command(s) specified in the session-stop configuration file are executed on the Freeside machine. The contents of the file are treated as a double-quoted perl string, with the following variables available: $ip, $nasip and $nasfqdn, which are the IP address of the starting session, and the IP address and fully-qualified domain name of the NAS this session is on. -
    -

    Dropping expired users

    -Run
    bin/freeside-session-kill username
    periodically from cron. - - diff --git a/httemplate/docs/signup.html b/httemplate/docs/signup.html deleted file mode 100644 index 97d7aa794..000000000 --- a/httemplate/docs/signup.html +++ /dev/null @@ -1,54 +0,0 @@ - - Signup server - - -

    Signup server

    -For security reasons, the signup server should run on an external public -webserver. On this machine, install: - -Then: -
      -
    • Add the user `freeside' to the the external machine. -
    • Copy or symlink fs_signup/FS-SignupClient/cgi/signup.cgi into the web server's document space. -
    • When linking to signup.cgi, you can include a referring custnum in the URL as follows: http://public.web.server/path/signup.cgi?ref=1542 -
    • Enable CGI execution for files with the `.cgi' extension. (with Apache) -
    • Create the /usr/local/freeside directory on the external machine (owned by the freeside user). -
    • touch /usr/local/freeside/fs_signupd_socket; chown freeside /usr/local/freeside/fs_signupd_socket; chmod 600 /usr/local/freeside/fs_signupd_socket -
    • Use suEXEC or setuid (see install.html for details) to run signup.cgi as the freeside user. -
    • Append the identity.pub from the freeside user on your freeside machine to the authorized_keys file of the newly created freeside user on the external machine(s). -
    • Run
      fs_signup_server user machine agentnum refnum
      on the Freeside machine. -
        -
      • user is a user from the mapsecrets file. -
      • machine is the name of the external machine. -
      • agentnum and refnum are the agent and referral, respectively, to use for customers who sign up via this signup server. -
      -
    -Optional: -
      -
    • If you create a /usr/local/freeside/ieak.template file on the external machine, it will be sent to IE users with MIME type application/x-Internet-signup. This file will be processed with Text::Template with the variables listed below available. - (an example file is included as fs_signup/ieak.template) See the section on internet settings files in the IEAK documentation for more information. -
    • If you create a /usr/local/freeside/success.html file on the external machine, it will be used as the success HTML page. Although template substiutions are available, a regular HTML file will work fine here, unlike signup.html. An example file is included as fs_signup/FS-SignupClient/cgi/success.html -
    • Variable substitutions available in ieak.template, cck.template and success.html: -
        -
      • $ac - area code of selected POP -
      • $exch - exchange of selected POP -
      • $loc - local part of selected POP -
      • $username -
      • $password -
      • $email_name - first and last name -
      • $pkg - package name -
      -
    • If you create a /usr/local/freeside/signup.html file on the external machine, it will be used as a template for the form HTML. This requires the template to be constructed appropriately; probably best to start with the example file included as fs_signup/FS-SignupClient/cgi/signup.html. -
    • If there are any entries in the prepay_credit table, a user can enter a string matching the identifier column to receive the credit specified in the amount column, and/or the time specified in the seconds column (for use with the session monitor), after which that identifier is no longer valid. This can be used to implement pre-paid "calling card" type signups. The bin/generate-prepay script can be used to populate the prepay_credit table. -
    - -- cgit v1.2.1 From ec5706f29a4b1d6826f150ed4e64bb79c4fe0cb7 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 10 May 2013 13:08:59 -0700 Subject: remove obsolete mapsecrets stuff, RT#21563 --- FS/bin/freeside-adduser | 56 +++----------------------------------- FS/bin/freeside-daily | 2 +- FS/bin/freeside-deluser | 64 -------------------------------------------- FS/bin/freeside-monthly | 2 +- bin/cdr_upstream_rate.import | 2 +- 5 files changed, 7 insertions(+), 119 deletions(-) delete mode 100644 FS/bin/freeside-deluser diff --git a/FS/bin/freeside-adduser b/FS/bin/freeside-adduser index 530481377..6bfb759f8 100644 --- a/FS/bin/freeside-adduser +++ b/FS/bin/freeside-adduser @@ -7,46 +7,9 @@ use Getopt::Std; my $FREESIDE_CONF = "%%%FREESIDE_CONF%%%"; -getopts("s:g:n"); +getopts("g:"); my $user = shift or die &usage; -if ( $opt_s ) { - - #if ( -e "$FREESIDE_CONF/mapsecrets" ) { - # open(MAPSECRETS,"<$FREESIDE_CONF/mapsecrets") - # or die "can't open $FREESIDE_CONF/mapsecrets: $!"; - # while () { - # /^(\S+) / or die "unparsable line in mapsecrets: $_"; - # die "user $user already exists\n" if $user eq $1; - # } - # close MAPSECRETS; - #} - - #insert new entry before a wildcard... - open(MAPSECRETS,"<$FREESIDE_CONF/mapsecrets") - and flock(MAPSECRETS,LOCK_EX) - or die "can't open $FREESIDE_CONF/mapsecrets: $!"; - open(NEW,">$FREESIDE_CONF/mapsecrets.new") - or die "can't open $FREESIDE_CONF/mapsecrets.new: $!"; - while() { - if ( /^\*\s/ ) { - print NEW "$user $opt_s\n"; - } - print NEW $_; - } - close MAPSECRETS or die "can't close $FREESIDE_CONF/mapsecrets: $!"; - close NEW or die "can't close $FREESIDE_CONF/mapsecrets.new: $!"; - rename("$FREESIDE_CONF/mapsecrets.new", "$FREESIDE_CONF/mapsecrets") - or die "can't move mapsecrets.new into place: $!"; - -} - -### - -exit if $opt_n; - -### - use FS::UID qw(adminsuidsetup); use FS::CurrentUser; use FS::access_user; @@ -58,7 +21,7 @@ adminsuidsetup $user; my $access_user = new FS::access_user { 'username' => $user, - '_password' => 'notyet', + '_password' => '', 'first' => 'Firstname', # $opt_f || 'last' => 'Lastname', # $opt_l || }; @@ -79,7 +42,7 @@ if ( $opt_g ) { ### sub usage { - die "Usage:\n\n freeside-adduser [ -n ] [ -s ] [ -g groupnum ] username [ password ]" + die "Usage:\n\n freeside-adduser [ -g groupnum ] username [ password ]" } =head1 NAME @@ -88,7 +51,7 @@ freeside-adduser - Command line interface to add (freeside) users. =head1 SYNOPSIS - freeside-adduser [ -n ] [ -s ] [ -g groupnum ] username [ password ] + freeside-adduser [ -g groupnum ] username [ password ] =head1 DESCRIPTION @@ -100,17 +63,6 @@ B. -g: initial groupnum - Development/multi-DB options: - - -s: alternate secrets file - - -n: no ACL added, for bootstrapping - -=head1 NOTE - -No explicit htpasswd options are available in 1.7 - passwords are now -maintained automatically. - =head1 SEE ALSO Base Freeside documentation diff --git a/FS/bin/freeside-daily b/FS/bin/freeside-daily index ac93aaf2f..0e43276ad 100755 --- a/FS/bin/freeside-daily +++ b/FS/bin/freeside-daily @@ -149,7 +149,7 @@ the bill and collect methods of a cust_main object. See L. -k: skip notify_flat_delay -user: From the mapsecrets file - see config.html from the base documentation +user: Typically "fs_daily" custnum: if one or more customer numbers are specified, only bills those customers. Otherwise, bills all customers. diff --git a/FS/bin/freeside-deluser b/FS/bin/freeside-deluser deleted file mode 100644 index a2a361a83..000000000 --- a/FS/bin/freeside-deluser +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -use vars qw($opt_h); -use Fcntl qw(:flock); -use Getopt::Std; - -my $FREESIDE_CONF = "%%%FREESIDE_CONF%%%"; - -getopts("h:"); -my $user = shift or die &usage; - -if ( $opt_h ) { - open(HTPASSWD,"<$opt_h") - and flock(HTPASSWD,LOCK_EX) - or die "can't open $opt_h: $!"; - open(HTPASSWD_TMP,">$opt_h.tmp") or die "can't open $opt_h.tmp: $!"; - while () { - print HTPASSWD_TMP $_ unless /^$user:/; - } - close HTPASSWD_TMP; - rename "$opt_h.tmp", "$opt_h" or die $!; - flock(HTPASSWD,LOCK_UN); - close HTPASSWD; -} - -open(MAPSECRETS,"<$FREESIDE_CONF/mapsecrets") - and flock(MAPSECRETS,LOCK_EX) - or die "can't open $FREESIDE_CONF/mapsecrets: $!"; -open(MAPSECRETS_TMP,">>$FREESIDE_CONF/mapsecrets.tmp") - or die "can't open $FREESIDE_CONF/mapsecrets.tmp: $!"; -while () { - print MAPSECRETS_TMP $_ unless /^$user\s/; -} -close MAPSECRETS_TMP; -rename "$FREESIDE_CONF/mapsecrets.tmp", "$FREESIDE_CONF/mapsecrets" or die $!; -flock(MAPSECRETS,LOCK_UN); -close MAPSECRETS; - -sub usage { - die "Usage:\n\n freeside-deluser [ -h htpasswd_file ] username" -} - -=head1 NAME - -freeside-deluser - Command line interface to add (freeside) users. - -=head1 SYNOPSIS - - freeside-deluser [ -h htpasswd_file ] username - -=head1 DESCRIPTION - -Adds a user to the Freeside billing system. This is for adding users (internal -sales/tech folks) to the web interface, not for adding customer accounts. - - -h: Also delete from the given htpasswd filename - -=head1 SEE ALSO - -L, L(1), base Freeside documentation - -=cut - diff --git a/FS/bin/freeside-monthly b/FS/bin/freeside-monthly index 69502a01d..431fbd86f 100755 --- a/FS/bin/freeside-monthly +++ b/FS/bin/freeside-monthly @@ -74,7 +74,7 @@ the bill and collect methods of a cust_main object. See L. -m: Experimental multi-process mode (delay upload jobs until billing jobs complete) -user: From the mapsecrets file - see config.html from the base documentation +user: Typically "fs_daily" custnum: if one or more customer numbers are specified, only bills those customers. Otherwise, bills all customers. diff --git a/bin/cdr_upstream_rate.import b/bin/cdr_upstream_rate.import index fda3883b5..ac2856cee 100755 --- a/bin/cdr_upstream_rate.import +++ b/bin/cdr_upstream_rate.import @@ -6,7 +6,7 @@ # # Example: bin/cdr_upstream_rate.import ivan 1 ~ivan/convergent/sample_rate_table.csv # -# username: a freeside login (from /usr/local/etc/freeside/mapsecrets) +# username: a freeside login # ratenum: rate plan (FS::rate) created with the web UI # filename: CSV file # -- cgit v1.2.1 From aa7d05879906fde83caf3989d288c4e42de6df86 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 10 May 2013 13:12:22 -0700 Subject: remove obsolete mapsecrets stuff, RT#21563 --- FS/FS/InitHandler.pm | 91 -------------------------------------------------- FS/bin/freeside-email | 2 +- FS/bin/freeside-fetch | 2 +- FS/bin/freeside-queued | 2 +- bin/cust_pay_histogram | 2 +- bin/rebill | 2 +- 6 files changed, 5 insertions(+), 96 deletions(-) delete mode 100644 FS/FS/InitHandler.pm diff --git a/FS/FS/InitHandler.pm b/FS/FS/InitHandler.pm deleted file mode 100644 index 5038cf352..000000000 --- a/FS/FS/InitHandler.pm +++ /dev/null @@ -1,91 +0,0 @@ -package FS::InitHandler; - -# this leaks memory under graceful restarts and i wouldn't use it on any -# modern server. useful for very slow machines with memory to spare, just -# always do a full restart - -use strict; -use vars qw($DEBUG); -use FS::UID qw(adminsuidsetup); -use FS::Record; - -$DEBUG = 1; - -sub handler { - - use Date::Format; - use Date::Parse; - use Tie::IxHash; - use HTML::Entities; - use IO::Handle; - use IO::File; - use String::Approx; - use HTML::Widgets::SelectLayers 0.02; - #use FS::UID; - #use FS::Record; - use FS::Conf; - use FS::CGI; - use FS::Msgcat; - - use FS::agent; - use FS::agent_type; - use FS::domain_record; - use FS::cust_bill; - use FS::cust_bill_pay; - use FS::cust_credit; - use FS::cust_credit_bill; - use FS::cust_main; - use FS::cust_main_county; - use FS::cust_pay; - use FS::cust_pkg; - use FS::cust_refund; - use FS::cust_svc; - use FS::nas; - use FS::part_bill_event; - use FS::part_pkg; - use FS::part_referral; - use FS::part_svc; - use FS::pkg_svc; - use FS::port; - use FS::queue; - use FS::raddb; - use FS::session; - use FS::svc_acct; - use FS::svc_acct_pop; - use FS::svc_domain; - use FS::svc_forward; - use FS::svc_www; - use FS::type_pkgs; - use FS::part_export; - use FS::part_export_option; - use FS::export_svc; - use FS::msgcat; - - warn "[FS::InitHandler] handler called\n" if $DEBUG; - - #this is sure to be broken on freebsd - $> = $FS::UID::freeside_uid; - - open(MAPSECRETS,"<$FS::UID::conf_dir/mapsecrets") - or die "can't read $FS::UID::conf_dir/mapsecrets: $!"; - - my %seen; - while () { - next if /^\s*(#|$)/; - /^([\w\-\.]+)\s(.*)$/ - or do { warn "strange line in mapsecrets: $_"; next; }; - my($user, $datasrc) = ($1, $2); - next if $seen{$datasrc}++; - warn "[FS::InitHandler] preloading $datasrc for $user\n" if $DEBUG; - adminsuidsetup($user); - } - - close MAPSECRETS; - - #lalala probably broken on freebsd - ($<, $>) = ($>, $<); - $< = 0; - -} - -1; diff --git a/FS/bin/freeside-email b/FS/bin/freeside-email index 7a93f78ee..6e4e0fe6c 100755 --- a/FS/bin/freeside-email +++ b/FS/bin/freeside-email @@ -45,7 +45,7 @@ freeside-email - Prints email addresses of all users on STDOUT Prints the email addresses of all customers on STDOUT, separated by newlines. -user: From the mapsecrets file - see config.html from the base documentation +user: Freeside user =head1 BUGS diff --git a/FS/bin/freeside-fetch b/FS/bin/freeside-fetch index f689bfd93..c1ab78373 100755 --- a/FS/bin/freeside-fetch +++ b/FS/bin/freeside-fetch @@ -79,7 +79,7 @@ freeside-fetch - Send a freeside page to a list of employees. Fetches a web page specified by url as if employee and emails it to employee. Useful when run out of cron to send freeside web pages. - user: From the mapsecrets file - a user with access to the freeside database + user: Freeside user employee: the username of an employee to receive the emailed page. May be a comma separated list diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued index dcc6ac4ba..5eac06b24 100644 --- a/FS/bin/freeside-queued +++ b/FS/bin/freeside-queued @@ -296,7 +296,7 @@ Job queue daemon. Should be running at all times. -n: non-"secure" jobs only (other jobs) -user: from the mapsecrets file - see config.html from the base documentation +user: Typically "fs_queue" =head1 VERSION diff --git a/bin/cust_pay_histogram b/bin/cust_pay_histogram index 714b32140..42bd8844d 100755 --- a/bin/cust_pay_histogram +++ b/bin/cust_pay_histogram @@ -103,7 +103,7 @@ Displays a histogram of cust_pay records in the database. -a: Only process payments of customers with the specified agentnum -user: From the mapsecrets file - see config.html from the base documentation +user: Freeside username =head1 BUGS diff --git a/bin/rebill b/bin/rebill index 4f052384d..cf473398a 100755 --- a/bin/rebill +++ b/bin/rebill @@ -117,7 +117,7 @@ the bill and collect methods of a cust_main object. See L. -k: skip notify_flat_delay and vacuum -user: From the mapsecrets file - see config.html from the base documentation +user: Freeside user custnum: if one or more customer numbers are specified, only bills those customers. Otherwise, bills all customers. -- cgit v1.2.1 From 4c07c048c76c1aa8fe0f7aa8e8de7243ba60d777 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 10 May 2013 14:26:05 -0700 Subject: add -s flag to skip CDR files that error out, RT#20763 --- FS/FS/Record.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 15636af9c..3886c3333 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -1697,7 +1697,7 @@ sub batch_import { my $data = slurp($file); my $asn_output = $parser->decode( $data ) - or die "No ". $asn_format->{'macro'}. " found\n"; + or return "No ". $asn_format->{'macro'}. " found\n"; $asn_header_buffer = &{ $asn_format->{'header_buffer'} }( $asn_output ); @@ -1881,7 +1881,7 @@ sub batch_import { return "Empty file!"; } - $dbh->commit or die $dbh->errstr if $oldAutoCommit;; + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; #no error -- cgit v1.2.1 From 4d00bdc38de74723b1f577edec0490fcad747e18 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 10 May 2013 14:23:22 -0700 Subject: fix mostly-harmless warning --- FS/FS/part_event/Condition.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_event/Condition.pm b/FS/FS/part_event/Condition.pm index fc69f1d0c..60697c196 100644 --- a/FS/FS/part_event/Condition.pm +++ b/FS/FS/part_event/Condition.pm @@ -524,7 +524,7 @@ comparison to other integers is type-correct. sub condition_sql_option_integer { my ($class, $option, $driver_name) = @_; - my $integer = ($driver_name =~ /^mysql/) ? 'UNSIGNED INTEGER' : 'INTEGER'; + my $integer = (driver_name() =~ /^mysql/) ? 'UNSIGNED INTEGER' : 'INTEGER'; 'CAST( COALESCE('. $class->condition_sql_option($option). -- cgit v1.2.1 From 9970378e485e86b2c5281aeab4411087c4550bd6 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 11 May 2013 13:18:41 -0700 Subject: updating shitty multi-tree tools --- bin/32add | 22 ++++++++++++++++++++++ bin/32commit | 29 +++++++++++++++++++++++++++++ bin/3commit | 2 +- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100755 bin/32add create mode 100755 bin/32commit diff --git a/bin/32add b/bin/32add new file mode 100755 index 000000000..856c2f133 --- /dev/null +++ b/bin/32add @@ -0,0 +1,22 @@ +#!/usr/bin/perl + +use Cwd; +use String::ShellQuote; + +my $USER = $ENV{USER}; + +my $dir = getcwd; +( my $prefix = $dir ) =~ s(^/home/$USER/freeside/?)() or die $dir; #eventually from anywhere + +system join('', + "git add @ARGV ; ", + "( for file in @ARGV; do ", + "cp -i \$file /home/$USER/freeside3/$prefix/`dirname \$file`;", + "cp -i \$file /home/$USER/freeside2.3/$prefix/`dirname \$file`;", + "done ) && ", + "cd /home/$USER/freeside3/$prefix/ && ", + "git add @ARGV; ", + "cd /home/$USER/freeside2.3/$prefix/ && ", + "git add @ARGV" +); + diff --git a/bin/32commit b/bin/32commit new file mode 100755 index 000000000..903722e4e --- /dev/null +++ b/bin/32commit @@ -0,0 +1,29 @@ +#!/usr/bin/perl + +# usage: 32commit 'log message' filename filename ... + +use Cwd; +use String::ShellQuote; + +my $USER = $ENV{USER}; + +my $dir = getcwd; +( my $prefix = $dir ) =~ s(^/home/$USER/freeside/?)() or die $dir; #eventually from anywhere + +my $desc = shell_quote(shift @ARGV); # -m + +die "no files!" unless @ARGV; + +#warn "$prefix"; + +#print < Date: Sat, 11 May 2013 13:22:00 -0700 Subject: depend on Email::Sender::Transport::SMTP::TLS 0.11 to fix Can't locate object method "code" via package "Net::SMTP::TLS::ButMaintained", RT#22962 --- FS/FS/Misc.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm index de9fb522f..afe056f87 100644 --- a/FS/FS/Misc.pm +++ b/FS/FS/Misc.pm @@ -108,7 +108,7 @@ use Date::Format; use MIME::Entity; use Email::Sender::Simple qw(sendmail); use Email::Sender::Transport::SMTP; -use Email::Sender::Transport::SMTP::TLS; +use Email::Sender::Transport::SMTP::TLS 0.11; use FS::UID; FS::UID->install_callback( sub { -- cgit v1.2.1 From 178a4a3b111cb1cae3b44b2de4a86c8491096bfa Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 13 May 2013 13:12:34 -0700 Subject: add custnum to phone_shellcommands export, RT#23062 --- FS/FS/part_export/phone_shellcommands.pm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FS/FS/part_export/phone_shellcommands.pm b/FS/FS/part_export/phone_shellcommands.pm index 161ffe0f5..411c263d2 100644 --- a/FS/FS/part_export/phone_shellcommands.pm +++ b/FS/FS/part_export/phone_shellcommands.pm @@ -52,6 +52,7 @@ old_ for replace operations):
  • $pin - Personal identification number
  • $cust_name - Customer name (quoted for the shell)
  • $pkgnum - Internal package number +
  • $custnum - Internal customer number
  • $mac_addr - MAC address (Device MAC address insert and delete commands only) END @@ -107,6 +108,7 @@ sub _export_command { } my $cust_pkg = $svc_phone->cust_svc->cust_pkg; my $pkgnum = $cust_pkg ? $cust_pkg->pkgnum : ''; + my $custnum = $cust_pkg ? $cust_pkg->custnum : ''; my $cust_name = $cust_pkg ? $cust_pkg->cust_main->name : ''; $cust_name = shell_quote $cust_name; my $sip_password = shell_quote $svc_phone->sip_password; @@ -133,8 +135,10 @@ sub _export_replace { my $old_cust_pkg = $old->cust_svc->cust_pkg; my $old_pkgnum = $old_cust_pkg ? $old_cust_pkg->pkgnum : ''; + my $old_custnum = $old_cust_pkg ? $old_cust_pkg->custnum : ''; my $cust_pkg = $new->cust_svc->cust_pkg; my $new_pkgnum = $cust_pkg ? $cust_pkg->pkgnum : ''; + my $new_custnum = $new_cust_pkg ? $new_cust_pkg->custnum : ''; my $new_cust_name = $cust_pkg ? $cust_pkg->cust_main->name : ''; $new_cust_name = shell_quote $new_cust_name; #done setting variables for the command -- cgit v1.2.1 From d3c4fed49558ea5a99d379bf7e1cbefc8049d2d0 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 13 May 2013 14:19:07 -0700 Subject: add anniversary-rollback option to roll the anniversary date back to the 28th instead of forward into the following month, RT#22723 --- FS/FS/Conf.pm | 7 +++++++ FS/FS/part_pkg.pm | 3 +++ 2 files changed, 10 insertions(+) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 3c445200c..0a9b781d7 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -865,6 +865,13 @@ sub reason_type_options { 'type' => 'checkbox', }, + { + 'key' => 'anniversary-rollback', + 'section' => 'billing', + 'description' => 'When billing an anniversary package ordered after the 28th, roll the anniversary date back to the 28th instead of forward into the following month.', + 'type' => 'checkbox', + }, + { 'key' => 'encryption', 'section' => 'billing', diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index e788269f7..605c84f95 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -1081,6 +1081,9 @@ sub add_freq { if ( $freq =~ /^\d+$/ ) { $mon += $freq; until ( $mon < 12 ) { $mon -= 12; $year++; } + + $mday = 28 if $mday > 28 && FS::Conf->new->exists('anniversary-rollback'); + } elsif ( $freq =~ /^(\d+)w$/ ) { my $weeks = $1; $mday += $weeks * 7; -- cgit v1.2.1 From 080f96d15c8fb9aa02527670707840f6f5ef1e2b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 13 May 2013 14:19:36 -0700 Subject: anniversary-rollback default in new installs starting with 4.x, RT#22723 --- conf/anniversary-rollback | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 conf/anniversary-rollback diff --git a/conf/anniversary-rollback b/conf/anniversary-rollback new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.1 From 7a33a40d9f17d73e7f14410070675da02e25ad5e Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 13 May 2013 23:04:46 -0700 Subject: whitespace --- httemplate/elements/menu.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 5689b12d2..044426b7f 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -207,10 +207,10 @@ foreach my $svcdb ( FS::part_svc->svc_tables() ) { ]; } - $report_svc{"Advanced $lcsname reports"} = - [ $fsurl."search/report_$svcdb.html", '' ] - if $svcdb =~ /^svc_(acct|broadband|hardware|phone)$/ - && $curuser->access_right("Services: $name: Advanced search"); + $report_svc{"Advanced $lcsname reports"} = + [ $fsurl."search/report_$svcdb.html", '' ] + if $svcdb =~ /^svc_(acct|broadband|hardware|phone)$/ + && $curuser->access_right("Services: $name: Advanced search"); if ( $svcdb eq 'svc_phone' ) { -- cgit v1.2.1 From 7c41eea8dca02a399739c29a0dfbda7efdd6df86 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 14 May 2013 00:28:33 -0700 Subject: svc_cable, RT#22009 --- FS/FS/AccessRight.pm | 1 + FS/FS/Schema.pm | 24 +++++ FS/FS/access_right.pm | 1 + FS/FS/cable_device.pm | 140 ++++++++++++++++++++++++++++++ FS/FS/device_Common.pm | 78 +++++++++++++++++ FS/FS/svc_cable.pm | 114 ++++++++++++++++++++++++ FS/MANIFEST | 4 + FS/t/cable_device.t | 5 ++ FS/t/svc_cable.t | 5 ++ httemplate/docs/part_svc-table.html | 1 + httemplate/edit/cable_device.html | 114 ++++++++++++++++++++++++ httemplate/edit/process/cable_device.html | 23 +++++ httemplate/view/elements/svc_Common.html | 5 ++ httemplate/view/elements/svc_devices.html | 10 ++- httemplate/view/svc_phone.cgi | 1 + 15 files changed, 522 insertions(+), 4 deletions(-) create mode 100644 FS/FS/cable_device.pm create mode 100644 FS/FS/device_Common.pm create mode 100644 FS/FS/svc_cable.pm create mode 100644 FS/t/cable_device.t create mode 100644 FS/t/svc_cable.t create mode 100644 httemplate/edit/cable_device.html create mode 100644 httemplate/edit/process/cable_device.html diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index 373617e36..4753d3166 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -293,6 +293,7 @@ tie my %rights, 'Tie::IxHash', 'Services: Wireless broadband services', 'Services: Wireless broadband services: Advanced search', 'Services: DSLs', + 'Services: Cable subscribers', 'Services: Dish services', 'Services: Hardware', 'Services: Hardware: Advanced search', diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 28c7fc465..ed23d31b6 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -4129,6 +4129,30 @@ sub tables_hashref { 'index' => [], }, + 'svc_cable' => { + 'columns' => [ + 'svcnum', 'int', '', '', '', '', + #nothing so far... there should be _something_ uniquely identifying + # each subscriber besides the device info...? + ], + 'primary_key' => 'svcnum', + 'unique' => [], + 'index' => [], + }, + + 'cable_device' => { + 'columns' => [ + 'devicenum', 'serial', '', '', '', '', + 'devicepart', 'int', '', '', '', '', + 'svcnum', 'int', '', '', '', '', + 'mac_addr', 'varchar', 'NULL', 12, '', '', + 'serial', 'varchar', 'NULL', $char_d, '', '', + ], + 'primary_key' => 'devicenum', + 'unique' => [ [ 'mac_addr' ], ], + 'index' => [ [ 'devicepart' ], [ 'svcnum' ], ], + }, + %{ tables_hashref_torrus() }, # tables of ours for doing torrus virtual port combining diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm index 5bcf92214..a42d7f280 100644 --- a/FS/FS/access_right.pm +++ b/FS/FS/access_right.pm @@ -233,6 +233,7 @@ sub _upgrade_data { # class method 'Employees: Audit Report', ], 'Change customer package' => 'Detach customer package', + 'Services: Accounts' => 'Services: Cable Subscribers', ; foreach my $old_acl ( keys %onetime ) { diff --git a/FS/FS/cable_device.pm b/FS/FS/cable_device.pm new file mode 100644 index 000000000..1a0f1b998 --- /dev/null +++ b/FS/FS/cable_device.pm @@ -0,0 +1,140 @@ +package FS::cable_device; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearchs ); # qsearch ); +use FS::part_device; +use FS::svc_cable; + +=head1 NAME + +FS::cable_device - Object methods for cable_device records + +=head1 SYNOPSIS + + use FS::cable_device; + + $record = new FS::cable_device \%hash; + $record = new FS::cable_device { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::cable_device object represents a specific customer cable modem. +FS::cable_device inherits from FS::Record. The following fields are currently +supported: + +=over 4 + +=item devicenum + +primary key + +=item devicepart + +devicepart + +=item svcnum + +svcnum + +=item mac_addr + +mac_addr + +=item serial + +serial + + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new record. To add the record to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +sub table { 'cable_device'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=item check + +Checks all fields to make sure this is a valid record. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $mac = $self->mac_addr; + $mac =~ s/\s+//g; + $mac =~ s/://g; + $self->mac_addr($mac); + + my $error = + $self->ut_numbern('devicenum') + || $self->ut_number('devicepart') + || $self->ut_foreign_key('devicepart', 'part_device', 'devicepart') + || $self->ut_foreign_key('svcnum', 'svc_cable', 'svcnum' ) #cust_svc? + || $self->ut_hexn('mac_addr') + || $self->ut_textn('serial') + ; + return $error if $error; + + $self->SUPER::check; +} + +=item part_device + +Returns the device type record (see L) associated with this +customer device. + +=cut + +sub part_device { + my $self = shift; + qsearchs( 'part_device', { 'devicepart' => $self->devicepart } ); +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L + +=cut + +1; + diff --git a/FS/FS/device_Common.pm b/FS/FS/device_Common.pm new file mode 100644 index 000000000..ac00b7669 --- /dev/null +++ b/FS/FS/device_Common.pm @@ -0,0 +1,78 @@ +package FS::device_Common; + +use strict; +use NEXT; +use FS::Record qw( qsearch dbh ); # qsearchs ); + +=head1 NAME + +FS::device_Common - Base class for svc_X classes which have associated X_devices + +=head1 SYNOPSIS + + package FS::svc_newservice + use base qw( FS::device_Common FS::svc_Common ); + +=head1 DESCRIPTION + +=cut + +sub _device_table { + my $self = shift; + ( my $device_table = $self->table ) =~ s/^svc_//; + $device_table.'_device'; +} + +sub device_table { + my $self = shift; + my $device_table = $self->_device_table; + eval "use FS::$device_table;"; + die $@ if $@; + $device_table; +} + +sub device_objects { + my $self = shift; + qsearch($self->device_table, { 'svcnum' => $self->svcnum } ); +} + +sub delete { + my $self = shift; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + foreach my $device ( $self->device_objects ) { + my $error = $device->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + my $error = $self->NEXT::delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + +} + +=head1 BUGS + +=head1 SEE ALSO + +=cut + +1; diff --git a/FS/FS/svc_cable.pm b/FS/FS/svc_cable.pm new file mode 100644 index 000000000..f588f43c3 --- /dev/null +++ b/FS/FS/svc_cable.pm @@ -0,0 +1,114 @@ +package FS::svc_cable; +use base qw( FS::device_Common FS::svc_Common ); + +use strict; +use base qw( FS::Record ); +use FS::Record; # qw( qsearch qsearchs ); + +=head1 NAME + +FS::svc_cable - Object methods for svc_cable records + +=head1 SYNOPSIS + + use FS::svc_cable; + + $record = new FS::svc_cable \%hash; + $record = new FS::svc_cable { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::svc_cable object represents a cable subscriber. FS::svc_cable inherits +from FS::Record. The following fields are currently supported: + +=over 4 + +=item svcnum + +primary key + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new record. To add the record to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +sub table { 'svc_cable'; } + +sub table_info { + { + 'name' => 'Cable Subscriber', + #'name_plural' => '', #optional, + #'longname_plural' => '', #optional + 'sorts' => [ 'svcnum', ], #, 'serviceid' ], # optional sort field (or arrayref of sort fields, main first) + 'display_weight' => 54, + 'cancel_weight' => 70, #? no deps, so + 'fields' => { + 'svcnum' => 'Service', + 'identifier' => 'Identifier', + }, + }; +} + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=item check + +Checks all fields to make sure this is a valid record. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('svcnum') + ; + return $error if $error; + + $self->SUPER::check; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index ee184071e..3a58c8e8f 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -696,3 +696,7 @@ FS/part_pkg_msgcat.pm t/part_pkg_msgcat.t FS/access_user_session.pm t/access_user_session.t +FS/svc_cable.pm +t/svc_cable.t +FS/cable_device.pm +t/cable_device.t diff --git a/FS/t/cable_device.t b/FS/t/cable_device.t new file mode 100644 index 000000000..016d2c5c1 --- /dev/null +++ b/FS/t/cable_device.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::cable_device; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/svc_cable.t b/FS/t/svc_cable.t new file mode 100644 index 000000000..505765990 --- /dev/null +++ b/FS/t/svc_cable.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::svc_cable; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/docs/part_svc-table.html b/httemplate/docs/part_svc-table.html index 48841f550..8d3711d23 100644 --- a/httemplate/docs/part_svc-table.html +++ b/httemplate/docs/part_svc-table.html @@ -21,6 +21,7 @@
    • svc_dsl: DSL
    • svc_broadband: Wireless broadband +
    • svc_cable: Cable
    • svc_dish: DISH Network
    diff --git a/httemplate/edit/cable_device.html b/httemplate/edit/cable_device.html new file mode 100644 index 000000000..eb91ad728 --- /dev/null +++ b/httemplate/edit/cable_device.html @@ -0,0 +1,114 @@ +<% include( 'elements/edit.html', + 'name' => 'Cable device', + 'table' => 'cable_device', + 'labels' => { + 'devicenum' => 'Device', + 'devicepart' => 'Device type', + 'mac_addr' => 'MAC address', + 'serial' => 'Serial number', + }, + 'fields' => [ { 'field' => 'devicepart', + 'type' => 'select-table', + 'table' => 'part_device', + 'name_col' => 'devicename', + 'onchange' => 'devicepart_changed', + 'empty_label' =>'Select device type', + #'hashref' =>{ disabled => '' }, + }, + { field => 'mac_addr', + type => 'select-mac', + }, + { 'field' => 'svcnum', + 'type' => 'hidden', + }, + ], + 'menubar' => [], #disable viewall + #'viewall_dir' => 'browse', + 'new_callback' => sub { + my( $cgi, $object ) = @_; + $object->svcnum( $cgi->param('svcnum') ); + }, + 'html_foot' => $html_foot, + ) +%> +<%init> + +#bad: pretty much entirely false laziness w/phone_device, except for labels and +# the serial field + +my @deviceparts_with_inventory = + map $_->devicepart, + qsearch({ 'table' => 'part_device', + 'extra_sql' => 'WHERE inventory_classnum IS NOT NULL', + }); + +my $html_foot = sub { + my $js = " +"; + + $js; +}; + +# :/ needs agent-virt so you can't futz with arbitrary devices + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + + + diff --git a/httemplate/edit/process/cable_device.html b/httemplate/edit/process/cable_device.html new file mode 100644 index 000000000..97b4f81d9 --- /dev/null +++ b/httemplate/edit/process/cable_device.html @@ -0,0 +1,23 @@ +<% include( 'elements/process.html', + 'table' => 'cable_device', + 'redirect' => sub { + my( $cgi, $cable_device ) = @_; + #popurl(3).'view/svc_cable.html?'. + popurl(3).'view/svc_Common.html?svcdb=svc_cable;'. + 'svcnum='. $cable_device->svcnum. + ';devicenum='; + }, + ) +%> +<%init> + +if($cgi->param('sel_mac_addr') && !$cgi->param('mac_addr')) { + $cgi->param('mac_addr',$cgi->param('sel_mac_addr')); +} + +# :/ needs agent-virt so you can't futz with arbitrary devices + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + + diff --git a/httemplate/view/elements/svc_Common.html b/httemplate/view/elements/svc_Common.html index 997ac142a..3c1cc66fa 100644 --- a/httemplate/view/elements/svc_Common.html +++ b/httemplate/view/elements/svc_Common.html @@ -119,6 +119,11 @@ function areyousure(href) {
    +<& svc_devices.html, + 'svc_x' => $svc_x, + 'table' => $svc_x->device_table, +&> + % if ( defined($opt{'html_foot'}) ) { <% ref($opt{'html_foot'}) diff --git a/httemplate/view/elements/svc_devices.html b/httemplate/view/elements/svc_devices.html index 38c6d0919..745eabd9d 100644 --- a/httemplate/view/elements/svc_devices.html +++ b/httemplate/view/elements/svc_devices.html @@ -30,7 +30,7 @@ <& /elements/table-grid.html &> -% if ( $table eq 'phone_device' ) { +% if ( $table eq 'phone_device' || $table eq 'cable_device' ) { Type % } MAC Addr @@ -58,7 +58,8 @@ % if $device->can('export_links'); -% if ( $table eq 'phone_device' ) { #$devices->can('part_device') +% #$devices->can('part_device') +% if ( $table eq 'phone_device' || $svc_x->isa('FS::device_Common') ) { <% $td %><% $device->part_device->devicename |h %> % } <% $td %><% $device->mac_addr %> @@ -84,7 +85,7 @@ my $table = $opt{'table'}; #part_device, dsl_device my $svc_x = $opt{'svc_x'}; my $num_part_device = 0; -if ( $table eq 'phone_device' ) { +if ( $table eq 'phone_device' || $table eq 'cable_device' ) { my $sth = dbh->prepare("SELECT COUNT(*) FROM part_device") #WHERE disabled = '' OR disabled IS NULL;"); or die dbh->errstr; @@ -92,6 +93,7 @@ if ( $table eq 'phone_device' ) { $num_part_device = $sth->fetchrow_arrayref->[0]; } -my @devices = $svc_x->$table(); +my @devices = $svc_x->isa('FS::device_Common') ? $svc_x->device_objects() + : $svc_x->$table(); diff --git a/httemplate/view/svc_phone.cgi b/httemplate/view/svc_phone.cgi index ed95c4cea..408364aeb 100644 --- a/httemplate/view/svc_phone.cgi +++ b/httemplate/view/svc_phone.cgi @@ -67,6 +67,7 @@ my $html_foot = sub { ### # Devices ### + #remove this when svc_phone isa device_Common, as elements/svc_Common will display it my $devices = include('/view/elements/svc_devices.html', 'svc_x' => $svc_phone, 'table' => 'phone_device', -- cgit v1.2.1 From 9a9d1eab4ca49da5598b489b05569a253a13c798 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 14 May 2013 00:30:38 -0700 Subject: svc_cable, RT#22009 --- FS/FS.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FS/FS.pm b/FS/FS.pm index 042c756d0..4b2e527db 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -210,6 +210,8 @@ L - Certificate service class L - Dish network service class +L - Cable service class + L - Inventory classes L - Inventory items -- cgit v1.2.1 From 52e932f780b1a2775a147e590782621c3be369d9 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 14 May 2013 00:31:47 -0700 Subject: svc_cable, RT#22009 --- FS/FS/Mason.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 6653fb7e1..90ced1f96 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -339,6 +339,8 @@ if ( -e $addl_handler_use_file ) { use FS::part_pkg_usage; use FS::cdr_cust_pkg_usage; use FS::part_pkg_msgcat; + use FS::svc_cable; + use FS::cable_device; # Sammath Naur if ( $FS::Mason::addl_handler_use ) { -- cgit v1.2.1 From 1ab3d1021689645456ef4073066c60043ea1633b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 14 May 2013 00:31:56 -0700 Subject: comment nit --- FS/FS/svc_phone.pm | 2 -- 1 file changed, 2 deletions(-) diff --git a/FS/FS/svc_phone.pm b/FS/FS/svc_phone.pm index bab8537bb..ee25740c3 100644 --- a/FS/FS/svc_phone.pm +++ b/FS/FS/svc_phone.pm @@ -358,8 +358,6 @@ sub delete { } -# the delete method can be inherited from FS::Record - =item replace OLD_RECORD Replaces the OLD_RECORD with this one in the database. If there is an error, -- cgit v1.2.1 From 1a67fad0119e58b139307d866d8c331d9f41f014 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 14 May 2013 18:45:40 -0700 Subject: add "Tokenized" card type to searches, RT#22953 --- httemplate/search/elements/cust_pay_or_refund.html | 15 +++++++++++++-- httemplate/search/elements/report_cust_pay_or_refund.html | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/httemplate/search/elements/cust_pay_or_refund.html b/httemplate/search/elements/cust_pay_or_refund.html index 7b2a17058..234121fa3 100755 --- a/httemplate/search/elements/cust_pay_or_refund.html +++ b/httemplate/search/elements/cust_pay_or_refund.html @@ -271,7 +271,7 @@ if ( $cgi->param('magic') ) { foreach my $payby ( $cgi->param('payby') ) { $payby =~ - /^(CARD|CHEK|BILL|PREP|CASH|WEST|MCRD)(-(VisaMC|Amex|Discover|Maestro))?$/ + /^(CARD|CHEK|BILL|PREP|CASH|WEST|MCRD)(-(VisaMC|Amex|Discover|Maestro|Tokenized))?$/ or die "illegal payby $payby"; my $payby_search = "$table.payby = '$1'"; @@ -282,6 +282,7 @@ if ( $cgi->param('magic') ) { my $search; if ( $cardtype eq 'VisaMC' ) { + #avoid posix regexes for portability $search = " ( ( substring($table.payinfo from 1 for 1) = '4' ". @@ -305,11 +306,14 @@ if ( $cgi->param('magic') ) { " OR substring($table.payinfo from 1 for 2) = '55' ". # " OR substring($table.payinfo from 1 for 2) = '36' ". #Diner's int'l was processed as Visa/MC inside US, now Discover " ) "; + } elsif ( $cardtype eq 'Amex' ) { + $search = " ( substring($table.payinfo from 1 for 2 ) = '34' ". " OR substring($table.payinfo from 1 for 2 ) = '37' ". " ) "; + } elsif ( $cardtype eq 'Discover' ) { my $conf = new FS::Conf; @@ -347,7 +351,9 @@ if ( $cgi->param('magic') ) { ). " OR substring($table.payinfo from 1 for 3 ) = '622' ". #China Union Pay processed as Discover outside CN " ) "; - } elsif ( $cardtype eq 'Maestro' ) { + + } elsif ( $cardtype eq 'Maestro' ) { + $search = " ( substring($table.payinfo from 1 for 2 ) = '63' ". " OR substring($table.payinfo from 1 for 2 ) = '67' ". @@ -364,6 +370,11 @@ if ( $cgi->param('magic') ) { " OR substring($table.payinfo from 1 for 6 ) ". " SIMILAR TO '49118[1-2]' ". " ) "; + + } elsif ( $cardtype eq 'Tokenized' ) { + + $search = " substring($table.payinfo from 1 for 2 ) = '99' "; + } else { die "unknown card type $cardtype"; } diff --git a/httemplate/search/elements/report_cust_pay_or_refund.html b/httemplate/search/elements/report_cust_pay_or_refund.html index 0462f1cd9..cdbcee234 100644 --- a/httemplate/search/elements/report_cust_pay_or_refund.html +++ b/httemplate/search/elements/report_cust_pay_or_refund.html @@ -37,6 +37,7 @@ Examples: + -- cgit v1.2.1 From 326bef027d6eaa521825f72ee26f10f087f71cf8 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 14 May 2013 19:59:35 -0700 Subject: fix bulk (during billing period) billing error if services are provisioned first, RT#22923 --- FS/FS/part_pkg/bulk.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FS/FS/part_pkg/bulk.pm b/FS/FS/part_pkg/bulk.pm index fd96f8bc2..4a55858de 100644 --- a/FS/FS/part_pkg/bulk.pm +++ b/FS/FS/part_pkg/bulk.pm @@ -44,6 +44,9 @@ sub _bulk_recur { if $self->option('no_prorate',1); my $last_bill = $cust_pkg->last_bill; + + return (0, '') if $$sdate == $last_bill; + my $svc_start = max( $h_cust_svc->date_inserted, $last_bill); my $svc_end = $h_cust_svc->date_deleted; $svc_end = ( !$svc_end || $svc_end > $$sdate ) ? $$sdate : $svc_end; -- cgit v1.2.1 From b2223120f597028442998ac1eed9165ad82a001c Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 14 May 2013 22:50:46 -0700 Subject: bigserial (bigint) keys for queue tables and h_ tables of things that already have bigserial keys, RT#22566 --- FS/FS/Schema.pm | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index ed23d31b6..1da302d5e 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -236,6 +236,12 @@ sub dbdef_dist { } + my $historynum_type = ( $tableobj->column($tableobj->primary_key)->type + =~ /^(bigserial|bigint|int8)$/i + ? 'bigserial' + : 'serial' + ); + my $h_tableobj = DBIx::DBSchema::Table->new( { 'name' => "h_$table", 'primary_key' => 'historynum', @@ -244,7 +250,7 @@ sub dbdef_dist { 'columns' => [ DBIx::DBSchema::Column->new( { 'name' => 'historynum', - 'type' => 'serial', + 'type' => $historynum_type, 'null' => 'NOT NULL', 'length' => '', 'default' => '', @@ -1533,7 +1539,7 @@ sub tables_hashref { 'gatewaynum', 'int', 'NULL', '', '', '', #'cust_balance', @money_type, '', '', 'paynum', 'int', 'NULL', '', '', '', - 'jobnum', 'int', 'NULL', '', '', '', + 'jobnum', 'bigint', 'NULL', '', '', '', ], 'primary_key' => 'paypendingnum', 'unique' => [ [ 'payunique' ] ], @@ -2664,7 +2670,7 @@ sub tables_hashref { 'queue' => { 'columns' => [ - 'jobnum', 'serial', '', '', '', '', + 'jobnum', 'bigserial', '', '', '', '', 'job', 'varchar', '', 512, '', '', '_date', 'int', '', '', '', '', 'status', 'varchar', '', $char_d, '', '', @@ -2683,10 +2689,10 @@ sub tables_hashref { 'queue_arg' => { 'columns' => [ - 'argnum', 'serial', '', '', '', '', - 'jobnum', 'int', '', '', '', '', - 'frozen', 'char', 'NULL', 1, '', '', - 'arg', 'text', 'NULL', '', '', '', + 'argnum', 'bigserial', '', '', '', '', + 'jobnum', 'bigint', '', '', '', '', + 'frozen', 'char', 'NULL', 1, '', '', + 'arg', 'text', 'NULL', '', '', '', ], 'primary_key' => 'argnum', 'unique' => [], @@ -2695,9 +2701,9 @@ sub tables_hashref { 'queue_depend' => { 'columns' => [ - 'dependnum', 'serial', '', '', '', '', - 'jobnum', 'int', '', '', '', '', - 'depend_jobnum', 'int', '', '', '', '', + 'dependnum', 'bigserial', '', '', '', '', + 'jobnum', 'bigint', '', '', '', '', + 'depend_jobnum', 'bigint', '', '', '', '', ], 'primary_key' => 'dependnum', 'unique' => [], -- cgit v1.2.1 From ddddcba7554c00271135c3e69d7d5ad5039b6707 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 15 May 2013 01:02:55 -0700 Subject: fix quotations RT#23068 fallout from RT#19906 RT#21293 --- FS/FS/Template_Mixin.pm | 122 ++++++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 55 deletions(-) diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index dd1796c7d..ad49ac806 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -122,9 +122,7 @@ sub print_latex { UNLINK => 0, ) or die "can't open temp file: $!\n"; - my $cust_main = $self->cust_main; - my $prospect_main = $self->prospect_main; - my $agentnum = $cust_main ? $cust_main->agentnum : $prospect_main->agentnum; + my $agentnum = $self->agentnum; if ( $template && $conf->exists("logo_${template}.eps", $agentnum) ) { print $lh $conf->config_binary("logo_${template}.eps", $agentnum) @@ -176,6 +174,12 @@ sub print_latex { } +sub agentnum { + my $self = shift; + my $cust_main = $self->cust_main; + $cust_main ? $cust_main->agentnum : $self->prospect_main->agentnum; +} + =item print_generic OPTION => VALUE ... Internal method - returns a filled-in template for this invoice as a scalar. @@ -597,54 +601,60 @@ sub print_generic { # info from customer's last invoice before this one, for some # summary formats $invoice_data{'last_bill'} = {}; + # returns the last unpaid bill, not the last bill #my $last_bill = $pr_cust_bill[-1]; - # THIS returns the customer's last bill before this one - my $last_bill = qsearchs({ - 'table' => 'cust_bill', - 'hashref' => { 'custnum' => $self->custnum, - 'invnum' => { op => '<', value => $self->invnum }, - }, - 'order_by' => ' ORDER BY invnum DESC LIMIT 1' - }); - if ( $last_bill ) { - $invoice_data{'last_bill'} = { - '_date' => $last_bill->_date, #unformatted - # all we need for now - }; - my (@payments, @credits); - # for formats that itemize previous payments - foreach my $cust_pay ( qsearch('cust_pay', { - 'custnum' => $self->custnum, - '_date' => { op => '>=', - value => $last_bill->_date } - } ) ) - { - next if $cust_pay->_date > $self->_date; - push @payments, { - '_date' => $cust_pay->_date, - 'date' => time2str($date_format, $cust_pay->_date), - 'payinfo' => $cust_pay->payby_payinfo_pretty, - 'amount' => sprintf('%.2f', $cust_pay->paid), - }; - # not concerned about applications - } - foreach my $cust_credit ( qsearch('cust_credit', { - 'custnum' => $self->custnum, - '_date' => { op => '>=', - value => $last_bill->_date } - } ) ) - { - next if $cust_credit->_date > $self->_date; - push @credits, { - '_date' => $cust_credit->_date, - 'date' => time2str($date_format, $cust_credit->_date), - 'creditreason'=> $cust_credit->cust_credit->reason, - 'amount' => sprintf('%.2f', $cust_credit->amount), + + if ( $self->custnum && $self->invnum ) { + + # THIS returns the customer's last bill before this one + my $last_bill = qsearchs({ + 'table' => 'cust_bill', + 'hashref' => { 'custnum' => $self->custnum, + 'invnum' => { op => '<', value => $self->invnum }, + }, + 'order_by' => ' ORDER BY invnum DESC LIMIT 1' + }); + if ( $last_bill ) { + $invoice_data{'last_bill'} = { + '_date' => $last_bill->_date, #unformatted + # all we need for now }; + my (@payments, @credits); + # for formats that itemize previous payments + foreach my $cust_pay ( qsearch('cust_pay', { + 'custnum' => $self->custnum, + '_date' => { op => '>=', + value => $last_bill->_date } + } ) ) + { + next if $cust_pay->_date > $self->_date; + push @payments, { + '_date' => $cust_pay->_date, + 'date' => time2str($date_format, $cust_pay->_date), + 'payinfo' => $cust_pay->payby_payinfo_pretty, + 'amount' => sprintf('%.2f', $cust_pay->paid), + }; + # not concerned about applications + } + foreach my $cust_credit ( qsearch('cust_credit', { + 'custnum' => $self->custnum, + '_date' => { op => '>=', + value => $last_bill->_date } + } ) ) + { + next if $cust_credit->_date > $self->_date; + push @credits, { + '_date' => $cust_credit->_date, + 'date' => time2str($date_format, $cust_credit->_date), + 'creditreason'=> $cust_credit->cust_credit->reason, + 'amount' => sprintf('%.2f', $cust_credit->amount), + }; + } + $invoice_data{'previous_payments'} = \@payments; + $invoice_data{'previous_credits'} = \@credits; } - $invoice_data{'previous_payments'} = \@payments; - $invoice_data{'previous_credits'} = \@credits; + } my $summarypage = ''; @@ -2239,7 +2249,6 @@ sub _items_cust_bill_pkg { my $cust_main = $self->cust_main;#for per-agent cust_bill-line_item-ate_style # and location labels - my $locale = $cust_main->locale; my @b = (); my ($s, $r, $u) = ( undef, undef, undef ); @@ -2284,7 +2293,7 @@ sub _items_cust_bill_pkg { my $type = $display->type; - my $desc = $cust_bill_pkg->desc( $cust_main->locale ); + my $desc = $cust_bill_pkg->desc( $cust_main ? $cust_main->locale : '' ); $desc = substr($desc, 0, $maxlength). '...' if $format eq 'latex' && length($desc) > $maxlength; @@ -2361,8 +2370,9 @@ sub _items_cust_bill_pkg { unless $cust_bill_pkg->pkgpart_override; #don't redisplay services $svc_label = $svc_labels[0]; - if ( ! $cust_pkg->locationnum or - $cust_pkg->locationnum != $cust_main->ship_locationnum ) { + my $lnum = $cust_main ? $cust_main->ship_locationnum + : $self->prospect_main->locationnum; + if ( ! $cust_pkg->locationnum or $cust_pkg->locationnum != $lnum ) { my $loc = $cust_pkg->location_label; $loc = substr($loc, 0, $maxlength). '...' if $format eq 'latex' && length($loc) > $maxlength; @@ -2425,17 +2435,17 @@ sub _items_cust_bill_pkg { my $time_period; my $date_style = ''; $date_style = $conf->config( 'cust_bill-line_item-date_style-non_monhtly', - $cust_main->agentnum + $self->agentnum ) if $part_pkg && $part_pkg->freq !~ /^1m?$/; $date_style ||= $conf->config( 'cust_bill-line_item-date_style', - $cust_main->agentnum + $self->agentnum ); if ( defined($date_style) && $date_style eq 'month_of' ) { $time_period = time2str('The month of %B', $cust_bill_pkg->sdate); } elsif ( defined($date_style) && $date_style eq 'X_month' ) { my $desc = $conf->config( 'cust_bill-line_item-date_description', - $cust_main->agentnum + $self->agentnum ); $desc .= ' ' unless $desc =~ /\s$/; $time_period = $desc. time2str('%B', $cust_bill_pkg->sdate); @@ -2476,7 +2486,9 @@ sub _items_cust_bill_pkg { warn "$me _items_cust_bill_pkg done adding service details\n" if $DEBUG > 1; - if ( $cust_pkg->locationnum != $cust_main->ship_locationnum ) { + my $lnum = $cust_main ? $cust_main->ship_locationnum + : $self->prospect_main->locationnum; + if ( $cust_pkg->locationnum != $lnum ) { my $loc = $cust_pkg->location_label; $loc = substr($loc, 0, $maxlength). '...' if $format eq 'latex' && length($loc) > $maxlength; -- cgit v1.2.1 From c60a792261878dd4148471b10e3f82980cea4b1e Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 15 May 2013 01:25:45 -0700 Subject: add h_svc_cable for invoices, RT#22009 --- FS/FS/h_svc_cable.pm | 32 ++++++++++++++++++++++++++++++++ FS/MANIFEST | 2 ++ FS/t/h_svc_cable.t | 5 +++++ 3 files changed, 39 insertions(+) create mode 100644 FS/FS/h_svc_cable.pm create mode 100644 FS/t/h_svc_cable.t diff --git a/FS/FS/h_svc_cable.pm b/FS/FS/h_svc_cable.pm new file mode 100644 index 000000000..cee290882 --- /dev/null +++ b/FS/FS/h_svc_cable.pm @@ -0,0 +1,32 @@ +package FS::h_svc_cable; + +use strict; +use vars qw( @ISA ); +use FS::h_Common; +use FS::svc_cable; + +@ISA = qw( FS::h_Common FS::svc_cable ); + +sub table { 'h_svc_cable' }; + +=head1 NAME + +FS::h_svc_cable - Historical PBX objects + +=head1 SYNOPSIS + +=head1 DESCRIPTION + +An FS::h_svc_cable object represents a historical cable subscriber. +FS::h_svc_cable inherits from FS::h_Common and FS::svc_cable. + +=head1 BUGS + +=head1 SEE ALSO + +L, L, L + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 3a58c8e8f..eb4426a21 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -700,3 +700,5 @@ FS/svc_cable.pm t/svc_cable.t FS/cable_device.pm t/cable_device.t +FS/h_svc_cable.pm +t/h_svc_cable.t diff --git a/FS/t/h_svc_cable.t b/FS/t/h_svc_cable.t new file mode 100644 index 000000000..7f9fad585 --- /dev/null +++ b/FS/t/h_svc_cable.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::h_svc_cable; +$loaded=1; +print "ok 1\n"; -- cgit v1.2.1 From 686ac9dce198f8ddf01e507b3289485b4ef20946 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 15 May 2013 02:09:30 -0700 Subject: payment voids exist, time for deletepayments to go --- FS/FS/Conf.pm | 7 ------- FS/FS/cust_pay.pm | 32 -------------------------------- 2 files changed, 39 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 0a9b781d7..0784cd050 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1065,13 +1065,6 @@ sub reason_type_options { 'type' => 'checkbox', }, - { - 'key' => 'deletepayments', - 'section' => 'billing', - 'description' => 'Enable deletion of unclosed payments. Really, with voids this is pretty much not recommended in any situation anymore. Be very careful! Only delete payments that were data-entry errors, not adjustments. Optionally specify one or more comma-separated email addresses to be notified when a payment is deleted.', - 'type' => [qw( checkbox text )], - }, - { 'key' => 'deletecredits', #not actually deprecated yet diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm index da9143909..86fcf9b4d 100644 --- a/FS/FS/cust_pay.pm +++ b/FS/FS/cust_pay.pm @@ -459,38 +459,6 @@ sub delete { return $error; } - if ( $conf->exists('deletepayments') - && $conf->config('deletepayments') ne '' ) { - - my $cust_main = $self->cust_main; - - my $error = send_email( - 'from' => $conf->config('invoice_from', $self->cust_main->agentnum), - #invoice_from??? well as good as any - 'to' => $conf->config('deletepayments'), - 'subject' => 'FREESIDE NOTIFICATION: Payment deleted', - 'body' => [ - "This is an automatic message from your Freeside installation\n", - "informing you that the following payment has been deleted:\n", - "\n", - 'paynum: '. $self->paynum. "\n", - 'custnum: '. $self->custnum. - " (". $cust_main->last. ", ". $cust_main->first. ")\n", - 'paid: $'. sprintf("%.2f", $self->paid). "\n", - 'date: '. time2str("%a %b %e %T %Y", $self->_date). "\n", - 'payby: '. $self->payby. "\n", - 'payinfo: '. $self->paymask. "\n", - 'paybatch: '. $self->paybatch. "\n", - ], - ); - - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "can't send payment deletion notification: $error"; - } - - } - $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; -- cgit v1.2.1 From cc9bdd96a6a3c70b87ef3ed1a9aa15bb0923d61c Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 15 May 2013 02:32:57 -0700 Subject: queue all email receipts, RT#22731, RT#23023 --- FS/FS/Misc.pm | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm index afe056f87..dbebf33b8 100644 --- a/FS/FS/Misc.pm +++ b/FS/FS/Misc.pm @@ -414,6 +414,20 @@ sub process_send_email { ''; } +=item process_send_generated_email OPTION => VALUE ... + +Takes arguments as per send_email() and sends the message. This +will die on any error and can be used in the job queue. + +=cut + +sub process_send_generated_email { + my %args = @_; + my $error = send_email(%args); + die "$error\n" if $error; + ''; +} + =item send_fax OPTION => VALUE ... Options: -- cgit v1.2.1 From ffe2da5352a459c39f8e9bd999e96a03c86324fb Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 15 May 2013 02:39:26 -0700 Subject: queue all email receipts, RT#22731, RT#23023 --- FS/FS/cust_pay.pm | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm index 86fcf9b4d..f6954a4bc 100644 --- a/FS/FS/cust_pay.pm +++ b/FS/FS/cust_pay.pm @@ -9,7 +9,6 @@ use vars qw( $DEBUG $me $conf @encrypted_fields use Date::Format; use Business::CreditCard; use Text::Template; -use FS::Misc qw( send_email ); use FS::Record qw( dbh qsearch qsearchs ); use FS::CurrentUser; use FS::payby; @@ -593,11 +592,18 @@ sub send_receipt { { my $msgnum = $conf->config('payment_receipt_msgnum', $cust_main->agentnum); if ( $msgnum ) { - my $msg_template = FS::msg_template->by_key($msgnum); - $error = $msg_template->send( - 'cust_main' => $cust_main, - 'object' => $self, - 'from_config' => 'payment_receipt_from', + + my $queue = new FS::queue { + 'job' => 'FS::Misc::process_send_email', + 'paynum' => $self->paynum, + 'custnum' => $cust_main->custnum, + }; + $error = $queue->insert( + FS::msg_template->by_key($msgnum)->prepare( + 'cust_main' => $cust_main, + 'object' => $self, + 'from_config' => 'payment_receipt_from', + ) ); } elsif ( $conf->exists('payment_receipt_email') ) { @@ -636,7 +642,12 @@ sub send_receipt { #setup date, other things? } - $error = send_email( + my $queue = new FS::queue { + 'job' => 'FS::Misc::process_send_generated_email', + 'paynum' => $self->paynum, + 'custnum' => $cust_main->custnum, + }; + $error = $queue->insert( 'from' => $conf->config('invoice_from', $cust_main->agentnum), #invoice_from??? well as good as any 'to' => \@invoicing_list, @@ -653,8 +664,9 @@ sub send_receipt { } elsif ( ! $cust_main->invoice_noemail ) { #not manual my $queue = new FS::queue { - 'paynum' => $self->paynum, - 'job' => 'FS::cust_bill::queueable_email', + 'job' => 'FS::cust_bill::queueable_email', + 'paynum' => $self->paynum, + 'custnum' => $cust_main->custnum, }; $error = $queue->insert( @@ -666,7 +678,7 @@ sub send_receipt { } - warn "send_receipt: $error\n" if $error; + warn "send_receipt: $error\n" if $error; } =item cust_bill_pay -- cgit v1.2.1 From 7ee4bace7200b1ff7b2510c45a08c8a77bd714e0 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 8 May 2013 14:35:10 -0400 Subject: #23120 Fix Freeswitch export --- FS/FS/part_export/freeswitch_multifile.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_export/freeswitch_multifile.pm b/FS/FS/part_export/freeswitch_multifile.pm index 105ff02e1..90a2b0469 100644 --- a/FS/FS/part_export/freeswitch_multifile.pm +++ b/FS/FS/part_export/freeswitch_multifile.pm @@ -60,7 +60,7 @@ sub _export_insert { my $svcnum = $svc_phone->svcnum; my $fh = new File::Temp( - TEMPLATE => "$tempdir/freeswitch.$svcnum.XXXXXXXX", + TEMPLATE => "freeswitch.$svcnum.XXXXXXXX", DIR => $tempdir, #UNLINK => 0, ); -- cgit v1.2.1 From cf5ea7941e280b3f30761213b393ead465124c52 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 16 May 2013 10:01:43 -0700 Subject: fix displaying invoices with credits, RT#23123, fallout from RT#21293 --- FS/FS/Template_Mixin.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index ad49ac806..b3d3cf2ed 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -647,7 +647,7 @@ sub print_generic { push @credits, { '_date' => $cust_credit->_date, 'date' => time2str($date_format, $cust_credit->_date), - 'creditreason'=> $cust_credit->cust_credit->reason, + 'creditreason'=> $cust_credit->reason, 'amount' => sprintf('%.2f', $cust_credit->amount), }; } -- cgit v1.2.1 From 67d6d7a6c446837af1855eef8495c286a58a9ac1 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 16 May 2013 13:31:08 -0700 Subject: statement link display by default, better label, statements say "statement" and have no dates/numbers, RT#23148 --- FS/FS/Conf.pm | 7 ------ FS/FS/Template_Mixin.pm | 11 ++++++--- httemplate/view/cust_main/payment_history.html | 5 ++-- httemplate/view/cust_main_statement-pdf.cgi | 32 ++++++++++++++++---------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 0784cd050..3dffa4584 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -5236,13 +5236,6 @@ and customer address. Include units.', 'select_enum' => [ 'Classic', 'Recurring' ], }, - { - 'key' => 'cust_main-print_statement_link', - 'section' => 'UI', - 'description' => 'Show a link to download a current statement for the customer.', - 'type' => 'checkbox', - }, - { 'key' => 'username-pound', 'section' => 'username', diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index b3d3cf2ed..be9d68a88 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -106,7 +106,7 @@ sub print_latex { $params{'time'} = $today if $today; $params{'template'} = $template if $template; $params{$_} = $opt{$_} - foreach grep $opt{$_}, qw( unsquelch_cdr notice_name ); + foreach grep $opt{$_}, qw( unsquelch_cdr notice_name no_date no_number ); $template ||= $self->_agent_template if $self->can('_agent_template'); @@ -445,9 +445,14 @@ sub print_generic { 'agent' => &$escape_function($cust_main->agent->agent), #invoice/quotation info - 'invnum' => $self->invnum, + 'no_number' => $params{'no_number'}, + 'invnum' => ( $params{'no_number'} ? '' : $self->invnum ), 'quotationnum' => $self->quotationnum, - 'date' => time2str($date_format, $self->_date), + 'no_date' => $params{'no_date'}, + 'date' => ( $params{'no_date'} + ? '' + : time2str($date_format, $self->_date) + ), 'today' => time2str($date_format_long, $today), 'terms' => $self->terms, 'template' => $template, #params{'template'}, diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html index 915be49e5..c7bf3748c 100644 --- a/httemplate/view/cust_main/payment_history.html +++ b/httemplate/view/cust_main/payment_history.html @@ -141,10 +141,9 @@ %# invoice reports, combined statement % if ( $curuser->access_right('List invoices') ) { -% if ( $conf->exists('cust_main-print_statement_link') -% and $num_cust_bill > 0 ) { +% if ( $num_cust_bill > 0 ) { <% - mt('Print a current statement') |h %> + mt('Download typeset statement PDF') |h %>
    % } <% mt('Invoice reports') |h %> diff --git a/httemplate/view/cust_main_statement-pdf.cgi b/httemplate/view/cust_main_statement-pdf.cgi index 7c2c20799..79110ee20 100755 --- a/httemplate/view/cust_main_statement-pdf.cgi +++ b/httemplate/view/cust_main_statement-pdf.cgi @@ -1,29 +1,34 @@ +<% $pdf %>\ <%doc> Like view/cust_statement-pdf.cgi, but for viewing/printing the implicit statement containing all of a customer's invoices. Slightly redundant. I don't see the need to create an equivalent to view/cust_statement.html for this case, but one can be added if necessary. -<% $pdf %> <%init> die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('View invoices'); -#untaint statement my($query) = $cgi->keywords; -$query =~ /^((.+)-)?(\d+)$/; -my $templatename = $2 || 'statement'; #XXX configure... via event?? eh.. -my $custnum = $3; +$query =~ /^(\d+)$/; +my $custnum = $1; +#mostly for the agent-virt, i guess. could probably bolt it onto the cust_bill +# search my $cust_main = qsearchs({ 'select' => 'cust_main.*', 'table' => 'cust_main', 'hashref' => { 'custnum' => $custnum }, 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, -}); -die "Customer #$custnum not found!" unless $cust_main; -my $cust_bill = ($cust_main->cust_bill)[-1] +}) + or die "Customer #$custnum not found!"; + +my $cust_bill = qsearchs({ + 'table' => 'cust_bill', + 'hashref' => { 'custnum' => $custnum }, + 'order_by' => 'ORDER BY _date desc LIMIT 1', +}) or die "Customer #$custnum has no invoices!"; my $cust_statement = FS::cust_statement->new({ @@ -33,11 +38,14 @@ my $cust_statement = FS::cust_statement->new({ '_date' => time, }); +my $pdf = $cust_statement->print_pdf({ + 'notice_name' => 'Statement', + 'no_date' => 1, + 'no_number' => 1, +}); -my $pdf = $cust_statement->print_pdf( '', $templatename ); - -http_header('Content-Type' => 'application/pdf' ); +http_header('Content-Type' => 'application/pdf' ); http_header('Content-Length' => length($pdf) ); -http_header('Cache-control' => 'max-age=60' ); +http_header('Cache-control' => 'max-age=60' ); -- cgit v1.2.1 From a1a1fbca688fda6c737bf016f6f3565b5192497b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 16 May 2013 13:31:32 -0700 Subject: statement link display by default, better label, statements say "statement" and have no dates/numbers, RT#23148 --- conf/invoice_latex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/conf/invoice_latex b/conf/invoice_latex index 533e8340d..b169b617f 100644 --- a/conf/invoice_latex +++ b/conf/invoice_latex @@ -127,7 +127,11 @@ \ifthenelse{\equal{\thepage}{1}} { % First page \begin{tabular}{ccc} - [@-- join(' & ', emt('Invoice date'), emt('Invoice #'), emt('Customer #') ) --@]\\ + [@-- join(' & ', ( $no_date ? '' : emt('Invoice date') ), + ( $no_number ? '' : emt('Invoice #') ), + emt('Customer #') + ) + --@]\\ \vspace{0.2cm} \textbf{[@-- $date --@]} & \textbf{[@-- $invnum --@]} & \textbf{[@-- $custnum --@]} \\\hline \rule{0pt}{5ex} &~~ \huge{\textsc{[@-- emt($notice_name) --@]}} & \\ -- cgit v1.2.1 From 67a2ec7e476c9a78092f451cc1d1f2e09ac39700 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 17 May 2013 13:22:37 -0700 Subject: history_user -> history_usernum --- FS/FS/Record.pm | 4 ++-- FS/FS/Schema.pm | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 3886c3333..cdbcae049 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -1907,10 +1907,10 @@ sub _h_statement { my @values = map { _quote( $self->getfield($_), $self->table, $_) } @fields; "INSERT INTO h_". $self->table. " ( ". - join(', ', qw(history_date history_user history_action), @fields ). + join(', ', qw(history_date history_usernum history_action), @fields ). ") VALUES (". join(', ', $time, - dbh->quote( $FS::CurrentUser::CurrentUser->username ), + $FS::CurrentUser::CurrentUser->usernum, dbh->quote($action), @values ). diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 1da302d5e..5f1611cf7 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -267,11 +267,19 @@ sub dbdef_dist { DBIx::DBSchema::Column->new( { 'name' => 'history_user', 'type' => 'varchar', - 'null' => 'NOT NULL', + 'null' => 'NULL', 'length' => '80', 'default' => '', 'local' => '', } ), + DBIx::DBSchema::Column->new( { + 'name' => 'history_usernum', + 'type' => 'int', + 'null' => 'NULL', + 'length' => '', + 'default' => '', + 'local' => '', + } ), DBIx::DBSchema::Column->new( { 'name' => 'history_action', 'type' => 'varchar', -- cgit v1.2.1 From 508756cf10352b6cf54a32fbce18ec57121214ce Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 17 May 2013 15:09:13 -0700 Subject: add contract_end to Package age condition, RT#23171 --- FS/FS/part_event/Condition/pkg_age.pm | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/FS/FS/part_event/Condition/pkg_age.pm b/FS/FS/part_event/Condition/pkg_age.pm index 4a8538780..24a73e22f 100644 --- a/FS/FS/part_event/Condition/pkg_age.pm +++ b/FS/FS/part_event/Condition/pkg_age.pm @@ -23,16 +23,18 @@ sub option_fields { }, 'field' => { 'label' => 'Compare date', 'type' => 'select', - 'options' => - [qw( setup last_bill bill adjourn susp expire cancel )], + 'options' => [qw( + setup last_bill bill adjourn susp expire cancel contract_end + )], 'labels' => { - 'setup' => 'Setup date', - 'last_bill' => 'Last bill date', - 'bill' => 'Next bill date', - 'adjourn' => 'Adjournment date', - 'susp' => 'Suspension date', - 'expire' => 'Expiration date', - 'cancel' => 'Cancellation date', + 'setup' => 'Setup date', + 'last_bill' => 'Last bill date', + 'bill' => 'Next bill date', + 'adjourn' => 'Adjournment date', + 'susp' => 'Suspension date', + 'expire' => 'Expiration date', + 'cancel' => 'Cancellation date', + 'contract_end' => 'Contract end date', }, }, ); -- cgit v1.2.1 From eef99d4b1595d23b73f8800900ba984fe242b8c4 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 20 May 2013 12:36:06 -0700 Subject: allow friendly from: addresses on email notices, #22962 --- FS/FS/Misc.pm | 11 +++++++++-- FS/FS/UI/Web.pm | 4 ++++ FS/FS/cust_main_Mixin.pm | 1 + httemplate/misc/email-customers.html | 31 +++++++++++++++++++++++-------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm index dbebf33b8..9c18961ea 100644 --- a/FS/FS/Misc.pm +++ b/FS/FS/Misc.pm @@ -171,8 +171,15 @@ sub send_email { } + my $from = $options{from}; + $from =~ s/^\s*//; $from =~ s/\s*$//; + if ( $from =~ /^(.*)\s*<(.*@.*)>$/ ) { + # a common idiom + $from = $2; + } + my $domain; - if ( $options{'from'} =~ /\@([\w\.\-]+)/ ) { + if ( $from =~ /\@([\w\.\-]+)/ ) { $domain = $1; } else { warn 'no domain found in invoice from address '. $options{'from'}. @@ -247,7 +254,7 @@ sub send_email { push @to, $options{bcc} if defined($options{bcc}); local $@; # just in case eval { sendmail($message, { transport => $transport, - from => $options{from}, + from => $from, to => \@to }) }; my $error = ''; diff --git a/FS/FS/UI/Web.pm b/FS/FS/UI/Web.pm index f63854ca0..ccba1de3a 100644 --- a/FS/FS/UI/Web.pm +++ b/FS/FS/UI/Web.pm @@ -678,6 +678,10 @@ sub start_job { #warn 'froze string of size '. length(nfreeze(\%param)). " for job args\n" # if $DEBUG; + # + # XXX FS::queue::insert knows how to do this. + # not changing it here because that requires changing it everywhere else, + # too, but we should eventually fix it my $error = $job->insert( '_JOB', encode_base64(nfreeze(\%param)) ); diff --git a/FS/FS/cust_main_Mixin.pm b/FS/FS/cust_main_Mixin.pm index a0677060e..212c04e0f 100644 --- a/FS/FS/cust_main_Mixin.pm +++ b/FS/FS/cust_main_Mixin.pm @@ -539,6 +539,7 @@ sub process_email_search_result { die "error loading FS::$table: $@\n" if $@; my $error = "FS::$table"->email_search_result( $param ); + dbh->commit; # save failed jobs before rethrowing the error die $error if $error; } diff --git a/httemplate/misc/email-customers.html b/httemplate/misc/email-customers.html index fcd79d7f8..ad67b8d7e 100644 --- a/httemplate/misc/email-customers.html +++ b/httemplate/misc/email-customers.html @@ -104,13 +104,19 @@ Template: ) %>
    - <% include('/elements/tr-input-text.html', - 'field' => 'from', - 'label' => 'From:', - 'size' => 50, - ) - %> - + <& /elements/tr-td-label.html, 'label' => 'From:' &> + + <% include('/elements/tr-input-text.html', 'field' => 'subject', 'label' => 'Subject:', @@ -151,6 +157,7 @@ Template: die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Bulk send customer notices'); +my $conf = FS::Conf->new; my $table = $cgi->param('table') or die "'table' required"; my %search; if ( $cgi->param('search') ) { @@ -169,7 +176,15 @@ else { my $title = 'Send customer notices'; my $num_cust; -my $from = $cgi->param('from') || ''; +my $from = ''; +if ( $cgi->param('from') ) { + $from = $cgi->param('from'); +} elsif ( $cgi->param('from_name') ) { + $from = ($cgi->param('from_name') . ' <' . $cgi->param('from_addr') . '>'); +} elsif ( $cgi->param('from_addr') ) { + $from = $cgi->param('from_addr'); +} + my $subject = $cgi->param('subject') || ''; my $html_body = $cgi->param('html_body') || ''; -- cgit v1.2.1 From 6ce6794cdbf96da682249d66504fef237b54bf0f Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 20 May 2013 16:20:09 -0700 Subject: option for inactive_age condition to ignore some kinds of charges, #19873 --- FS/FS/part_event/Condition/inactive_age.pm | 38 +++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/FS/FS/part_event/Condition/inactive_age.pm b/FS/FS/part_event/Condition/inactive_age.pm index 8918a1a3c..cbf4b9e0a 100644 --- a/FS/FS/part_event/Condition/inactive_age.pm +++ b/FS/FS/part_event/Condition/inactive_age.pm @@ -11,6 +11,10 @@ sub option_fields { 'age' => { 'label' => 'No activity within', 'type' => 'freq', }, + 'ignore_pkgclass' => + { 'label' => 'Except charges of class', + 'type' => 'select-pkg_class', + }, # flags to select kinds of activity, # like if you just want "no payments since"? # not relevant yet @@ -22,23 +26,51 @@ sub condition { my $custnum = $obj->custnum; my $age = $self->option_age_from('age', $opt{'time'} ); - foreach my $t (qw(cust_bill cust_pay cust_credit cust_refund)) { + my $ignore_pkgclass = $self->option('ignore_pkgclass'); + + my $where = "custnum = $custnum AND _date >= $age"; + + foreach my $t (qw(cust_pay cust_credit cust_refund)) { my $class = "FS::$t"; - return 0 if $class->count("custnum = $custnum AND _date >= $age"); + return 0 if $class->count($where); } + + # cust_bill: handle the ignore_pkgclass option + if ( $ignore_pkgclass =~ /^\d+$/ ) { + $where .= " AND EXISTS( ". + "SELECT 1 FROM cust_bill_pkg JOIN cust_pkg USING (pkgnum) " . + "JOIN part_pkg USING (pkgpart) " . + "WHERE cust_bill_pkg.invnum = cust_bill.invnum " . + "AND COALESCE(part_pkg.classnum, -1) != $ignore_pkgclass" . + " )"; + } + #warn "$where\n"; + return 0 if FS::cust_bill->count($where); + 1; } sub condition_sql { my( $class, $table, %opt ) = @_; my $age = $class->condition_sql_option_age_from('age', $opt{'time'}); + my $ignore_pkgclass = $class->condition_sql_option_integer('ignore_pkgclass'); + # will evaluate to zero if there isn't one my @sql; - for my $t (qw(cust_bill cust_pay cust_credit cust_refund)) { + for my $t (qw(cust_pay cust_credit cust_refund)) { push @sql, "NOT EXISTS( SELECT 1 FROM $t ". "WHERE $t.custnum = cust_main.custnum AND $t._date >= $age". ")"; } + #cust_bill + push @sql, + "NOT EXISTS( ". + "SELECT 1 FROM cust_bill JOIN cust_bill_pkg USING (invnum) ". + "JOIN cust_pkg USING (pkgnum) JOIN part_pkg USING (pkgpart) ". + "WHERE cust_bill.custnum = cust_main.custnum ". + "AND cust_bill._date >= $age ". + "AND COALESCE(part_pkg.classnum, -1) != $ignore_pkgclass ". + ")"; join(' AND ', @sql); } -- cgit v1.2.1 From 2d2fad4dc5654636abf690e0980b851540f64a5b Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 22 May 2013 14:41:10 -0700 Subject: fix interaction between customer location change and supplemental packages, #23124 --- FS/FS/cust_location.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm index 4560716d5..1cb5e52c4 100644 --- a/FS/FS/cust_location.pm +++ b/FS/FS/cust_location.pm @@ -424,9 +424,13 @@ sub move_to { } } + # find all packages that have the old location as their service address, + # and aren't canceled, + # and aren't supplemental to another package. my @pkgs = qsearch('cust_pkg', { 'locationnum' => $old->locationnum, - 'cancel' => '' + 'cancel' => '', + 'main_pkgnum' => '', }); foreach my $cust_pkg (@pkgs) { $error = $cust_pkg->change( -- cgit v1.2.1 From e6210bad824b2efc0a2d54abe8fc79093e7cc5ed Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 22 May 2013 16:58:31 -0700 Subject: fully automate coordinate lookups, #23040 --- FS/FS/Cron/cleanup.pm | 18 ++++++++++++++++++ FS/FS/cust_location.pm | 43 +++++++++++++++++++++++++++++++++++++++++++ FS/bin/freeside-daily | 4 ++++ 3 files changed, 65 insertions(+) create mode 100644 FS/FS/Cron/cleanup.pm diff --git a/FS/FS/Cron/cleanup.pm b/FS/FS/Cron/cleanup.pm new file mode 100644 index 000000000..4c5cff278 --- /dev/null +++ b/FS/FS/Cron/cleanup.pm @@ -0,0 +1,18 @@ +package FS::Cron::cleanup; +use base 'Exporter'; +use vars '@EXPORT_OK'; +use FS::queue; + +@EXPORT_OK = qw( cleanup ); + +# start janitor jobs +sub cleanup { +# fix locations that are missing coordinates + my $job = FS::queue->new({ + 'job' => 'FS::cust_location::process_set_coord', + 'status' => 'new' + }); + $job->insert('_JOB'); +} + +1; diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm index 1cb5e52c4..d772dab08 100644 --- a/FS/FS/cust_location.pm +++ b/FS/FS/cust_location.pm @@ -322,6 +322,11 @@ sub check { } ); } + # set coordinates, unless we already have them + if (!$import and !$self->latitude and !$self->longitude) { + $self->set_coord; + } + $self->SUPER::check; } @@ -638,6 +643,44 @@ sub in_county_sql { } } +sub process_set_coord { + my $job = shift; + # avoid starting multiple instances of this job + my @others = qsearch('queue', { + 'status' => 'locked', + 'job' => $job->job, + 'jobnum' => {op=>'!=', value=>$job->jobnum}, + }); + return if @others; + + $job->update_statustext('finding locations to update'); + my @missing_coords = qsearch('cust_location', { + 'disabled' => '', + 'latitude' => '', + 'longitude' => '', + }); + my $i = 0; + my $n = scalar @missing_coords; + for my $cust_location (@missing_coords) { + $cust_location->set_coord; + my $error = $cust_location->replace; + if ( $error ) { + warn "error geocoding location#".$cust_location->locationnum.": $error\n"; + } else { + $i++; + $job->update_statustext("updated $i / $n locations"); + dbh->commit; # so that we don't have to wait for the whole thing to finish + # Rate-limit to stay under the Google Maps usage limit (2500/day). + # 86,400 / 35 = 2,468 lookups per day. + } + sleep 35; + } + if ( $i < $n ) { + die "failed to update ".$n-$i." locations\n"; + } + return; +} + =head1 BUGS =head1 SEE ALSO diff --git a/FS/bin/freeside-daily b/FS/bin/freeside-daily index 0e43276ad..b6ee5188e 100755 --- a/FS/bin/freeside-daily +++ b/FS/bin/freeside-daily @@ -77,6 +77,10 @@ unlink <${deldir}.CGItemp*>; use FS::Cron::backup qw(backup); backup(); +#except we'd rather not start cleanup jobs until the backup is done +use FS::Cron::cleanup qw(cleanup); +cleanup(); + $log->info('finish'); ### -- cgit v1.2.1 From b1125e2124009bffe9946e7b31d4ba1beb58f83e Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 24 May 2013 18:12:35 -0700 Subject: E911 fee summary, #23056 --- httemplate/elements/menu.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 044426b7f..aff55484a 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -358,6 +358,9 @@ if( $curuser->access_right('Financial reports') ) { $report_financial{'Tax Liability (vendor tax data)'} = [ $fsurl.'search/report_newtax.html', 'Tax liability report (vendor tax data)' ] if $taxproducts; + # most sites don't need this but there isn't really a config to enable it + $report_financial{'E911 Fee Summary'} = [ $fsurl.'search/report_e911.html', 'E911 fee summary' ]; + $report_financial{'Customer Accounting Summary'} = [ $fsurl.'search/report_customer_accounting_summary.html', 'Customer accounting summary report' ]; } elsif($curuser->access_right('Receivables report')) { -- cgit v1.2.1 From 376c002c0e68282aa4365e69581bd1e8b2b0d0b6 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sat, 25 May 2013 22:27:25 -0700 Subject: E911 fee summary, #23056 --- httemplate/search/e911.html | 106 +++++++++++++++++++++++++++++++++++++ httemplate/search/report_e911.html | 41 ++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 httemplate/search/e911.html create mode 100644 httemplate/search/report_e911.html diff --git a/httemplate/search/e911.html b/httemplate/search/e911.html new file mode 100644 index 000000000..6a9dd0a16 --- /dev/null +++ b/httemplate/search/e911.html @@ -0,0 +1,106 @@ +% if ( $row ) { +%# pretty minimal report +<& /elements/header.html, 'E911 Fee Report' &> +<& /elements/table-grid.html &> + + + + + + + + + + + + + + + + + + +
    <& /elements/input-text.html, + 'field' => 'from_name', + 'value' => $conf->config('company_name'), #? + 'size' => 20, + &> <\ + <& /elements/input-text.html, + 'field' => 'from_addr', + 'type' => 'email', # HTML5, woot + 'value' => $conf->config('invoice_from'), + 'size' => 20, + &>>
    <% $legend %>
    E911 access lines:<% $row->{quantity} || 0 %>
    Total fees collected: <% $money_char.sprintf('%.2f', $row->{paid_amount}) %>
    Administrative fee (1%): <% $money_char.sprintf('%.2f', $row->{paid_amount} * $admin_fee) %>
    Amount due: <% $money_char.sprintf('%.2f', $row->{paid_amount} * (1-$admin_fee) ) %> +
    +<& /elements/footer.html &> +% } else { # no data +% $cgi->param('error' => 'No paid E911 fees found.'); +<& /elements/errorpage.html &> +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + +my $money_char = FS::Conf->new->config('money_char') || '$'; + +my($begin, $end) = FS::UI::Web::parse_beginning_ending($cgi); + +$cgi->param('e911pkgpart') =~ /^(\d+)$/; +my $pkgpart = $1 or die 'bad e911pkgpart'; + +$cgi->param('agentnum') =~ /^(\d*)$/; +my $agentnum = $1; + +# This has the potential to become as nightmarish as the old tax report. +# If we end up doing multiple rows for some reason (date intervals, +# package classes, etc.), do NOT simply loop through this and do a +# bazillion scalar_sql queries. Use a properly grouped aggregate query. + +my $select = 'SELECT cust_bill_pkg.billpkgnum, cust_bill_pkg.quantity, '. +'SUM(cust_bill_pay_pkg.amount) AS paid_amount'; + +my $from = 'FROM cust_pkg + JOIN cust_bill_pkg USING (pkgnum) + JOIN cust_bill USING (invnum) + JOIN cust_bill_pay_pkg USING (billpkgnum) + JOIN cust_bill_pay USING (billpaynum) +'; +# going by payment application date here, which should be +# max(invoice date, payment date) +my $where = "WHERE cust_pkg.pkgpart = $pkgpart +AND cust_bill_pay._date >= $begin AND cust_bill_pay._date < $end"; + +if ( $agentnum ) { + $from .= ' JOIN cust_main ON (cust_pkg.custnum = cust_main.custnum)'; + $where .= "\n AND cust_main.agentnum = $agentnum"; +} + +my $subquery = "$select $from $where +GROUP BY cust_bill_pkg.billpkgnum, cust_bill_pkg.quantity"; +# This has one row for each E911 line item that has any payments applied. +# Fields are the billpkgnum of the item (currently unused), the number of +# E911 charges, and the total amount paid (always > 0). + +# now sum those rows. +my $sql = "SELECT SUM(quantity) AS quantity, SUM(paid_amount) AS paid_amount +FROM ($subquery) AS paid_fees"; # no grouping + +my $sth = dbh->prepare($sql); +$sth->execute; +my $row = $sth->fetchrow_hashref; + +my $admin_fee = 0.01; # 1% admin fee, allowed in Texas + +$end = '' if $end == 4294967295; +my $legend = ''; +if ( $agentnum ) { + $legend = FS::agent->by_key($agentnum)->agent . ', '; +} +if ( $begin and $end ) { + $legend .= time2str('%h %o %Y', $begin) . '—' . + time2str('%h %o %Y', $end); +} elsif ( $begin ) { + $legend .= time2str('after %h %o %Y', $begin); +} elsif ( $end ) { + $legend .= time2str('before %h %o %Y', $end); +} else { + $legend .= 'any time'; +} +$legend = ucfirst($legend); + diff --git a/httemplate/search/report_e911.html b/httemplate/search/report_e911.html new file mode 100644 index 000000000..fd9686028 --- /dev/null +++ b/httemplate/search/report_e911.html @@ -0,0 +1,41 @@ +<& /elements/header.html, 'E911 Fee Report' &> + + + + + + <& /elements/tr-select-agent.html, + curr_value => scalar( $cgi->param('agentnum') ), + disable_empty => 0, + &> + + <& /elements/tr-input-beginning_ending.html &> + + <& /elements/tr-select-part_pkg.html, + field => 'e911pkgpart', + label => 'E911 package', + curr_value => $e911pkgpart, + disable_empty => 1, + &> + +
    + +
    + + + + +<& /elements/footer.html &> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + +my $e911pkgpart; +# make an educated guess +my $e911_pkg = qsearchs('part_pkg', + { 'pkg' => { op=>'LIKE', value=>'%E911%' }, + 'disabled' => '', } ); +$e911pkgpart = $e911_pkg->pkgpart if $e911_pkg; + + -- cgit v1.2.1 From 8f8283f365995ff83040ee6b62920dd0149c1eac Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 28 May 2013 17:18:46 -0700 Subject: fix some problems with ordering packages on alt. locations, #23189, #940 --- httemplate/edit/process/quick-cust_pkg.cgi | 2 ++ httemplate/elements/location.html | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi index 14dbda166..fe5ee5e9e 100644 --- a/httemplate/edit/process/quick-cust_pkg.cgi +++ b/httemplate/edit/process/quick-cust_pkg.cgi @@ -160,6 +160,8 @@ if ( $quotationnum ) { ('custnum', FS::cust_main->location_fields) }); $opt{'cust_location'} = $cust_location; + } else { + $opt{'locationnum'} = $locationnum; } $error = $cust_main->order_pkg( \%opt ); diff --git a/httemplate/elements/location.html b/httemplate/elements/location.html index 685523314..41a67a0cb 100644 --- a/httemplate/elements/location.html +++ b/httemplate/elements/location.html @@ -219,8 +219,7 @@ Example: % } -% if ( $conf->config('tax_district_method') ) { -% if ( $opt{enable_district} ) { +% if ( $opt{enable_district} and $conf->config('tax_district_method') ) { Tax district @@ -231,9 +230,8 @@ Example: <% '(automatic)' %> -% } else { +% } else { -% } % } %# For address standardization: -- cgit v1.2.1 From ac272d7302249e13fbf07084087ae642059d63a0 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 28 May 2013 22:36:19 -0700 Subject: fix error viewing svc_broadband services, RT#23181, fallout from svc_cable, RT#22009 --- httemplate/view/elements/svc_devices.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/httemplate/view/elements/svc_devices.html b/httemplate/view/elements/svc_devices.html index 745eabd9d..9458c922c 100644 --- a/httemplate/view/elements/svc_devices.html +++ b/httemplate/view/elements/svc_devices.html @@ -94,6 +94,7 @@ if ( $table eq 'phone_device' || $table eq 'cable_device' ) { } my @devices = $svc_x->isa('FS::device_Common') ? $svc_x->device_objects() - : $svc_x->$table(); + : $table ? $svc_x->$table() + : (); -- cgit v1.2.1 From ea32f987f9c72ad6990bfa326af2935f79bf580c Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 29 May 2013 13:15:22 -0700 Subject: display date custom fields as real dates, #23121 --- rt/lib/RT/Interface/Web_Vendor.pm | 27 +++++++++++++++ rt/share/html/Elements/ColumnMap | 40 +++++++++++++++------- rt/share/html/Elements/RT__Ticket/ColumnMap | 15 +++----- .../html/Search/Elements/ResultsStructuredView | 10 ++---- 4 files changed, 61 insertions(+), 31 deletions(-) diff --git a/rt/lib/RT/Interface/Web_Vendor.pm b/rt/lib/RT/Interface/Web_Vendor.pm index ae7f0899a..fb2b80717 100644 --- a/rt/lib/RT/Interface/Web_Vendor.pm +++ b/rt/lib/RT/Interface/Web_Vendor.pm @@ -553,5 +553,32 @@ sub ProcessUpdateMessage { return @results; } +sub default_FormatDate { $_[0]->AsString } + +sub ProcessColumnMapValue { + my $value = shift; + my %args = ( Arguments => [], + Escape => 1, + FormatDate => \&default_FormatDate, + @_ ); + + if ( ref $value ) { + if ( ref $value eq 'RT::Date' ) { + return $args{FormatDate}->($value); + } elsif ( UNIVERSAL::isa( $value, 'CODE' ) ) { + my @tmp = $value->( @{ $args{'Arguments'} } ); + return ProcessColumnMapValue( ( @tmp > 1 ? \@tmp : $tmp[0] ), %args ); + } elsif ( UNIVERSAL::isa( $value, 'ARRAY' ) ) { + return join '', map ProcessColumnMapValue( $_, %args ), @$value; + } elsif ( UNIVERSAL::isa( $value, 'SCALAR' ) ) { + return $$value; + } + } + + return $m->interp->apply_escapes( $value, 'h' ) if $args{'Escape'}; + return $value; +} + + 1; diff --git a/rt/share/html/Elements/ColumnMap b/rt/share/html/Elements/ColumnMap index f268a5d1c..878950bff 100644 --- a/rt/share/html/Elements/ColumnMap +++ b/rt/share/html/Elements/ColumnMap @@ -64,8 +64,7 @@ my $COLUMN_MAP = { Created => { attribute => 'Created', title => 'Created', # loc - date => sub { return $_[0]->CreatedObj }, - value => sub { return $_[0]->CreatedObj->AsString } + value => sub { return $_[0]->CreatedObj }, }, CreatedRelative => { attribute => 'Created', @@ -80,8 +79,7 @@ my $COLUMN_MAP = { LastUpdated => { attribute => 'LastUpdated', title => 'Last Updated', # loc - date => sub { return $_[0]->LastUpdatedObj }, - value => sub { return $_[0]->LastUpdatedObj->AsString } + value => sub { return $_[0]->LastUpdatedObj }, }, LastUpdatedRelative => { attribute => 'LastUpdated', @@ -101,15 +99,31 @@ my $COLUMN_MAP = { # Display custom field contents, separated by newlines. # For Image custom fields we also show a thumbnail here. - my $values = $_[0]->CustomFieldValues( $_[-1] ); - my @values = map { - ( - ($_->CustomFieldObj->Type eq 'Image') - ? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ )) - : $_->Content - ), - \'
    ', - } @{ $values->ItemsArrayRef }; + my $object = shift; + my $cfname = pop; + my $values = $object->CustomFieldValues( $cfname ); + return if $values->Count == 0; + my @values; + # it is guaranteed to be the same type for all fields, right? + my $v = $values->First; + my $cftype = $v->CustomFieldObj->Type; + + do { + if ($cftype eq 'Image') { + push @values, + \($m->scomp( '/Elements/ShowCustomFieldImage', + Object => $v )); + } elsif ( $cftype eq 'Date' or $cftype eq 'DateTime' ) { + # then actually return the date object; + # ProcessColumnMapValue will stringify it + my $DateObj = RT::Date->new( $session{'CurrentUser'} ); + $DateObj->Set(Format => 'unknown', Value => $v->Content); + push @values, $DateObj; + } else { + push @values, $v->Content; + } + push @values, \'
    '; # this is deeply silly + } while ($v = $values->Next); pop @values; # Remove that last
    return @values; }, diff --git a/rt/share/html/Elements/RT__Ticket/ColumnMap b/rt/share/html/Elements/RT__Ticket/ColumnMap index 787862d6a..239e58183 100644 --- a/rt/share/html/Elements/RT__Ticket/ColumnMap +++ b/rt/share/html/Elements/RT__Ticket/ColumnMap @@ -220,32 +220,27 @@ $COLUMN_MAP = { Starts => { title => 'Starts', # loc attribute => 'Starts', - date => sub { return $_[0]->StartsObj }, - value => sub { return $_[0]->StartsObj->AsString } + value => sub { return $_[0]->StartsObj } }, Started => { title => 'Started', # loc attribute => 'Started', - date => sub { return $_[0]->StartedObj }, - value => sub { return $_[0]->StartedObj->AsString } + value => sub { return $_[0]->StartedObj }, }, Told => { title => 'Told', # loc attribute => 'Told', - date => sub { return $_[0]->ToldObj }, - value => sub { return $_[0]->ToldObj->AsString } + value => sub { return $_[0]->ToldObj }, }, Due => { title => 'Due', # loc attribute => 'Due', - date => sub { return $_[0]->DueObj }, - value => sub { return $_[0]->DueObj->AsString } + value => sub { return $_[0]->DueObj }, }, Resolved => { title => 'Resolved', # loc attribute => 'Resolved', - date => sub { return $_[0]->ResolvedObj }, - value => sub { return $_[0]->ResolvedObj->AsString } + value => sub { return $_[0]->ResolvedObj } }, UpdateStatus => { title => 'New messages', # loc diff --git a/rt/share/html/Search/Elements/ResultsStructuredView b/rt/share/html/Search/Elements/ResultsStructuredView index 495f0d0c8..0e9457c45 100644 --- a/rt/share/html/Search/Elements/ResultsStructuredView +++ b/rt/share/html/Search/Elements/ResultsStructuredView @@ -132,7 +132,7 @@ while ( my $Ticket = $Tickets->Next()) { if ( !exists $ColumnMap->{$col}{'value'} ) { my $map = {}; - foreach ('attribute', 'value', 'date') { + foreach ('attribute', 'value') { $map->{$_} = $m->comp( '/Elements/ColumnMap', Class => 'RT__Ticket', @@ -140,19 +140,13 @@ while ( my $Ticket = $Tickets->Next()) { Attr => $_, ); } - # Canonicalize dates - if ( defined $map->{'date'} ) { - $map->{value} = sub { - my $DateObj = $map->{'date'}->(@_) or return undef; - $FormatDate->($DateObj); - }; - } $ColumnMap->{$col} = $map; } push @out, ProcessColumnMapValue( $ColumnMap->{$col}{'value'}, Arguments => [ $Ticket, $row ], + FormatDate => $FormatDate, ); } #foreach $subcol $value = join('', '', @out, ''); -- cgit v1.2.1 From 83a80303c6bc862de098ed693bd43e0d52807156 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 31 May 2013 12:59:30 -0700 Subject: its time. no more edit dates in 4.x. --- httemplate/edit/REAL_cust_pkg.cgi | 244 ------------------- httemplate/edit/process/REAL_cust_pkg.cgi | 59 ----- httemplate/misc/confirm-cust_pkg-edit_dates.html | 289 ----------------------- httemplate/view/cust_main/packages/package.html | 12 +- 4 files changed, 1 insertion(+), 603 deletions(-) delete mode 100755 httemplate/edit/REAL_cust_pkg.cgi delete mode 100755 httemplate/edit/process/REAL_cust_pkg.cgi delete mode 100755 httemplate/misc/confirm-cust_pkg-edit_dates.html diff --git a/httemplate/edit/REAL_cust_pkg.cgi b/httemplate/edit/REAL_cust_pkg.cgi deleted file mode 100755 index 99e911ae5..000000000 --- a/httemplate/edit/REAL_cust_pkg.cgi +++ /dev/null @@ -1,244 +0,0 @@ -<% include("/elements/header.html",'Customer package - Edit dates') %> - -%#, menubar( -%# "View this customer (#$custnum)" => popurl(2). "view/cust_main.cgi?$custnum", -%#)); - - - - - - - -
    - - -% # raw error from below -% if ( $error ) { - Error: <% $error %> -% } -% #or, regular error handler -<% include('/elements/error.html') %> - -<% ntable("#cccccc",2) %> - - - Package number - <% $cust_pkg->pkgnum %> - - - - Package - <% $part_pkg->pkg %> - - -% if ( $cust_pkg->main_pkgnum ) { -% my $main_pkg = $cust_pkg->main_pkg; - - Supplemental to - Package #<% $cust_pkg->main_pkgnum%>: \ - <% $main_pkg->part_pkg->pkg %> - - -% } - - Custom - <% $part_pkg->custom %> - - - - Comment - <% $part_pkg->comment |h %> - - - - Order taker - <% $cust_pkg->otaker %> - - - <& .row_display, cust_pkg=>$cust_pkg, column=>'order_date', label=>'Order' &> -% if ( $cust_pkg->setup && ! $cust_pkg->start_date ) { - <& .row_display, cust_pkg=>$cust_pkg, column=>'start_date', label=>'Start' &> -% } else { - <& .row_edit, cust_pkg=>$cust_pkg, column=>'start_date', label=>'Start', if_primary=>1 &> -% } - - <& .row_edit, cust_pkg=>$cust_pkg, column=>'setup', label=>'Setup', if_primary=>1 &> - <& .row_edit, cust_pkg=>$cust_pkg, column=>'last_bill', label=>$last_bill_or_renewed &> - <& .row_edit, cust_pkg=>$cust_pkg, column=>'bill', label=>$next_bill_or_prepaid_until &> -%#if ( $cust_pkg->contract_end or $part_pkg->option('contract_end_months',1) ) { - <& .row_edit, cust_pkg=>$cust_pkg, column=>'contract_end',label=>'Contract end', if_primary=>1 &> -%#} - <& .row_display, cust_pkg=>$cust_pkg, column=>'adjourn', label=>'Adjournment', note=>'(will suspend this package when the date is reached)' &> - <& .row_display, cust_pkg=>$cust_pkg, column=>'susp', label=>'Suspension' &> - <& .row_display, cust_pkg=>$cust_pkg, column=>'resume', label=>'Resumption', note=> '(will unsuspend this package when the date is reached' &> - - <& .row_display, cust_pkg=>$cust_pkg, column=>'expire', label=>'Expiration', note=>'(will cancel this package when the date is reached)' &> - <& .row_display, cust_pkg=>$cust_pkg, column=>'cancel', label=>'Cancellation' &> - - -<%def .row_edit> -<%args> - $cust_pkg - $column - $label - $note => '' - $if_primary => 0 - -% my $value = $cust_pkg->get($column); -% $value = $value ? time2str($format, $value) : ""; -% -% # if_primary for the dates that can't be edited on supplemental packages -% if ($if_primary and $cust_pkg->main_pkgnum) { - - - <& .row_display, %ARGS &> -% } else { - - <% $label %> date - - - -% if ( $note ) { -
    <% $note %> -% } - - - - -% } - - -<%def .row_display> -<%args> - $cust_pkg - $column - $label - $note => '' - $is_primary => 0 #ignored - -% if ( $cust_pkg->get($column) ) { - - <% $label %> date - <% time2str($format,$cust_pkg->get($column)) %> -% if ( $note ) { -
    <% $note %> -% } - - -% } - - - - -
    - -
    - -<% include('/elements/footer.html') %> -<%shared> - -my $conf = new FS::Conf; -my $date_format = $conf->config('date_format') || '%m/%d/%Y'; - -my $format = $date_format. ' %T'; # %z (%Z)'; - - -<%init> - -die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('Edit customer package dates'); - - -my $error = ''; -my( $pkgnum, $cust_pkg ); - -if ( $cgi->param('error') ) { - - $pkgnum = $cgi->param('pkgnum'); - - if ( $cgi->param('error') =~ /^_/ ) { - - my @errors = (); - my %errors = map { $_=>1 } split(',', $cgi->param('error')); - $cgi->param('error', ''); - $error = join('

    ', @errors ); - - } - - #get package record - $cust_pkg = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); - die "No package!" unless $cust_pkg; - - foreach my $col (qw( start_date setup last_bill bill )) { - my $value = $cgi->param($col); - $cust_pkg->set( $col, $value ? parse_datetime($value) : '' ); - } - -} else { - - my($query) = $cgi->keywords; - $query =~ /^(\d+)$/ or die "no pkgnum"; - $pkgnum = $1; - - #get package record - $cust_pkg = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); - die "No package!" unless $cust_pkg; - -} - -my $part_pkg = qsearchs( 'part_pkg', { 'pkgpart' => $cust_pkg->pkgpart } ); - -my( $last_bill_or_renewed, $next_bill_or_prepaid_until ); -unless ( $part_pkg->is_prepaid ) { - #$billed_or_prepaid = 'billed'; - $last_bill_or_renewed = 'Last bill'; - $next_bill_or_prepaid_until = 'Next bill'; -} else { - #$billed_or_prepaid = 'prepaid'; - $last_bill_or_renewed = 'Renewed'; - $next_bill_or_prepaid_until = 'Prepaid until'; -} - - diff --git a/httemplate/edit/process/REAL_cust_pkg.cgi b/httemplate/edit/process/REAL_cust_pkg.cgi deleted file mode 100755 index fd2893487..000000000 --- a/httemplate/edit/process/REAL_cust_pkg.cgi +++ /dev/null @@ -1,59 +0,0 @@ -%if ( $error ) { -% $cgi->param('error', $error); -<% $cgi->redirect(popurl(2). "REAL_cust_pkg.cgi?". $cgi->query_string ) %> -%} else { -% my $custnum = $new->custnum; -% my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/ -% ? '' -% : ';show=packages'; -% my $frag = "cust_pkg$pkgnum"; #hack for IE ignoring real #fragment -<% $cgi->redirect(popurl(3). "view/cust_main.cgi?custnum=$custnum$show;fragment=$frag#$frag" ) %> -%} -<%init> - -my $curuser = $FS::CurrentUser::CurrentUser; - -die "access denied" - unless $curuser->access_right('Edit customer package dates'); - -my $pkgnum = $cgi->param('pkgnum') or die; -my $old = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); -my %hash = $old->hash; -foreach ( qw( start_date setup bill last_bill contract_end ) ) { - if ( $cgi->param($_) =~ /^(\d+)$/ ) { - $hash{$_} = $1; - } else { - $hash{$_} = ''; - } - # adjourn, expire, resume not editable this way -} - -my $new; -my $error; -$new = new FS::cust_pkg \%hash; -$error = $new->replace($old); - -if (!$error) { - my @supp_pkgs = $old->supplemental_pkgs; - foreach $new (@supp_pkgs) { - foreach ( qw( start_date setup contract_end ) ) { - # propagate these to supplementals - $new->set($_, $hash{$_}); - } - if ( $hash{'bill'} ne $old->get('bill') ) { - if ( $hash{'bill'} and $old->get('bill') ) { - # adjust by the same interval - my $diff = $hash{'bill'} - $old->get('bill'); - $new->set('bill', $new->get('bill') + $diff); - } else { - # absolute date - $new->set('bill', $hash{'bill'}); - } - } - $error = $new->replace; - $error .= ' (supplemental package '.$new->pkgnum.')' if $error; - last if $error; - } -} - - diff --git a/httemplate/misc/confirm-cust_pkg-edit_dates.html b/httemplate/misc/confirm-cust_pkg-edit_dates.html deleted file mode 100755 index 8e548527a..000000000 --- a/httemplate/misc/confirm-cust_pkg-edit_dates.html +++ /dev/null @@ -1,289 +0,0 @@ -<%init> -my $curuser = $FS::CurrentUser::CurrentUser; - -die "access denied" - unless $curuser->access_right('Edit customer package dates'); - -my %arg = $cgi->Vars; - -my $pkgnum = $arg{'pkgnum'}; -$pkgnum =~ /^\d+$/ or die "bad pkgnum '$pkgnum'"; -my $cust_pkg = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); -my %hash = $cust_pkg->hash; -foreach (qw( start_date setup bill last_bill contract_end )) { - # adjourn, expire, resume not editable this way - if( $arg{$_} =~ /^\d+$/ ) { - $hash{$_} = $arg{$_}; - } elsif ( $arg{$_} ) { - $hash{$_} = parse_datetime($arg{$_}); - } else { - $hash{$_} = ''; - } -} - -my (@changes, @confirm, @errors); - -my $part_pkg = $cust_pkg->part_pkg; -my @supp_pkgs = $cust_pkg->supplemental_pkgs; -my $main_pkg = $cust_pkg->main_pkg; - -my $conf = FS::Conf->new; -my $date_format = $conf->config('date_format') || '%b %o, %Y'; -# Start date -if ( $hash{'start_date'} != $cust_pkg->get('start_date') and !$hash{'setup'} ) { - my $start = ''; - $start = time2str($date_format, $hash{'start_date'}) if $hash{'start_date'}; - my $text = 'Set this package'; - if ( @supp_pkgs ) { - $text .= ' and all its supplemental packages'; - } - $text .= ' to start billing'; - if ( $start ) { - $text .= ' on [_1].'; - push @changes, mt($text, $start); - } else { - $text .= ' immediately.'; - push @changes, mt($text); - } - push @confirm, ''; -} - -# Setup date changes -if ( $hash{'setup'} != $cust_pkg->get('setup') ) { - my $setup = time2str($date_format, $hash{'setup'}); - my $has_setup_fee = grep { $_->part_pkg->option('setup_fee',1) > 0 } - $cust_pkg, @supp_pkgs; - if ( !$hash{'setup'} ) { - my $text = 'Remove the setup date'; - $text .= ' from this and all its supplemental packages' if @supp_pkgs; - $text .= '.'; - push @changes, mt($text); - if ( $has_setup_fee ) { - push @confirm, mt('This will re-charge the customer for the setup fee.'); - } else { - push @confirm, ''; - } - } elsif ( $hash{'setup'} and !$cust_pkg->get('setup') ) { - my $text = 'Add a setup date of [_1]'; - $text .= ' to this and all its supplemental packages' if @supp_pkgs; - $text .= '.'; - push @changes, mt($text, $setup); - if ( $has_setup_fee ) { - push @confirm, mt('This will prevent charging the setup fee.'); - } else { - push @confirm, ''; - } - } else { - my $text = 'Set the setup date to [_1]'; - $text .= ' on this and all its supplemental packages' if @supp_pkgs; - $text .= '.'; - push @changes, mt($text, $setup); - push @confirm, ''; - } -} - -# Check for start date + setup date -if ( $hash{'start_date'} and $hash{'setup'} ) { - if ( $cust_pkg->get('setup') ) { - push @errors, mt('Since the package has already started billing, it '. - 'cannot have a start date.'); - } else { - push @errors, mt('You cannot set both a start date and a setup date on '. - 'the same package.'); - } -} - -# Last bill date change -if ( $hash{'last_bill'} != $cust_pkg->get('last_bill') ) { - my $last_bill = time2str($date_format, $hash{'last_bill'}); - my $name = 'last bill date'; - $name = 'last renewal date' if $part_pkg->is_prepaid; - if ( $hash{'last_bill'} ) { - push @changes, mt('Set the [_1] to [_2].', $name, $last_bill); - } else { - push @changes, mt('Remove the [_1].', $name); - } - push @confirm, ''; - # I don't think we want to adjust this on supplemental packages. -} - -# Bill date change -if ( $hash{'bill'} != $cust_pkg->get('bill') ) { - my $bill = time2str($date_format, $hash{'bill'}); - $bill = 'today' if !$hash{'bill'}; # or 'the end of today'?... - my $name = 'next bill date'; - $name = 'end of the prepaid period' if $part_pkg->is_prepaid; - push @changes, mt('Set the [_1] to [_2].', $name, $bill); - - if ( $hash{'bill'} < time and $hash{'bill'} ) { - push @confirm, - mt('The customer will be charged for the interval from [_1] until now.', - $bill); - } elsif ( !$hash{'bill'} and ($hash{'last_bill'} or $hash{'setup'}) ) { - my $last_bill = - time2str($date_format, $hash{'last_bill'} || $hash{'setup'}); - push @confirm, - mt('The customer will be charged for the interval from [_1] until now.', - $last_bill); - } else { - push @confirm, ''; - } - - if ( @supp_pkgs ) { - push @changes, ''; - if ( $cust_pkg->get('bill') and $hash{'bill'} ) { - # the package already has a bill date, so adjust the dates - # of supplementals by the same interval - my $diff = $hash{'bill'} - $cust_pkg->get('bill'); - my $sign = $diff < 0 ? -1 : 1; - $diff = $diff * $sign / 86400; - if ( $diff < 1 ) { - $diff = mt('[quant,_1,hour]', int($diff * 24)); - } else { - $diff = mt('[quant,_1,day]', int($diff)); - } - push @confirm, - mt('[_1] supplemental package will also be billed [_2] [_3].', - (@supp_pkgs > 1 ? 'Each' : 'The'), - $diff, - ($sign > 0 ? 'later' : 'earlier') - ); - } else { - # the package hasn't been billed yet, or you've set bill = null - push @confirm, - mt('[_1] supplemental package will also be billed on [_2].', - (@supp_pkgs > 1 ? 'Each' : 'The'), - $bill - ); - } - } #if @supp_pkgs - - if ( $main_pkg ) { - push @changes, ''; - push @confirm, - mt('This package is a supplemental package. The bill date of its '. - 'main package will not be adjusted.'); - } -} - -# Contract end change -if ( $hash{'contract_end'} != $cust_pkg->get('contract_end') ) { - if ( $hash{'contract_end'} ) { - my $contract_end = time2str($date_format, $hash{'contract_end'}); - push @changes, - mt('Set this package\'s contract end date to [_1]', $contract_end); - } else { - push @changes, mt('Remove this package\'s contract end date.'); - } - if ( @supp_pkgs ) { - my $text = 'This change will also apply to ' . - (@supp_pkgs > 1 ? - 'all supplemental packages.': - 'the supplemental package.'); - push @confirm, mt($text); - } else { - push @confirm, ''; - } -} - -my $title = ''; -if ( @errors ) { - $title = 'Error changing package dates'; -} else { - $title = 'Confirm date changes'; -} - -<& /elements/header-popup.html, { title => $title, etc => 'BGCOLOR=""' } &> - -
    -<% emt('Package #') %><% $pkgnum %>: <% $cust_pkg->part_pkg->pkg %>
    -% if ( @changes ) { - <% emt('The following changes will be made:') %> -% } else { - <% emt('No changes will be made.') %> -% } -
    - -% if ( @errors ) { -% foreach my $error ( @errors ) { - - - - -% } -% } else { -% while (@changes, @confirm) { -% my $text = shift @changes; -% if (length $text) { - - - - -% } -% $text = shift @confirm; -% if (length $text) { - - - - -% } -% } -% } -
    <% $error %>
    <% $text %>
    - - <% $text %>
    -%# action buttons -
    - -% if (!@errors ) { - -
    -% } -
    -% foreach (keys %hash) { - -% } -
    - -<& /elements/footer.html &> diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html index 520305a9a..2267294b3 100644 --- a/httemplate/view/cust_main/packages/package.html +++ b/httemplate/view/cust_main/packages/package.html @@ -29,11 +29,8 @@ % if ( $supplemental or $part_pkg->freq eq '0' ) { % # Supplemental packages can't be changed independently. % # One-time charges don't need to be changed. -% # For both of those, we only show "Edit dates", "Add comments", +% # For both of those, we only show "Add comments", % # and "Add invoice details". -% if ( $curuser->access_right('Edit customer package dates') ) { - ( <%pkg_dates_link($cust_pkg)%> ) -% } % } else { % # the usual case: links to change package definition, % # discount, and customization @@ -43,11 +40,6 @@ ( <%pkg_change_link($cust_pkg)%> ) % } % -% if ( $curuser->access_right('Edit customer package dates') ) { -% $br=1; - ( <%pkg_dates_link($cust_pkg)%> ) -% } -% % if ( $curuser->access_right('Discount customer package') % && $part_pkg->can_discount % && ! scalar($cust_pkg->cust_pkg_discount_active) @@ -290,8 +282,6 @@ sub pkg_change_quantity_link { ); } -sub pkg_dates_link { pkg_link('edit/REAL_cust_pkg', emt('Edit dates'), @_ ); } - sub pkg_discount_link { my $cust_pkg = shift or return ''; include( '/elements/popup_link-cust_pkg.html', -- cgit v1.2.1 From 54a78752a0fc9a82c82dacd111289e886cca6532 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 31 May 2013 14:58:10 -0700 Subject: allow broadband_nas services to be reexported, #23147 --- FS/FS/part_export/broadband_nas.pm | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/FS/FS/part_export/broadband_nas.pm b/FS/FS/part_export/broadband_nas.pm index 5a8ffac3b..8c152be45 100644 --- a/FS/FS/part_export/broadband_nas.pm +++ b/FS/FS/part_export/broadband_nas.pm @@ -50,6 +50,11 @@ FS::UID->install_callback( address and description of the broadband service. This can be used with 'sqlradius' or 'broadband_sqlradius' exports to maintain entries in the client table on a RADIUS server.

    +

    The checkboxes at the bottom of this page correspond to RADIUS server +databases that Freeside knows about (i.e. 'sqlradius' or 'broadband_sqlradius' +exports that you have configured). Check the box for each server that you +want the NAS entries to be exported to. Do not create multiple broadband_nas +exports for the same service definition; this will fail.

    Most broadband configurations should not use this, even if they use RADIUS for access control.

    END @@ -67,19 +72,33 @@ will be applied to the attached NAS record. sub export_insert { my $self = shift; my $svc_broadband = shift; - my %hash = map { $_ => $svc_broadband->get($_) } FS::nas->fields; - my $nas = $self->default_nas( - %hash, + my %hash = ( 'nasname' => $svc_broadband->ip_addr, 'description' => $svc_broadband->description, 'svcnum' => $svc_broadband->svcnum, ); - - my $error = - $nas->insert() - || $nas->process_m2m('link_table' => 'export_nas', - 'target_table' => 'part_export', - 'params' => { $self->options }); + foreach (FS::nas->fields) { + if ( length($svc_broadband->get($_)) ) { + $hash{$_} = $svc_broadband->get($_); + } + } + # if there's somehow a completely identical NAS in the table already, + # use that one. + my $nas = qsearchs('nas', \%hash); + my $error; + if ($nas) { + # propagate the export message + foreach my $part_export ($nas->part_export) { + $error = $part_export->export_nas_insert($nas); + die $error if $error; + } + } else { + $nas = $self->default_nas( %hash ); + $error = $nas->insert || + $nas->process_m2m('link_table' => 'export_nas', + 'target_table' => 'part_export', + 'params' => { $self->options }); + } die $error if $error; return; } -- cgit v1.2.1 From 781a4348dd3cbe705d6265d36ac5e08b3ed5d01f Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 31 May 2013 15:36:42 -0700 Subject: service smart search, #23297, fallout from #22385 --- FS/FS/cust_svc.pm | 3 ++- httemplate/search/cust_svc.html | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm index 627410729..94f04e9b7 100644 --- a/FS/FS/cust_svc.pm +++ b/FS/FS/cust_svc.pm @@ -890,7 +890,8 @@ sub smart_search_param { ( 'table' => 'cust_svc', 'select' => 'svc_all.svcnum AS svcnum, '. - 'COALESCE(svc_all.svcdb, part_svc.svcdb) AS svcdb', + 'COALESCE(svc_all.svcdb, part_svc.svcdb) AS svcdb, '. + 'cust_svc.*', 'addl_from' => $addl_from, 'hashref' => {}, 'extra_sql' => $extra_sql, diff --git a/httemplate/search/cust_svc.html b/httemplate/search/cust_svc.html index b245d3114..6fa93905e 100644 --- a/httemplate/search/cust_svc.html +++ b/httemplate/search/cust_svc.html @@ -47,8 +47,8 @@ die "access denied" my $sql_query; -my $orderby = 'ORDER BY svcnum'; #has to be ordered by something - #for pagination to work +my $orderby = 'ORDER BY cust_svc.svcnum'; #has to be ordered by something + #for pagination to work if ( length( $cgi->param('search_svc') ) ) { -- cgit v1.2.1 From e0c23bec998267cf2d72ee2a98fa2a88ee1de066 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 31 May 2013 17:02:48 -0700 Subject: better multiple-select behavior in part_svc edit, #23251 --- httemplate/edit/elements/part_svc_column.html | 3 +++ httemplate/edit/part_svc.cgi | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/httemplate/edit/elements/part_svc_column.html b/httemplate/edit/elements/part_svc_column.html index d03c49d2f..fbea9bd6d 100644 --- a/httemplate/edit/elements/part_svc_column.html +++ b/httemplate/edit/elements/part_svc_column.html @@ -157,6 +157,9 @@ that field. 'multiple' => $def->{'multiple'}, 'disable_empty' => 1, 'curr_value' => $value, + # these can be switched between multiple and singular, + # so put the complete curr_value in an attribute + 'element_etc' => 'default="'.encode_entities($value).'"', &> % } else { % my (@options, %labels); diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi index 58c237efd..2ec024269 100755 --- a/httemplate/edit/part_svc.cgi +++ b/httemplate/edit/part_svc.cgi @@ -72,6 +72,17 @@ function flag_changed(obj) { select.className = 'enabled'; if ( newflag == 'S' || select.getAttribute('should_be_multiple') ) { select.multiple = true; + var defaults = select.getAttribute('default'); + if ( defaults ) { + defaults = defaults.split(','); + for (var i = 0; i < defaults.length; i++) { + for (j = 0; j < select.options.length; j++ ) { + if ( defaults[i] == select.options[j].value ) { + select.options[j].selected = true; + } + } + } + } } else { select.multiple = false; } -- cgit v1.2.1 From 055ca451ae55f5deec95ce113d3dd648c9cc9b49 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 31 May 2013 17:40:06 -0700 Subject: remove obsolete files --- FS/MANIFEST | 2 -- 1 file changed, 2 deletions(-) diff --git a/FS/MANIFEST b/FS/MANIFEST index eb4426a21..96191229d 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -11,7 +11,6 @@ bin/freeside-count-active-customers bin/freeside-daily bin/freeside-deloutsource bin/freeside-deloutsourceuser -bin/freeside-deluser bin/freeside-email bin/freeside-phonenum_list bin/freeside-queued @@ -32,7 +31,6 @@ FS/Auth/external.pm FS/Auth/internal.pm FS/Auth/legacy.pm FS/CGI.pm -FS/InitHandler.pm FS/ClientAPI.pm FS/ClientAPI_SessionCache.pm FS/ClientAPI_XMLRPC.pm -- cgit v1.2.1 From 13a5508296bd6760314bdccdb52926d67e955d9e Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 31 May 2013 17:40:32 -0700 Subject: convert mac addresses to uppercase on upgrade --- FS/FS/svc_broadband.pm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index 002aa55ce..b5012caa3 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -440,6 +440,11 @@ sub _upgrade_data { local($FS::svc_Common::noexport_hack) = 1; + # fix wrong-case MAC addresses + my $dbh = dbh; + $dbh->do('UPDATE svc_broadband SET mac_addr = UPPER(mac_addr);') + or die $dbh->errstr; + # set routernum to addr_block.routernum foreach my $self (qsearch('svc_broadband', { blocknum => {op => '!=', value => ''}, -- cgit v1.2.1 From 5c70d9af4f7b07ccd9b67c203abd23f25218293e Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Fri, 31 May 2013 22:26:51 -0700 Subject: add raw date to invoice templates, RT#21007 --- FS/FS/Template_Mixin.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index be9d68a88..e4db2eeda 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -449,6 +449,7 @@ sub print_generic { 'invnum' => ( $params{'no_number'} ? '' : $self->invnum ), 'quotationnum' => $self->quotationnum, 'no_date' => $params{'no_date'}, + '_date' => ( $params{'no_date'} ? '' : $self->_date ), 'date' => ( $params{'no_date'} ? '' : time2str($date_format, $self->_date) -- cgit v1.2.1 From 169aa0275e0fda1e3c8dc459091cc16d403f72b4 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 1 Jun 2013 02:26:16 -0700 Subject: fix XSS --- httemplate/edit/cust_pkg.cgi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/httemplate/edit/cust_pkg.cgi b/httemplate/edit/cust_pkg.cgi index 88e925460..d86049940 100755 --- a/httemplate/edit/cust_pkg.cgi +++ b/httemplate/edit/cust_pkg.cgi @@ -27,13 +27,13 @@ > <% $pkgnum %>: - <% $all_pkg{$pkgpart} %> - <% $all_comment{$pkgpart} %> + <% $all_pkg{$pkgpart} |h %> - <% $all_comment{$pkgpart} |h %> % foreach my $supp_pkg ( @{ $supp_pkgs_of{$pkgnum} } ) { - + <% $all_pkg{$supp_pkg->pkgpart} %> - <% $all_comment{$supp_pkg->pkgpart} %> + + <% $all_pkg{$supp_pkg->pkgpart} |h %> - <% $all_comment{$supp_pkg->pkgpart} |h %> % } % } @@ -79,7 +79,7 @@ Order new packages " VALUE="<% $value %>" SIZE="2" MAXLENGTH="2"> <% $pkgpart %>: - <% $pkg{$pkgpart} %> - <% $comment{$pkgpart}%> + <% $pkg{$pkgpart} |h %> - <% $comment{$pkgpart} |h %> % % $count ++ ; -- cgit v1.2.1 From 5f0aa2aba91b468367ea726d308253cb05f8faed Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 1 Jun 2013 03:45:44 -0700 Subject: remove obsolete maestroconference stuff --- FS/FS/Maestro.pm | 249 ------------------------------------------------------- FS/MANIFEST | 1 - 2 files changed, 250 deletions(-) delete mode 100644 FS/FS/Maestro.pm diff --git a/FS/FS/Maestro.pm b/FS/FS/Maestro.pm deleted file mode 100644 index 399e7406f..000000000 --- a/FS/FS/Maestro.pm +++ /dev/null @@ -1,249 +0,0 @@ -package FS::Maestro; - -use strict; -use Date::Format; -use FS::Conf; -use FS::Record qw( qsearchs ); -use FS::cust_main; -use FS::cust_pkg; -use FS::part_svc; - -#i guess this is kind of deprecated in favor of service_status, but keeping it -#around until they say they don't need it. -sub customer_status { - my( $custnum ) = shift; #@_; - my $svcnum = @_ ? shift : ''; - - my $curuser = $FS::CurrentUser::CurrentUser; - - my $cust_main = qsearchs({ - 'table' => 'cust_main', - 'hashref' => { 'custnum' => $custnum }, - 'extra_sql' => ' AND '. $curuser->agentnums_sql, - }) - or return { 'status' => 'E', - 'error' => "custnum $custnum not found" }; - - return service_status($svcnum) if $svcnum; - - ### - # regular customer to maestro (single package) - ### - - my %result = (); - - my @cust_pkg = $cust_main->cust_pkg; - - #things specific to the non-reseller scenario - - $result{'status'} = substr($cust_main->ucfirst_status,0,1); - - $result{'products'} = - [ map $_->pkgpart, grep !$_->get('cancel'), @cust_pkg ]; - - #find svc_pbx - - my @cust_svc = map $_->cust_svc, @cust_pkg; - - my @cust_svc_pbx = - grep { my($n,$l,$t) = $_->label; $t eq 'svc_pbx' } - @cust_svc; - - if ( ! @cust_svc_pbx ) { - return { 'status' => 'E', - 'error' => "customer $custnum has no conference service" }; - } elsif ( scalar(@cust_svc_pbx) > 1 ) { - return { 'status' => 'E', - 'error' => - "customer $custnum has more than one conference". - " service (reseller?); specify a svcnum as a second argument", - }; - } - - my $cust_svc_pbx = $cust_svc_pbx[0]; - - my $svc_pbx = $cust_svc_pbx->svc_x; - - # find "outbound service" y/n - - my $conf = new FS::Conf; - my %outbound_pkgs = map { $_=>1 } $conf->config('mc-outbound_packages'); - $result{'outbound_service'} = - scalar( grep { $outbound_pkgs{ $_->pkgpart } - && !$_->get('cancel') - } - @cust_pkg - ) - ? 1 : 0; - - # find "good till" date/time stamp - - my @active_cust_pkg = - sort { $a->bill <=> $b->bill } - grep { !$_->get('cancel') && $_->part_pkg->freq ne '0' } - @cust_pkg; - $result{'good_till'} = time2str('%c', $active_cust_pkg[0]->bill || time ); - - return { - 'name' => $cust_main->name, - 'email' => $cust_main->invoicing_list_emailonly_scalar, - #'agentnum' => $cust_main->agentnum, - #'agent' => $cust_main->agent->agent, - 'max_lines' => $svc_pbx ? $svc_pbx->max_extensions : '', - 'max_simultaneous' => $svc_pbx ? $svc_pbx->max_simultaneous : '', - %result, - }; - -} - -sub service_status { - my $svcnum = shift; - - my $svc_pbx = qsearchs({ - 'table' => 'svc_pbx', - 'addl_from' => ' LEFT JOIN cust_svc USING ( svcnum ) '. - ' LEFT JOIN cust_pkg USING ( pkgnum ) ', - 'hashref' => { 'svcnum' => $svcnum }, - #'extra_sql' => " AND custnum = $custnum", - }) - or return { 'status' => 'E', - 'error' => "svcnum $svcnum not found" }; - - my $cust_pkg = $svc_pbx->cust_svc->cust_pkg; - my $cust_main = $cust_pkg->cust_main; - - my %result = (); - - #status in the reseller scenario - $result{'status'} = substr($cust_pkg->ucfirst_status,0,1); - $result{'status'} = 'A' if $result{'status'} eq 'N'; - - # find "outbound service" y/n - my @cust_pkg = $cust_main->cust_pkg; - #XXX what about outbound service per-reseller ? - my $conf = new FS::Conf; - my %outbound_pkgs = map { $_=>1 } $conf->config('mc-outbound_packages'); - $result{'outbound_service'} = - scalar( grep { $outbound_pkgs{ $_->pkgpart } - && !$_->get('cancel') - } - @cust_pkg - ) - ? 1 : 0; - - # find "good till" date/time stamp (this package) - $result{'good_till'} = time2str('%c', $cust_pkg->bill || time ); - - return { - 'custnum' => $cust_main->custnum, - 'name' => ( $svc_pbx->title || $cust_main->name ), - 'email' => $cust_main->invoicing_list_emailonly_scalar, - #'agentnum' => $cust_main->agentnum, - #'agent' => $cust_main->agent->agent, - 'max_lines' => $svc_pbx->max_extensions, - 'max_simultaneous' => $svc_pbx->max_simultaneous, - %result, - }; - -} - -#some false laziness w/ MyAccount order_pkg -sub order_pkg { - my $opt = ref($_[0]) ? shift : { @_ }; - - $opt->{'title'} = delete $opt->{'name'} - if !exists($opt->{'title'}) && exists($opt->{'name'}); - - my $custnum = $opt->{'custnum'}; - - my $curuser = $FS::CurrentUser::CurrentUser; - - my $cust_main = qsearchs({ - 'table' => 'cust_main', - 'hashref' => { 'custnum' => $custnum }, - 'extra_sql' => ' AND '. $curuser->agentnums_sql, - }) - or return { 'error' => "custnum $custnum not found" }; - - my $status = $cust_main->status; - #false laziness w/ClientAPI/Signup.pm - - my $cust_pkg = new FS::cust_pkg ( { - 'custnum' => $custnum, - 'pkgpart' => $opt->{'pkgpart'}, - } ); - my $error = $cust_pkg->check; - return { 'error' => $error } if $error; - - my @svc = (); - unless ( $opt->{'svcpart'} eq 'none' ) { - - my $svcpart = ''; - if ( $opt->{'svcpart'} =~ /^(\d+)$/ ) { - $svcpart = $1; - } else { - $svcpart = $cust_pkg->part_pkg->svcpart; #($svcdb); - } - - my $part_svc = qsearchs('part_svc', { 'svcpart' => $svcpart } ); - return { 'error' => "Unknown svcpart $svcpart" } unless $part_svc; - - my $svcdb = $part_svc->svcdb; - - my %fields = ( - 'svc_acct' => [ qw( username domsvc _password sec_phrase popnum ) ], - 'svc_domain' => [ qw( domain ) ], - 'svc_phone' => [ qw( phonenum pin sip_password phone_name ) ], - 'svc_external' => [ qw( id title ) ], - 'svc_pbx' => [ qw( id title ) ], - ); - - my $svc_x = "FS::$svcdb"->new( { - 'svcpart' => $svcpart, - map { $_ => $opt->{$_} } @{$fields{$svcdb}} - } ); - - #snarf processing not necessary here (or probably at all, anymore) - - my $y = $svc_x->setdefault; # arguably should be in new method - return { 'error' => $y } if $y && !ref($y); - - $error = $svc_x->check; - return { 'error' => $error } if $error; - - push @svc, $svc_x; - - } - - use Tie::RefHash; - tie my %hash, 'Tie::RefHash'; - %hash = ( $cust_pkg => \@svc ); - #msgcat - $error = $cust_main->order_pkgs( \%hash, 'noexport' => 1 ); - return { 'error' => $error } if $error; - -# currently they're using this in the reseller scenario, so don't -# bill the package immediately -# my $conf = new FS::Conf; -# if ( $conf->exists('signup_server-realtime') ) { -# -# my $bill_error = _do_bop_realtime( $cust_main, $status ); -# -# if ($bill_error) { -# $cust_pkg->cancel('quiet'=>1); -# return $bill_error; -# } else { -# $cust_pkg->reexport; -# } -# -# } else { - $cust_pkg->reexport; -# } - - my $svcnum = $svc[0] ? $svc[0]->svcnum : ''; - - return { error=>'', pkgnum=>$cust_pkg->pkgnum, svcnum=>$svcnum }; - -} - -1; diff --git a/FS/MANIFEST b/FS/MANIFEST index 96191229d..68b4accd8 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -46,7 +46,6 @@ FS/Cron/backup.pm FS/Cron/bill.pm FS/Cron/vacuum.pm FS/Daemon.pm -FS/Maestro.pm FS/Misc.pm FS/Record.pm FS/Report.pm -- cgit v1.2.1 From e370df05d108dd71cc58d50b2eebd42ca23284d6 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 1 Jun 2013 03:46:08 -0700 Subject: remove obsolete maestroconference stuff --- httemplate/misc/maestro-customer_status-test.html | 34 ----------------------- httemplate/misc/maestro-customer_status.cgi | 16 ----------- httemplate/misc/maestro-customer_status.html | 16 ----------- 3 files changed, 66 deletions(-) delete mode 100644 httemplate/misc/maestro-customer_status-test.html delete mode 100644 httemplate/misc/maestro-customer_status.cgi delete mode 100644 httemplate/misc/maestro-customer_status.html diff --git a/httemplate/misc/maestro-customer_status-test.html b/httemplate/misc/maestro-customer_status-test.html deleted file mode 100644 index 006492919..000000000 --- a/httemplate/misc/maestro-customer_status-test.html +++ /dev/null @@ -1,34 +0,0 @@ -<% include('/elements/header.html', { - 'title' => "Customer $custnum status", - }) %> - -<% include('/elements/small_custview.html', $custnum, '', 1) %> -
    - - -% foreach my $key (keys %$return) { -% my $value = $return->{$key}; -% $value = join(', ', @$value) if ref($value) eq 'ARRAY'; - - - - -% } -
    <% $key %>:<% $value %>
    - -<% include('/elements/footer.html') %> -<%init> - -my $return; - -my($custnum, $svcnum) = $cgi->keywords; -if ( $custnum =~ /^(\d+)$/ ) { - - use FS::Maestro; - $return = FS::Maestro::customer_status($1, $svcnum); - -} else { - $return = { 'error' => 'No custnum' }; -} - - diff --git a/httemplate/misc/maestro-customer_status.cgi b/httemplate/misc/maestro-customer_status.cgi deleted file mode 100644 index ffeb53c91..000000000 --- a/httemplate/misc/maestro-customer_status.cgi +++ /dev/null @@ -1,16 +0,0 @@ -<% $uri->query %> -<%init> - -my $uri = new URI; - -my($custnum, $svcnum) = $cgi->keywords; -if ( $custnum =~ /^(\d+)$/ ) { - - use FS::Maestro; - $uri->query_form( FS::Maestro::customer_status($1) ); - -} else { - $uri->query_form( { 'error' => 'No custnum' } ); -} - - diff --git a/httemplate/misc/maestro-customer_status.html b/httemplate/misc/maestro-customer_status.html deleted file mode 100644 index a872d4997..000000000 --- a/httemplate/misc/maestro-customer_status.html +++ /dev/null @@ -1,16 +0,0 @@ -<% encode_json( $return ) %>\ -<%init> - -my $return; - -my($custnum, $svcnum) = $cgi->keywords; -if ( $custnum =~ /^(\d+)$/ ) { - - use FS::Maestro; - $return = FS::Maestro::customer_status($1, $svcnum); - -} else { - $return = { 'error' => 'No custnum' }; -} - - -- cgit v1.2.1 From 62f9085f731b12a25db4418b1b9bf6fb24d01d07 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 3 Jun 2013 10:16:59 -0700 Subject: fix per-day radius usage, RT#22699 --- FS/FS/part_pkg/sqlradacct_daily.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FS/FS/part_pkg/sqlradacct_daily.pm b/FS/FS/part_pkg/sqlradacct_daily.pm index d0d3e1006..27fc1df3e 100644 --- a/FS/FS/part_pkg/sqlradacct_daily.pm +++ b/FS/FS/part_pkg/sqlradacct_daily.pm @@ -96,15 +96,15 @@ sub calc_recur { # bill that day, we didn't have a full picture of the day's usage) # and ending with sdate exclusive (same reason) - my($l_day, $l_mon, $l_year) = (localtime($last_bill))[3,5]; + my($l_day, $l_mon, $l_year) = (localtime($last_bill))[3..5]; my $day_start = timelocal(0,0,0, $l_day, $l_mon, $l_year); - my($s_day, $s_mon, $s_year) = (localtime($$sdate))[3,5]; + my($s_day, $s_mon, $s_year) = (localtime($$sdate))[3..5]; my $billday_start = timelocal(0,0,0, $s_day, $s_mon, $s_year); while ( $day_start < $billday_start ) { - my($day, $mon, $year) = (localtime($day_start))[3,5]; + my($day, $mon, $year) = (localtime($day_start))[3..5]; my $tomorrow = timelocal_nocheck(0,0,0, $day+1, $mon, $year); #afact the usage methods already use the lower bound inclusive and the upper -- cgit v1.2.1 From 92b9791e93ad2de8ad60df75e0e342dac43b845a Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 3 Jun 2013 11:44:07 -0700 Subject: fix quotations vs. per-package contacts, RT#23165 --- httemplate/elements/tr-select-contact.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/elements/tr-select-contact.html b/httemplate/elements/tr-select-contact.html index d6bc67f36..e37d26d1b 100644 --- a/httemplate/elements/tr-select-contact.html +++ b/httemplate/elements/tr-select-contact.html @@ -138,7 +138,7 @@ if ( $cgi->param('error') ) { if ( length($opt{'curr_value'}) ) { $contactnum = $opt{'curr_value'}; } elsif ($prospect_main) { - my @cust_contact = $prospect_main->cust_contact; + my @cust_contact = $prospect_main->contact; $contactnum = $cust_contact[0]->contactnum if scalar(@cust_contact)==1; } else { #$cust_main $cgi->param('contactnum') =~ /^(\-?\d*)$/ or die "illegal contactnum"; -- cgit v1.2.1 From 87ccff97601d522326f56184a41037278ad328c5 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Mon, 3 Jun 2013 21:12:38 -0700 Subject: upgrade fckeditor to ckeditor, for IE10 compatibility, RT#22014 --- httemplate/docs/license.html | 2 +- httemplate/elements/ckeditor/build-config.js | 162 ++++ httemplate/elements/ckeditor/ckeditor.js | 919 +++++++++++++++++++++ httemplate/elements/ckeditor/config.js | 10 + httemplate/elements/ckeditor/contents.css | 103 +++ httemplate/elements/ckeditor/lang/af.js | 5 + httemplate/elements/ckeditor/lang/ar.js | 5 + httemplate/elements/ckeditor/lang/bg.js | 5 + httemplate/elements/ckeditor/lang/bn.js | 5 + httemplate/elements/ckeditor/lang/bs.js | 5 + httemplate/elements/ckeditor/lang/ca.js | 5 + httemplate/elements/ckeditor/lang/cs.js | 5 + httemplate/elements/ckeditor/lang/cy.js | 5 + httemplate/elements/ckeditor/lang/da.js | 5 + httemplate/elements/ckeditor/lang/de.js | 5 + httemplate/elements/ckeditor/lang/el.js | 5 + httemplate/elements/ckeditor/lang/en-au.js | 5 + httemplate/elements/ckeditor/lang/en-ca.js | 5 + httemplate/elements/ckeditor/lang/en-gb.js | 5 + httemplate/elements/ckeditor/lang/en.js | 5 + httemplate/elements/ckeditor/lang/eo.js | 5 + httemplate/elements/ckeditor/lang/es.js | 5 + httemplate/elements/ckeditor/lang/et.js | 5 + httemplate/elements/ckeditor/lang/eu.js | 5 + httemplate/elements/ckeditor/lang/fa.js | 5 + httemplate/elements/ckeditor/lang/fi.js | 5 + httemplate/elements/ckeditor/lang/fo.js | 5 + httemplate/elements/ckeditor/lang/fr-ca.js | 5 + httemplate/elements/ckeditor/lang/fr.js | 5 + httemplate/elements/ckeditor/lang/gl.js | 5 + httemplate/elements/ckeditor/lang/gu.js | 5 + httemplate/elements/ckeditor/lang/he.js | 5 + httemplate/elements/ckeditor/lang/hi.js | 5 + httemplate/elements/ckeditor/lang/hr.js | 5 + httemplate/elements/ckeditor/lang/hu.js | 5 + httemplate/elements/ckeditor/lang/is.js | 5 + httemplate/elements/ckeditor/lang/it.js | 5 + httemplate/elements/ckeditor/lang/ja.js | 5 + httemplate/elements/ckeditor/lang/ka.js | 5 + httemplate/elements/ckeditor/lang/km.js | 5 + httemplate/elements/ckeditor/lang/ko.js | 5 + httemplate/elements/ckeditor/lang/ku.js | 5 + httemplate/elements/ckeditor/lang/lt.js | 5 + httemplate/elements/ckeditor/lang/lv.js | 5 + httemplate/elements/ckeditor/lang/mk.js | 5 + httemplate/elements/ckeditor/lang/mn.js | 5 + httemplate/elements/ckeditor/lang/ms.js | 5 + httemplate/elements/ckeditor/lang/nb.js | 5 + httemplate/elements/ckeditor/lang/nl.js | 5 + httemplate/elements/ckeditor/lang/no.js | 5 + httemplate/elements/ckeditor/lang/pl.js | 5 + httemplate/elements/ckeditor/lang/pt-br.js | 5 + httemplate/elements/ckeditor/lang/pt.js | 5 + httemplate/elements/ckeditor/lang/ro.js | 5 + httemplate/elements/ckeditor/lang/ru.js | 5 + httemplate/elements/ckeditor/lang/sk.js | 5 + httemplate/elements/ckeditor/lang/sl.js | 5 + httemplate/elements/ckeditor/lang/sq.js | 5 + httemplate/elements/ckeditor/lang/sr-latn.js | 5 + httemplate/elements/ckeditor/lang/sr.js | 5 + httemplate/elements/ckeditor/lang/sv.js | 5 + httemplate/elements/ckeditor/lang/th.js | 5 + httemplate/elements/ckeditor/lang/tr.js | 5 + httemplate/elements/ckeditor/lang/ug.js | 5 + httemplate/elements/ckeditor/lang/uk.js | 5 + httemplate/elements/ckeditor/lang/vi.js | 5 + httemplate/elements/ckeditor/lang/zh-cn.js | 5 + httemplate/elements/ckeditor/lang/zh.js | 5 + .../ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js | 10 + .../a11yhelp/dialogs/lang/_translationstatus.txt | 25 + .../ckeditor/plugins/a11yhelp/dialogs/lang/ar.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/bg.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/ca.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/cs.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/cy.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/da.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/de.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/el.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/en.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/eo.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/es.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/et.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/fa.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/fi.js | 10 + .../plugins/a11yhelp/dialogs/lang/fr-ca.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/fr.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/gu.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/he.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/hi.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/hr.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/hu.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/it.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/ja.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/km.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/ku.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/lt.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/lv.js | 11 + .../ckeditor/plugins/a11yhelp/dialogs/lang/mk.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/mn.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/nb.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/nl.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/no.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/pl.js | 10 + .../plugins/a11yhelp/dialogs/lang/pt-br.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/pt.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/ro.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/ru.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/sk.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/sl.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/sq.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/sv.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/th.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/tr.js | 10 + .../ckeditor/plugins/a11yhelp/dialogs/lang/ug.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/uk.js | 9 + .../ckeditor/plugins/a11yhelp/dialogs/lang/vi.js | 9 + .../plugins/a11yhelp/dialogs/lang/zh-cn.js | 7 + .../ckeditor/plugins/about/dialogs/about.js | 6 + .../plugins/about/dialogs/logo_ckeditor.png | Bin 0 -> 2759 bytes .../ckeditor/plugins/clipboard/dialogs/paste.js | 11 + .../plugins/colordialog/dialogs/colordialog.js | 13 + .../ckeditor/plugins/dialog/dialogDefinition.js | 4 + .../elements/ckeditor/plugins/div/dialogs/div.js | 9 + .../ckeditor/plugins/fakeobjects/images/spacer.gif | Bin 0 -> 43 bytes .../elements/ckeditor/plugins/find/dialogs/find.js | 24 + .../ckeditor/plugins/flash/dialogs/flash.js | 24 + .../ckeditor/plugins/flash/images/placeholder.png | Bin 0 -> 256 bytes .../ckeditor/plugins/forms/dialogs/button.js | 8 + .../ckeditor/plugins/forms/dialogs/checkbox.js | 8 + .../ckeditor/plugins/forms/dialogs/form.js | 8 + .../ckeditor/plugins/forms/dialogs/hiddenfield.js | 8 + .../ckeditor/plugins/forms/dialogs/radio.js | 8 + .../ckeditor/plugins/forms/dialogs/select.js | 20 + .../ckeditor/plugins/forms/dialogs/textarea.js | 8 + .../ckeditor/plugins/forms/dialogs/textfield.js | 10 + .../ckeditor/plugins/forms/images/hiddenfield.gif | Bin 0 -> 105 bytes httemplate/elements/ckeditor/plugins/icons.png | Bin 0 -> 20881 bytes .../ckeditor/plugins/iframe/dialogs/iframe.js | 10 + .../ckeditor/plugins/iframe/images/placeholder.png | Bin 0 -> 449 bytes .../ckeditor/plugins/image/dialogs/image.js | 43 + .../ckeditor/plugins/image/images/noimage.png | Bin 0 -> 2115 bytes .../ckeditor/plugins/link/dialogs/anchor.js | 8 + .../elements/ckeditor/plugins/link/dialogs/link.js | 36 + .../ckeditor/plugins/link/images/anchor.png | Bin 0 -> 566 bytes .../plugins/liststyle/dialogs/liststyle.js | 10 + .../ckeditor/plugins/magicline/images/icon.png | Bin 0 -> 172 bytes .../plugins/pagebreak/images/pagebreak.gif | Bin 0 -> 54 bytes .../plugins/pastefromword/filter/default.js | 31 + .../elements/ckeditor/plugins/preview/preview.html | 10 + .../elements/ckeditor/plugins/scayt/LICENSE.md | 28 + .../elements/ckeditor/plugins/scayt/README.md | 25 + .../ckeditor/plugins/scayt/dialogs/options.js | 20 + .../ckeditor/plugins/scayt/dialogs/toolbar.css | 71 ++ .../plugins/showblocks/images/block_address.png | Bin 0 -> 171 bytes .../plugins/showblocks/images/block_blockquote.png | Bin 0 -> 181 bytes .../plugins/showblocks/images/block_div.png | Bin 0 -> 136 bytes .../plugins/showblocks/images/block_h1.png | Bin 0 -> 127 bytes .../plugins/showblocks/images/block_h2.png | Bin 0 -> 134 bytes .../plugins/showblocks/images/block_h3.png | Bin 0 -> 131 bytes .../plugins/showblocks/images/block_h4.png | Bin 0 -> 133 bytes .../plugins/showblocks/images/block_h5.png | Bin 0 -> 133 bytes .../plugins/showblocks/images/block_h6.png | Bin 0 -> 129 bytes .../ckeditor/plugins/showblocks/images/block_p.png | Bin 0 -> 119 bytes .../plugins/showblocks/images/block_pre.png | Bin 0 -> 136 bytes .../ckeditor/plugins/smiley/dialogs/smiley.js | 10 + .../ckeditor/plugins/smiley/images/angel_smile.gif | Bin 0 -> 465 bytes .../ckeditor/plugins/smiley/images/angry_smile.gif | Bin 0 -> 443 bytes .../plugins/smiley/images/broken_heart.gif | Bin 0 -> 192 bytes .../plugins/smiley/images/confused_smile.gif | Bin 0 -> 464 bytes .../ckeditor/plugins/smiley/images/cry_smile.gif | Bin 0 -> 468 bytes .../ckeditor/plugins/smiley/images/devil_smile.gif | Bin 0 -> 436 bytes .../plugins/smiley/images/embaressed_smile.gif | Bin 0 -> 442 bytes .../plugins/smiley/images/embarrassed_smile.gif | Bin 0 -> 442 bytes .../ckeditor/plugins/smiley/images/envelope.gif | Bin 0 -> 426 bytes .../ckeditor/plugins/smiley/images/heart.gif | Bin 0 -> 183 bytes .../ckeditor/plugins/smiley/images/kiss.gif | Bin 0 -> 241 bytes .../ckeditor/plugins/smiley/images/lightbulb.gif | Bin 0 -> 368 bytes .../ckeditor/plugins/smiley/images/omg_smile.gif | Bin 0 -> 451 bytes .../plugins/smiley/images/regular_smile.gif | Bin 0 -> 450 bytes .../ckeditor/plugins/smiley/images/sad_smile.gif | Bin 0 -> 460 bytes .../plugins/smiley/images/shades_smile.gif | Bin 0 -> 449 bytes .../ckeditor/plugins/smiley/images/teeth_smile.gif | Bin 0 -> 442 bytes .../ckeditor/plugins/smiley/images/thumbs_down.gif | Bin 0 -> 408 bytes .../ckeditor/plugins/smiley/images/thumbs_up.gif | Bin 0 -> 396 bytes .../plugins/smiley/images/tongue_smile.gif | Bin 0 -> 446 bytes .../plugins/smiley/images/tounge_smile.gif | Bin 0 -> 446 bytes .../smiley/images/whatchutalkingabout_smile.gif | Bin 0 -> 452 bytes .../ckeditor/plugins/smiley/images/wink_smile.gif | Bin 0 -> 458 bytes .../dialogs/lang/_translationstatus.txt | 20 + .../plugins/specialchar/dialogs/lang/ca.js | 14 + .../plugins/specialchar/dialogs/lang/cs.js | 13 + .../plugins/specialchar/dialogs/lang/cy.js | 14 + .../plugins/specialchar/dialogs/lang/de.js | 13 + .../plugins/specialchar/dialogs/lang/el.js | 13 + .../plugins/specialchar/dialogs/lang/en.js | 13 + .../plugins/specialchar/dialogs/lang/eo.js | 12 + .../plugins/specialchar/dialogs/lang/es.js | 13 + .../plugins/specialchar/dialogs/lang/et.js | 13 + .../plugins/specialchar/dialogs/lang/fa.js | 12 + .../plugins/specialchar/dialogs/lang/fi.js | 13 + .../plugins/specialchar/dialogs/lang/fr-ca.js | 10 + .../plugins/specialchar/dialogs/lang/fr.js | 11 + .../plugins/specialchar/dialogs/lang/he.js | 13 + .../plugins/specialchar/dialogs/lang/hr.js | 13 + .../plugins/specialchar/dialogs/lang/it.js | 14 + .../plugins/specialchar/dialogs/lang/ku.js | 13 + .../plugins/specialchar/dialogs/lang/lv.js | 13 + .../plugins/specialchar/dialogs/lang/nb.js | 11 + .../plugins/specialchar/dialogs/lang/nl.js | 13 + .../plugins/specialchar/dialogs/lang/no.js | 11 + .../plugins/specialchar/dialogs/lang/pl.js | 12 + .../plugins/specialchar/dialogs/lang/pt-br.js | 11 + .../plugins/specialchar/dialogs/lang/sk.js | 13 + .../plugins/specialchar/dialogs/lang/sq.js | 13 + .../plugins/specialchar/dialogs/lang/sv.js | 11 + .../plugins/specialchar/dialogs/lang/th.js | 13 + .../plugins/specialchar/dialogs/lang/tr.js | 12 + .../plugins/specialchar/dialogs/lang/ug.js | 13 + .../plugins/specialchar/dialogs/lang/zh-cn.js | 9 + .../plugins/specialchar/dialogs/specialchar.js | 14 + .../ckeditor/plugins/table/dialogs/table.js | 21 + .../plugins/tabletools/dialogs/tableCell.js | 16 + .../plugins/templates/dialogs/templates.css | 84 ++ .../plugins/templates/dialogs/templates.js | 10 + .../plugins/templates/templates/default.js | 6 + .../templates/templates/images/template1.gif | Bin 0 -> 375 bytes .../templates/templates/images/template2.gif | Bin 0 -> 333 bytes .../templates/templates/images/template3.gif | Bin 0 -> 422 bytes .../elements/ckeditor/plugins/wsc/LICENSE.md | 28 + httemplate/elements/ckeditor/plugins/wsc/README.md | 25 + .../ckeditor/plugins/wsc/dialogs/ciframe.html | 49 ++ .../ckeditor/plugins/wsc/dialogs/tmpFrameset.html | 52 ++ .../elements/ckeditor/plugins/wsc/dialogs/wsc.css | 82 ++ .../elements/ckeditor/plugins/wsc/dialogs/wsc.js | 11 + httemplate/elements/ckeditor/skins/kama/dialog.css | 5 + .../elements/ckeditor/skins/kama/dialog_ie.css | 5 + .../elements/ckeditor/skins/kama/dialog_ie7.css | 5 + .../elements/ckeditor/skins/kama/dialog_ie8.css | 5 + .../ckeditor/skins/kama/dialog_iequirks.css | 5 + .../elements/ckeditor/skins/kama/dialog_opera.css | 5 + httemplate/elements/ckeditor/skins/kama/editor.css | 5 + .../elements/ckeditor/skins/kama/editor_ie.css | 5 + .../elements/ckeditor/skins/kama/editor_ie7.css | 5 + .../elements/ckeditor/skins/kama/editor_ie8.css | 5 + .../ckeditor/skins/kama/editor_iequirks.css | 5 + httemplate/elements/ckeditor/skins/kama/icons.png | Bin 0 -> 13034 bytes .../ckeditor/skins/kama/images/dialog_sides.gif | Bin 0 -> 48 bytes .../ckeditor/skins/kama/images/dialog_sides.png | Bin 0 -> 178 bytes .../skins/kama/images/dialog_sides_rtl.png | Bin 0 -> 181 bytes .../elements/ckeditor/skins/kama/images/mini.gif | Bin 0 -> 183 bytes .../ckeditor/skins/kama/images/sprites.png | Bin 0 -> 7086 bytes .../ckeditor/skins/kama/images/sprites_ie6.png | Bin 0 -> 2724 bytes .../ckeditor/skins/kama/images/toolbar_start.gif | Bin 0 -> 105 bytes httemplate/elements/ckeditor/skins/kama/readme.md | 40 + httemplate/elements/ckeditor/skins/kama/skin.js | 8 + .../elements/ckeditor/skins/moono/dialog.css | 5 + .../elements/ckeditor/skins/moono/dialog_ie.css | 5 + .../elements/ckeditor/skins/moono/dialog_ie7.css | 5 + .../elements/ckeditor/skins/moono/dialog_ie8.css | 5 + .../ckeditor/skins/moono/dialog_iequirks.css | 5 + .../elements/ckeditor/skins/moono/dialog_opera.css | 5 + .../elements/ckeditor/skins/moono/editor.css | 5 + .../elements/ckeditor/skins/moono/editor_gecko.css | 5 + .../elements/ckeditor/skins/moono/editor_ie.css | 5 + .../elements/ckeditor/skins/moono/editor_ie7.css | 5 + .../elements/ckeditor/skins/moono/editor_ie8.css | 5 + .../ckeditor/skins/moono/editor_iequirks.css | 5 + httemplate/elements/ckeditor/skins/moono/icons.png | Bin 0 -> 20881 bytes .../elements/ckeditor/skins/moono/images/arrow.png | Bin 0 -> 261 bytes .../elements/ckeditor/skins/moono/images/close.png | Bin 0 -> 389 bytes .../elements/ckeditor/skins/moono/images/mini.png | Bin 0 -> 818 bytes httemplate/elements/ckeditor/skins/moono/readme.md | 51 ++ .../elements/ckeditor/skins/moonocolor/dialog.css | 5 + .../ckeditor/skins/moonocolor/dialog_ie.css | 5 + .../ckeditor/skins/moonocolor/dialog_ie7.css | 5 + .../ckeditor/skins/moonocolor/dialog_ie8.css | 5 + .../ckeditor/skins/moonocolor/dialog_iequirks.css | 5 + .../ckeditor/skins/moonocolor/dialog_opera.css | 5 + .../elements/ckeditor/skins/moonocolor/editor.css | 5 + .../ckeditor/skins/moonocolor/editor_gecko.css | 5 + .../ckeditor/skins/moonocolor/editor_ie.css | 5 + .../ckeditor/skins/moonocolor/editor_ie7.css | 5 + .../ckeditor/skins/moonocolor/editor_ie8.css | 5 + .../ckeditor/skins/moonocolor/editor_iequirks.css | 5 + .../elements/ckeditor/skins/moonocolor/icons.png | Bin 0 -> 28072 bytes .../ckeditor/skins/moonocolor/icons/about.png | Bin 0 -> 776 bytes .../ckeditor/skins/moonocolor/icons/anchor-rtl.png | Bin 0 -> 751 bytes .../ckeditor/skins/moonocolor/icons/anchor.png | Bin 0 -> 769 bytes .../ckeditor/skins/moonocolor/icons/bgcolor.png | Bin 0 -> 156 bytes .../ckeditor/skins/moonocolor/icons/bidiltr.png | Bin 0 -> 485 bytes .../ckeditor/skins/moonocolor/icons/bidirtl.png | Bin 0 -> 485 bytes .../ckeditor/skins/moonocolor/icons/blockquote.png | Bin 0 -> 462 bytes .../ckeditor/skins/moonocolor/icons/bold.png | Bin 0 -> 405 bytes .../skins/moonocolor/icons/bulletedlist-rtl.png | Bin 0 -> 337 bytes .../skins/moonocolor/icons/bulletedlist.png | Bin 0 -> 335 bytes .../ckeditor/skins/moonocolor/icons/button.png | Bin 0 -> 341 bytes .../ckeditor/skins/moonocolor/icons/checkbox.png | Bin 0 -> 424 bytes .../ckeditor/skins/moonocolor/icons/copy-rtl.png | Bin 0 -> 745 bytes .../ckeditor/skins/moonocolor/icons/copy.png | Bin 0 -> 774 bytes .../ckeditor/skins/moonocolor/icons/creatediv.png | Bin 0 -> 426 bytes .../ckeditor/skins/moonocolor/icons/cut-rtl.png | Bin 0 -> 677 bytes .../ckeditor/skins/moonocolor/icons/cut.png | Bin 0 -> 662 bytes .../ckeditor/skins/moonocolor/icons/find-rtl.png | Bin 0 -> 605 bytes .../ckeditor/skins/moonocolor/icons/find.png | Bin 0 -> 608 bytes .../ckeditor/skins/moonocolor/icons/flash.png | Bin 0 -> 729 bytes .../ckeditor/skins/moonocolor/icons/form.png | Bin 0 -> 560 bytes .../skins/moonocolor/icons/hiddenfield.png | Bin 0 -> 465 bytes .../skins/moonocolor/icons/horizontalrule.png | Bin 0 -> 307 bytes .../ckeditor/skins/moonocolor/icons/iframe.png | Bin 0 -> 827 bytes .../ckeditor/skins/moonocolor/icons/image.png | Bin 0 -> 663 bytes .../skins/moonocolor/icons/imagebutton.png | Bin 0 -> 501 bytes .../ckeditor/skins/moonocolor/icons/indent-rtl.png | Bin 0 -> 341 bytes .../ckeditor/skins/moonocolor/icons/indent.png | Bin 0 -> 341 bytes .../ckeditor/skins/moonocolor/icons/italic.png | Bin 0 -> 297 bytes .../skins/moonocolor/icons/justifyblock.png | Bin 0 -> 236 bytes .../skins/moonocolor/icons/justifycenter.png | Bin 0 -> 251 bytes .../skins/moonocolor/icons/justifyleft.png | Bin 0 -> 240 bytes .../skins/moonocolor/icons/justifyright.png | Bin 0 -> 234 bytes .../ckeditor/skins/moonocolor/icons/link.png | Bin 0 -> 652 bytes .../ckeditor/skins/moonocolor/icons/maximize.png | Bin 0 -> 615 bytes .../skins/moonocolor/icons/newpage-rtl.png | Bin 0 -> 428 bytes .../ckeditor/skins/moonocolor/icons/newpage.png | Bin 0 -> 430 bytes .../skins/moonocolor/icons/numberedlist-rtl.png | Bin 0 -> 363 bytes .../skins/moonocolor/icons/numberedlist.png | Bin 0 -> 366 bytes .../skins/moonocolor/icons/outdent-rtl.png | Bin 0 -> 346 bytes .../ckeditor/skins/moonocolor/icons/outdent.png | Bin 0 -> 338 bytes .../skins/moonocolor/icons/pagebreak-rtl.png | Bin 0 -> 408 bytes .../ckeditor/skins/moonocolor/icons/pagebreak.png | Bin 0 -> 410 bytes .../ckeditor/skins/moonocolor/icons/paste-rtl.png | Bin 0 -> 793 bytes .../ckeditor/skins/moonocolor/icons/paste.png | Bin 0 -> 808 bytes .../skins/moonocolor/icons/pastefromword-rtl.png | Bin 0 -> 822 bytes .../skins/moonocolor/icons/pastefromword.png | Bin 0 -> 822 bytes .../skins/moonocolor/icons/pastetext-rtl.png | Bin 0 -> 848 bytes .../ckeditor/skins/moonocolor/icons/pastetext.png | Bin 0 -> 834 bytes .../skins/moonocolor/icons/preview-rtl.png | Bin 0 -> 623 bytes .../ckeditor/skins/moonocolor/icons/preview.png | Bin 0 -> 638 bytes .../ckeditor/skins/moonocolor/icons/print.png | Bin 0 -> 834 bytes .../ckeditor/skins/moonocolor/icons/radio.png | Bin 0 -> 548 bytes .../ckeditor/skins/moonocolor/icons/redo-rtl.png | Bin 0 -> 628 bytes .../ckeditor/skins/moonocolor/icons/redo.png | Bin 0 -> 632 bytes .../skins/moonocolor/icons/removeformat.png | Bin 0 -> 691 bytes .../ckeditor/skins/moonocolor/icons/replace.png | Bin 0 -> 745 bytes .../ckeditor/skins/moonocolor/icons/save.png | Bin 0 -> 728 bytes .../ckeditor/skins/moonocolor/icons/scayt.png | Bin 0 -> 679 bytes .../ckeditor/skins/moonocolor/icons/select-rtl.png | Bin 0 -> 358 bytes .../ckeditor/skins/moonocolor/icons/select.png | Bin 0 -> 354 bytes .../ckeditor/skins/moonocolor/icons/selectall.png | Bin 0 -> 530 bytes .../skins/moonocolor/icons/showblocks-rtl.png | Bin 0 -> 340 bytes .../ckeditor/skins/moonocolor/icons/showblocks.png | Bin 0 -> 354 bytes .../ckeditor/skins/moonocolor/icons/smiley.png | Bin 0 -> 732 bytes .../ckeditor/skins/moonocolor/icons/source-rtl.png | Bin 0 -> 650 bytes .../ckeditor/skins/moonocolor/icons/source.png | Bin 0 -> 647 bytes .../skins/moonocolor/icons/specialchar.png | Bin 0 -> 565 bytes .../skins/moonocolor/icons/spellchecker.png | Bin 0 -> 679 bytes .../ckeditor/skins/moonocolor/icons/strike.png | Bin 0 -> 389 bytes .../ckeditor/skins/moonocolor/icons/subscript.png | Bin 0 -> 438 bytes .../skins/moonocolor/icons/superscript.png | Bin 0 -> 446 bytes .../ckeditor/skins/moonocolor/icons/table.png | Bin 0 -> 568 bytes .../skins/moonocolor/icons/templates-rtl.png | Bin 0 -> 608 bytes .../ckeditor/skins/moonocolor/icons/templates.png | Bin 0 -> 610 bytes .../skins/moonocolor/icons/textarea-rtl.png | Bin 0 -> 431 bytes .../ckeditor/skins/moonocolor/icons/textarea.png | Bin 0 -> 433 bytes .../ckeditor/skins/moonocolor/icons/textcolor.png | Bin 0 -> 218 bytes .../skins/moonocolor/icons/textfield-rtl.png | Bin 0 -> 323 bytes .../ckeditor/skins/moonocolor/icons/textfield.png | Bin 0 -> 324 bytes .../ckeditor/skins/moonocolor/icons/underline.png | Bin 0 -> 338 bytes .../ckeditor/skins/moonocolor/icons/undo-rtl.png | Bin 0 -> 632 bytes .../ckeditor/skins/moonocolor/icons/undo.png | Bin 0 -> 628 bytes .../ckeditor/skins/moonocolor/icons/unlink.png | Bin 0 -> 662 bytes .../ckeditor/skins/moonocolor/images/arrow.png | Bin 0 -> 342 bytes .../ckeditor/skins/moonocolor/images/close.png | Bin 0 -> 375 bytes .../ckeditor/skins/moonocolor/images/mini.png | Bin 0 -> 1190 bytes .../elements/ckeditor/skins/moonocolor/readme.md | 51 ++ .../elements/ckeditor/skins/moonocolor/skin.js | 10 + httemplate/elements/ckeditor/styles.js | 111 +++ .../editor/css/behaviors/disablehandles.htc | 15 - .../editor/css/behaviors/showtableborders.htc | 36 - .../fckeditor/editor/css/fck_editorarea.css | 110 --- .../elements/fckeditor/editor/css/fck_internal.css | 199 ----- .../editor/css/fck_showtableborders_gecko.css | 49 -- .../fckeditor/editor/css/images/block_address.png | Bin 288 -> 0 bytes .../editor/css/images/block_blockquote.png | Bin 293 -> 0 bytes .../fckeditor/editor/css/images/block_div.png | Bin 229 -> 0 bytes .../fckeditor/editor/css/images/block_h1.png | Bin 218 -> 0 bytes .../fckeditor/editor/css/images/block_h2.png | Bin 220 -> 0 bytes .../fckeditor/editor/css/images/block_h3.png | Bin 219 -> 0 bytes .../fckeditor/editor/css/images/block_h4.png | Bin 229 -> 0 bytes .../fckeditor/editor/css/images/block_h5.png | Bin 236 -> 0 bytes .../fckeditor/editor/css/images/block_h6.png | Bin 216 -> 0 bytes .../fckeditor/editor/css/images/block_p.png | Bin 205 -> 0 bytes .../fckeditor/editor/css/images/block_pre.png | Bin 223 -> 0 bytes .../fckeditor/editor/css/images/fck_anchor.gif | Bin 184 -> 0 bytes .../fckeditor/editor/css/images/fck_flashlogo.gif | Bin 599 -> 0 bytes .../editor/css/images/fck_hiddenfield.gif | Bin 105 -> 0 bytes .../fckeditor/editor/css/images/fck_pagebreak.gif | Bin 54 -> 0 bytes .../fckeditor/editor/css/images/fck_plugin.gif | Bin 1709 -> 0 bytes .../editor/dialog/common/fck_dialog_common.css | 85 -- .../editor/dialog/common/fck_dialog_common.js | 347 -------- .../editor/dialog/common/fcknumericfield.htc | 24 - .../editor/dialog/common/images/locked.gif | Bin 74 -> 0 bytes .../editor/dialog/common/images/reset.gif | Bin 104 -> 0 bytes .../editor/dialog/common/images/unlocked.gif | Bin 75 -> 0 bytes .../editor/dialog/common/moz-bindings.xml | 30 - .../fckeditor/editor/dialog/fck_about.html | 161 ---- .../editor/dialog/fck_about/logo_fckeditor.gif | Bin 2044 -> 0 bytes .../editor/dialog/fck_about/logo_fredck.gif | Bin 920 -> 0 bytes .../dialog/fck_about/sponsors/spellchecker_net.gif | Bin 1447 -> 0 bytes .../fckeditor/editor/dialog/fck_anchor.html | 220 ----- .../fckeditor/editor/dialog/fck_button.html | 104 --- .../fckeditor/editor/dialog/fck_checkbox.html | 104 --- .../fckeditor/editor/dialog/fck_colorselector.html | 172 ---- .../elements/fckeditor/editor/dialog/fck_div.html | 396 --------- .../fckeditor/editor/dialog/fck_docprops.html | 600 -------------- .../dialog/fck_docprops/fck_document_preview.html | 113 --- .../elements/fckeditor/editor/dialog/fck_find.html | 173 ---- .../fckeditor/editor/dialog/fck_flash.html | 152 ---- .../fckeditor/editor/dialog/fck_flash/fck_flash.js | 300 ------- .../editor/dialog/fck_flash/fck_flash_preview.html | 50 -- .../elements/fckeditor/editor/dialog/fck_form.html | 109 --- .../fckeditor/editor/dialog/fck_hiddenfield.html | 115 --- .../fckeditor/editor/dialog/fck_image.html | 258 ------ .../fckeditor/editor/dialog/fck_image/fck_image.js | 512 ------------ .../editor/dialog/fck_image/fck_image_preview.html | 72 -- .../elements/fckeditor/editor/dialog/fck_link.html | 295 ------- .../fckeditor/editor/dialog/fck_link/fck_link.js | 893 -------------------- .../fckeditor/editor/dialog/fck_listprop.html | 120 --- .../fckeditor/editor/dialog/fck_paste.html | 347 -------- .../fckeditor/editor/dialog/fck_radiobutton.html | 104 --- .../fckeditor/editor/dialog/fck_replace.html | 650 --------------- .../fckeditor/editor/dialog/fck_scayt.html | 746 ----------------- .../editor/dialog/fck_scayt/scayt_dialog.css | 169 ---- .../fckeditor/editor/dialog/fck_select.html | 180 ---- .../editor/dialog/fck_select/fck_select.js | 194 ----- .../fckeditor/editor/dialog/fck_smiley.html | 111 --- .../fckeditor/editor/dialog/fck_source.html | 68 -- .../fckeditor/editor/dialog/fck_specialchar.html | 121 --- .../fckeditor/editor/dialog/fck_spellerpages.html | 70 -- .../fck_spellerpages/spellerpages/blank.html | 0 .../fck_spellerpages/spellerpages/controlWindow.js | 87 -- .../fck_spellerpages/spellerpages/controls.html | 153 ---- .../spellerpages/server-scripts/spellchecker.pl | 181 ---- .../fck_spellerpages/spellerpages/spellChecker.js | 461 ----------- .../spellerpages/spellchecker.html | 71 -- .../fck_spellerpages/spellerpages/spellerStyle.css | 49 -- .../fck_spellerpages/spellerpages/wordWindow.js | 272 ------ .../fckeditor/editor/dialog/fck_table.html | 440 ---------- .../fckeditor/editor/dialog/fck_tablecell.html | 293 ------- .../fckeditor/editor/dialog/fck_template.html | 242 ------ .../dialog/fck_template/images/template1.gif | Bin 375 -> 0 bytes .../dialog/fck_template/images/template2.gif | Bin 333 -> 0 bytes .../dialog/fck_template/images/template3.gif | Bin 422 -> 0 bytes .../fckeditor/editor/dialog/fck_textarea.html | 94 --- .../fckeditor/editor/dialog/fck_textfield.html | 136 --- .../fckeditor/editor/dtd/fck_dtd_test.html | 41 - .../fckeditor/editor/dtd/fck_xhtml10strict.js | 116 --- .../editor/dtd/fck_xhtml10transitional.js | 140 ---- httemplate/elements/fckeditor/editor/fckdebug.html | 153 ---- .../elements/fckeditor/editor/fckdialog.html | 819 ------------------ .../elements/fckeditor/editor/fckeditor.html | 317 ------- .../fckeditor/editor/fckeditor.original.html | 425 ---------- .../editor/filemanager/browser/default/browser.css | 87 -- .../filemanager/browser/default/browser.html | 200 ----- .../browser/default/connectors/perl/basexml.pl | 63 -- .../browser/default/connectors/perl/commands.pl | 158 ---- .../browser/default/connectors/perl/connector.cgi | 137 --- .../browser/default/connectors/perl/io.pl | 131 --- .../browser/default/connectors/perl/upload_fck.pl | 667 --------------- .../browser/default/connectors/perl/util.pl | 60 -- .../browser/default/frmactualfolder.html | 95 --- .../browser/default/frmcreatefolder.html | 114 --- .../filemanager/browser/default/frmfolders.html | 198 ----- .../browser/default/frmresourceslist.html | 169 ---- .../browser/default/frmresourcetype.html | 69 -- .../filemanager/browser/default/frmupload.html | 115 --- .../browser/default/images/ButtonArrow.gif | Bin 138 -> 0 bytes .../filemanager/browser/default/images/Folder.gif | Bin 128 -> 0 bytes .../browser/default/images/Folder32.gif | Bin 281 -> 0 bytes .../browser/default/images/FolderOpened.gif | Bin 132 -> 0 bytes .../browser/default/images/FolderOpened32.gif | Bin 264 -> 0 bytes .../browser/default/images/FolderUp.gif | Bin 132 -> 0 bytes .../browser/default/images/icons/32/ai.gif | Bin 1140 -> 0 bytes .../browser/default/images/icons/32/avi.gif | Bin 454 -> 0 bytes .../browser/default/images/icons/32/bmp.gif | Bin 709 -> 0 bytes .../browser/default/images/icons/32/cs.gif | Bin 224 -> 0 bytes .../default/images/icons/32/default.icon.gif | Bin 177 -> 0 bytes .../browser/default/images/icons/32/dll.gif | Bin 258 -> 0 bytes .../browser/default/images/icons/32/doc.gif | Bin 260 -> 0 bytes .../browser/default/images/icons/32/exe.gif | Bin 170 -> 0 bytes .../browser/default/images/icons/32/fla.gif | Bin 946 -> 0 bytes .../browser/default/images/icons/32/gif.gif | Bin 704 -> 0 bytes .../browser/default/images/icons/32/htm.gif | Bin 1527 -> 0 bytes .../browser/default/images/icons/32/html.gif | Bin 1527 -> 0 bytes .../browser/default/images/icons/32/jpg.gif | Bin 463 -> 0 bytes .../browser/default/images/icons/32/js.gif | Bin 274 -> 0 bytes .../browser/default/images/icons/32/mdb.gif | Bin 274 -> 0 bytes .../browser/default/images/icons/32/mp3.gif | Bin 454 -> 0 bytes .../browser/default/images/icons/32/pdf.gif | Bin 567 -> 0 bytes .../browser/default/images/icons/32/png.gif | Bin 464 -> 0 bytes .../browser/default/images/icons/32/ppt.gif | Bin 254 -> 0 bytes .../browser/default/images/icons/32/rdp.gif | Bin 1493 -> 0 bytes .../browser/default/images/icons/32/swf.gif | Bin 725 -> 0 bytes .../browser/default/images/icons/32/swt.gif | Bin 724 -> 0 bytes .../browser/default/images/icons/32/txt.gif | Bin 213 -> 0 bytes .../browser/default/images/icons/32/vsd.gif | Bin 277 -> 0 bytes .../browser/default/images/icons/32/xls.gif | Bin 271 -> 0 bytes .../browser/default/images/icons/32/xml.gif | Bin 408 -> 0 bytes .../browser/default/images/icons/32/zip.gif | Bin 368 -> 0 bytes .../browser/default/images/icons/ai.gif | Bin 403 -> 0 bytes .../browser/default/images/icons/avi.gif | Bin 249 -> 0 bytes .../browser/default/images/icons/bmp.gif | Bin 126 -> 0 bytes .../browser/default/images/icons/cs.gif | Bin 128 -> 0 bytes .../browser/default/images/icons/default.icon.gif | Bin 113 -> 0 bytes .../browser/default/images/icons/dll.gif | Bin 132 -> 0 bytes .../browser/default/images/icons/doc.gif | Bin 140 -> 0 bytes .../browser/default/images/icons/exe.gif | Bin 109 -> 0 bytes .../browser/default/images/icons/fla.gif | Bin 382 -> 0 bytes .../browser/default/images/icons/gif.gif | Bin 125 -> 0 bytes .../browser/default/images/icons/htm.gif | Bin 621 -> 0 bytes .../browser/default/images/icons/html.gif | Bin 621 -> 0 bytes .../browser/default/images/icons/jpg.gif | Bin 125 -> 0 bytes .../browser/default/images/icons/js.gif | Bin 139 -> 0 bytes .../browser/default/images/icons/mdb.gif | Bin 146 -> 0 bytes .../browser/default/images/icons/mp3.gif | Bin 249 -> 0 bytes .../browser/default/images/icons/pdf.gif | Bin 230 -> 0 bytes .../browser/default/images/icons/png.gif | Bin 125 -> 0 bytes .../browser/default/images/icons/ppt.gif | Bin 139 -> 0 bytes .../browser/default/images/icons/rdp.gif | Bin 606 -> 0 bytes .../browser/default/images/icons/swf.gif | Bin 388 -> 0 bytes .../browser/default/images/icons/swt.gif | Bin 388 -> 0 bytes .../browser/default/images/icons/txt.gif | Bin 122 -> 0 bytes .../browser/default/images/icons/vsd.gif | Bin 136 -> 0 bytes .../browser/default/images/icons/xls.gif | Bin 138 -> 0 bytes .../browser/default/images/icons/xml.gif | Bin 231 -> 0 bytes .../browser/default/images/icons/zip.gif | Bin 235 -> 0 bytes .../filemanager/browser/default/images/spacer.gif | Bin 43 -> 0 bytes .../filemanager/browser/default/js/common.js | 88 -- .../filemanager/browser/default/js/fckxml.js | 147 ---- .../editor/filemanager/connectors/perl/basexml.pl | 68 -- .../editor/filemanager/connectors/perl/commands.pl | 200 ----- .../editor/filemanager/connectors/perl/config.pl | 39 - .../filemanager/connectors/perl/connector.cgi | 129 --- .../editor/filemanager/connectors/perl/io.pl | 141 ---- .../editor/filemanager/connectors/perl/upload.cgi | 87 -- .../filemanager/connectors/perl/upload_fck.pl | 686 --------------- .../editor/filemanager/connectors/perl/util.pl | 66 -- .../editor/filemanager/connectors/test.html | 210 ----- .../editor/filemanager/connectors/uploadtest.html | 192 ----- .../fckeditor/editor/filemanager/upload/test.html | 133 --- .../elements/fckeditor/editor/images/anchor.gif | Bin 184 -> 0 bytes .../elements/fckeditor/editor/images/arrow_ltr.gif | Bin 49 -> 0 bytes .../elements/fckeditor/editor/images/arrow_rtl.gif | Bin 49 -> 0 bytes .../editor/images/smiley/msn/angel_smile.gif | Bin 445 -> 0 bytes .../editor/images/smiley/msn/angry_smile.gif | Bin 453 -> 0 bytes .../editor/images/smiley/msn/broken_heart.gif | Bin 423 -> 0 bytes .../fckeditor/editor/images/smiley/msn/cake.gif | Bin 453 -> 0 bytes .../editor/images/smiley/msn/confused_smile.gif | Bin 322 -> 0 bytes .../editor/images/smiley/msn/cry_smile.gif | Bin 473 -> 0 bytes .../editor/images/smiley/msn/devil_smile.gif | Bin 444 -> 0 bytes .../editor/images/smiley/msn/embaressed_smile.gif | Bin 1077 -> 0 bytes .../editor/images/smiley/msn/envelope.gif | Bin 1030 -> 0 bytes .../fckeditor/editor/images/smiley/msn/heart.gif | Bin 1012 -> 0 bytes .../fckeditor/editor/images/smiley/msn/kiss.gif | Bin 978 -> 0 bytes .../editor/images/smiley/msn/lightbulb.gif | Bin 303 -> 0 bytes .../editor/images/smiley/msn/omg_smile.gif | Bin 342 -> 0 bytes .../editor/images/smiley/msn/regular_smile.gif | Bin 1036 -> 0 bytes .../editor/images/smiley/msn/sad_smile.gif | Bin 1039 -> 0 bytes .../editor/images/smiley/msn/shades_smile.gif | Bin 1059 -> 0 bytes .../editor/images/smiley/msn/teeth_smile.gif | Bin 1064 -> 0 bytes .../editor/images/smiley/msn/thumbs_down.gif | Bin 992 -> 0 bytes .../editor/images/smiley/msn/thumbs_up.gif | Bin 989 -> 0 bytes .../editor/images/smiley/msn/tounge_smile.gif | Bin 1055 -> 0 bytes .../smiley/msn/whatchutalkingabout_smile.gif | Bin 1034 -> 0 bytes .../editor/images/smiley/msn/wink_smile.gif | Bin 1041 -> 0 bytes .../elements/fckeditor/editor/images/spacer.gif | Bin 43 -> 0 bytes .../elements/fckeditor/editor/js/fckadobeair.js | 176 ---- .../fckeditor/editor/js/fckeditorcode_gecko.js | 109 --- .../fckeditor/editor/js/fckeditorcode_ie.js | 110 --- .../fckeditor/editor/lang/_getfontformat.html | 85 -- .../fckeditor/editor/lang/_translationstatus.txt | 79 -- httemplate/elements/fckeditor/editor/lang/af.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/ar.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/bg.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/bn.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/bs.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/ca.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/cs.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/da.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/de.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/el.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/en-au.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/en-ca.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/en-uk.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/en.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/eo.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/es.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/et.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/eu.js | 540 ------------ httemplate/elements/fckeditor/editor/lang/fa.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/fi.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/fo.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/fr-ca.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/fr.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/gl.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/gu.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/he.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/hi.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/hr.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/hu.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/is.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/it.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/ja.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/km.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/ko.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/lt.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/lv.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/mn.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/ms.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/nb.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/nl.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/no.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/pl.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/pt-br.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/pt.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/ro.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/ru.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/sk.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/sl.js | 539 ------------ .../elements/fckeditor/editor/lang/sr-latn.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/sr.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/sv.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/th.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/tr.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/uk.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/vi.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/zh-cn.js | 539 ------------ httemplate/elements/fckeditor/editor/lang/zh.js | 539 ------------ .../fckeditor/editor/plugins/autogrow/fckplugin.js | 111 --- .../fckeditor/editor/plugins/bbcode/fckplugin.js | 123 --- .../editor/plugins/dragresizetable/fckplugin.js | 529 ------------ .../plugins/placeholder/fck_placeholder.html | 105 --- .../editor/plugins/placeholder/fckplugin.js | 187 ----- .../editor/plugins/placeholder/lang/de.js | 27 - .../editor/plugins/placeholder/lang/en.js | 27 - .../editor/plugins/placeholder/lang/es.js | 27 - .../editor/plugins/placeholder/lang/fr.js | 27 - .../editor/plugins/placeholder/lang/it.js | 27 - .../editor/plugins/placeholder/lang/pl.js | 27 - .../editor/plugins/placeholder/placeholder.gif | Bin 96 -> 0 bytes .../editor/plugins/simplecommands/fckplugin.js | 29 - .../editor/plugins/tablecommands/fckplugin.js | 33 - .../fckeditor/editor/skins/_fckviewstrips.html | 121 --- .../fckeditor/editor/skins/default/fck_dialog.css | 402 --------- .../editor/skins/default/fck_dialog_ie6.js | 110 --- .../fckeditor/editor/skins/default/fck_editor.css | 464 ----------- .../fckeditor/editor/skins/default/fck_strip.gif | Bin 5175 -> 0 bytes .../editor/skins/default/images/dialog.sides.gif | Bin 48 -> 0 bytes .../editor/skins/default/images/dialog.sides.png | Bin 178 -> 0 bytes .../skins/default/images/dialog.sides.rtl.png | Bin 181 -> 0 bytes .../editor/skins/default/images/sprites.gif | Bin 959 -> 0 bytes .../editor/skins/default/images/sprites.png | Bin 3250 -> 0 bytes .../skins/default/images/toolbar.arrowright.gif | Bin 53 -> 0 bytes .../skins/default/images/toolbar.buttonarrow.gif | Bin 46 -> 0 bytes .../skins/default/images/toolbar.collapse.gif | Bin 152 -> 0 bytes .../editor/skins/default/images/toolbar.end.gif | Bin 43 -> 0 bytes .../editor/skins/default/images/toolbar.expand.gif | Bin 152 -> 0 bytes .../skins/default/images/toolbar.separator.gif | Bin 58 -> 0 bytes .../editor/skins/default/images/toolbar.start.gif | Bin 105 -> 0 bytes .../editor/skins/office2003/fck_dialog.css | 402 --------- .../editor/skins/office2003/fck_dialog_ie6.js | 110 --- .../editor/skins/office2003/fck_editor.css | 476 ----------- .../editor/skins/office2003/fck_strip.gif | Bin 9668 -> 0 bytes .../skins/office2003/images/dialog.sides.gif | Bin 48 -> 0 bytes .../skins/office2003/images/dialog.sides.png | Bin 203 -> 0 bytes .../skins/office2003/images/dialog.sides.rtl.png | Bin 205 -> 0 bytes .../editor/skins/office2003/images/sprites.gif | Bin 959 -> 0 bytes .../editor/skins/office2003/images/sprites.png | Bin 3305 -> 0 bytes .../skins/office2003/images/toolbar.arrowright.gif | Bin 53 -> 0 bytes .../editor/skins/office2003/images/toolbar.bg.gif | Bin 73 -> 0 bytes .../office2003/images/toolbar.buttonarrow.gif | Bin 46 -> 0 bytes .../skins/office2003/images/toolbar.collapse.gif | Bin 152 -> 0 bytes .../editor/skins/office2003/images/toolbar.end.gif | Bin 124 -> 0 bytes .../skins/office2003/images/toolbar.expand.gif | Bin 152 -> 0 bytes .../skins/office2003/images/toolbar.separator.gif | Bin 67 -> 0 bytes .../skins/office2003/images/toolbar.start.gif | Bin 99 -> 0 bytes .../fckeditor/editor/skins/silver/fck_dialog.css | 402 --------- .../editor/skins/silver/fck_dialog_ie6.js | 110 --- .../fckeditor/editor/skins/silver/fck_editor.css | 473 ----------- .../fckeditor/editor/skins/silver/fck_strip.gif | Bin 5175 -> 0 bytes .../editor/skins/silver/images/dialog.sides.gif | Bin 48 -> 0 bytes .../editor/skins/silver/images/dialog.sides.png | Bin 198 -> 0 bytes .../skins/silver/images/dialog.sides.rtl.png | Bin 200 -> 0 bytes .../editor/skins/silver/images/sprites.gif | Bin 959 -> 0 bytes .../editor/skins/silver/images/sprites.png | Bin 3278 -> 0 bytes .../skins/silver/images/toolbar.arrowright.gif | Bin 53 -> 0 bytes .../skins/silver/images/toolbar.buttonarrow.gif | Bin 46 -> 0 bytes .../skins/silver/images/toolbar.buttonbg.gif | Bin 829 -> 0 bytes .../skins/silver/images/toolbar.collapse.gif | Bin 152 -> 0 bytes .../editor/skins/silver/images/toolbar.end.gif | Bin 43 -> 0 bytes .../editor/skins/silver/images/toolbar.expand.gif | Bin 152 -> 0 bytes .../skins/silver/images/toolbar.separator.gif | Bin 58 -> 0 bytes .../editor/skins/silver/images/toolbar.start.gif | Bin 105 -> 0 bytes .../elements/fckeditor/editor/wsc/ciframe.html | 65 -- .../elements/fckeditor/editor/wsc/tmpFrameset.html | 67 -- httemplate/elements/fckeditor/editor/wsc/w.html | 227 ----- httemplate/elements/fckeditor/fckconfig.js | 325 -------- httemplate/elements/fckeditor/fckeditor.js | 330 -------- httemplate/elements/fckeditor/fckpackager.xml | 264 ------ httemplate/elements/fckeditor/fckstyles.xml | 111 --- httemplate/elements/fckeditor/fcktemplates.xml | 103 --- httemplate/elements/htmlarea.html | 26 +- 710 files changed, 3703 insertions(+), 54652 deletions(-) create mode 100644 httemplate/elements/ckeditor/build-config.js create mode 100644 httemplate/elements/ckeditor/ckeditor.js create mode 100644 httemplate/elements/ckeditor/config.js create mode 100644 httemplate/elements/ckeditor/contents.css create mode 100644 httemplate/elements/ckeditor/lang/af.js create mode 100644 httemplate/elements/ckeditor/lang/ar.js create mode 100644 httemplate/elements/ckeditor/lang/bg.js create mode 100644 httemplate/elements/ckeditor/lang/bn.js create mode 100644 httemplate/elements/ckeditor/lang/bs.js create mode 100644 httemplate/elements/ckeditor/lang/ca.js create mode 100644 httemplate/elements/ckeditor/lang/cs.js create mode 100644 httemplate/elements/ckeditor/lang/cy.js create mode 100644 httemplate/elements/ckeditor/lang/da.js create mode 100644 httemplate/elements/ckeditor/lang/de.js create mode 100644 httemplate/elements/ckeditor/lang/el.js create mode 100644 httemplate/elements/ckeditor/lang/en-au.js create mode 100644 httemplate/elements/ckeditor/lang/en-ca.js create mode 100644 httemplate/elements/ckeditor/lang/en-gb.js create mode 100644 httemplate/elements/ckeditor/lang/en.js create mode 100644 httemplate/elements/ckeditor/lang/eo.js create mode 100644 httemplate/elements/ckeditor/lang/es.js create mode 100644 httemplate/elements/ckeditor/lang/et.js create mode 100644 httemplate/elements/ckeditor/lang/eu.js create mode 100644 httemplate/elements/ckeditor/lang/fa.js create mode 100644 httemplate/elements/ckeditor/lang/fi.js create mode 100644 httemplate/elements/ckeditor/lang/fo.js create mode 100644 httemplate/elements/ckeditor/lang/fr-ca.js create mode 100644 httemplate/elements/ckeditor/lang/fr.js create mode 100644 httemplate/elements/ckeditor/lang/gl.js create mode 100644 httemplate/elements/ckeditor/lang/gu.js create mode 100644 httemplate/elements/ckeditor/lang/he.js create mode 100644 httemplate/elements/ckeditor/lang/hi.js create mode 100644 httemplate/elements/ckeditor/lang/hr.js create mode 100644 httemplate/elements/ckeditor/lang/hu.js create mode 100644 httemplate/elements/ckeditor/lang/is.js create mode 100644 httemplate/elements/ckeditor/lang/it.js create mode 100644 httemplate/elements/ckeditor/lang/ja.js create mode 100644 httemplate/elements/ckeditor/lang/ka.js create mode 100644 httemplate/elements/ckeditor/lang/km.js create mode 100644 httemplate/elements/ckeditor/lang/ko.js create mode 100644 httemplate/elements/ckeditor/lang/ku.js create mode 100644 httemplate/elements/ckeditor/lang/lt.js create mode 100644 httemplate/elements/ckeditor/lang/lv.js create mode 100644 httemplate/elements/ckeditor/lang/mk.js create mode 100644 httemplate/elements/ckeditor/lang/mn.js create mode 100644 httemplate/elements/ckeditor/lang/ms.js create mode 100644 httemplate/elements/ckeditor/lang/nb.js create mode 100644 httemplate/elements/ckeditor/lang/nl.js create mode 100644 httemplate/elements/ckeditor/lang/no.js create mode 100644 httemplate/elements/ckeditor/lang/pl.js create mode 100644 httemplate/elements/ckeditor/lang/pt-br.js create mode 100644 httemplate/elements/ckeditor/lang/pt.js create mode 100644 httemplate/elements/ckeditor/lang/ro.js create mode 100644 httemplate/elements/ckeditor/lang/ru.js create mode 100644 httemplate/elements/ckeditor/lang/sk.js create mode 100644 httemplate/elements/ckeditor/lang/sl.js create mode 100644 httemplate/elements/ckeditor/lang/sq.js create mode 100644 httemplate/elements/ckeditor/lang/sr-latn.js create mode 100644 httemplate/elements/ckeditor/lang/sr.js create mode 100644 httemplate/elements/ckeditor/lang/sv.js create mode 100644 httemplate/elements/ckeditor/lang/th.js create mode 100644 httemplate/elements/ckeditor/lang/tr.js create mode 100644 httemplate/elements/ckeditor/lang/ug.js create mode 100644 httemplate/elements/ckeditor/lang/uk.js create mode 100644 httemplate/elements/ckeditor/lang/vi.js create mode 100644 httemplate/elements/ckeditor/lang/zh-cn.js create mode 100644 httemplate/elements/ckeditor/lang/zh.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/_translationstatus.txt create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/ar.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/bg.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/ca.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/cs.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/cy.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/da.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/de.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/el.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/en.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/eo.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/es.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/et.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/fa.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/fi.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/fr-ca.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/fr.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/gu.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/he.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/hi.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/hr.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/hu.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/it.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/ja.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/km.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/ku.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/lt.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/lv.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/mk.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/mn.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/nb.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/nl.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/no.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/pl.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/pt-br.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/pt.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/ro.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/ru.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/sk.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/sl.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/sq.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/sv.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/th.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/tr.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/ug.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/uk.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/vi.js create mode 100644 httemplate/elements/ckeditor/plugins/a11yhelp/dialogs/lang/zh-cn.js create mode 100644 httemplate/elements/ckeditor/plugins/about/dialogs/about.js create mode 100644 httemplate/elements/ckeditor/plugins/about/dialogs/logo_ckeditor.png create mode 100644 httemplate/elements/ckeditor/plugins/clipboard/dialogs/paste.js create mode 100644 httemplate/elements/ckeditor/plugins/colordialog/dialogs/colordialog.js create mode 100644 httemplate/elements/ckeditor/plugins/dialog/dialogDefinition.js create mode 100644 httemplate/elements/ckeditor/plugins/div/dialogs/div.js create mode 100644 httemplate/elements/ckeditor/plugins/fakeobjects/images/spacer.gif create mode 100644 httemplate/elements/ckeditor/plugins/find/dialogs/find.js create mode 100644 httemplate/elements/ckeditor/plugins/flash/dialogs/flash.js create mode 100644 httemplate/elements/ckeditor/plugins/flash/images/placeholder.png create mode 100644 httemplate/elements/ckeditor/plugins/forms/dialogs/button.js create mode 100644 httemplate/elements/ckeditor/plugins/forms/dialogs/checkbox.js create mode 100644 httemplate/elements/ckeditor/plugins/forms/dialogs/form.js create mode 100644 httemplate/elements/ckeditor/plugins/forms/dialogs/hiddenfield.js create mode 100644 httemplate/elements/ckeditor/plugins/forms/dialogs/radio.js create mode 100644 httemplate/elements/ckeditor/plugins/forms/dialogs/select.js create mode 100644 httemplate/elements/ckeditor/plugins/forms/dialogs/textarea.js create mode 100644 httemplate/elements/ckeditor/plugins/forms/dialogs/textfield.js create mode 100644 httemplate/elements/ckeditor/plugins/forms/images/hiddenfield.gif create mode 100644 httemplate/elements/ckeditor/plugins/icons.png create mode 100644 httemplate/elements/ckeditor/plugins/iframe/dialogs/iframe.js create mode 100644 httemplate/elements/ckeditor/plugins/iframe/images/placeholder.png create mode 100644 httemplate/elements/ckeditor/plugins/image/dialogs/image.js create mode 100644 httemplate/elements/ckeditor/plugins/image/images/noimage.png create mode 100644 httemplate/elements/ckeditor/plugins/link/dialogs/anchor.js create mode 100644 httemplate/elements/ckeditor/plugins/link/dialogs/link.js create mode 100644 httemplate/elements/ckeditor/plugins/link/images/anchor.png create mode 100644 httemplate/elements/ckeditor/plugins/liststyle/dialogs/liststyle.js create mode 100644 httemplate/elements/ckeditor/plugins/magicline/images/icon.png create mode 100644 httemplate/elements/ckeditor/plugins/pagebreak/images/pagebreak.gif create mode 100644 httemplate/elements/ckeditor/plugins/pastefromword/filter/default.js create mode 100644 httemplate/elements/ckeditor/plugins/preview/preview.html create mode 100644 httemplate/elements/ckeditor/plugins/scayt/LICENSE.md create mode 100644 httemplate/elements/ckeditor/plugins/scayt/README.md create mode 100644 httemplate/elements/ckeditor/plugins/scayt/dialogs/options.js create mode 100644 httemplate/elements/ckeditor/plugins/scayt/dialogs/toolbar.css create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_address.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_blockquote.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_div.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_h1.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_h2.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_h3.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_h4.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_h5.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_h6.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_p.png create mode 100644 httemplate/elements/ckeditor/plugins/showblocks/images/block_pre.png create mode 100644 httemplate/elements/ckeditor/plugins/smiley/dialogs/smiley.js create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/angel_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/angry_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/broken_heart.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/confused_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/cry_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/devil_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/embaressed_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/embarrassed_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/envelope.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/heart.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/kiss.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/lightbulb.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/omg_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/regular_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/sad_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/shades_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/teeth_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/thumbs_down.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/thumbs_up.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/tongue_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/tounge_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/whatchutalkingabout_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/smiley/images/wink_smile.gif create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/_translationstatus.txt create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/ca.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/cs.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/cy.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/de.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/el.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/en.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/eo.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/es.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/et.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/fa.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/fi.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/fr-ca.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/fr.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/he.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/hr.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/it.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/ku.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/lv.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/nb.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/nl.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/no.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/pl.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/pt-br.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/sk.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/sq.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/sv.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/th.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/tr.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/ug.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/lang/zh-cn.js create mode 100644 httemplate/elements/ckeditor/plugins/specialchar/dialogs/specialchar.js create mode 100644 httemplate/elements/ckeditor/plugins/table/dialogs/table.js create mode 100644 httemplate/elements/ckeditor/plugins/tabletools/dialogs/tableCell.js create mode 100644 httemplate/elements/ckeditor/plugins/templates/dialogs/templates.css create mode 100644 httemplate/elements/ckeditor/plugins/templates/dialogs/templates.js create mode 100644 httemplate/elements/ckeditor/plugins/templates/templates/default.js create mode 100644 httemplate/elements/ckeditor/plugins/templates/templates/images/template1.gif create mode 100644 httemplate/elements/ckeditor/plugins/templates/templates/images/template2.gif create mode 100644 httemplate/elements/ckeditor/plugins/templates/templates/images/template3.gif create mode 100644 httemplate/elements/ckeditor/plugins/wsc/LICENSE.md create mode 100644 httemplate/elements/ckeditor/plugins/wsc/README.md create mode 100644 httemplate/elements/ckeditor/plugins/wsc/dialogs/ciframe.html create mode 100644 httemplate/elements/ckeditor/plugins/wsc/dialogs/tmpFrameset.html create mode 100644 httemplate/elements/ckeditor/plugins/wsc/dialogs/wsc.css create mode 100644 httemplate/elements/ckeditor/plugins/wsc/dialogs/wsc.js create mode 100644 httemplate/elements/ckeditor/skins/kama/dialog.css create mode 100644 httemplate/elements/ckeditor/skins/kama/dialog_ie.css create mode 100644 httemplate/elements/ckeditor/skins/kama/dialog_ie7.css create mode 100644 httemplate/elements/ckeditor/skins/kama/dialog_ie8.css create mode 100644 httemplate/elements/ckeditor/skins/kama/dialog_iequirks.css create mode 100644 httemplate/elements/ckeditor/skins/kama/dialog_opera.css create mode 100644 httemplate/elements/ckeditor/skins/kama/editor.css create mode 100644 httemplate/elements/ckeditor/skins/kama/editor_ie.css create mode 100644 httemplate/elements/ckeditor/skins/kama/editor_ie7.css create mode 100644 httemplate/elements/ckeditor/skins/kama/editor_ie8.css create mode 100644 httemplate/elements/ckeditor/skins/kama/editor_iequirks.css create mode 100644 httemplate/elements/ckeditor/skins/kama/icons.png create mode 100644 httemplate/elements/ckeditor/skins/kama/images/dialog_sides.gif create mode 100644 httemplate/elements/ckeditor/skins/kama/images/dialog_sides.png create mode 100644 httemplate/elements/ckeditor/skins/kama/images/dialog_sides_rtl.png create mode 100644 httemplate/elements/ckeditor/skins/kama/images/mini.gif create mode 100644 httemplate/elements/ckeditor/skins/kama/images/sprites.png create mode 100644 httemplate/elements/ckeditor/skins/kama/images/sprites_ie6.png create mode 100644 httemplate/elements/ckeditor/skins/kama/images/toolbar_start.gif create mode 100644 httemplate/elements/ckeditor/skins/kama/readme.md create mode 100644 httemplate/elements/ckeditor/skins/kama/skin.js create mode 100644 httemplate/elements/ckeditor/skins/moono/dialog.css create mode 100644 httemplate/elements/ckeditor/skins/moono/dialog_ie.css create mode 100644 httemplate/elements/ckeditor/skins/moono/dialog_ie7.css create mode 100644 httemplate/elements/ckeditor/skins/moono/dialog_ie8.css create mode 100644 httemplate/elements/ckeditor/skins/moono/dialog_iequirks.css create mode 100644 httemplate/elements/ckeditor/skins/moono/dialog_opera.css create mode 100644 httemplate/elements/ckeditor/skins/moono/editor.css create mode 100644 httemplate/elements/ckeditor/skins/moono/editor_gecko.css create mode 100644 httemplate/elements/ckeditor/skins/moono/editor_ie.css create mode 100644 httemplate/elements/ckeditor/skins/moono/editor_ie7.css create mode 100644 httemplate/elements/ckeditor/skins/moono/editor_ie8.css create mode 100644 httemplate/elements/ckeditor/skins/moono/editor_iequirks.css create mode 100644 httemplate/elements/ckeditor/skins/moono/icons.png create mode 100644 httemplate/elements/ckeditor/skins/moono/images/arrow.png create mode 100644 httemplate/elements/ckeditor/skins/moono/images/close.png create mode 100644 httemplate/elements/ckeditor/skins/moono/images/mini.png create mode 100644 httemplate/elements/ckeditor/skins/moono/readme.md create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/dialog.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/dialog_ie.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/dialog_ie7.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/dialog_ie8.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/dialog_iequirks.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/dialog_opera.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/editor.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/editor_gecko.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/editor_ie.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/editor_ie7.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/editor_ie8.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/editor_iequirks.css create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/about.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/anchor-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/anchor.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/bgcolor.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/bidiltr.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/bidirtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/blockquote.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/bold.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/bulletedlist-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/bulletedlist.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/button.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/checkbox.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/copy-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/copy.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/creatediv.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/cut-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/cut.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/find-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/find.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/flash.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/form.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/hiddenfield.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/horizontalrule.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/iframe.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/image.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/imagebutton.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/indent-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/indent.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/italic.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/justifyblock.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/justifycenter.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/justifyleft.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/justifyright.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/link.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/maximize.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/newpage-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/newpage.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/numberedlist-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/numberedlist.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/outdent-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/outdent.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/pagebreak-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/pagebreak.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/paste-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/paste.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/pastefromword-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/pastefromword.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/pastetext-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/pastetext.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/preview-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/preview.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/print.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/radio.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/redo-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/redo.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/removeformat.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/replace.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/save.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/scayt.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/select-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/select.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/selectall.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/showblocks-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/showblocks.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/smiley.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/source-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/source.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/specialchar.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/spellchecker.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/strike.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/subscript.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/superscript.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/table.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/templates-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/templates.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/textarea-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/textarea.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/textcolor.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/textfield-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/textfield.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/underline.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/undo-rtl.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/undo.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/icons/unlink.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/images/arrow.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/images/close.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/images/mini.png create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/readme.md create mode 100644 httemplate/elements/ckeditor/skins/moonocolor/skin.js create mode 100644 httemplate/elements/ckeditor/styles.js delete mode 100644 httemplate/elements/fckeditor/editor/css/behaviors/disablehandles.htc delete mode 100644 httemplate/elements/fckeditor/editor/css/behaviors/showtableborders.htc delete mode 100644 httemplate/elements/fckeditor/editor/css/fck_editorarea.css delete mode 100644 httemplate/elements/fckeditor/editor/css/fck_internal.css delete mode 100644 httemplate/elements/fckeditor/editor/css/fck_showtableborders_gecko.css delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_address.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_blockquote.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_div.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_h1.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_h2.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_h3.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_h4.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_h5.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_h6.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_p.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/block_pre.png delete mode 100644 httemplate/elements/fckeditor/editor/css/images/fck_anchor.gif delete mode 100644 httemplate/elements/fckeditor/editor/css/images/fck_flashlogo.gif delete mode 100644 httemplate/elements/fckeditor/editor/css/images/fck_hiddenfield.gif delete mode 100644 httemplate/elements/fckeditor/editor/css/images/fck_pagebreak.gif delete mode 100644 httemplate/elements/fckeditor/editor/css/images/fck_plugin.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/common/fck_dialog_common.css delete mode 100644 httemplate/elements/fckeditor/editor/dialog/common/fck_dialog_common.js delete mode 100644 httemplate/elements/fckeditor/editor/dialog/common/fcknumericfield.htc delete mode 100644 httemplate/elements/fckeditor/editor/dialog/common/images/locked.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/common/images/reset.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/common/images/unlocked.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/common/moz-bindings.xml delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_about.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_about/logo_fckeditor.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_about/logo_fredck.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_about/sponsors/spellchecker_net.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_anchor.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_button.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_checkbox.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_colorselector.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_div.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_docprops.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_find.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_flash.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_flash/fck_flash.js delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_flash/fck_flash_preview.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_form.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_hiddenfield.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_image.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_image/fck_image.js delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_image/fck_image_preview.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_link.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_link/fck_link.js delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_listprop.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_paste.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_radiobutton.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_replace.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_scayt.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_scayt/scayt_dialog.css delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_select.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_select/fck_select.js delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_smiley.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_source.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_specialchar.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_table.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_tablecell.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_template.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_template/images/template1.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_template/images/template2.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_template/images/template3.gif delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_textarea.html delete mode 100644 httemplate/elements/fckeditor/editor/dialog/fck_textfield.html delete mode 100644 httemplate/elements/fckeditor/editor/dtd/fck_dtd_test.html delete mode 100644 httemplate/elements/fckeditor/editor/dtd/fck_xhtml10strict.js delete mode 100644 httemplate/elements/fckeditor/editor/dtd/fck_xhtml10transitional.js delete mode 100644 httemplate/elements/fckeditor/editor/fckdebug.html delete mode 100644 httemplate/elements/fckeditor/editor/fckdialog.html delete mode 100644 httemplate/elements/fckeditor/editor/fckeditor.html delete mode 100644 httemplate/elements/fckeditor/editor/fckeditor.original.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/browser.css delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/browser.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/connectors/perl/basexml.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/connectors/perl/commands.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/connectors/perl/connector.cgi delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/connectors/perl/io.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/connectors/perl/upload_fck.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/connectors/perl/util.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/frmactualfolder.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/frmfolders.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/frmresourceslist.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/frmresourcetype.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/frmupload.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/ButtonArrow.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/Folder.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/Folder32.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/FolderOpened.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/FolderOpened32.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/FolderUp.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/ai.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/avi.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/bmp.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/cs.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/default.icon.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/dll.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/doc.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/exe.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/fla.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/gif.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/htm.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/html.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/jpg.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/js.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/mdb.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/mp3.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/pdf.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/png.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/ppt.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/rdp.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/swf.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/swt.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/txt.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/vsd.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/xls.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/xml.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/32/zip.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/ai.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/avi.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/bmp.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/cs.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/default.icon.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/dll.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/doc.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/exe.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/fla.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/gif.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/htm.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/html.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/jpg.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/js.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/mdb.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/mp3.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/pdf.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/png.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/ppt.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/rdp.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/swf.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/swt.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/txt.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/vsd.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/xls.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/xml.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/icons/zip.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/images/spacer.gif delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/js/common.js delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/browser/default/js/fckxml.js delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/perl/basexml.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/perl/commands.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/perl/config.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/perl/connector.cgi delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/perl/io.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/perl/upload.cgi delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/perl/upload_fck.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/perl/util.pl delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/test.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/connectors/uploadtest.html delete mode 100644 httemplate/elements/fckeditor/editor/filemanager/upload/test.html delete mode 100644 httemplate/elements/fckeditor/editor/images/anchor.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/arrow_ltr.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/arrow_rtl.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/angel_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/angry_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/broken_heart.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/cake.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/confused_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/cry_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/devil_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/embaressed_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/envelope.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/heart.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/kiss.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/lightbulb.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/omg_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/regular_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/sad_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/shades_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/teeth_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/thumbs_down.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/thumbs_up.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/tounge_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/whatchutalkingabout_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/smiley/msn/wink_smile.gif delete mode 100644 httemplate/elements/fckeditor/editor/images/spacer.gif delete mode 100644 httemplate/elements/fckeditor/editor/js/fckadobeair.js delete mode 100644 httemplate/elements/fckeditor/editor/js/fckeditorcode_gecko.js delete mode 100644 httemplate/elements/fckeditor/editor/js/fckeditorcode_ie.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/_getfontformat.html delete mode 100644 httemplate/elements/fckeditor/editor/lang/_translationstatus.txt delete mode 100644 httemplate/elements/fckeditor/editor/lang/af.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/ar.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/bg.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/bn.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/bs.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/ca.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/cs.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/da.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/de.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/el.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/en-au.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/en-ca.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/en-uk.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/en.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/eo.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/es.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/et.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/eu.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/fa.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/fi.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/fo.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/fr-ca.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/fr.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/gl.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/gu.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/he.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/hi.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/hr.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/hu.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/is.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/it.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/ja.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/km.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/ko.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/lt.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/lv.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/mn.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/ms.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/nb.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/nl.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/no.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/pl.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/pt-br.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/pt.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/ro.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/ru.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/sk.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/sl.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/sr-latn.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/sr.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/sv.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/th.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/tr.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/uk.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/vi.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/zh-cn.js delete mode 100644 httemplate/elements/fckeditor/editor/lang/zh.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/autogrow/fckplugin.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/bbcode/fckplugin.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/dragresizetable/fckplugin.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/fck_placeholder.html delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/fckplugin.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/lang/de.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/lang/en.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/lang/es.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/lang/fr.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/lang/it.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/lang/pl.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/placeholder/placeholder.gif delete mode 100644 httemplate/elements/fckeditor/editor/plugins/simplecommands/fckplugin.js delete mode 100644 httemplate/elements/fckeditor/editor/plugins/tablecommands/fckplugin.js delete mode 100644 httemplate/elements/fckeditor/editor/skins/_fckviewstrips.html delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/fck_dialog.css delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/fck_dialog_ie6.js delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/fck_editor.css delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/fck_strip.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/dialog.sides.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/dialog.sides.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/dialog.sides.rtl.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/sprites.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/sprites.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/toolbar.arrowright.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/toolbar.buttonarrow.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/toolbar.collapse.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/toolbar.end.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/toolbar.expand.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/toolbar.separator.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/default/images/toolbar.start.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/fck_dialog.css delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/fck_dialog_ie6.js delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/fck_editor.css delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/fck_strip.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/dialog.sides.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/dialog.sides.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/dialog.sides.rtl.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/sprites.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/sprites.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/toolbar.arrowright.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/toolbar.bg.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/toolbar.buttonarrow.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/toolbar.collapse.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/toolbar.end.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/toolbar.expand.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/toolbar.separator.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/office2003/images/toolbar.start.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/fck_dialog.css delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/fck_dialog_ie6.js delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/fck_editor.css delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/fck_strip.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/dialog.sides.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/dialog.sides.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/dialog.sides.rtl.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/sprites.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/sprites.png delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/toolbar.arrowright.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/toolbar.buttonarrow.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/toolbar.buttonbg.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/toolbar.collapse.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/toolbar.end.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/toolbar.expand.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/toolbar.separator.gif delete mode 100644 httemplate/elements/fckeditor/editor/skins/silver/images/toolbar.start.gif delete mode 100644 httemplate/elements/fckeditor/editor/wsc/ciframe.html delete mode 100644 httemplate/elements/fckeditor/editor/wsc/tmpFrameset.html delete mode 100644 httemplate/elements/fckeditor/editor/wsc/w.html delete mode 100644 httemplate/elements/fckeditor/fckconfig.js delete mode 100644 httemplate/elements/fckeditor/fckeditor.js delete mode 100644 httemplate/elements/fckeditor/fckpackager.xml delete mode 100644 httemplate/elements/fckeditor/fckstyles.xml delete mode 100644 httemplate/elements/fckeditor/fcktemplates.xml diff --git a/httemplate/docs/license.html b/httemplate/docs/license.html index 05a89c1f0..5262f7a34 100644 --- a/httemplate/docs/license.html +++ b/httemplate/docs/license.html @@ -68,7 +68,7 @@ Contains "JS Calendar" by Mihai Bazon licensed under the terms of the GNU LGPL.

    -Contains FCKeditor by Frederico Caldeira Knabben, licensed under the terms of +Contains CKeditor by Frederico Caldeira Knabben, licensed under the terms of the GNU GPL.

    diff --git a/httemplate/elements/ckeditor/build-config.js b/httemplate/elements/ckeditor/build-config.js new file mode 100644 index 000000000..aedc9a87e --- /dev/null +++ b/httemplate/elements/ckeditor/build-config.js @@ -0,0 +1,162 @@ + +/** + * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.html or http://ckeditor.com/license + */ + +/** + * This file was added automatically by CKEditor builder. + * You may re-use it at any time at http://ckeditor.com/builder to build CKEditor again. + * + * NOTE: + * This file is not used by CKEditor, you may remove it. + * Changing this file will not change your CKEditor configuration. + */ + +var CKBUILDER_CONFIG = { + skin: 'moono', + preset: 'full', + ignore: [ + 'dev', + '.gitignore', + '.gitattributes', + 'README.md', + '.mailmap' + ], + plugins : { + 'about' : 1, + 'a11yhelp' : 1, + 'dialogadvtab' : 1, + 'basicstyles' : 1, + 'bidi' : 1, + 'blockquote' : 1, + 'clipboard' : 1, + 'colorbutton' : 1, + 'colordialog' : 1, + 'templates' : 1, + 'contextmenu' : 1, + 'div' : 1, + 'resize' : 1, + 'toolbar' : 1, + 'elementspath' : 1, + 'enterkey' : 1, + 'entities' : 1, + 'filebrowser' : 1, + 'find' : 1, + 'flash' : 1, + 'floatingspace' : 1, + 'font' : 1, + 'forms' : 1, + 'format' : 1, + 'htmlwriter' : 1, + 'horizontalrule' : 1, + 'iframe' : 1, + 'wysiwygarea' : 1, + 'image' : 1, + 'indent' : 1, + 'smiley' : 1, + 'justify' : 1, + 'link' : 1, + 'list' : 1, + 'liststyle' : 1, + 'magicline' : 1, + 'maximize' : 1, + 'newpage' : 1, + 'pagebreak' : 1, + 'pastetext' : 1, + 'pastefromword' : 1, + 'preview' : 1, + 'print' : 1, + 'removeformat' : 1, + 'save' : 1, + 'selectall' : 1, + 'showblocks' : 1, + 'showborders' : 1, + 'sourcearea' : 1, + 'specialchar' : 1, + 'scayt' : 1, + 'stylescombo' : 1, + 'tab' : 1, + 'table' : 1, + 'tabletools' : 1, + 'undo' : 1, + 'wsc' : 1, + 'dialog' : 1, + 'dialogui' : 1, + 'panelbutton' : 1, + 'button' : 1, + 'floatpanel' : 1, + 'panel' : 1, + 'menu' : 1, + 'popup' : 1, + 'fakeobjects' : 1, + 'richcombo' : 1, + 'listblock' : 1, + 'menubutton' : 1 + }, + languages : { + 'af' : 1, + 'sq' : 1, + 'ar' : 1, + 'eu' : 1, + 'bn' : 1, + 'bs' : 1, + 'bg' : 1, + 'ca' : 1, + 'zh-cn' : 1, + 'zh' : 1, + 'hr' : 1, + 'cs' : 1, + 'da' : 1, + 'nl' : 1, + 'en' : 1, + 'en-au' : 1, + 'en-ca' : 1, + 'en-gb' : 1, + 'eo' : 1, + 'et' : 1, + 'fo' : 1, + 'fi' : 1, + 'fr' : 1, + 'fr-ca' : 1, + 'gl' : 1, + 'ka' : 1, + 'de' : 1, + 'el' : 1, + 'gu' : 1, + 'he' : 1, + 'hi' : 1, + 'hu' : 1, + 'is' : 1, + 'it' : 1, + 'ja' : 1, + 'km' : 1, + 'ko' : 1, + 'ku' : 1, + 'lv' : 1, + 'lt' : 1, + 'mk' : 1, + 'ms' : 1, + 'mn' : 1, + 'no' : 1, + 'nb' : 1, + 'fa' : 1, + 'pl' : 1, + 'pt-br' : 1, + 'pt' : 1, + 'ro' : 1, + 'ru' : 1, + 'sr' : 1, + 'sr-latn' : 1, + 'sk' : 1, + 'sl' : 1, + 'es' : 1, + 'sv' : 1, + 'th' : 1, + 'tr' : 1, + 'ug' : 1, + 'uk' : 1, + 'vi' : 1, + 'cy' : 1, + } +}; \ No newline at end of file diff --git a/httemplate/elements/ckeditor/ckeditor.js b/httemplate/elements/ckeditor/ckeditor.js new file mode 100644 index 000000000..cfdeec4a3 --- /dev/null +++ b/httemplate/elements/ckeditor/ckeditor.js @@ -0,0 +1,919 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.html or http://ckeditor.com/license +*/ +(function(){if(window.CKEDITOR&&window.CKEDITOR.dom)return;window.CKEDITOR||(window.CKEDITOR=function(){var a={timestamp:"D3NA",version:"4.1.1",revision:"5a2a7e3",rnd:Math.floor(900*Math.random())+100,_:{pending:[]},status:"unloaded",basePath:function(){var b=window.CKEDITOR_BASEPATH||"";if(!b)for(var a=document.getElementsByTagName("script"),d=0;d=0;p--)if(n[p].priority<=l){n.splice(p+1,0,i);return{removeListener:m}}n.unshift(i)}return{removeListener:m}}, +once:function(){var b=arguments[1];arguments[1]=function(a){a.removeListener();return b.apply(this,arguments)};return this.on.apply(this,arguments)},capture:function(){CKEDITOR.event.useCapture=1;var b=this.on.apply(this,arguments);CKEDITOR.event.useCapture=0;return b},fire:function(){var b=0,a=function(){b=1},d=0,j=function(){d=1};return function(l,i,m){var n=c(this)[l],l=b,r=d;b=d=0;if(n){var p=n.listeners;if(p.length)for(var p=p.slice(0),g,h=0;h=0&&d.listeners.splice(j,1)}},removeAllListeners:function(){var b=c(this),a;for(a in b)delete b[a]},hasListeners:function(b){return(b=c(this)[b])&&b.listeners.length>0}}}()); +CKEDITOR.editor||(CKEDITOR.editor=function(){CKEDITOR._.pending.push([this,arguments]);CKEDITOR.event.call(this)},CKEDITOR.editor.prototype.fire=function(a,c){a in{instanceReady:1,loaded:1}&&(this[a]=true);return CKEDITOR.event.prototype.fire.call(this,a,c,this)},CKEDITOR.editor.prototype.fireOnce=function(a,c){a in{instanceReady:1,loaded:1}&&(this[a]=true);return CKEDITOR.event.prototype.fireOnce.call(this,a,c,this)},CKEDITOR.event.implementOn(CKEDITOR.editor.prototype)); +CKEDITOR.env||(CKEDITOR.env=function(){var a=navigator.userAgent.toLowerCase(),c=window.opera,b={ie:eval("/*@cc_on!@*/false"),opera:!!c&&c.version,webkit:a.indexOf(" applewebkit/")>-1,air:a.indexOf(" adobeair/")>-1,mac:a.indexOf("macintosh")>-1,quirks:document.compatMode=="BackCompat",mobile:a.indexOf("mobile")>-1,iOS:/(ipad|iphone|ipod)/.test(a),isCustomDomain:function(){if(!this.ie)return false;var b=document.domain,a=window.location.hostname;return b!=a&&b!="["+a+"]"},secure:location.protocol== +"https:"};b.gecko=navigator.product=="Gecko"&&!b.webkit&&!b.opera;if(b.webkit)a.indexOf("chrome")>-1?b.chrome=true:b.safari=true;var f=0;if(b.ie){f=b.quirks||!document.documentMode?parseFloat(a.match(/msie (\d+)/)[1]):document.documentMode;b.ie9Compat=f==9;b.ie8Compat=f==8;b.ie7Compat=f==7;b.ie6Compat=f<7||b.quirks}if(b.gecko){var e=a.match(/rv:([\d\.]+)/);if(e){e=e[1].split(".");f=e[0]*1E4+(e[1]||0)*100+(e[2]||0)*1}}b.opera&&(f=parseFloat(c.version()));b.air&&(f=parseFloat(a.match(/ adobeair\/(\d+)/)[1])); +b.webkit&&(f=parseFloat(a.match(/ applewebkit\/(\d+)/)[1]));b.version=f;b.isCompatible=b.iOS&&f>=534||!b.mobile&&(b.ie&&f>6||b.gecko&&f>=10801||b.opera&&f>=9.5||b.air&&f>=1||b.webkit&&f>=522||false);b.cssClass="cke_browser_"+(b.ie?"ie":b.gecko?"gecko":b.opera?"opera":b.webkit?"webkit":"unknown");if(b.quirks)b.cssClass=b.cssClass+" cke_browser_quirks";if(b.ie){b.cssClass=b.cssClass+(" cke_browser_ie"+(b.quirks||b.version<7?"6":b.version));if(b.quirks)b.cssClass=b.cssClass+" cke_browser_iequirks"}if(b.gecko)if(f< +10900)b.cssClass=b.cssClass+" cke_browser_gecko18";else if(f<=11E3)b.cssClass=b.cssClass+" cke_browser_gecko19";if(b.air)b.cssClass=b.cssClass+" cke_browser_air";return b}()); +"unloaded"==CKEDITOR.status&&function(){CKEDITOR.event.implementOn(CKEDITOR);CKEDITOR.loadFullCore=function(){if(CKEDITOR.status!="basic_ready")CKEDITOR.loadFullCore._load=1;else{delete CKEDITOR.loadFullCore;var a=document.createElement("script");a.type="text/javascript";a.src=CKEDITOR.basePath+"ckeditor.js";document.getElementsByTagName("head")[0].appendChild(a)}};CKEDITOR.loadFullCoreTimeout=0;CKEDITOR.add=function(a){(this._.pending||(this._.pending=[])).push(a)};(function(){CKEDITOR.domReady(function(){var a= +CKEDITOR.loadFullCore,c=CKEDITOR.loadFullCoreTimeout;if(a){CKEDITOR.status="basic_ready";a&&a._load?a():c&&setTimeout(function(){CKEDITOR.loadFullCore&&CKEDITOR.loadFullCore()},c*1E3)}})})();CKEDITOR.status="basic_loaded"}();CKEDITOR.dom={}; +(function(){var a=[],c=CKEDITOR.env.gecko?"-moz-":CKEDITOR.env.webkit?"-webkit-":CKEDITOR.env.opera?"-o-":CKEDITOR.env.ie?"-ms-":"";CKEDITOR.on("reset",function(){a=[]});CKEDITOR.tools={arrayCompare:function(b,a){if(!b&&!a)return true;if(!b||!a||b.length!=a.length)return false;for(var e=0;e"+a+""):e.push('');return e.join("")},htmlEncode:function(b){return(""+b).replace(/&/g,"&").replace(/>/g,">").replace(//g,">")},getNextNumber:function(){var b=0;return function(){return++b}}(),getNextId:function(){return"cke_"+this.getNextNumber()},override:function(b,a){var e=a(b);e.prototype=b.prototype;return e},setTimeout:function(b,a,e,d,c){c||(c=window);e||(e=c);return c.setTimeout(function(){d?b.apply(e,[].concat(d)):b.apply(e)},a||0)},trim:function(){var b=/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g;return function(a){return a.replace(b,"")}}(),ltrim:function(){var b=/^[ \t\n\r]+/g; +return function(a){return a.replace(b,"")}}(),rtrim:function(){var b=/[ \t\n\r]+$/g;return function(a){return a.replace(b,"")}}(),indexOf:function(b,a){if(typeof a=="function")for(var e=0,d=b.length;e=0?b[e]:null},bind:function(b,a){return function(){return b.apply(a,arguments)}},createClass:function(b){var a=b.$, +e=b.base,d=b.privates||b._,c=b.proto,b=b.statics;!a&&(a=function(){e&&this.base.apply(this,arguments)});if(d)var l=a,a=function(){var b=this._||(this._={}),a;for(a in d){var f=d[a];b[a]=typeof f=="function"?CKEDITOR.tools.bind(f,this):f}l.apply(this,arguments)};if(e){a.prototype=this.prototypedCopy(e.prototype);a.prototype.constructor=a;a.base=e;a.baseProto=e.prototype;a.prototype.base=function(){this.base=e.prototype.base;e.apply(this,arguments);this.base=arguments.callee}}c&&this.extend(a.prototype, +c,true);b&&this.extend(a,b,true);return a},addFunction:function(b,f){return a.push(function(){return b.apply(f||this,arguments)})-1},removeFunction:function(b){a[b]=null},callFunction:function(b){var f=a[b];return f&&f.apply(window,Array.prototype.slice.call(arguments,1))},cssLength:function(){var b=/^-?\d+\.?\d*px$/,a;return function(e){a=CKEDITOR.tools.trim(e+"")+"px";return b.test(a)?a:e||""}}(),convertToPx:function(){var b;return function(a){if(!b){b=CKEDITOR.dom.element.createFromHtml('

    ', +CKEDITOR.document);CKEDITOR.document.getBody().append(b)}if(!/%$/.test(a)){b.setStyle("width",a);return b.$.clientWidth}return a}}(),repeat:function(b,a){return Array(a+1).join(b)},tryThese:function(){for(var b,a=0,e=arguments.length;a8)&&c)a=c+":"+a;return new CKEDITOR.dom.nodeList(this.$.getElementsByTagName(a))},getHead:function(){var a=this.$.getElementsByTagName("head")[0];return a= +a?new CKEDITOR.dom.element(a):this.getDocumentElement().append(new CKEDITOR.dom.element("head"),true)},getBody:function(){return new CKEDITOR.dom.element(this.$.body)},getDocumentElement:function(){return new CKEDITOR.dom.element(this.$.documentElement)},getWindow:function(){var a=new CKEDITOR.dom.window(this.$.parentWindow||this.$.defaultView);return(this.getWindow=function(){return a})()},write:function(a){this.$.open("text/html","replace");CKEDITOR.env.isCustomDomain()&&(this.$.domain=document.domain); +this.$.write(a);this.$.close()}});CKEDITOR.dom.nodeList=function(a){this.$=a};CKEDITOR.dom.nodeList.prototype={count:function(){return this.$.length},getItem:function(a){if(a<0||a>=this.$.length)return null;return(a=this.$[a])?new CKEDITOR.dom.node(a):null}};CKEDITOR.dom.element=function(a,c){typeof a=="string"&&(a=(c?c.$:document).createElement(a));CKEDITOR.dom.domObject.call(this,a)}; +CKEDITOR.dom.element.get=function(a){return(a=typeof a=="string"?document.getElementById(a)||document.getElementsByName(a)[0]:a)&&(a.$?a:new CKEDITOR.dom.element(a))};CKEDITOR.dom.element.prototype=new CKEDITOR.dom.node;CKEDITOR.dom.element.createFromHtml=function(a,c){var b=new CKEDITOR.dom.element("div",c);b.setHtml(a);return b.getFirst().remove()}; +CKEDITOR.dom.element.setMarker=function(a,c,b,f){var e=c.getCustomData("list_marker_id")||c.setCustomData("list_marker_id",CKEDITOR.tools.getNextNumber()).getCustomData("list_marker_id"),d=c.getCustomData("list_marker_names")||c.setCustomData("list_marker_names",{}).getCustomData("list_marker_names");a[e]=c;d[b]=1;return c.setCustomData(b,f)};CKEDITOR.dom.element.clearAllMarkers=function(a){for(var c in a)CKEDITOR.dom.element.clearMarkers(a,a[c],1)}; +CKEDITOR.dom.element.clearMarkers=function(a,c,b){var f=c.getCustomData("list_marker_names"),e=c.getCustomData("list_marker_id"),d;for(d in f)c.removeCustomData(d);c.removeCustomData("list_marker_names");if(b){c.removeCustomData("list_marker_id");delete a[e]}}; +(function(){function a(b){for(var a=0,e=0,d=c[b].length;e]*>/g, +""):b},getOuterHtml:function(){if(this.$.outerHTML)return this.$.outerHTML.replace(/<\?[^>]*>/,"");var b=this.$.ownerDocument.createElement("div");b.appendChild(this.$.cloneNode(true));return b.innerHTML},getClientRect:function(){var b=CKEDITOR.tools.extend({},this.$.getBoundingClientRect());!b.width&&(b.width=b.right-b.left);!b.height&&(b.height=b.bottom-b.top);return b},setHtml:function(){var b=function(b){return this.$.innerHTML=b};return CKEDITOR.env.ie&&CKEDITOR.env.version<9?function(b){try{return this.$.innerHTML= +b}catch(a){this.$.innerHTML="";var c=new CKEDITOR.dom.element("body",this.getDocument());c.$.innerHTML=b;for(c=c.getChildren();c.count();)this.append(c.getItem(0));return b}}:b}(),setText:function(b){CKEDITOR.dom.element.prototype.setText=this.$.innerText!=void 0?function(b){return this.$.innerText=b}:function(b){return this.$.textContent=b};return this.setText(b)},getAttribute:function(){var b=function(b){return this.$.getAttribute(b,2)};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)? +function(b){switch(b){case "class":b="className";break;case "http-equiv":b="httpEquiv";break;case "name":return this.$.name;case "tabindex":b=this.$.getAttribute(b,2);b!==0&&this.$.tabIndex===0&&(b=null);return b;case "checked":b=this.$.attributes.getNamedItem(b);return(b.specified?b.nodeValue:this.$.checked)?"checked":null;case "hspace":case "value":return this.$[b];case "style":return this.$.style.cssText;case "contenteditable":case "contentEditable":return this.$.attributes.getNamedItem("contentEditable").specified? +this.$.getAttribute("contentEditable"):null}return this.$.getAttribute(b,2)}:b}(),getChildren:function(){return new CKEDITOR.dom.nodeList(this.$.childNodes)},getComputedStyle:CKEDITOR.env.ie?function(b){return this.$.currentStyle[CKEDITOR.tools.cssStyleToDomStyle(b)]}:function(b){var a=this.getWindow().$.getComputedStyle(this.$,null);return a?a.getPropertyValue(b):""},getDtd:function(){var b=CKEDITOR.dtd[this.getName()];this.getDtd=function(){return b};return b},getElementsByTag:CKEDITOR.dom.document.prototype.getElementsByTag, +getTabIndex:CKEDITOR.env.ie?function(){var b=this.$.tabIndex;b===0&&(!CKEDITOR.dtd.$tabIndex[this.getName()]&&parseInt(this.getAttribute("tabindex"),10)!==0)&&(b=-1);return b}:CKEDITOR.env.webkit?function(){var b=this.$.tabIndex;if(b==void 0){b=parseInt(this.getAttribute("tabindex"),10);isNaN(b)&&(b=-1)}return b}:function(){return this.$.tabIndex},getText:function(){return this.$.textContent||this.$.innerText||""},getWindow:function(){return this.getDocument().getWindow()},getId:function(){return this.$.id|| +null},getNameAtt:function(){return this.$.name||null},getName:function(){var b=this.$.nodeName.toLowerCase();if(CKEDITOR.env.ie&&!(document.documentMode>8)){var a=this.$.scopeName;a!="HTML"&&(b=a.toLowerCase()+":"+b)}return(this.getName=function(){return b})()},getValue:function(){return this.$.value},getFirst:function(b){var a=this.$.firstChild;(a=a&&new CKEDITOR.dom.node(a))&&(b&&!b(a))&&(a=a.getNext(b));return a},getLast:function(b){var a=this.$.lastChild;(a=a&&new CKEDITOR.dom.node(a))&&(b&&!b(a))&& +(a=a.getPrevious(b));return a},getStyle:function(b){return this.$.style[CKEDITOR.tools.cssStyleToDomStyle(b)]},is:function(){var b=this.getName();if(typeof arguments[0]=="object")return!!arguments[0][b];for(var a=0;a0&&(a>2||!c[b[0].nodeName]||a==2&&!c[b[1].nodeName])},hasAttribute:function(){function b(b){b=this.$.attributes.getNamedItem(b); +return!(!b||!b.specified)}return CKEDITOR.env.ie&&CKEDITOR.env.version<8?function(a){return a=="name"?!!this.$.name:b.call(this,a)}:b}(),hide:function(){this.setStyle("display","none")},moveChildren:function(b,a){var c=this.$,b=b.$;if(c!=b){var d;if(a)for(;d=c.lastChild;)b.insertBefore(c.removeChild(d),b.firstChild);else for(;d=c.firstChild;)b.appendChild(c.removeChild(d))}},mergeSiblings:function(){function b(b,a,c){if(a&&a.type==CKEDITOR.NODE_ELEMENT){for(var j=[];a.data("cke-bookmark")||a.isEmptyInlineRemoveable();){j.push(a); +a=c?a.getNext():a.getPrevious();if(!a||a.type!=CKEDITOR.NODE_ELEMENT)return}if(b.isIdentical(a)){for(var l=c?b.getLast():b.getFirst();j.length;)j.shift().move(b,!c);a.moveChildren(b,!c);a.remove();l&&l.type==CKEDITOR.NODE_ELEMENT&&l.mergeSiblings()}}}return function(a){if(a===false||CKEDITOR.dtd.$removeEmpty[this.getName()]||this.is("a")){b(this,this.getNext(),true);b(this,this.getPrevious())}}}(),show:function(){this.setStyles({display:"",visibility:""})},setAttribute:function(){var b=function(b, +a){this.$.setAttribute(b,a);return this};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)?function(a,c){a=="class"?this.$.className=c:a=="style"?this.$.style.cssText=c:a=="tabindex"?this.$.tabIndex=c:a=="checked"?this.$.checked=c:a=="contenteditable"?b.call(this,"contentEditable",c):b.apply(this,arguments);return this}:CKEDITOR.env.ie8Compat&&CKEDITOR.env.secure?function(a,c){if(a=="src"&&c.match(/^http:\/\//))try{b.apply(this,arguments)}catch(d){}else b.apply(this,arguments); +return this}:b}(),setAttributes:function(b){for(var a in b)this.setAttribute(a,b[a]);return this},setValue:function(b){this.$.value=b;return this},removeAttribute:function(){var b=function(b){this.$.removeAttribute(b)};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)?function(b){b=="class"?b="className":b=="tabindex"?b="tabIndex":b=="contenteditable"&&(b="contentEditable");this.$.removeAttribute(b)}:b}(),removeAttributes:function(b){if(CKEDITOR.tools.isArray(b))for(var a=0;a< +b.length;a++)this.removeAttribute(b[a]);else for(a in b)b.hasOwnProperty(a)&&this.removeAttribute(a)},removeStyle:function(b){var a=this.$.style;if(!a.removeProperty&&(b=="border"||b=="margin"||b=="padding")){var c=["top","left","right","bottom"],d;b=="border"&&(d=["color","style","width"]);for(var a=[],j=0;j=100?"":"progid:DXImageTransform.Microsoft.Alpha(opacity="+b+")")}else this.setStyle("opacity",b)},unselectable:function(){this.setStyles(CKEDITOR.tools.cssVendorPrefix("user-select", +"none"));if(CKEDITOR.env.ie||CKEDITOR.env.opera){this.setAttribute("unselectable","on");for(var b,a=this.getElementsByTag("*"),c=0,d=a.count();c0)m(0,a===true?i:a===false?j:i<0?i:j);if(c&&(l<0||d>0))m(l<0?l:d,0)},setState:function(b,a,c){a=a||"cke";switch(b){case CKEDITOR.TRISTATE_ON:this.addClass(a+"_on");this.removeClass(a+"_off");this.removeClass(a+"_disabled");c&&this.setAttribute("aria-pressed",true);c&&this.removeAttribute("aria-disabled"); +break;case CKEDITOR.TRISTATE_DISABLED:this.addClass(a+"_disabled");this.removeClass(a+"_off");this.removeClass(a+"_on");c&&this.setAttribute("aria-disabled",true);c&&this.removeAttribute("aria-pressed");break;default:this.addClass(a+"_off");this.removeClass(a+"_on");this.removeClass(a+"_disabled");c&&this.removeAttribute("aria-pressed");c&&this.removeAttribute("aria-disabled")}},getFrameDocument:function(){var b=this.$;try{b.contentWindow.document}catch(a){b.src=b.src}return b&&new CKEDITOR.dom.document(b.contentWindow.document)}, +copyAttributes:function(b,a){for(var c=this.$.attributes,a=a||{},d=0;d=0&&a0&&c;)c=b(c,a.shift());else c=b(c,a);return c?new CKEDITOR.dom.node(c):null}}(),getChildCount:function(){return this.$.childNodes.length},disableContextMenu:function(){this.on("contextmenu", +function(b){b.data.getTarget().hasClass("cke_enable_context_menu")||b.data.preventDefault()})},getDirection:function(b){return b?this.getComputedStyle("direction")||this.getDirection()||this.getParent()&&this.getParent().getDirection(1)||this.getDocument().$.dir||"ltr":this.getStyle("direction")||this.getAttribute("dir")},data:function(b,a){b="data-"+b;if(a===void 0)return this.getAttribute(b);a===false?this.removeAttribute(b):this.setAttribute(b,a);return null},getEditor:function(){var b=CKEDITOR.instances, +a,c;for(a in b){c=b[a];if(c.element.equals(this)&&c.elementMode!=CKEDITOR.ELEMENT_MODE_APPENDTO)return c}return null}});var c={width:["border-left-width","border-right-width","padding-left","padding-right"],height:["border-top-width","border-bottom-width","padding-top","padding-bottom"]};CKEDITOR.dom.element.prototype.setSize=function(b,c,e){if(typeof c=="number"){if(e&&(!CKEDITOR.env.ie||!CKEDITOR.env.quirks))c=c-a.call(this,b);this.setStyle(b,c+"px")}};CKEDITOR.dom.element.prototype.getSize=function(b, +c){var e=Math.max(this.$["offset"+CKEDITOR.tools.capitalize(b)],this.$["client"+CKEDITOR.tools.capitalize(b)])||0;c&&(e=e-a.call(this,b));return e}})();CKEDITOR.dom.documentFragment=function(a){a=a||CKEDITOR.document;this.$=a.type==CKEDITOR.NODE_DOCUMENT?a.$.createDocumentFragment():a}; +CKEDITOR.tools.extend(CKEDITOR.dom.documentFragment.prototype,CKEDITOR.dom.element.prototype,{type:CKEDITOR.NODE_DOCUMENT_FRAGMENT,insertAfterNode:function(a){a=a.$;a.parentNode.insertBefore(this.$,a.nextSibling)}},!0,{append:1,appendBogus:1,getFirst:1,getLast:1,getParent:1,getNext:1,getPrevious:1,appendTo:1,moveChildren:1,insertBefore:1,insertAfterNode:1,replace:1,trim:1,type:1,ltrim:1,rtrim:1,getDocument:1,getChildCount:1,getChild:1,getChildren:1}); +(function(){function a(a,b){var c=this.range;if(this._.end)return null;if(!this._.start){this._.start=1;if(c.collapsed){this.end();return null}c.optimize()}var d,n=c.startContainer;d=c.endContainer;var r=c.startOffset,p=c.endOffset,g,h=this.guard,u=this.type,f=a?"getPreviousSourceNode":"getNextSourceNode";if(!a&&!this._.guardLTR){var k=d.type==CKEDITOR.NODE_ELEMENT?d:d.getParent(),e=d.type==CKEDITOR.NODE_ELEMENT?d.getChild(p):d.getNext();this._.guardLTR=function(a,b){return(!b||!k.equals(a))&&(!e|| +!a.equals(e))&&(a.type!=CKEDITOR.NODE_ELEMENT||!b||!a.equals(c.root))}}if(a&&!this._.guardRTL){var F=n.type==CKEDITOR.NODE_ELEMENT?n:n.getParent(),D=n.type==CKEDITOR.NODE_ELEMENT?r?n.getChild(r-1):null:n.getPrevious();this._.guardRTL=function(a,b){return(!b||!F.equals(a))&&(!D||!a.equals(D))&&(a.type!=CKEDITOR.NODE_ELEMENT||!b||!a.equals(c.root))}}var B=a?this._.guardRTL:this._.guardLTR;g=h?function(a,b){return B(a,b)===false?false:h(a,b)}:B;if(this.current)d=this.current[f](false,u,g);else{if(a)d.type== +CKEDITOR.NODE_ELEMENT&&(d=p>0?d.getChild(p-1):g(d,true)===false?null:d.getPreviousSourceNode(true,u,g));else{d=n;if(d.type==CKEDITOR.NODE_ELEMENT&&!(d=d.getChild(r)))d=g(n,true)===false?null:n.getNextSourceNode(true,u,g)}d&&g(d)===false&&(d=null)}for(;d&&!this._.end;){this.current=d;if(!this.evaluator||this.evaluator(d)!==false){if(!b)return d}else if(b&&this.evaluator)return false;d=d[f](false,u,g)}this.end();return this.current=null}function c(b){for(var c,d=null;c=a.call(this,b);)d=c;return d} +CKEDITOR.dom.walker=CKEDITOR.tools.createClass({$:function(a){this.range=a;this._={}},proto:{end:function(){this._.end=1},next:function(){return a.call(this)},previous:function(){return a.call(this,1)},checkForward:function(){return a.call(this,0,1)!==false},checkBackward:function(){return a.call(this,1,1)!==false},lastForward:function(){return c.call(this)},lastBackward:function(){return c.call(this,1)},reset:function(){delete this.current;this._={}}}});var b={block:1,"list-item":1,table:1,"table-row-group":1, +"table-header-group":1,"table-footer-group":1,"table-row":1,"table-column-group":1,"table-column":1,"table-cell":1,"table-caption":1};CKEDITOR.dom.element.prototype.isBlockBoundary=function(a){a=a?CKEDITOR.tools.extend({},CKEDITOR.dtd.$block,a||{}):CKEDITOR.dtd.$block;return this.getComputedStyle("float")=="none"&&b[this.getComputedStyle("display")]||a[this.getName()]};CKEDITOR.dom.walker.blockBoundary=function(a){return function(b){return!(b.type==CKEDITOR.NODE_ELEMENT&&b.isBlockBoundary(a))}};CKEDITOR.dom.walker.listItemBoundary= +function(){return this.blockBoundary({br:1})};CKEDITOR.dom.walker.bookmark=function(a,b){function c(a){return a&&a.getName&&a.getName()=="span"&&a.data("cke-bookmark")}return function(d){var n,r;n=d&&d.type!=CKEDITOR.NODE_ELEMENT&&(r=d.getParent())&&c(r);n=a?n:n||c(d);return!!(b^n)}};CKEDITOR.dom.walker.whitespaces=function(a){return function(b){var c;b&&b.type==CKEDITOR.NODE_TEXT&&(c=!CKEDITOR.tools.trim(b.getText())||CKEDITOR.env.webkit&&b.getText()=="​");return!!(a^c)}};CKEDITOR.dom.walker.invisible= +function(a){var b=CKEDITOR.dom.walker.whitespaces();return function(c){if(b(c))c=1;else{c.type==CKEDITOR.NODE_TEXT&&(c=c.getParent());c=!c.$.offsetHeight}return!!(a^c)}};CKEDITOR.dom.walker.nodeType=function(a,b){return function(c){return!!(b^c.type==a)}};CKEDITOR.dom.walker.bogus=function(a){function b(a){return!e(a)&&!d(a)}return function(c){var d=!CKEDITOR.env.ie?c.is&&c.is("br"):c.getText&&f.test(c.getText());if(d){d=c.getParent();c=c.getNext(b);d=d.isBlockBoundary()&&(!c||c.type==CKEDITOR.NODE_ELEMENT&& +c.isBlockBoundary())}return!!(a^d)}};var f=/^[\t\r\n ]*(?: |\xa0)$/,e=CKEDITOR.dom.walker.whitespaces(),d=CKEDITOR.dom.walker.bookmark();CKEDITOR.dom.element.prototype.getBogus=function(){var a=this;do a=a.getPreviousSourceNode();while(d(a)||e(a)||a.type==CKEDITOR.NODE_ELEMENT&&a.getName()in CKEDITOR.dtd.$inline&&!(a.getName()in CKEDITOR.dtd.$empty));return a&&(!CKEDITOR.env.ie?a.is&&a.is("br"):a.getText&&f.test(a.getText()))?a:false}})(); +CKEDITOR.dom.range=function(a){this.endOffset=this.endContainer=this.startOffset=this.startContainer=null;this.collapsed=true;var c=a instanceof CKEDITOR.dom.document;this.document=c?a:a.getDocument();this.root=c?a.getBody():a}; +(function(){function a(){var a=false,b=CKEDITOR.dom.walker.whitespaces(),c=CKEDITOR.dom.walker.bookmark(true),g=CKEDITOR.dom.walker.bogus();return function(h){if(c(h)||b(h))return true;if(g(h)&&!a)return a=true;return h.type==CKEDITOR.NODE_TEXT&&(h.hasAscendant("pre")||CKEDITOR.tools.trim(h.getText()).length)||h.type==CKEDITOR.NODE_ELEMENT&&!h.is(d)?false:true}}function c(a){var b=CKEDITOR.dom.walker.whitespaces(),c=CKEDITOR.dom.walker.bookmark(1);return function(g){return c(g)||b(g)?true:!a&&j(g)|| +g.type==CKEDITOR.NODE_ELEMENT&&g.is(CKEDITOR.dtd.$removeEmpty)}}function b(a){return!l(a)&&!i(a)}var f=function(a){a.collapsed=a.startContainer&&a.endContainer&&a.startContainer.equals(a.endContainer)&&a.startOffset==a.endOffset},e=function(a,b,c,g){a.optimizeBookmark();var h=a.startContainer,d=a.endContainer,f=a.startOffset,k=a.endOffset,e,j;if(d.type==CKEDITOR.NODE_TEXT)d=d.split(k);else if(d.getChildCount()>0)if(k>=d.getChildCount()){d=d.append(a.document.createText(""));j=true}else d=d.getChild(k); +if(h.type==CKEDITOR.NODE_TEXT){h.split(f);h.equals(d)&&(d=h.getNext())}else if(f)if(f>=h.getChildCount()){h=h.append(a.document.createText(""));e=true}else h=h.getChild(f).getPrevious();else{h=h.append(a.document.createText(""),1);e=true}var f=h.getParents(),k=d.getParents(),l,i,q;for(l=0;l0&&!s.equals(d)&&(A=m.append(s.clone()));if(!f[c]||s.$.parentNode!=f[c].$.parentNode)for(s=s.getPrevious();s;){if(s.equals(f[c])||s.equals(h))break;v=s.getPrevious();if(b==2)m.$.insertBefore(s.$.cloneNode(true),m.$.firstChild);else{s.remove();b==1&&m.$.insertBefore(s.$,m.$.firstChild)}s=v}m&&(m=A)}if(b==2){i=a.startContainer;if(i.type==CKEDITOR.NODE_TEXT){i.$.data=i.$.data+i.$.nextSibling.data; +i.$.parentNode.removeChild(i.$.nextSibling)}a=a.endContainer;if(a.type==CKEDITOR.NODE_TEXT&&a.$.nextSibling){a.$.data=a.$.data+a.$.nextSibling.data;a.$.parentNode.removeChild(a.$.nextSibling)}}else{if(i&&q&&(h.$.parentNode!=i.$.parentNode||d.$.parentNode!=q.$.parentNode)){b=q.getIndex();e&&q.$.parentNode==h.$.parentNode&&b--;if(g&&i.type==CKEDITOR.NODE_ELEMENT){g=CKEDITOR.dom.element.createFromHtml(' ',a.document);g.insertAfter(i);i.mergeSiblings(false); +a.moveToBookmark({startNode:g})}else a.setStart(q.getParent(),b)}a.collapse(true)}e&&h.remove();j&&d.$.parentNode&&d.remove()},d={abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,"var":1},j=CKEDITOR.dom.walker.bogus(),l=new CKEDITOR.dom.walker.whitespaces,i=new CKEDITOR.dom.walker.bookmark,m=/^[\t\r\n ]*(?: |\xa0)$/;CKEDITOR.dom.range.prototype={clone:function(){var a=new CKEDITOR.dom.range(this.root); +a.startContainer=this.startContainer;a.startOffset=this.startOffset;a.endContainer=this.endContainer;a.endOffset=this.endOffset;a.collapsed=this.collapsed;return a},collapse:function(a){if(a){this.endContainer=this.startContainer;this.endOffset=this.startOffset}else{this.startContainer=this.endContainer;this.startOffset=this.endOffset}this.collapsed=true},cloneContents:function(){var a=new CKEDITOR.dom.documentFragment(this.document);this.collapsed||e(this,2,a);return a},deleteContents:function(a){this.collapsed|| +e(this,0,null,a)},extractContents:function(a){var b=new CKEDITOR.dom.documentFragment(this.document);this.collapsed||e(this,1,b,a);return b},createBookmark:function(a){var b,c,g,h,d=this.collapsed;b=this.document.createElement("span");b.data("cke-bookmark",1);b.setStyle("display","none");b.setHtml(" ");if(a){g="cke_bm_"+CKEDITOR.tools.getNextNumber();b.setAttribute("id",g+(d?"C":"S"))}if(!d){c=b.clone();c.setHtml(" ");a&&c.setAttribute("id",g+"E");h=this.clone();h.collapse();h.insertNode(c)}h= +this.clone();h.collapse(true);h.insertNode(b);if(c){this.setStartAfter(b);this.setEndBefore(c)}else this.moveToPosition(b,CKEDITOR.POSITION_AFTER_END);return{startNode:a?g+(d?"C":"S"):b,endNode:a?g+"E":c,serializable:a,collapsed:d}},createBookmark2:function(a){var b=this.startContainer,c=this.endContainer,g=this.startOffset,h=this.endOffset,d=this.collapsed,f,k;if(!b||!c)return{start:0,end:0};if(a){if(b.type==CKEDITOR.NODE_ELEMENT){if((f=b.getChild(g))&&f.type==CKEDITOR.NODE_TEXT&&g>0&&f.getPrevious().type== +CKEDITOR.NODE_TEXT){b=f;g=0}f&&f.type==CKEDITOR.NODE_ELEMENT&&(g=f.getIndex(1))}for(;b.type==CKEDITOR.NODE_TEXT&&(k=b.getPrevious())&&k.type==CKEDITOR.NODE_TEXT;){b=k;g=g+k.getLength()}if(!d){if(c.type==CKEDITOR.NODE_ELEMENT){if((f=c.getChild(h))&&f.type==CKEDITOR.NODE_TEXT&&h>0&&f.getPrevious().type==CKEDITOR.NODE_TEXT){c=f;h=0}f&&f.type==CKEDITOR.NODE_ELEMENT&&(h=f.getIndex(1))}for(;c.type==CKEDITOR.NODE_TEXT&&(k=c.getPrevious())&&k.type==CKEDITOR.NODE_TEXT;){c=k;h=h+k.getLength()}}}return{start:b.getAddress(a), +end:d?null:c.getAddress(a),startOffset:g,endOffset:h,normalized:a,collapsed:d,is2:true}},moveToBookmark:function(a){if(a.is2){var b=this.document.getByAddress(a.start,a.normalized),c=a.startOffset,g=a.end&&this.document.getByAddress(a.end,a.normalized),a=a.endOffset;this.setStart(b,c);g?this.setEnd(g,a):this.collapse(true)}else{b=(c=a.serializable)?this.document.getById(a.startNode):a.startNode;a=c?this.document.getById(a.endNode):a.endNode;this.setStartBefore(b);b.remove();if(a){this.setEndBefore(a); +a.remove()}else this.collapse(true)}},getBoundaryNodes:function(){var a=this.startContainer,b=this.endContainer,c=this.startOffset,g=this.endOffset,h;if(a.type==CKEDITOR.NODE_ELEMENT){h=a.getChildCount();if(h>c)a=a.getChild(c);else if(h<1)a=a.getPreviousSourceNode();else{for(a=a.$;a.lastChild;)a=a.lastChild;a=new CKEDITOR.dom.node(a);a=a.getNextSourceNode()||a}}if(b.type==CKEDITOR.NODE_ELEMENT){h=b.getChildCount();if(h>g)b=b.getChild(g).getPreviousSourceNode(true);else if(h<1)b=b.getPreviousSourceNode(); +else{for(b=b.$;b.lastChild;)b=b.lastChild;b=new CKEDITOR.dom.node(b)}}a.getPosition(b)&CKEDITOR.POSITION_FOLLOWING&&(a=b);return{startNode:a,endNode:b}},getCommonAncestor:function(a,b){var c=this.startContainer,g=this.endContainer,c=c.equals(g)?a&&c.type==CKEDITOR.NODE_ELEMENT&&this.startOffset==this.endOffset-1?c.getChild(this.startOffset):c:c.getCommonAncestor(g);return b&&!c.is?c.getParent():c},optimize:function(){var a=this.startContainer,b=this.startOffset;a.type!=CKEDITOR.NODE_ELEMENT&&(b?b>= +a.getLength()&&this.setStartAfter(a):this.setStartBefore(a));a=this.endContainer;b=this.endOffset;a.type!=CKEDITOR.NODE_ELEMENT&&(b?b>=a.getLength()&&this.setEndAfter(a):this.setEndBefore(a))},optimizeBookmark:function(){var a=this.startContainer,b=this.endContainer;a.is&&(a.is("span")&&a.data("cke-bookmark"))&&this.setStartAt(a,CKEDITOR.POSITION_BEFORE_START);b&&(b.is&&b.is("span")&&b.data("cke-bookmark"))&&this.setEndAt(b,CKEDITOR.POSITION_AFTER_END)},trim:function(a,b){var c=this.startContainer, +g=this.startOffset,h=this.collapsed;if((!a||h)&&c&&c.type==CKEDITOR.NODE_TEXT){if(g)if(g>=c.getLength()){g=c.getIndex()+1;c=c.getParent()}else{var d=c.split(g),g=c.getIndex()+1,c=c.getParent();if(this.startContainer.equals(this.endContainer))this.setEnd(d,this.endOffset-this.startOffset);else if(c.equals(this.endContainer))this.endOffset=this.endOffset+1}else{g=c.getIndex();c=c.getParent()}this.setStart(c,g);if(h){this.collapse(true);return}}c=this.endContainer;g=this.endOffset;if(!b&&!h&&c&&c.type== +CKEDITOR.NODE_TEXT){if(g){g>=c.getLength()||c.split(g);g=c.getIndex()+1}else g=c.getIndex();c=c.getParent();this.setEnd(c,g)}},enlarge:function(a,b){switch(a){case CKEDITOR.ENLARGE_INLINE:var c=1;case CKEDITOR.ENLARGE_ELEMENT:if(this.collapsed)break;var g=this.getCommonAncestor(),h=this.root,d,f,k,e,j,l=false,i,q;i=this.startContainer;q=this.startOffset;if(i.type==CKEDITOR.NODE_TEXT){if(q){i=!CKEDITOR.tools.trim(i.substring(0,q)).length&&i;l=!!i}if(i&&!(e=i.getPrevious()))k=i.getParent()}else{q&& +(e=i.getChild(q-1)||i.getLast());e||(k=i)}for(;k||e;){if(k&&!e){!j&&k.equals(g)&&(j=true);if(c?k.isBlockBoundary():!h.contains(k))break;if(!l||k.getComputedStyle("display")!="inline"){l=false;j?d=k:this.setStartBefore(k)}e=k.getPrevious()}for(;e;){i=false;if(e.type==CKEDITOR.NODE_COMMENT)e=e.getPrevious();else{if(e.type==CKEDITOR.NODE_TEXT){q=e.getText();/[^\s\ufeff]/.test(q)&&(e=null);i=/[\s\ufeff]$/.test(q)}else if((e.$.offsetWidth>0||b&&e.is("br"))&&!e.data("cke-bookmark"))if(l&&CKEDITOR.dtd.$removeEmpty[e.getName()]){q= +e.getText();if(/[^\s\ufeff]/.test(q))e=null;else for(var m=e.$.getElementsByTagName("*"),s=0,A;A=m[s++];)if(!CKEDITOR.dtd.$removeEmpty[A.nodeName.toLowerCase()]){e=null;break}e&&(i=!!q.length)}else e=null;i&&(l?j?d=k:k&&this.setStartBefore(k):l=true);if(e){i=e.getPrevious();if(!k&&!i){k=e;e=null;break}e=i}else k=null}}k&&(k=k.getParent())}i=this.endContainer;q=this.endOffset;k=e=null;j=l=false;if(i.type==CKEDITOR.NODE_TEXT){i=!CKEDITOR.tools.trim(i.substring(q)).length&&i;l=!(i&&i.getLength());if(i&& +!(e=i.getNext()))k=i.getParent()}else(e=i.getChild(q))||(k=i);for(;k||e;){if(k&&!e){!j&&k.equals(g)&&(j=true);if(c?k.isBlockBoundary():!h.contains(k))break;if(!l||k.getComputedStyle("display")!="inline"){l=false;j?f=k:k&&this.setEndAfter(k)}e=k.getNext()}for(;e;){i=false;if(e.type==CKEDITOR.NODE_TEXT){q=e.getText();/[^\s\ufeff]/.test(q)&&(e=null);i=/^[\s\ufeff]/.test(q)}else if(e.type==CKEDITOR.NODE_ELEMENT){if((e.$.offsetWidth>0||b&&e.is("br"))&&!e.data("cke-bookmark"))if(l&&CKEDITOR.dtd.$removeEmpty[e.getName()]){q= +e.getText();if(/[^\s\ufeff]/.test(q))e=null;else{m=e.$.getElementsByTagName("*");for(s=0;A=m[s++];)if(!CKEDITOR.dtd.$removeEmpty[A.nodeName.toLowerCase()]){e=null;break}}e&&(i=!!q.length)}else e=null}else i=1;i&&l&&(j?f=k:this.setEndAfter(k));if(e){i=e.getNext();if(!k&&!i){k=e;e=null;break}e=i}else k=null}k&&(k=k.getParent())}if(d&&f){g=d.contains(f)?f:d;this.setStartBefore(g);this.setEndAfter(g)}break;case CKEDITOR.ENLARGE_BLOCK_CONTENTS:case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:k=new CKEDITOR.dom.range(this.root); +h=this.root;k.setStartAt(h,CKEDITOR.POSITION_AFTER_START);k.setEnd(this.startContainer,this.startOffset);k=new CKEDITOR.dom.walker(k);var v,o,x=CKEDITOR.dom.walker.blockBoundary(a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS?{br:1}:null),I=function(a){var b=x(a);b||(v=a);return b},c=function(a){var b=I(a);!b&&(a.is&&a.is("br"))&&(o=a);return b};k.guard=I;k=k.lastBackward();v=v||h;this.setStartAt(v,!v.is("br")&&(!k&&this.checkStartOfBlock()||k&&v.contains(k))?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_AFTER_END); +if(a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS){k=this.clone();k=new CKEDITOR.dom.walker(k);var G=CKEDITOR.dom.walker.whitespaces(),C=CKEDITOR.dom.walker.bookmark();k.evaluator=function(a){return!G(a)&&!C(a)};if((k=k.previous())&&k.type==CKEDITOR.NODE_ELEMENT&&k.is("br"))break}k=this.clone();k.collapse();k.setEndAt(h,CKEDITOR.POSITION_BEFORE_END);k=new CKEDITOR.dom.walker(k);k.guard=a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS?c:I;v=null;k=k.lastForward();v=v||h;this.setEndAt(v,!k&&this.checkEndOfBlock()||k&& +v.contains(k)?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_BEFORE_START);o&&this.setEndAfter(o)}},shrink:function(a,b,c){if(!this.collapsed){var a=a||CKEDITOR.SHRINK_TEXT,g=this.clone(),h=this.startContainer,d=this.endContainer,e=this.startOffset,f=this.endOffset,j=1,i=1;if(h&&h.type==CKEDITOR.NODE_TEXT)if(e)if(e>=h.getLength())g.setStartAfter(h);else{g.setStartBefore(h);j=0}else g.setStartBefore(h);if(d&&d.type==CKEDITOR.NODE_TEXT)if(f)if(f>=d.getLength())g.setEndAfter(d);else{g.setEndAfter(d); +i=0}else g.setEndBefore(d);var g=new CKEDITOR.dom.walker(g),l=CKEDITOR.dom.walker.bookmark();g.evaluator=function(b){return b.type==(a==CKEDITOR.SHRINK_ELEMENT?CKEDITOR.NODE_ELEMENT:CKEDITOR.NODE_TEXT)};var m;g.guard=function(b,g){if(l(b))return true;if(a==CKEDITOR.SHRINK_ELEMENT&&b.type==CKEDITOR.NODE_TEXT||g&&b.equals(m)||c===false&&b.type==CKEDITOR.NODE_ELEMENT&&b.isBlockBoundary())return false;!g&&b.type==CKEDITOR.NODE_ELEMENT&&(m=b);return true};if(j)(h=g[a==CKEDITOR.SHRINK_ELEMENT?"lastForward": +"next"]())&&this.setStartAt(h,b?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_BEFORE_START);if(i){g.reset();(g=g[a==CKEDITOR.SHRINK_ELEMENT?"lastBackward":"previous"]())&&this.setEndAt(g,b?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_AFTER_END)}return!(!j&&!i)}},insertNode:function(a){this.optimizeBookmark();this.trim(false,true);var b=this.startContainer,c=b.getChild(this.startOffset);c?a.insertBefore(c):b.append(a);a.getParent()&&a.getParent().equals(this.endContainer)&&this.endOffset++;this.setStartBefore(a)}, +moveToPosition:function(a,b){this.setStartAt(a,b);this.collapse(true)},moveToRange:function(a){this.setStart(a.startContainer,a.startOffset);this.setEnd(a.endContainer,a.endOffset)},selectNodeContents:function(a){this.setStart(a,0);this.setEnd(a,a.type==CKEDITOR.NODE_TEXT?a.getLength():a.getChildCount())},setStart:function(a,b){if(a.type==CKEDITOR.NODE_ELEMENT&&CKEDITOR.dtd.$empty[a.getName()]){b=a.getIndex();a=a.getParent()}this.startContainer=a;this.startOffset=b;if(!this.endContainer){this.endContainer= +a;this.endOffset=b}f(this)},setEnd:function(a,b){if(a.type==CKEDITOR.NODE_ELEMENT&&CKEDITOR.dtd.$empty[a.getName()]){b=a.getIndex()+1;a=a.getParent()}this.endContainer=a;this.endOffset=b;if(!this.startContainer){this.startContainer=a;this.startOffset=b}f(this)},setStartAfter:function(a){this.setStart(a.getParent(),a.getIndex()+1)},setStartBefore:function(a){this.setStart(a.getParent(),a.getIndex())},setEndAfter:function(a){this.setEnd(a.getParent(),a.getIndex()+1)},setEndBefore:function(a){this.setEnd(a.getParent(), +a.getIndex())},setStartAt:function(a,b){switch(b){case CKEDITOR.POSITION_AFTER_START:this.setStart(a,0);break;case CKEDITOR.POSITION_BEFORE_END:a.type==CKEDITOR.NODE_TEXT?this.setStart(a,a.getLength()):this.setStart(a,a.getChildCount());break;case CKEDITOR.POSITION_BEFORE_START:this.setStartBefore(a);break;case CKEDITOR.POSITION_AFTER_END:this.setStartAfter(a)}f(this)},setEndAt:function(a,b){switch(b){case CKEDITOR.POSITION_AFTER_START:this.setEnd(a,0);break;case CKEDITOR.POSITION_BEFORE_END:a.type== +CKEDITOR.NODE_TEXT?this.setEnd(a,a.getLength()):this.setEnd(a,a.getChildCount());break;case CKEDITOR.POSITION_BEFORE_START:this.setEndBefore(a);break;case CKEDITOR.POSITION_AFTER_END:this.setEndAfter(a)}f(this)},fixBlock:function(a,b){var c=this.createBookmark(),g=this.document.createElement(b);this.collapse(a);this.enlarge(CKEDITOR.ENLARGE_BLOCK_CONTENTS);this.extractContents().appendTo(g);g.trim();CKEDITOR.env.ie||g.appendBogus();this.insertNode(g);this.moveToBookmark(c);return g},splitBlock:function(a){var b= +new CKEDITOR.dom.elementPath(this.startContainer,this.root),c=new CKEDITOR.dom.elementPath(this.endContainer,this.root),g=b.block,h=c.block,d=null;if(!b.blockLimit.equals(c.blockLimit))return null;if(a!="br"){if(!g){g=this.fixBlock(true,a);h=(new CKEDITOR.dom.elementPath(this.endContainer,this.root)).block}h||(h=this.fixBlock(false,a))}a=g&&this.checkStartOfBlock();b=h&&this.checkEndOfBlock();this.deleteContents();if(g&&g.equals(h))if(b){d=new CKEDITOR.dom.elementPath(this.startContainer,this.root); +this.moveToPosition(h,CKEDITOR.POSITION_AFTER_END);h=null}else if(a){d=new CKEDITOR.dom.elementPath(this.startContainer,this.root);this.moveToPosition(g,CKEDITOR.POSITION_BEFORE_START);g=null}else{h=this.splitElement(g);!CKEDITOR.env.ie&&!g.is("ul","ol")&&g.appendBogus()}return{previousBlock:g,nextBlock:h,wasStartOfBlock:a,wasEndOfBlock:b,elementPath:d}},splitElement:function(a){if(!this.collapsed)return null;this.setEndAt(a,CKEDITOR.POSITION_BEFORE_END);var b=this.extractContents(),c=a.clone(false); +b.appendTo(c);c.insertAfter(a);this.moveToPosition(a,CKEDITOR.POSITION_AFTER_END);return c},removeEmptyBlocksAtEnd:function(){function a(g){return function(a){return b(a)||(c(a)||a.type==CKEDITOR.NODE_ELEMENT&&a.isEmptyInlineRemoveable())||g.is("table")&&a.is("caption")?false:true}}var b=CKEDITOR.dom.walker.whitespaces(),c=CKEDITOR.dom.walker.bookmark(false);return function(b){for(var c=this.createBookmark(),d=this[b?"endPath":"startPath"](),e=d.block||d.blockLimit,f;e&&!e.equals(d.root)&&!e.getFirst(a(e));){f= +e.getParent();this[b?"setEndAt":"setStartAt"](e,CKEDITOR.POSITION_AFTER_END);e.remove(1);e=f}this.moveToBookmark(c)}}(),startPath:function(){return new CKEDITOR.dom.elementPath(this.startContainer,this.root)},endPath:function(){return new CKEDITOR.dom.elementPath(this.endContainer,this.root)},checkBoundaryOfElement:function(a,b){var d=b==CKEDITOR.START,g=this.clone();g.collapse(d);g[d?"setStartAt":"setEndAt"](a,d?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_BEFORE_END);g=new CKEDITOR.dom.walker(g); +g.evaluator=c(d);return g[d?"checkBackward":"checkForward"]()},checkStartOfBlock:function(){var b=this.startContainer,c=this.startOffset;if(CKEDITOR.env.ie&&c&&b.type==CKEDITOR.NODE_TEXT){b=CKEDITOR.tools.ltrim(b.substring(0,c));m.test(b)&&this.trim(0,1)}this.trim();b=new CKEDITOR.dom.elementPath(this.startContainer,this.root);c=this.clone();c.collapse(true);c.setStartAt(b.block||b.blockLimit,CKEDITOR.POSITION_AFTER_START);b=new CKEDITOR.dom.walker(c);b.evaluator=a();return b.checkBackward()},checkEndOfBlock:function(){var b= +this.endContainer,c=this.endOffset;if(CKEDITOR.env.ie&&b.type==CKEDITOR.NODE_TEXT){b=CKEDITOR.tools.rtrim(b.substring(c));m.test(b)&&this.trim(1,0)}this.trim();b=new CKEDITOR.dom.elementPath(this.endContainer,this.root);c=this.clone();c.collapse(false);c.setEndAt(b.block||b.blockLimit,CKEDITOR.POSITION_BEFORE_END);b=new CKEDITOR.dom.walker(c);b.evaluator=a();return b.checkForward()},getPreviousNode:function(a,b,c){var d=this.clone();d.collapse(1);d.setStartAt(c||this.root,CKEDITOR.POSITION_AFTER_START); +c=new CKEDITOR.dom.walker(d);c.evaluator=a;c.guard=b;return c.previous()},getNextNode:function(a,b,c){var d=this.clone();d.collapse();d.setEndAt(c||this.root,CKEDITOR.POSITION_BEFORE_END);c=new CKEDITOR.dom.walker(d);c.evaluator=a;c.guard=b;return c.next()},checkReadOnly:function(){function a(b,c){for(;b;){if(b.type==CKEDITOR.NODE_ELEMENT){if(b.getAttribute("contentEditable")=="false"&&!b.data("cke-editable"))return 0;if(b.is("html")||b.getAttribute("contentEditable")=="true"&&(b.contains(c)||b.equals(c)))break}b= +b.getParent()}return 1}return function(){var b=this.startContainer,c=this.endContainer;return!(a(b,c)&&a(c,b))}}(),moveToElementEditablePosition:function(a,c){if(a.type==CKEDITOR.NODE_ELEMENT&&!a.isEditable(false)){this.moveToPosition(a,c?CKEDITOR.POSITION_AFTER_END:CKEDITOR.POSITION_BEFORE_START);return true}for(var d=0;a;){if(a.type==CKEDITOR.NODE_TEXT){c&&this.checkEndOfBlock()&&m.test(a.getText())?this.moveToPosition(a,CKEDITOR.POSITION_BEFORE_START):this.moveToPosition(a,c?CKEDITOR.POSITION_AFTER_END: +CKEDITOR.POSITION_BEFORE_START);d=1;break}if(a.type==CKEDITOR.NODE_ELEMENT)if(a.isEditable()){this.moveToPosition(a,c?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_AFTER_START);d=1}else c&&(a.is("br")&&this.checkEndOfBlock())&&this.moveToPosition(a,CKEDITOR.POSITION_BEFORE_START);var g=a,h=d,e=void 0;g.type==CKEDITOR.NODE_ELEMENT&&g.isEditable(false)&&(e=g[c?"getLast":"getFirst"](b));!h&&!e&&(e=g[c?"getPrevious":"getNext"](b));a=e}return!!d},moveToElementEditStart:function(a){return this.moveToElementEditablePosition(a)}, +moveToElementEditEnd:function(a){return this.moveToElementEditablePosition(a,true)},getEnclosedNode:function(){var a=this.clone();a.optimize();if(a.startContainer.type!=CKEDITOR.NODE_ELEMENT||a.endContainer.type!=CKEDITOR.NODE_ELEMENT)return null;var a=new CKEDITOR.dom.walker(a),b=CKEDITOR.dom.walker.bookmark(false,true),c=CKEDITOR.dom.walker.whitespaces(true);a.evaluator=function(a){return c(a)&&b(a)};var d=a.next();a.reset();return d&&d.equals(a.previous())?d:null},getTouchedStartNode:function(){var a= +this.startContainer;return this.collapsed||a.type!=CKEDITOR.NODE_ELEMENT?a:a.getChild(this.startOffset)||a},getTouchedEndNode:function(){var a=this.endContainer;return this.collapsed||a.type!=CKEDITOR.NODE_ELEMENT?a:a.getChild(this.endOffset-1)||a},scrollIntoView:function(){var a=new CKEDITOR.dom.element.createFromHtml(" ",this.document),b,c,d,h=this.clone();h.optimize();if(d=h.startContainer.type==CKEDITOR.NODE_TEXT){c=h.startContainer.getText();b=h.startContainer.split(h.startOffset); +a.insertAfter(h.startContainer)}else h.insertNode(a);a.scrollIntoView();if(d){h.startContainer.setText(c);b.remove()}a.remove()}}})();CKEDITOR.POSITION_AFTER_START=1;CKEDITOR.POSITION_BEFORE_END=2;CKEDITOR.POSITION_BEFORE_START=3;CKEDITOR.POSITION_AFTER_END=4;CKEDITOR.ENLARGE_ELEMENT=1;CKEDITOR.ENLARGE_BLOCK_CONTENTS=2;CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS=3;CKEDITOR.ENLARGE_INLINE=4;CKEDITOR.START=1;CKEDITOR.END=2;CKEDITOR.SHRINK_ELEMENT=1;CKEDITOR.SHRINK_TEXT=2; +(function(){function a(a){if(!(arguments.length<1)){this.range=a;this.forceBrBreak=0;this.enlargeBr=1;this.enforceRealBlocks=0;this._||(this._={})}}function c(a,b,c){for(a=a.getNextSourceNode(b,null,c);!f(a);)a=a.getNextSourceNode(b,null,c);return a}var b=/^[\r\n\t ]+$/,f=CKEDITOR.dom.walker.bookmark(false,true),e=CKEDITOR.dom.walker.whitespaces(true),d=function(a){return f(a)&&e(a)};a.prototype={getNextParagraph:function(a){a=a||"p";if(!CKEDITOR.dtd[this.range.root.getName()][a])return null;var e, +i,m,n,r,p;if(!this._.started){i=this.range.clone();i.shrink(CKEDITOR.NODE_ELEMENT,true);n=i.endContainer.hasAscendant("pre",true)||i.startContainer.hasAscendant("pre",true);i.enlarge(this.forceBrBreak&&!n||!this.enlargeBr?CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:CKEDITOR.ENLARGE_BLOCK_CONTENTS);if(!i.collapsed){n=new CKEDITOR.dom.walker(i.clone());var g=CKEDITOR.dom.walker.bookmark(true,true);n.evaluator=g;this._.nextNode=n.next();n=new CKEDITOR.dom.walker(i.clone());n.evaluator=g;n=n.previous();this._.lastNode= +n.getNextSourceNode(true);if(this._.lastNode&&this._.lastNode.type==CKEDITOR.NODE_TEXT&&!CKEDITOR.tools.trim(this._.lastNode.getText())&&this._.lastNode.getParent().isBlockBoundary()){g=this.range.clone();g.moveToPosition(this._.lastNode,CKEDITOR.POSITION_AFTER_END);if(g.checkEndOfBlock()){g=new CKEDITOR.dom.elementPath(g.endContainer,g.root);this._.lastNode=(g.block||g.blockLimit).getNextSourceNode(true)}}if(!this._.lastNode){this._.lastNode=this._.docEndMarker=i.document.createText("");this._.lastNode.insertAfter(n)}i= +null}this._.started=1}g=this._.nextNode;n=this._.lastNode;for(this._.nextNode=null;g;){var h=0,u=g.hasAscendant("pre"),w=g.type!=CKEDITOR.NODE_ELEMENT,k=0;if(w)g.type==CKEDITOR.NODE_TEXT&&b.test(g.getText())&&(w=0);else{var t=g.getName();if(g.isBlockBoundary(this.forceBrBreak&&!u&&{br:1})){if(t=="br")w=1;else if(!i&&!g.getChildCount()&&t!="hr"){e=g;m=g.equals(n);break}if(i){i.setEndAt(g,CKEDITOR.POSITION_BEFORE_START);if(t!="br")this._.nextNode=g}h=1}else{if(g.getFirst()){if(!i){i=this.range.clone(); +i.setStartAt(g,CKEDITOR.POSITION_BEFORE_START)}g=g.getFirst();continue}w=1}}if(w&&!i){i=this.range.clone();i.setStartAt(g,CKEDITOR.POSITION_BEFORE_START)}m=(!h||w)&&g.equals(n);if(i&&!h)for(;!g.getNext(d)&&!m;){t=g.getParent();if(t.isBlockBoundary(this.forceBrBreak&&!u&&{br:1})){h=1;w=0;m||t.equals(n);i.setEndAt(t,CKEDITOR.POSITION_BEFORE_END);break}g=t;w=1;m=g.equals(n);k=1}w&&i.setEndAt(g,CKEDITOR.POSITION_AFTER_END);g=c(g,k,n);if((m=!g)||h&&i)break}if(!e){if(!i){this._.docEndMarker&&this._.docEndMarker.remove(); +return this._.nextNode=null}e=new CKEDITOR.dom.elementPath(i.startContainer,i.root);g=e.blockLimit;h={div:1,th:1,td:1};e=e.block;if(!e&&g&&!this.enforceRealBlocks&&h[g.getName()]&&i.checkStartOfBlock()&&i.checkEndOfBlock()&&!g.equals(i.root))e=g;else if(!e||this.enforceRealBlocks&&e.getName()=="li"){e=this.range.document.createElement(a);i.extractContents().appendTo(e);e.trim();i.insertNode(e);r=p=true}else if(e.getName()!="li"){if(!i.checkStartOfBlock()||!i.checkEndOfBlock()){e=e.clone(false);i.extractContents().appendTo(e); +e.trim();p=i.splitBlock();r=!p.wasStartOfBlock;p=!p.wasEndOfBlock;i.insertNode(e)}}else if(!m)this._.nextNode=e.equals(n)?null:c(i.getBoundaryNodes().endNode,1,n)}if(r)(i=e.getPrevious())&&i.type==CKEDITOR.NODE_ELEMENT&&(i.getName()=="br"?i.remove():i.getLast()&&i.getLast().$.nodeName.toLowerCase()=="br"&&i.getLast().remove());if(p)(i=e.getLast())&&i.type==CKEDITOR.NODE_ELEMENT&&i.getName()=="br"&&(CKEDITOR.env.ie||i.getPrevious(f)||i.getNext(f))&&i.remove();if(!this._.nextNode)this._.nextNode=m|| +e.equals(n)||!n?null:c(e,1,n);return e}};CKEDITOR.dom.range.prototype.createIterator=function(){return new a(this)}})(); +CKEDITOR.command=function(a,c){this.uiItems=[];this.exec=function(b){if(this.state==CKEDITOR.TRISTATE_DISABLED||!this.checkAllowed())return false;this.editorFocus&&a.focus();return this.fire("exec")===false?true:c.exec.call(this,a,b)!==false};this.refresh=function(a,b){if(!this.readOnly&&a.readOnly)return true;if(this.context&&!b.isContextFor(this.context)){this.disable();return true}this.enable();return this.fire("refresh",{editor:a,path:b})===false?true:c.refresh&&c.refresh.apply(this,arguments)!== +false};var b;this.checkAllowed=function(){return typeof b=="boolean"?b:b=a.filter.checkFeature(this)};CKEDITOR.tools.extend(this,c,{modes:{wysiwyg:1},editorFocus:1,contextSensitive:!!c.context,state:CKEDITOR.TRISTATE_DISABLED});CKEDITOR.event.call(this)}; +CKEDITOR.command.prototype={enable:function(){this.state==CKEDITOR.TRISTATE_DISABLED&&this.checkAllowed()&&this.setState(!this.preserveState||typeof this.previousState=="undefined"?CKEDITOR.TRISTATE_OFF:this.previousState)},disable:function(){this.setState(CKEDITOR.TRISTATE_DISABLED)},setState:function(a){if(this.state==a||!this.checkAllowed())return false;this.previousState=this.state;this.state=a;this.fire("state");return true},toggleState:function(){this.state==CKEDITOR.TRISTATE_OFF?this.setState(CKEDITOR.TRISTATE_ON): +this.state==CKEDITOR.TRISTATE_ON&&this.setState(CKEDITOR.TRISTATE_OFF)}};CKEDITOR.event.implementOn(CKEDITOR.command.prototype);CKEDITOR.ENTER_P=1;CKEDITOR.ENTER_BR=2;CKEDITOR.ENTER_DIV=3; +CKEDITOR.config={customConfig:"config.js",autoUpdateElement:!0,language:"",defaultLanguage:"en",contentsLangDirection:"",enterMode:CKEDITOR.ENTER_P,forceEnterMode:!1,shiftEnterMode:CKEDITOR.ENTER_BR,docType:"",bodyId:"",bodyClass:"",fullPage:!1,height:200,extraPlugins:"",removePlugins:"",protectedSource:[],tabIndex:0,width:"",baseFloatZIndex:1E4,blockedKeystrokes:[CKEDITOR.CTRL+66,CKEDITOR.CTRL+73,CKEDITOR.CTRL+85]}; +(function(){function a(a,b,d,g,h){var f=b.name;if((g||typeof a.elements!="function"||a.elements(f))&&(!a.match||a.match(b))){if(g=!h){a:if(a.nothingRequired)g=true;else{if(h=a.requiredClasses){f=b.classes;for(g=0;g0;){k=d[--f];if(e&&(k.type==CKEDITOR.NODE_TEXT||k.type==CKEDITOR.NODE_ELEMENT&&D.$inline[k.name])){if(!j){j=new CKEDITOR.htmlParser.element(b);j.insertAfter(a);c.push({check:"parent-down",el:j})}j.add(k,0)}else{j=null;k.insertAfter(a);h.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT&&(k.type== +CKEDITOR.NODE_ELEMENT&&!D[h.name][k.name])&&c.push({check:"el-up",el:k})}}a.remove()}}else if(d=="style")a.remove();else{a.parent&&c.push({check:"it",el:a.parent});a.replaceWithChildren()}}function u(a,b,c){var d,g;for(d=0;d";if(e in this._.cachedChecks)return this._.cachedChecks[e];h=j(a).$1;g=h.styles;var k=h.classes;h.name=h.elements;h.classes=k=k?k.split(/\s*,\s*/): +[];h.styles=d(g);h.attributes=d(h.attributes);h.children=[];k.length&&(h.attributes["class"]=k.join(" "));if(g)h.attributes.style=CKEDITOR.tools.writeCssText(h.styles);g=h}else{h=a.getDefinition();g=h.styles;k=h.attributes||{};if(g){g=B(g);k.style=CKEDITOR.tools.writeCssText(g,true)}else g={};g={name:h.element,attributes:k,classes:k["class"]?k["class"].split(/\s+/):[],styles:g,children:[]}}var k=CKEDITOR.tools.clone(g),o=[],p;if(b!==false&&(p=this._.transformations[g.name])){for(h=0;h0?false:CKEDITOR.tools.objectCompare(g.attributes,k.attributes,true)?true:false;typeof a=="string"&&(this._.cachedChecks[e]=b);return b}};var s={styles:1,attributes:1,classes:1},A={styles:"requiredStyles",attributes:"requiredAttributes",classes:"requiredClasses"},v=/^([a-z0-9*\s]+)((?:\s*\{[!\w\-,\s\*]+\}\s*|\s*\[[!\w\-,\s\*]+\]\s*|\s*\([!\w\-,\s\*]+\)\s*){0,3})(?:;\s*|$)/i,o={styles:/{([^}]+)}/,attrs:/\[([^\]]+)\]/, +classes:/\(([^\)]+)\)/},x=CKEDITOR.filter.transformationsTools={sizeToStyle:function(a){this.lengthToStyle(a,"width");this.lengthToStyle(a,"height")},sizeToAttribute:function(a){this.lengthToAttribute(a,"width");this.lengthToAttribute(a,"height")},lengthToStyle:function(a,b,c){c=c||b;if(!(c in a.styles)){var d=a.attributes[b];if(d){/^\d+$/.test(d)&&(d=d+"px");a.styles[c]=d}}delete a.attributes[b]},lengthToAttribute:function(a,b,c){c=c||b;if(!(c in a.attributes)){var d=a.styles[b],h=d&&d.match(/^(\d+)(?:\.\d*)?px$/); +h?a.attributes[c]=h[1]:d==z&&(a.attributes[c]=z)}delete a.styles[b]},alignmentToStyle:function(a){if(!("float"in a.styles)){var b=a.attributes.align;if(b=="left"||b=="right")a.styles["float"]=b}delete a.attributes.align},alignmentToAttribute:function(a){if(!("align"in a.attributes)){var b=a.styles["float"];if(b=="left"||b=="right")a.attributes.align=b}delete a.styles["float"]},matchesStyle:w,transform:function(a,b){if(typeof b=="string")a.name=b;else{var c=b.getDefinition(),d=c.styles,h=c.attributes, +g,e,k,f;a.name=c.element;for(g in h)if(g=="class"){c=a.classes.join("|");for(k=h[g].split(/\s+/);f=k.pop();)c.indexOf(f)==-1&&a.classes.push(f)}else a.attributes[g]=h[g];for(e in d)a.styles[e]=d[e]}}}})(); +(function(){CKEDITOR.focusManager=function(a){if(a.focusManager)return a.focusManager;this.hasFocus=false;this.currentActive=null;this._={editor:a};return this};CKEDITOR.focusManager._={blurDelay:200};CKEDITOR.focusManager.prototype={focus:function(){this._.timer&&clearTimeout(this._.timer);if(!this.hasFocus&&!this._.locked){var a=CKEDITOR.currentInstance;a&&a.focusManager.blur(1);this.hasFocus=true;(a=this._.editor.container)&&a.addClass("cke_focus");this._.editor.fire("focus")}},lock:function(){this._.locked= +1},unlock:function(){delete this._.locked},blur:function(a){function c(){if(this.hasFocus){this.hasFocus=false;var a=this._.editor.container;a&&a.removeClass("cke_focus");this._.editor.fire("blur")}}if(!this._.locked){this._.timer&&clearTimeout(this._.timer);var b=CKEDITOR.focusManager._.blurDelay;a||!b?c.call(this):this._.timer=CKEDITOR.tools.setTimeout(function(){delete this._.timer;c.call(this)},b,this)}},add:function(a,c){var b=a.getCustomData("focusmanager");if(!b||b!=this){b&&b.remove(a);var b= +"focus",f="blur";if(c)if(CKEDITOR.env.ie){b="focusin";f="focusout"}else CKEDITOR.event.useCapture=1;var e={blur:function(){a.equals(this.currentActive)&&this.blur()},focus:function(){this.currentActive=a;this.focus()}};a.on(b,e.focus,this);a.on(f,e.blur,this);if(c)CKEDITOR.event.useCapture=0;a.setCustomData("focusmanager",this);a.setCustomData("focusmanager_handlers",e)}},remove:function(a){a.removeCustomData("focusmanager");var c=a.removeCustomData("focusmanager_handlers");a.removeListener("blur", +c.blur);a.removeListener("focus",c.focus)}}})();CKEDITOR.keystrokeHandler=function(a){if(a.keystrokeHandler)return a.keystrokeHandler;this.keystrokes={};this.blockedKeystrokes={};this._={editor:a};return this}; +(function(){var a,c=function(b){var b=b.data,c=b.getKeystroke(),d=this.keystrokes[c],j=this._.editor;a=j.fire("key",{keyCode:c})===false;if(!a){d&&(a=j.execCommand(d,{from:"keystrokeHandler"})!==false);a||(a=!!this.blockedKeystrokes[c])}a&&b.preventDefault(true);return!a},b=function(b){if(a){a=false;b.data.preventDefault(true)}};CKEDITOR.keystrokeHandler.prototype={attach:function(a){a.on("keydown",c,this);if(CKEDITOR.env.opera||CKEDITOR.env.gecko&&CKEDITOR.env.mac)a.on("keypress",b,this)}}})(); +(function(){CKEDITOR.lang={languages:{af:1,ar:1,bg:1,bn:1,bs:1,ca:1,cs:1,cy:1,da:1,de:1,el:1,"en-au":1,"en-ca":1,"en-gb":1,en:1,eo:1,es:1,et:1,eu:1,fa:1,fi:1,fo:1,"fr-ca":1,fr:1,gl:1,gu:1,he:1,hi:1,hr:1,hu:1,is:1,it:1,ja:1,ka:1,km:1,ko:1,ku:1,lt:1,lv:1,mk:1,mn:1,ms:1,nb:1,nl:1,no:1,pl:1,"pt-br":1,pt:1,ro:1,ru:1,sk:1,sl:1,sq:1,"sr-latn":1,sr:1,sv:1,th:1,tr:1,ug:1,uk:1,vi:1,"zh-cn":1,zh:1},load:function(a,c,b){if(!a||!CKEDITOR.lang.languages[a])a=this.detect(c,a);this[a]?b(a,this[a]):CKEDITOR.scriptLoader.load(CKEDITOR.getUrl("lang/"+ +a+".js"),function(){b(a,this[a])},this)},detect:function(a,c){var b=this.languages,c=c||navigator.userLanguage||navigator.language||a,f=c.toLowerCase().match(/([a-z]+)(?:-([a-z]+))?/),e=f[1],f=f[2];b[e+"-"+f]?e=e+"-"+f:b[e]||(e=null);CKEDITOR.lang.detect=e?function(){return e}:function(a){return a};return e||a}}})(); +CKEDITOR.scriptLoader=function(){var a={},c={};return{load:function(b,f,e,d){var j=typeof b=="string";j&&(b=[b]);e||(e=CKEDITOR);var l=b.length,i=[],m=[],n=function(a){f&&(j?f.call(e,a):f.call(e,i,m))};if(l===0)n(true);else{var r=function(a,b){(b?i:m).push(a);if(--l<=0){d&&CKEDITOR.document.getDocumentElement().removeStyle("cursor");n(b)}},p=function(b,d){a[b]=1;var h=c[b];delete c[b];for(var g=0;g +1)){var h=new CKEDITOR.dom.element("script");h.setAttributes({type:"text/javascript",src:b});if(f)if(CKEDITOR.env.ie)h.$.onreadystatechange=function(){if(h.$.readyState=="loaded"||h.$.readyState=="complete"){h.$.onreadystatechange=null;p(b,true)}};else{h.$.onload=function(){setTimeout(function(){p(b,true)},0)};h.$.onerror=function(){p(b,false)}}h.appendTo(CKEDITOR.document.getHead())}}};d&&CKEDITOR.document.getDocumentElement().setStyle("cursor","wait");for(var h=0;h=0)p=a.langCode;else{p=a.langCode.replace(/-.*/,"");p=p!=a.langCode&&CKEDITOR.tools.indexOf(o,p)>=0?p:CKEDITOR.tools.indexOf(o,"en")>=0?"en":o[0]}if(!j.langEntries||!j.langEntries[p])e.push(CKEDITOR.getUrl(j.path+"lang/"+p+".js"));else{a.lang[k]=j.langEntries[p];p=null}}g.push(p);d.push(j)}CKEDITOR.scriptLoader.load(e, +function(){for(var c=["beforeInit","init","afterInit"],e=0;e]+)>)|(?:!--([\\S|\\s]*?)--\>)|(?:([^\\s>]+)\\s*((?:(?:\"[^\"]*\")|(?:'[^']*')|[^\"'>])*)\\/?>))","g")}}; +(function(){var a=/([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,c={checked:1,compact:1,declare:1,defer:1,disabled:1,ismap:1,multiple:1,nohref:1,noresize:1,noshade:1,nowrap:1,readonly:1,selected:1};CKEDITOR.htmlParser.prototype={onTagOpen:function(){},onTagClose:function(){},onText:function(){},onCDATA:function(){},onComment:function(){},parse:function(b){for(var f,e,d=0,j;f=this._.htmlPartsRegex.exec(b);){e=f.index;if(e>d){d=b.substring(d,e);if(j)j.push(d);else this.onText(d)}d= +this._.htmlPartsRegex.lastIndex;if(e=f[1]){e=e.toLowerCase();if(j&&CKEDITOR.dtd.$cdata[e]){this.onCDATA(j.join(""));j=null}if(!j){this.onTagClose(e);continue}}if(j)j.push(f[0]);else if(e=f[3]){e=e.toLowerCase();if(!/="/.test(e)){var l={},i;f=f[4];var m=!!(f&&f.charAt(f.length-1)=="/");if(f)for(;i=a.exec(f);){var n=i[1].toLowerCase();i=i[2]||i[3]||i[4]||"";l[n]=!i&&c[n]?n:i}this.onTagOpen(e,l,m);!j&&CKEDITOR.dtd.$cdata[e]&&(j=[])}}else if(e=f[2])this.onComment(e)}if(b.length>d)this.onText(b.substring(d, +b.length))}}})(); +CKEDITOR.htmlParser.basicWriter=CKEDITOR.tools.createClass({$:function(){this._={output:[]}},proto:{openTag:function(a){this._.output.push("<",a)},openTagClose:function(a,c){c?this._.output.push(" />"):this._.output.push(">")},attribute:function(a,c){typeof c=="string"&&(c=CKEDITOR.tools.htmlEncodeAttr(c));this._.output.push(" ",a,'="',c,'"')},closeTag:function(a){this._.output.push("")},text:function(a){this._.output.push(a)},comment:function(a){this._.output.push("<\!--",a,"--\>")},write:function(a){this._.output.push(a)}, +reset:function(){this._.output=[];this._.indent=false},getHtml:function(a){var c=this._.output.join("");a&&this.reset();return c}}});"use strict"; +(function(){CKEDITOR.htmlParser.node=function(){};CKEDITOR.htmlParser.node.prototype={remove:function(){var a=this.parent.children,c=CKEDITOR.tools.indexOf(a,this),b=this.previous,f=this.next;b&&(b.next=f);f&&(f.previous=b);a.splice(c,1);this.parent=null},replaceWith:function(a){var c=this.parent.children,b=CKEDITOR.tools.indexOf(c,this),f=a.previous=this.previous,e=a.next=this.next;f&&(f.next=a);e&&(e.previous=a);c[b]=a;a.parent=this.parent;this.parent=null},insertAfter:function(a){var c=a.parent.children, +b=CKEDITOR.tools.indexOf(c,a),f=a.next;c.splice(b+1,0,this);this.next=a.next;this.previous=a;a.next=this;f&&(f.previous=this);this.parent=a.parent},insertBefore:function(a){var c=a.parent.children,b=CKEDITOR.tools.indexOf(c,a);c.splice(b,0,this);this.next=a;(this.previous=a.previous)&&(a.previous.next=this);a.previous=this;this.parent=a.parent}}})();"use strict";CKEDITOR.htmlParser.comment=function(a){this.value=a;this._={isBlockLike:false}}; +CKEDITOR.htmlParser.comment.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_COMMENT,filter:function(a){var c=this.value;if(!(c=a.onComment(c,this))){this.remove();return false}if(typeof c!="string"){this.replaceWith(c);return false}this.value=c;return true},writeHtml:function(a,c){c&&this.filter(c);a.comment(this.value)}});"use strict"; +(function(){CKEDITOR.htmlParser.text=function(a){this.value=a;this._={isBlockLike:false}};CKEDITOR.htmlParser.text.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_TEXT,filter:function(a){if(!(this.value=a.onText(this.value,this))){this.remove();return false}},writeHtml:function(a,c){c&&this.filter(c);a.text(this.value)}})})();"use strict"; +(function(){CKEDITOR.htmlParser.cdata=function(a){this.value=a};CKEDITOR.htmlParser.cdata.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_TEXT,filter:function(){},writeHtml:function(a){a.write(this.value)}})})();"use strict";CKEDITOR.htmlParser.fragment=function(){this.children=[];this.parent=null;this._={isBlockLike:true,hasInlineStarted:false}}; +(function(){function a(a){return a.name=="a"&&a.attributes.href||CKEDITOR.dtd.$removeEmpty[a.name]}var c=CKEDITOR.tools.extend({table:1,ul:1,ol:1,dl:1},CKEDITOR.dtd.table,CKEDITOR.dtd.ul,CKEDITOR.dtd.ol,CKEDITOR.dtd.dl),b={ol:1,ul:1},f=CKEDITOR.tools.extend({},{html:1},CKEDITOR.dtd.html,CKEDITOR.dtd.body,CKEDITOR.dtd.head,{style:1,script:1});CKEDITOR.htmlParser.fragment.fromHtml=function(e,d,j){function l(a){var b;if(u.length>0)for(var c=0;c=0;b--)if(a==u[b].name){u.splice(b,1);return}for(var c=[],d=[],g=k;g!=h&&g.name!=a;){g._.isBlockLike||d.unshift(g);c.push(g);g=g.returnPoint||g.parent}if(g!=h){for(b=0;b0?this.children[b-1]:null;if(c){if(a._.isBlockLike&&c.type==CKEDITOR.NODE_TEXT){c.value=CKEDITOR.tools.rtrim(c.value);if(c.value.length===0){this.children.pop();this.add(a);return}}c.next=a}a.previous=c;a.parent=this; +this.children.splice(b,0,a);if(!this._.hasInlineStarted)this._.hasInlineStarted=a.type==CKEDITOR.NODE_TEXT||a.type==CKEDITOR.NODE_ELEMENT&&!a._.isBlockLike},filter:function(a){a.onRoot(this);this.filterChildren(a)},filterChildren:function(a,b){if(this.childrenFilteredBy!=a.id){if(b&&!this.parent)a.onRoot(this);this.childrenFilteredBy=a.id;for(var c=0;c=0;f--)if(n=b[f]){n.pri=c;a.splice(e,0,n)}}}function b(a,b,c){if(b)for(var e in b){var m=a[e];a[e]=f(m,b[e],c);m||a.$length++}}function f(a,b,f){if(b){b.pri=f;if(a){if(a.splice)c(a,b,f);else{a=a.pri>f?[b,a]:[a,b];a.filter=e}return a}return b.filter=b}}function e(a){for(var b= +a.type||a instanceof CKEDITOR.htmlParser.fragment,c=0;c7||e.name in CKEDITOR.dtd.tr||e.name in CKEDITOR.dtd.$listItem))h=false;else{h=b(e);h=!h||e.name=="form"&&h.name=="input"}h&&e.add(g(a))}}}function k(a,b){if((!p||!CKEDITOR.env.ie)&&a.type==CKEDITOR.NODE_ELEMENT&&a.name=="br"&&!a.attributes["data-cke-eol"])return true;var c;if(a.type== +CKEDITOR.NODE_TEXT&&(c=a.value.match(F))){if(c.index){j(a,new CKEDITOR.htmlParser.text(a.value.substring(0,c.index)));a.value=c[0]}if(CKEDITOR.env.ie&&p&&(!b||a.parent.name in r))return true;if(!p)if((c=a.previous)&&c.name=="br"||!c||d(c))return true}return false}var o={elements:{}},p=c=="html",r=CKEDITOR.tools.extend({},z),u;for(u in r)"#"in B[u]||delete r[u];for(u in r)o.elements[u]=h(p,a.config.fillEmptyBlocks!==false);o.root=h(p);o.elements.br=function(a){return function(b){if(b.parent.type!= +CKEDITOR.NODE_DOCUMENT_FRAGMENT){var c=b.attributes;if("data-cke-bogus"in c||"data-cke-eol"in c)delete c["data-cke-bogus"];else{for(c=b.next;c&&e(c);)c=c.next;var h=f(b);!c&&d(b.parent)?l(b.parent,g(a)):d(c)&&(h&&!d(h))&&j(c,g(a))}}}}(p);return o}function c(a){return a.enterMode!=CKEDITOR.ENTER_BR&&a.autoParagraph!==false?a.enterMode==CKEDITOR.ENTER_DIV?"div":"p":false}function b(a){for(a=a.children[a.children.length-1];a&&e(a);)a=a.previous;return a}function f(a){for(a=a.previous;a&&e(a);)a=a.previous; +return a}function e(a){return a.type==CKEDITOR.NODE_TEXT&&!CKEDITOR.tools.trim(a.value)||a.type==CKEDITOR.NODE_ELEMENT&&a.attributes["data-cke-bookmark"]}function d(a){return a&&(a.type==CKEDITOR.NODE_ELEMENT&&a.name in z||a.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT)}function j(a,b){var c=a.parent.children,g=CKEDITOR.tools.indexOf(c,a);c.splice(g,0,b);c=a.previous;a.previous=b;b.next=a;b.parent=a.parent;if(c){b.previous=c;c.next=b}}function l(a,b){var c=a.children[a.children.length-1];a.children.push(b); +b.parent=a;if(c){c.next=b;b.previous=c}}function i(a){var b=a.parent.children,c=CKEDITOR.tools.indexOf(b,a),g=a.previous,a=a.next;g&&(g.next=a);a&&(a.previous=g);b.splice(c,1)}function m(a){var b=a.parent;return b?CKEDITOR.tools.indexOf(b.children,a):-1}function n(a){a=a.attributes;a.contenteditable!="false"&&(a["data-cke-editable"]=a.contenteditable?"true":1);a.contenteditable="false"}function r(a){a=a.attributes;switch(a["data-cke-editable"]){case "true":a.contenteditable="true";break;case "1":delete a.contenteditable}} +function p(a){return a.replace(o,function(a,b,c){return"<"+b+c.replace(x,function(a,b){return!/^on/.test(b)&&c.indexOf("data-cke-saved-"+b)==-1?" data-cke-saved-"+a+" data-cke-"+CKEDITOR.rnd+"-"+a:a})+">"})}function g(a,b){return a.replace(b,function(a,b,c){a.indexOf("/g,">")+"");return""+encodeURIComponent(a)+""})}function h(a){return a.replace(C,function(a,b){return decodeURIComponent(b)})}function u(a){return a.replace(/<\!--(?!{cke_protected})[\s\S]+?--\>/g, +function(a){return"<\!--"+D+"{C}"+encodeURIComponent(a).replace(/--/g,"%2D%2D")+"--\>"})}function w(a){return a.replace(/<\!--\{cke_protected\}\{C\}([\s\S]+?)--\>/g,function(a,b){return decodeURIComponent(b)})}function k(a,b){var c=b._.dataStore;return a.replace(/<\!--\{cke_protected\}([\s\S]+?)--\>/g,function(a,b){return decodeURIComponent(b)}).replace(/\{cke_protected_(\d+)\}/g,function(a,b){return c&&c[b]||""})}function t(a,b){for(var c=[],g=b.config.protectedSource,d=b._.dataStore||(b._.dataStore= +{id:1}),e=/<\!--\{cke_temp(comment)?\}(\d*?)--\>/g,g=[//gi,//gi].concat(g),a=a.replace(/<\!--[\s\S]*?--\>/g,function(a){return"<\!--{cke_tempcomment}"+(c.push(a)-1)+"--\>"}),h=0;h"});a=a.replace(e,function(a,b,g){return"<\!--"+D+(b?"{C}":"")+encodeURIComponent(c[g]).replace(/--/g,"%2D%2D")+ +"--\>"});return a.replace(/(['"]).*?\1/g,function(a){return a.replace(/<\!--\{cke_protected\}([\s\S]+?)--\>/g,function(a,b){d[d.id]=decodeURIComponent(b);return"{cke_protected_"+d.id++ +"}"})})}CKEDITOR.htmlDataProcessor=function(b){var d,e,f=this;this.editor=b;this.dataFilter=d=new CKEDITOR.htmlParser.filter;this.htmlFilter=e=new CKEDITOR.htmlParser.filter;this.writer=new CKEDITOR.htmlParser.basicWriter;d.addRules(s);d.addRules(a(b,"data"));e.addRules(A);e.addRules(a(b,"html"));b.on("toHtml",function(a){var a= +a.data,d=a.dataValue,d=t(d,b),d=g(d,G),d=p(d),d=g(d,I),d=d.replace(Q,"$1cke:$2"),d=d.replace(E,""),d=CKEDITOR.env.opera?d:d.replace(/(]*>)(\r\n|\n)/g,"$1$2$2"),e=a.context||b.editable().getName(),f;if(CKEDITOR.env.ie&&CKEDITOR.env.version<9&&e=="pre"){e="div";d="
    "+d+"
    ";f=1}e=b.document.createElement(e);e.setHtml("a"+d);d=e.getHtml().substr(1);d=d.replace(RegExp(" data-cke-"+CKEDITOR.rnd+"-","ig")," ");f&&(d=d.replace(/^
    |<\/pre>$/gi,""));d=d.replace(L,"$1$2");
    +d=h(d);d=w(d);a.dataValue=CKEDITOR.htmlParser.fragment.fromHtml(d,a.context,a.fixForBody===false?false:c(b.config))},null,null,5);b.on("toHtml",function(a){a.data.dataValue.filterChildren(f.dataFilter,true)},null,null,10);b.on("toHtml",function(a){var a=a.data,b=a.dataValue,c=new CKEDITOR.htmlParser.basicWriter;b.writeChildrenHtml(c);b=c.getHtml(true);a.dataValue=u(b)},null,null,15);b.on("toDataFormat",function(a){a.data.dataValue=CKEDITOR.htmlParser.fragment.fromHtml(a.data.dataValue,b.editable().getName(),
    +c(b.config))},null,null,5);b.on("toDataFormat",function(a){a.data.dataValue.filterChildren(f.htmlFilter,true)},null,null,10);b.on("toDataFormat",function(a){var c=a.data.dataValue,g=f.writer;g.reset();c.writeChildrenHtml(g);c=g.getHtml(true);c=w(c);c=k(c,b);a.data.dataValue=c},null,null,15)};CKEDITOR.htmlDataProcessor.prototype={toHtml:function(a,b,c,g){var d=this.editor;!b&&b!==null&&(b=d.editable().getName());return d.fire("toHtml",{dataValue:a,context:b,fixForBody:c,dontFilter:!!g}).dataValue},
    +toDataFormat:function(a){return this.editor.fire("toDataFormat",{dataValue:a}).dataValue}};var F=/(?: |\xa0)$/,D="{cke_protected}",B=CKEDITOR.dtd,q=["caption","colgroup","col","thead","tfoot","tbody"],z=CKEDITOR.tools.extend({},B.$blockLimit,B.$block),s={elements:{},attributeNames:[[/^on/,"data-cke-pa-on"]]},A={elementNames:[[/^cke:/,""],[/^\?xml:namespace$/,""]],attributeNames:[[/^data-cke-(saved|pa)-/,""],[/^data-cke-.*/,""],["hidefocus",""]],elements:{$:function(a){var b=a.attributes;if(b){if(b["data-cke-temp"])return false;
    +for(var c=["name","href","src"],g,d=0;d-1&&g>-1&&c!=g)){c=m(a);g=m(b)}return c>g?1:-1})},embed:function(a){var b=a.parent;if(b&&b.name=="object"){var c=b.attributes.width,b=b.attributes.height;c&&(a.attributes.width=c);b&&(a.attributes.height=
    +b)}},param:function(a){a.children=[];a.isEmpty=true;return a},a:function(a){if(!a.children.length&&!a.attributes.name&&!a.attributes["data-cke-saved-name"])return false},span:function(a){a.attributes["class"]=="Apple-style-span"&&delete a.name},html:function(a){delete a.attributes.contenteditable;delete a.attributes["class"]},body:function(a){delete a.attributes.spellcheck;delete a.attributes.contenteditable},style:function(a){var b=a.children[0];b&&b.value&&(b.value=CKEDITOR.tools.trim(b.value));
    +if(!a.attributes.type)a.attributes.type="text/css"},title:function(a){var b=a.children[0];!b&&l(a,b=new CKEDITOR.htmlParser.text);b.value=a.attributes["data-cke-title"]||""}},attributes:{"class":function(a){return CKEDITOR.tools.ltrim(a.replace(/(?:^|\s+)cke_[^\s]*/g,""))||false}}};if(CKEDITOR.env.ie)A.attributes.style=function(a){return a.replace(/(^|;)([^\:]+)/g,function(a){return a.toLowerCase()})};for(var v in{input:1,textarea:1}){s.elements[v]=n;A.elements[v]=r}var o=/<(a|area|img|input|source)\b([^>]*)>/gi,
    +x=/\b(on\w+|href|src|name)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi,I=/(?:])[^>]*>[\s\S]*?<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi,G=/(])[^>]*>)([\s\S]*?)(?:<\/textarea>)/gi,C=/([^<]*)<\/cke:encoded>/gi,Q=/(<\/?)((?:object|embed|param|html|body|head|title)[^>]*>)/gi,L=/(<\/?)cke:((?:html|body|head|title)[^>]*>)/gi,E=/]*?)\/?>(?!\s*<\/cke:\1)/gi})();"use strict";
    +CKEDITOR.htmlParser.element=function(a,c){this.name=a;this.attributes=c||{};this.children=[];var b=a||"",f=b.match(/^cke:(.*)/);f&&(b=f[1]);b=!(!CKEDITOR.dtd.$nonBodyContent[b]&&!CKEDITOR.dtd.$block[b]&&!CKEDITOR.dtd.$listItem[b]&&!CKEDITOR.dtd.$tableContent[b]&&!(CKEDITOR.dtd.$nonEditable[b]||b=="br"));this.isEmpty=!!CKEDITOR.dtd.$empty[a];this.isUnknown=!CKEDITOR.dtd[a];this._={isBlockLike:b,hasInlineStarted:this.isEmpty||!b}};
    +CKEDITOR.htmlParser.cssStyle=function(a){var c={};((a instanceof CKEDITOR.htmlParser.element?a.attributes.style:a)||"").replace(/"/g,'"').replace(/\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g,function(a,f,e){f=="font-family"&&(e=e.replace(/["']/g,""));c[f.toLowerCase()]=e});return{rules:c,populate:function(a){var c=this.toString();if(c)a instanceof CKEDITOR.dom.element?a.setAttribute("style",c):a instanceof CKEDITOR.htmlParser.element?a.attributes.style=c:a.style=c},toString:function(){var a=[],f;
    +for(f in c)c[f]&&a.push(f,":",c[f],";");return a.join("")}}};
    +(function(){var a=function(a,c){a=a[0];c=c[0];return ac?1:0},c=CKEDITOR.htmlParser.fragment.prototype;CKEDITOR.htmlParser.element.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_ELEMENT,add:c.add,clone:function(){return new CKEDITOR.htmlParser.element(this.name,this.attributes)},filter:function(a){var c=this,e,d;if(!c.parent)a.onRoot(c);for(;;){e=c.name;if(!(d=a.onElementName(e))){this.remove();return false}c.name=d;if(!(c=a.onElement(c))){this.remove();return false}if(c!==
    +this){this.replaceWith(c);return false}if(c.name==e)break;if(c.type!=CKEDITOR.NODE_ELEMENT){this.replaceWith(c);return false}if(!c.name){this.replaceWithChildren();return false}}e=c.attributes;var j,l;for(j in e){l=j;for(d=e[j];;)if(l=a.onAttributeName(j))if(l!=j){delete e[j];j=l}else break;else{delete e[j];break}l&&((d=a.onAttribute(c,l,d))===false?delete e[l]:e[l]=d)}c.isEmpty||this.filterChildren(a);return true},filterChildren:c.filterChildren,writeHtml:function(b,c){c&&this.filter(c);var e=this.name,
    +d=[],j=this.attributes,l,i;b.openTag(e,j);for(l in j)d.push([l,j[l]]);b.sortAttributes&&d.sort(a);l=0;for(i=d.length;l{voiceLabel}<{outerEl} class="cke_inner cke_reset" role="presentation">{topHtml}<{outerEl} id="{contentId}" class="cke_contents cke_reset" role="presentation">{bottomHtml}'));b=CKEDITOR.dom.element.createFromHtml(e.output({id:a.id,name:b,langDir:a.lang.dir,langCode:a.langCode,voiceLabel:a.lang.editor,
    +topHtml:m?''+m+"":"",contentId:a.ui.spaceId("contents"),bottomHtml:n?''+n+"":"",outerEl:CKEDITOR.env.ie?"span":"div"}));if(f==CKEDITOR.ELEMENT_MODE_REPLACE){c.hide();b.insertAfter(c)}else c.append(b);a.container=b;m&&a.ui.space("top").unselectable();n&&a.ui.space("bottom").unselectable();c=
    +a.config.width;f=a.config.height;c&&b.setStyle("width",CKEDITOR.tools.cssLength(c));f&&a.ui.space("contents").setStyle("height",CKEDITOR.tools.cssLength(f));b.disableContextMenu();CKEDITOR.env.webkit&&b.on("focus",function(){a.focus()});a.fireOnce("uiReady")}function f(a){var b=a.element;if(a.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE&&b.is("textarea")){var c=b.$.form&&new CKEDITOR.dom.element(b.$.form);if(c){var e=function(){a.updateElement()};c.on("submit",e);if(!c.$.submit.nodeName&&!c.$.submit.length)c.$.submit=
    +CKEDITOR.tools.override(c.$.submit,function(b){return function(){a.updateElement();b.apply?b.apply(this,arguments):b()}});a.on("destroy",function(){c.removeListener("submit",e)})}}}CKEDITOR.replace=function(b,c){return a(b,c,null,CKEDITOR.ELEMENT_MODE_REPLACE)};CKEDITOR.appendTo=function(b,c,e){return a(b,c,e,CKEDITOR.ELEMENT_MODE_APPENDTO)};CKEDITOR.replaceAll=function(){for(var a=document.getElementsByTagName("textarea"),b=0;b",k="",a=i+a.replace(f,function(){return k+i})+k}a=a.replace(/\n/g,"
    ");b||(a=a.replace(RegExp("
    (?=)"),function(a){return e.repeat(a,2)}));a=a.replace(/^ | $/g," ");a=a.replace(/(>|\s) /g,function(a,b){return b+" "}).replace(/ (?=<)/g," ");n(this,"text",a)},insertElement:function(a){d(this);for(var c=this.editor,g=c.config.enterMode, +e=c.getSelection(),f=e.getRanges(),i=a.getName(),k=CKEDITOR.dtd.$block[i],m,n,l,B=f.length-1;B>=0;B--){m=f[B];if(!m.checkReadOnly()){m.deleteContents(1);n=!B&&a||a.clone(1);var q,z;if(k)for(;(q=m.getCommonAncestor(0,1))&&(z=CKEDITOR.dtd[q.getName()])&&(!z||!z[i]);)if(q.getName()in CKEDITOR.dtd.span)m.splitElement(q);else if(m.checkStartOfBlock()&&m.checkEndOfBlock()){m.setStartBefore(q);m.collapse(true);q.remove()}else m.splitBlock(g==CKEDITOR.ENTER_DIV?"div":"p",c.editable());m.insertNode(n);l|| +(l=n)}}if(l){m.moveToPosition(l,CKEDITOR.POSITION_AFTER_END);if(k)if((a=l.getNext(b))&&a.type==CKEDITOR.NODE_ELEMENT&&a.is(CKEDITOR.dtd.$block))a.getDtd()["#"]?m.moveToElementEditStart(a):m.moveToElementEditEnd(l);else if(!a&&g!=CKEDITOR.ENTER_BR){a=m.fixBlock(true,g==CKEDITOR.ENTER_DIV?"div":"p");m.moveToElementEditStart(a)}}e.selectRanges([m]);j(this,CKEDITOR.env.opera)},setData:function(a,b){!b&&this.editor.dataProcessor&&(a=this.editor.dataProcessor.toHtml(a));this.setHtml(a);this.editor.fire("dataReady")}, +getData:function(a){var b=this.getHtml();!a&&this.editor.dataProcessor&&(b=this.editor.dataProcessor.toDataFormat(b));return b},setReadOnly:function(a){this.setAttribute("contenteditable",!a)},detach:function(){this.removeClass("cke_editable");var a=this.editor;this._.detach();delete a.document;delete a.window},isInline:function(){return this.getDocument().equals(CKEDITOR.document)},setup:function(){var a=this.editor;this.attachListener(a,"beforeGetData",function(){var b=this.getData();this.is("textarea")|| +a.config.ignoreEmptyParagraph!==false&&(b=b.replace(l,function(a,b){return b}));a.setData(b,null,1)},this);this.attachListener(a,"getSnapshot",function(a){a.data=this.getData(1)},this);this.attachListener(a,"afterSetData",function(){this.setData(a.getData(1))},this);this.attachListener(a,"loadSnapshot",function(a){this.setData(a.data,1)},this);this.attachListener(a,"beforeFocus",function(){var b=a.getSelection();(b=b&&b.getNative())&&b.type=="Control"||this.focus()},this);this.attachListener(a,"insertHtml", +function(a){this.insertHtml(a.data.dataValue,a.data.mode)},this);this.attachListener(a,"insertElement",function(a){this.insertElement(a.data)},this);this.attachListener(a,"insertText",function(a){this.insertText(a.data)},this);this.setReadOnly(a.readOnly);this.attachClass("cke_editable");this.attachClass(a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?"cke_editable_inline":a.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE||a.elementMode==CKEDITOR.ELEMENT_MODE_APPENDTO?"cke_editable_themed":"");this.attachClass("cke_contents_"+ +a.config.contentsLangDirection);a.keystrokeHandler.blockedKeystrokes[8]=a.readOnly;a.keystrokeHandler.attach(this);this.on("blur",function(a){CKEDITOR.env.opera&&CKEDITOR.document.getActive().equals(this.isInline()?this:this.getWindow().getFrame())?a.cancel():this.hasFocus=false},null,null,-1);this.on("focus",function(){this.hasFocus=true},null,null,-1);a.focusManager.add(this);if(this.equals(CKEDITOR.document.getActive())){this.hasFocus=true;a.once("contentDom",function(){a.focusManager.focus()})}this.isInline()&& +this.changeAttr("tabindex",a.tabIndex);if(!this.is("textarea")){a.document=this.getDocument();a.window=this.getWindow();var b=a.document;this.changeAttr("spellcheck",!a.config.disableNativeSpellChecker);var g=a.config.contentsLangDirection;this.getDirection(1)!=g&&this.changeAttr("dir",g);var d=CKEDITOR.getCss();if(d){g=b.getHead();if(!g.getCustomData("stylesheet")){d=b.appendStyleText(d);d=new CKEDITOR.dom.element(d.ownerNode||d.owningElement);g.setCustomData("stylesheet",d);d.data("cke-temp",1)}}g= +b.getCustomData("stylesheet_ref")||0;b.setCustomData("stylesheet_ref",g+1);this.setCustomData("cke_includeReadonly",!a.config.disableReadonlyStyling);this.attachListener(this,"click",function(a){var a=a.data,b=a.getTarget();b.is("a")&&(a.$.button!=2&&b.isReadOnly())&&a.preventDefault()});this.attachListener(a,"key",function(b){if(a.readOnly)return true;var c=b.data.keyCode,g;if(c in{8:1,46:1}){var d=a.getSelection(),b=d.getRanges()[0],h=b.startPath(),f,p,j,c=c==8;if(d=e(d)){a.fire("saveSnapshot"); +b.moveToPosition(d,CKEDITOR.POSITION_BEFORE_START);d.remove();b.select();a.fire("saveSnapshot");g=1}else if(b.collapsed)if((f=h.block)&&b[c?"checkStartOfBlock":"checkEndOfBlock"]()&&(j=f[c?"getPrevious":"getNext"](i))&&j.is("table")){a.fire("saveSnapshot");b[c?"checkEndOfBlock":"checkStartOfBlock"]()&&f.remove();b["moveToElementEdit"+(c?"End":"Start")](j);b.select();a.fire("saveSnapshot");g=1}else if(h.blockLimit&&h.blockLimit.is("td")&&(p=h.blockLimit.getAscendant("table"))&&b.checkBoundaryOfElement(p, +c?CKEDITOR.START:CKEDITOR.END)&&(j=p[c?"getPrevious":"getNext"](i))){a.fire("saveSnapshot");b["moveToElementEdit"+(c?"End":"Start")](j);b.checkStartOfBlock()&&b.checkEndOfBlock()?j.remove():b.select();a.fire("saveSnapshot");g=1}else if((p=h.contains(["td","th","caption"]))&&b.checkBoundaryOfElement(p,c?CKEDITOR.START:CKEDITOR.END))g=1}return!g});CKEDITOR.env.ie&&this.attachListener(this,"click",c);!CKEDITOR.env.ie&&!CKEDITOR.env.opera&&this.attachListener(this,"mousedown",function(b){var c=b.data.getTarget(); +if(c.is("img","hr","input","textarea","select")){a.getSelection().selectElement(c);c.is("input","textarea","select")&&b.data.preventDefault()}});CKEDITOR.env.gecko&&this.attachListener(this,"mouseup",function(b){if(b.data.$.button==2){b=b.data.getTarget();if(!b.getOuterHtml().replace(l,"")){var c=a.createRange();c.moveToElementEditStart(b);c.select(true)}}});if(CKEDITOR.env.webkit){this.attachListener(this,"click",function(a){a.data.getTarget().is("input","select")&&a.data.preventDefault()});this.attachListener(this, +"mouseup",function(a){a.data.getTarget().is("input","textarea")&&a.data.preventDefault()})}}}},_:{detach:function(){this.editor.setData(this.editor.getData(),0,1);this.clearListeners();this.restoreAttrs();var a;if(a=this.removeCustomData("classes"))for(;a.length;)this.removeClass(a.pop());a=this.getDocument();var b=a.getHead();if(b.getCustomData("stylesheet")){var c=a.getCustomData("stylesheet_ref");if(--c)a.setCustomData("stylesheet_ref",c);else{a.removeCustomData("stylesheet_ref");b.removeCustomData("stylesheet").remove()}}delete this.editor}}}); +CKEDITOR.editor.prototype.editable=function(a){var b=this._.editable;if(b&&a)return 0;if(arguments.length)b=this._.editable=a?a instanceof CKEDITOR.editable?a:new CKEDITOR.editable(this,a):(b&&b.detach(),null);return b};var l=/(^|]*>)\s*<(p|div|address|h\d|center|pre)[^>]*>\s*(?:]*>| |\u00A0| )?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi,i=CKEDITOR.dom.walker.whitespaces(true),m=CKEDITOR.dom.walker.bookmark(false,true);CKEDITOR.on("instanceLoaded",function(b){var c=b.editor;c.on("insertElement", +function(a){a=a.data;if(a.type==CKEDITOR.NODE_ELEMENT&&(a.is("input")||a.is("textarea"))){a.getAttribute("contentEditable")!="false"&&a.data("cke-editable",a.hasAttribute("contenteditable")?"true":"1");a.setAttribute("contentEditable",false)}});c.on("selectionChange",function(b){if(!c.readOnly){var d=c.getSelection();if(d&&!d.isLocked){d=c.checkDirty();c.fire("lockSnapshot");a(b);c.fire("unlockSnapshot");!d&&c.resetDirty()}}})});CKEDITOR.on("instanceCreated",function(a){var b=a.editor;b.on("mode", +function(){var a=b.editable();if(a&&a.isInline()){var c=this.lang.editor+", "+this.name;a.changeAttr("role","textbox");a.changeAttr("aria-label",c);a.changeAttr("title",c);if(c=this.ui.space(this.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?"top":"contents")){var d=CKEDITOR.tools.getNextId(),e=CKEDITOR.dom.element.createFromHtml(''+this.lang.common.editorHelp+"");c.append(e);a.changeAttr("aria-describedby",d)}}})});CKEDITOR.addCss(".cke_editable{cursor:text}.cke_editable img,.cke_editable input,.cke_editable textarea{cursor:default}"); +var n=function(){function a(b){return b.type==CKEDITOR.NODE_ELEMENT}function c(b,d){var g,e,h,f,o=[],i=d.range.startContainer;g=d.range.startPath();for(var i=k[i.getName()],j=0,m=b.getChildren(),n=m.count(),l=-1,u=-1,t=0,w=g.contains(k.$list);j-1)o[l].firstNotAllowed=1;if(u>-1)o[u].lastNotAllowed=1;return o}function d(b,c){var e=[],h=b.getChildren(),f=h.count(),i,o=0,j=k[c],p=!b.is(k.$inline)||b.is("br");for(p&&e.push(" ");o ",s.document);s.insertNode(x);s.setStartAfter(x)}I=new CKEDITOR.dom.elementPath(s.startContainer);q.endPath=G=new CKEDITOR.dom.elementPath(s.endContainer);if(!s.collapsed){var o=G.block||G.blockLimit,Q=s.getCommonAncestor(); +o&&(!o.equals(Q)&&!o.contains(Q)&&s.checkEndOfBlock())&&q.zombies.push(o);s.deleteContents()}for(;(C=a(s.startContainer)&&s.startContainer.getChild(s.startOffset-1))&&a(C)&&C.isBlockBoundary()&&I.contains(C);)s.moveToPosition(C,CKEDITOR.POSITION_BEFORE_END);f(s,q.blockLimit,I,G);if(x){s.setEndBefore(x);s.collapse();x.remove()}x=s.startPath();if(o=x.contains(e,false,1)){s.splitElement(o);q.inlineStylesRoot=o;q.inlineStylesPeak=x.lastElement}x=s.createBookmark();(o=x.startNode.getPrevious(b))&&a(o)&& +e(o)&&v.push(o);(o=x.startNode.getNext(b))&&a(o)&&e(o)&&v.push(o);for(o=x.startNode;(o=o.getParent())&&e(o);)v.push(o);s.moveToBookmark(x);if(t){C=t;t=q.range;if(q.type=="text"&&q.inlineStylesRoot){x=C;C=q.inlineStylesPeak;s=C.getDocument().createText("{cke-peak}");for(v=q.inlineStylesRoot.getParent();!C.equals(v);){s=s.appendTo(C.clone());C=C.getParent()}C=s.getOuterHtml().replace("{cke-peak}",x)}x=q.blockLimit.getName();if(/^\s+|\s+$/.test(C)&&"span"in CKEDITOR.dtd[x]){var L=' '; +C=L+C+L}C=q.editor.dataProcessor.toHtml(C,null,false,q.dontFilter);x=t.document.createElement("body");x.setHtml(C);if(L){x.getFirst().remove();x.getLast().remove()}if((L=t.startPath().block)&&!(L.getChildCount()==1&&L.getBogus()))a:{var E;if(x.getChildCount()==1&&a(E=x.getFirst())&&E.is(l)){L=E.getElementsByTag("*");t=0;for(s=L.count();t0;else{y=E.startPath();if(!G.isBlock&&(N=q.editor.config.enterMode!=CKEDITOR.ENTER_BR&&q.editor.config.autoParagraph!==false?q.editor.config.enterMode==CKEDITOR.ENTER_DIV?"div":"p":false)&&!y.block&&y.blockLimit&&y.blockLimit.equals(E.root)){N=L.createElement(N);!CKEDITOR.env.ie&&N.appendBogus();E.insertNode(N);!CKEDITOR.env.ie&&(J=N.getBogus())&&J.remove();E.moveToPosition(N,CKEDITOR.POSITION_BEFORE_END)}if((y= +E.startPath().block)&&!y.equals(H)){if(J=y.getBogus()){J.remove();C.push(y)}H=y}G.firstNotAllowed&&(s=1);if(s&&G.isElement){y=E.startContainer;for(K=null;y&&!k[y.getName()][G.name];){if(y.equals(t)){y=null;break}K=y;y=y.getParent()}if(y){if(K){O=E.splitElement(K);q.zombies.push(O);q.zombies.push(K)}}else{K=t.getName();P=!x;y=x==I.length-1;K=d(G.node,K);for(var M=[],R=K.length,T=0,U=void 0,V=0,W=-1;T1&&f&&f.intersectsNode(c.$)){d=[e.anchorOffset,e.focusOffset];f=e.focusNode==c.$&&e.focusOffset>0;e.anchorNode==c.$&&e.anchorOffset>0&&d[0]--;f&&d[1]--;var i;f=e;if(!f.isCollapsed){i=f.getRangeAt(0);i.setStart(f.anchorNode,f.anchorOffset);i.setEnd(f.focusNode,f.focusOffset);i=i.collapsed}i&&d.unshift(d.pop())}}c.setText(j(c.getText()));if(d){c=e.getRangeAt(0);c.setStart(c.startContainer,d[0]);c.setEnd(c.startContainer,d[1]);e.removeAllRanges();e.addRange(c)}}}function j(a){return a.replace(/\u200B( )?/g, +function(a){return a[1]?" ":""})}var l,i,m=CKEDITOR.dom.walker.invisible(1);CKEDITOR.on("instanceCreated",function(b){function g(){var a=e.getSelection();a&&a.removeAllRanges()}var e=b.editor;e.define("selectionChange",{errorProof:1});e.on("contentDom",function(){var b=e.document,g=CKEDITOR.document,f=e.editable(),i=b.getBody(),j=b.getDocumentElement(),p=f.isInline(),m;CKEDITOR.env.gecko&&f.attachListener(f,"focus",function(a){a.removeListener();if(m!==0){a=e.getSelection().getNative();if(a.isCollapsed&& +a.anchorNode==f.$){a=e.createRange();a.moveToElementEditStart(f);a.select()}}},null,null,-2);f.attachListener(f,"focus",function(){e.unlockSelection(m);m=0},null,null,-1);f.attachListener(f,"mousedown",function(){m=0});if(CKEDITOR.env.ie||CKEDITOR.env.opera||p){var l,r=function(){l=e.getSelection(1);l.lock()};n?f.attachListener(f,"beforedeactivate",r,null,null,-1):f.attachListener(e,"selectionCheck",r,null,null,-1);f.attachListener(f,"blur",function(){e.lockSelection(l);m=1},null,null,-1)}if(CKEDITOR.env.ie&& +!p){var s;f.attachListener(f,"mousedown",function(a){a.data.$.button==2&&e.document.$.selection.type=="None"&&(s=e.window.getScrollPosition())});f.attachListener(f,"mouseup",function(a){if(a.data.$.button==2&&s){e.document.$.documentElement.scrollLeft=s.x;e.document.$.documentElement.scrollTop=s.y}s=null});if(b.$.compatMode!="BackCompat"){if(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)j.on("mousedown",function(a){function b(a){a=a.data.$;if(d){var c=i.$.createTextRange();try{c.moveToPoint(a.x, +a.y)}catch(e){}d.setEndPoint(f.compareEndPoints("StartToStart",c)<0?"EndToEnd":"StartToStart",c);d.select()}}function c(){j.removeListener("mousemove",b);g.removeListener("mouseup",c);j.removeListener("mouseup",c);d.select()}a=a.data;if(a.getTarget().is("html")&&a.$.y7){j.on("mousedown", +function(a){if(a.data.getTarget().is("html")){g.on("mouseup",A);j.on("mouseup",A)}});var A=function(){g.removeListener("mouseup",A);j.removeListener("mouseup",A);var a=CKEDITOR.document.$.selection,c=a.createRange();a.type!="None"&&c.parentElement().ownerDocument==b.$&&c.select()}}}}f.attachListener(f,"selectionchange",a,e);f.attachListener(f,"keyup",c,e);f.attachListener(f,"focus",function(){e.forceNextSelectionCheck();e.selectionChange(1)});if(p?CKEDITOR.env.webkit||CKEDITOR.env.gecko:CKEDITOR.env.opera){var v; +f.attachListener(f,"mousedown",function(){v=1});f.attachListener(b.getDocumentElement(),"mouseup",function(){v&&c.call(e);v=0})}else f.attachListener(CKEDITOR.env.ie?f:b.getDocumentElement(),"mouseup",c,e);CKEDITOR.env.webkit&&f.attachListener(b,"keydown",function(a){switch(a.data.getKey()){case 13:case 33:case 34:case 35:case 36:case 37:case 39:case 8:case 45:case 46:d(f)}},null,null,-1)});e.on("contentDomUnload",e.forceNextSelectionCheck,e);e.on("dataReady",function(){e.selectionChange(1)});CKEDITOR.env.ie9Compat&& +e.on("beforeDestroy",g,null,null,9);CKEDITOR.env.webkit&&e.on("setData",g);e.on("contentDomUnload",function(){e.unlockSelection()})});CKEDITOR.on("instanceReady",function(a){var b=a.editor;if(CKEDITOR.env.webkit){b.on("selectionChange",function(){var a=b.editable(),c=e(a);c&&(c.getCustomData("ready")?d(a):c.setCustomData("ready",1))},null,null,-1);b.on("beforeSetMode",function(){d(b.editable())},null,null,-1);var c,f,a=function(){var a=b.editable();if(a)if(a=e(a)){var d=b.document.$.defaultView.getSelection(); +d.type=="Caret"&&d.anchorNode==a.$&&(f=1);c=a.getText();a.setText(j(c))}},i=function(){var a=b.editable();if(a)if(a=e(a)){a.setText(c);if(f){b.document.$.defaultView.getSelection().setPosition(a.$,a.getLength());f=0}}};b.on("beforeUndoImage",a);b.on("afterUndoImage",i);b.on("beforeGetData",a,null,null,0);b.on("getData",i)}});CKEDITOR.editor.prototype.selectionChange=function(b){(b?a:c).call(this)};CKEDITOR.editor.prototype.getSelection=function(a){if(this._.savedSelection&&!a)return this._.savedSelection; +return(a=this.editable())?new CKEDITOR.dom.selection(a):null};CKEDITOR.editor.prototype.lockSelection=function(a){a=a||this.getSelection(1);if(a.getType()!=CKEDITOR.SELECTION_NONE){!a.isLocked&&a.lock();this._.savedSelection=a;return true}return false};CKEDITOR.editor.prototype.unlockSelection=function(a){var b=this._.savedSelection;if(b){b.unlock(a);delete this._.savedSelection;return true}return false};CKEDITOR.editor.prototype.forceNextSelectionCheck=function(){delete this._.selectionPreviousPath}; +CKEDITOR.dom.document.prototype.getSelection=function(){return new CKEDITOR.dom.selection(this)};CKEDITOR.dom.range.prototype.select=function(){var a=this.root instanceof CKEDITOR.editable?this.root.editor.getSelection():new CKEDITOR.dom.selection(this.root);a.selectRanges([this]);return a};CKEDITOR.SELECTION_NONE=1;CKEDITOR.SELECTION_TEXT=2;CKEDITOR.SELECTION_ELEMENT=3;var n=typeof window.getSelection!="function";CKEDITOR.dom.selection=function(a){var b=a instanceof CKEDITOR.dom.element;this.document= +a instanceof CKEDITOR.dom.document?a:a.getDocument();this.root=b?a:this.document.getBody();this.isLocked=0;this._={cache:{}};if(CKEDITOR.env.webkit){a=this.document.getWindow().$.getSelection();if(a.type=="None"&&this.document.getActive().equals(this.root)||a.type=="Caret"&&a.anchorNode.nodeType==CKEDITOR.NODE_DOCUMENT){var c=new CKEDITOR.dom.range(this.root);c.moveToPosition(this.root,CKEDITOR.POSITION_AFTER_START);b=this.document.$.createRange();b.setStart(c.startContainer.$,c.startOffset);b.collapse(1); +var d=this.root.on("focus",function(a){a.cancel()},null,null,-100);a.addRange(b);d.removeListener()}}var a=this.getNative(),e;if(a)if(a.getRangeAt)e=(c=a.rangeCount&&a.getRangeAt(0))&&new CKEDITOR.dom.node(c.commonAncestorContainer);else{try{c=a.createRange()}catch(f){}e=c&&CKEDITOR.dom.element.get(c.item&&c.item(0)||c.parentElement())}if(!e||!this.root.equals(e)&&!this.root.contains(e)){this._.cache.type=CKEDITOR.SELECTION_NONE;this._.cache.startElement=null;this._.cache.selectedElement=null;this._.cache.selectedText= +"";this._.cache.ranges=new CKEDITOR.dom.rangeList}return this};var r={img:1,hr:1,li:1,table:1,tr:1,td:1,th:1,embed:1,object:1,ol:1,ul:1,a:1,input:1,form:1,select:1,textarea:1,button:1,fieldset:1,thead:1,tfoot:1};CKEDITOR.dom.selection.prototype={getNative:function(){return this._.cache.nativeSel!==void 0?this._.cache.nativeSel:this._.cache.nativeSel=n?this.document.$.selection:this.document.getWindow().$.getSelection()},getType:n?function(){var a=this._.cache;if(a.type)return a.type;var b=CKEDITOR.SELECTION_NONE; +try{var c=this.getNative(),d=c.type;if(d=="Text")b=CKEDITOR.SELECTION_TEXT;if(d=="Control")b=CKEDITOR.SELECTION_ELEMENT;if(c.createRange().parentElement())b=CKEDITOR.SELECTION_TEXT}catch(e){}return a.type=b}:function(){var a=this._.cache;if(a.type)return a.type;var b=CKEDITOR.SELECTION_TEXT,c=this.getNative();if(!c||!c.rangeCount)b=CKEDITOR.SELECTION_NONE;else if(c.rangeCount==1){var c=c.getRangeAt(0),d=c.startContainer;if(d==c.endContainer&&d.nodeType==1&&c.endOffset-c.startOffset==1&&r[d.childNodes[c.startOffset].nodeName.toLowerCase()])b= +CKEDITOR.SELECTION_ELEMENT}return a.type=b},getRanges:function(){var a=n?function(){function a(b){return(new CKEDITOR.dom.node(b)).getIndex()}var b=function(b,c){b=b.duplicate();b.collapse(c);var d=b.parentElement(),e=d.ownerDocument;if(!d.hasChildNodes())return{container:d,offset:0};for(var f=d.children,h,i,j=b.duplicate(),m=0,p=f.length-1,l=-1,n,o;m<=p;){l=Math.floor((m+p)/2);h=f[l];j.moveToElementText(h);n=j.compareEndPoints("StartToStart",b);if(n>0)p=l-1;else if(n<0)m=l+1;else{if(CKEDITOR.env.ie9Compat&& +h.tagName=="BR"){f=e.defaultView.getSelection();return{container:f[c?"anchorNode":"focusNode"],offset:f[c?"anchorOffset":"focusOffset"]}}return{container:d,offset:a(h)}}}if(l==-1||l==f.length-1&&n<0){j.moveToElementText(d);j.setEndPoint("StartToStart",b);e=j.text.replace(/(\r\n|\r)/g,"\n").length;f=d.childNodes;if(!e){h=f[f.length-1];return h.nodeType!=CKEDITOR.NODE_TEXT?{container:d,offset:f.length}:{container:h,offset:h.nodeValue.length}}for(d=f.length;e>0&&d>0;){i=f[--d];if(i.nodeType==CKEDITOR.NODE_TEXT){o= +i;e=e-i.nodeValue.length}}return{container:o,offset:-e}}j.collapse(n>0?true:false);j.setEndPoint(n>0?"StartToStart":"EndToStart",b);e=j.text.replace(/(\r\n|\r)/g,"\n").length;if(!e)return{container:d,offset:a(h)+(n>0?0:1)};for(;e>0;)try{i=h[n>0?"previousSibling":"nextSibling"];if(i.nodeType==CKEDITOR.NODE_TEXT){e=e-i.nodeValue.length;o=i}h=i}catch(x){return{container:d,offset:a(h)}}return{container:o,offset:n>0?-e:o.nodeValue.length+e}};return function(){var a=this.getNative(),c=a&&a.createRange(), +d=this.getType();if(!a)return[];if(d==CKEDITOR.SELECTION_TEXT){a=new CKEDITOR.dom.range(this.root);d=b(c,true);a.setStart(new CKEDITOR.dom.node(d.container),d.offset);d=b(c);a.setEnd(new CKEDITOR.dom.node(d.container),d.offset);a.endContainer.getPosition(a.startContainer)&CKEDITOR.POSITION_PRECEDING&&a.endOffset<=a.startContainer.getIndex()&&a.collapse();return[a]}if(d==CKEDITOR.SELECTION_ELEMENT){for(var d=[],e=0;e=b.getLength()?l.setStartAfter(b):l.setStartBefore(b));i&&i.type==CKEDITOR.NODE_TEXT&&(m?l.setEndAfter(i):l.setEndBefore(i));b=new CKEDITOR.dom.walker(l);b.evaluator=function(a){if(a.type==CKEDITOR.NODE_ELEMENT&&a.isReadOnly()){var b=f.clone();f.setEndBefore(a);f.collapsed&&d.splice(e--,1);if(!(a.getPosition(l.endContainer)&CKEDITOR.POSITION_CONTAINS)){b.setStartAfter(a);b.collapsed||d.splice(e+1,0,b)}return true}return false};b.next()}}return c.ranges}}(),getStartElement:function(){var a=this._.cache; +if(a.startElement!==void 0)return a.startElement;var b;switch(this.getType()){case CKEDITOR.SELECTION_ELEMENT:return this.getSelectedElement();case CKEDITOR.SELECTION_TEXT:var c=this.getRanges()[0];if(c){if(c.collapsed){b=c.startContainer;b.type!=CKEDITOR.NODE_ELEMENT&&(b=b.getParent())}else{for(c.optimize();;){b=c.startContainer;if(c.startOffset==(b.getChildCount?b.getChildCount():b.getLength())&&!b.isBlockBoundary())c.setStartAfter(b);else break}b=c.startContainer;if(b.type!=CKEDITOR.NODE_ELEMENT)return b.getParent(); +b=b.getChild(c.startOffset);if(!b||b.type!=CKEDITOR.NODE_ELEMENT)b=c.startContainer;else for(c=b.getFirst();c&&c.type==CKEDITOR.NODE_ELEMENT;){b=c;c=c.getFirst()}}b=b.$}}return a.startElement=b?new CKEDITOR.dom.element(b):null},getSelectedElement:function(){var a=this._.cache;if(a.selectedElement!==void 0)return a.selectedElement;var b=this,c=CKEDITOR.tools.tryThese(function(){return b.getNative().createRange().item(0)},function(){for(var a=b.getRanges()[0],c,d,e=2;e&&(!(c=a.getEnclosedNode())||!(c.type== +CKEDITOR.NODE_ELEMENT&&r[c.getName()]&&(d=c)));e--)a.shrink(CKEDITOR.SHRINK_ELEMENT);return d.$});return a.selectedElement=c?new CKEDITOR.dom.element(c):null},getSelectedText:function(){var a=this._.cache;if(a.selectedText!==void 0)return a.selectedText;var b=this.getNative(),b=n?b.type=="Control"?"":b.createRange().text:b.toString();return a.selectedText=b},lock:function(){this.getRanges();this.getStartElement();this.getSelectedElement();this.getSelectedText();this._.cache.nativeSel=null;this.isLocked= +1},unlock:function(a){if(this.isLocked){if(a)var b=this.getSelectedElement(),c=!b&&this.getRanges();this.isLocked=0;this.reset();if(a)(a=b||c[0]&&c[0].getCommonAncestor())&&a.getAscendant("body",1)&&(b?this.selectElement(b):this.selectRanges(c))}},reset:function(){this._.cache={}},selectElement:function(a){var b=new CKEDITOR.dom.range(this.root);b.setStartBefore(a);b.setEndAfter(a);this.selectRanges([b])},selectRanges:function(a){if(a.length)if(this.isLocked){var b=CKEDITOR.document.getActive();this.unlock(); +this.selectRanges(a);this.lock();!b.equals(this.root)&&b.focus()}else{if(n){var c=CKEDITOR.dom.walker.whitespaces(true),e=/\ufeff|\u00a0/,i={table:1,tbody:1,tr:1};if(a.length>1){b=a[a.length-1];a[0].setEnd(b.endContainer,b.endOffset)}var b=a[0],a=b.collapsed,k,j,m,l=b.getEnclosedNode();if(l&&l.type==CKEDITOR.NODE_ELEMENT&&l.getName()in r&&(!l.is("a")||!l.getText()))try{m=l.$.createControlRange();m.addElement(l.$);m.select();return}catch(B){}(b.startContainer.type==CKEDITOR.NODE_ELEMENT&&b.startContainer.getName()in +i||b.endContainer.type==CKEDITOR.NODE_ELEMENT&&b.endContainer.getName()in i)&&b.shrink(CKEDITOR.NODE_ELEMENT,true);m=b.createBookmark();var i=m.startNode,q;if(!a)q=m.endNode;m=b.document.$.body.createTextRange();m.moveToElementText(i.$);m.moveStart("character",1);if(q){e=b.document.$.body.createTextRange();e.moveToElementText(q.$);m.setEndPoint("EndToEnd",e);m.moveEnd("character",-1)}else{k=i.getNext(c);j=i.hasAscendant("pre");k=!(k&&k.getText&&k.getText().match(e))&&(j||!i.hasPrevious()||i.getPrevious().is&& +i.getPrevious().is("br"));j=b.document.createElement("span");j.setHtml("");j.insertBefore(i);k&&b.document.createText("").insertBefore(i)}b.setStartBefore(i);i.remove();if(a){if(k){m.moveStart("character",-1);m.select();b.document.$.selection.clear()}else m.select();b.moveToPosition(j,CKEDITOR.POSITION_BEFORE_START);j.remove()}else{b.setEndBefore(q);q.remove();m.select()}}else{q=this.getNative();if(!q)return;if(CKEDITOR.env.opera){b=this.document.$.createRange();b.selectNodeContents(this.root.$); +q.addRange(b)}this.removeAllRanges();for(e=0;e=0){b.collapse(1);m.setEnd(b.endContainer.$,b.endOffset)}else throw z;}q.addRange(m)}}this.reset();this.root.fire("selectionchange")}},createBookmarks:function(a){return this.getRanges().createBookmarks(a)},createBookmarks2:function(a){return this.getRanges().createBookmarks2(a)},selectBookmarks:function(a){for(var b=[],c=0;c< +a.length;c++){var d=new CKEDITOR.dom.range(this.root);d.moveToBookmark(a[c]);b.push(d)}this.selectRanges(b);return this},getCommonAncestor:function(){var a=this.getRanges();return a[0].startContainer.getCommonAncestor(a[a.length-1].endContainer)},scrollIntoView:function(){this.type!=CKEDITOR.SELECTION_NONE&&this.getRanges()[0].scrollIntoView()},removeAllRanges:function(){var a=this.getNative();try{a&&a[n?"empty":"removeAllRanges"]()}catch(b){}this.reset()}}})(); +CKEDITOR.editor.prototype.attachStyleStateChange=function(a,c){var b=this._.styleStateChangeCallbacks;if(!b){b=this._.styleStateChangeCallbacks=[];this.on("selectionChange",function(a){for(var c=0;c]*>)[ \t\r\n]*/gi,"$1");f=f.replace(/([ \t\n\r]+| )/g," ");f=f.replace(/]*>/gi,"\n");if(CKEDITOR.env.ie){var g=a.getDocument().createElement("div");g.append(d);d.$.outerHTML="
    "+f+"
    ";d.copyAttributes(g.getFirst());d=g.getFirst().remove()}else d.setHtml(f);b=d}else f?b=n(c?[a.getHtml()]:i(a),b):a.moveChildren(b);b.replace(a);if(e){var c=b,j;if((j=c.getPrevious(v))&&j.is&&j.is("pre")){e=m(j.getHtml(),/\n$/,"")+ +"\n\n"+m(c.getHtml(),/^\n/,"");CKEDITOR.env.ie?c.$.outerHTML="
    "+e+"
    ":c.setHtml(e);j.remove()}}else c&&h(b)}function i(a){a.getName();var b=[];m(a.getOuterHtml(),/(\S\s*)\n(?:\s|(]+data-cke-bookmark.*?\/span>))*\n(?!$)/gi,function(a,b,c){return b+"
    "+c+"
    "}).replace(/([\s\S]*?)<\/pre>/gi,function(a,c){b.push(c)});return b}function m(a,b,c){var e="",d="",a=a.replace(/(^]+data-cke-bookmark.*?\/span>)|(]+data-cke-bookmark.*?\/span>$)/gi,function(a,
    +b,c){b&&(e=b);c&&(d=c);return""});return e+a.replace(b,c)+d}function n(a,b){var c;a.length>1&&(c=new CKEDITOR.dom.documentFragment(b.getDocument()));for(var e=0;e"),d=d.replace(/[ \t]{2,}/g,function(a){return CKEDITOR.tools.repeat(" ",
    +a.length-1)+" "});if(c){var f=b.clone();f.setHtml(d);c.append(f)}else b.setHtml(d)}return c||b}function r(a){var b=this._.definition,c=b.attributes,b=b.styles,d=t(this)[a.getName()],e=CKEDITOR.tools.isEmpty(c)&&CKEDITOR.tools.isEmpty(b),f;for(f in c)if(!((f=="class"||this._.definition.fullMatch)&&a.getAttribute(f)!=F(f,c[f]))){e=a.hasAttribute(f);a.removeAttribute(f)}for(var i in b)if(!(this._.definition.fullMatch&&a.getStyle(i)!=F(i,b[i],true))){e=e||!!a.getStyle(i);a.removeStyle(i)}g(a,d,B[a.getName()]);
    +e&&(this._.definition.alwaysRemoveElement?h(a,1):!CKEDITOR.dtd.$block[a.getName()]||this._.enterMode==CKEDITOR.ENTER_BR&&!a.hasAttributes()?h(a):a.renameNode(this._.enterMode==CKEDITOR.ENTER_P?"p":"div"))}function p(a){for(var b=t(this),c=a.getElementsByTag(this.element),d=c.count();--d>=0;)r.call(this,c.getItem(d));for(var e in b)if(e!=this.element){c=a.getElementsByTag(e);for(d=c.count()-1;d>=0;d--){var f=c.getItem(d);g(f,b[e])}}}function g(a,b,c){if(b=b&&b.attributes)for(var d=0;d",a||b.name,"");return c.join("")},getDefinition:function(){return this._.definition}};CKEDITOR.style.getStyleText=function(a){var b=a._ST;
    +if(b)return b;var b=a.styles,c=a.attributes&&a.attributes.style||"",d="";c.length&&(c=c.replace(z,";"));for(var e in b){var f=b[e],g=(e+":"+f).replace(z,";");f=="inherit"?d=d+g:c=c+g}c.length&&(c=CKEDITOR.tools.normalizeCssText(c,true));return a._ST=c+d}})();CKEDITOR.styleCommand=function(a,c){this.requiredContent=this.allowedContent=this.style=a;CKEDITOR.tools.extend(this,c,true)};
    +CKEDITOR.styleCommand.prototype.exec=function(a){a.focus();this.state==CKEDITOR.TRISTATE_OFF?a.applyStyle(this.style):this.state==CKEDITOR.TRISTATE_ON&&a.removeStyle(this.style)};CKEDITOR.stylesSet=new CKEDITOR.resourceManager("","stylesSet");CKEDITOR.addStylesSet=CKEDITOR.tools.bind(CKEDITOR.stylesSet.add,CKEDITOR.stylesSet);CKEDITOR.loadStylesSet=function(a,c,b){CKEDITOR.stylesSet.addExternal(a,c,"");CKEDITOR.stylesSet.load(a,b)};
    +CKEDITOR.editor.prototype.getStylesSet=function(a){if(this._.stylesDefinitions)a(this._.stylesDefinitions);else{var c=this,b=c.config.stylesCombo_stylesSet||c.config.stylesSet;if(b===false)a(null);else if(b instanceof Array){c._.stylesDefinitions=b;a(b)}else{b||(b="default");var b=b.split(":"),f=b[0];CKEDITOR.stylesSet.addExternal(f,b[1]?b.slice(1).join(":"):CKEDITOR.getUrl("styles.js"),"");CKEDITOR.stylesSet.load(f,function(b){c._.stylesDefinitions=b[f];a(c._.stylesDefinitions)})}}};
    +CKEDITOR.dom.comment=function(a,c){typeof a=="string"&&(a=(c?c.$:document).createComment(a));CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.comment.prototype=new CKEDITOR.dom.node;CKEDITOR.tools.extend(CKEDITOR.dom.comment.prototype,{type:CKEDITOR.NODE_COMMENT,getOuterHtml:function(){return"<\!--"+this.$.nodeValue+"--\>"}});
    +(function(){var a={},c;for(c in CKEDITOR.dtd.$blockLimit)c in CKEDITOR.dtd.$list||(a[c]=1);var b={};for(c in CKEDITOR.dtd.$block)c in CKEDITOR.dtd.$blockLimit||c in CKEDITOR.dtd.$empty||(b[c]=1);CKEDITOR.dom.elementPath=function(c,e){var d=null,j=null,l=[],e=e||c.getDocument().getBody(),i=c;do if(i.type==CKEDITOR.NODE_ELEMENT){l.push(i);if(!this.lastElement){this.lastElement=i;if(i.is(CKEDITOR.dtd.$object))continue}var m=i.getName();if(!j){!d&&b[m]&&(d=i);if(a[m]){var n;if(n=!d){if(m=m=="div"){a:{m=
    +i.getChildren();n=0;for(var r=m.count();n-1}:typeof a=="function"?f=a:typeof a=="object"&&(f=
    +function(b){return b.getName()in a});var e=this.elements,d=e.length;c&&d--;if(b){e=Array.prototype.slice.call(e,0);e.reverse()}for(c=0;c=f){d=e.createText("");d.insertAfter(this)}else{a=e.createText("");a.insertAfter(d);a.remove()}return d},substring:function(a,
    +c){return typeof c!="number"?this.$.nodeValue.substr(a):this.$.nodeValue.substring(a,c)}});
    +(function(){function a(a,c,e){var d=a.serializable,j=c[e?"endContainer":"startContainer"],l=e?"endOffset":"startOffset",i=d?c.document.getById(a.startNode):a.startNode,a=d?c.document.getById(a.endNode):a.endNode;if(j.equals(i.getPrevious())){c.startOffset=c.startOffset-j.getLength()-a.getPrevious().getLength();j=a.getNext()}else if(j.equals(a.getPrevious())){c.startOffset=c.startOffset-j.getLength();j=a.getNext()}j.equals(i.getParent())&&c[l]++;j.equals(a.getParent())&&c[l]++;c[e?"endContainer":"startContainer"]=
    +j;return c}CKEDITOR.dom.rangeList=function(a){if(a instanceof CKEDITOR.dom.rangeList)return a;a?a instanceof CKEDITOR.dom.range&&(a=[a]):a=[];return CKEDITOR.tools.extend(a,c)};var c={createIterator:function(){var a=this,c=CKEDITOR.dom.walker.bookmark(),e=[],d;return{getNextRange:function(j){d=d==void 0?0:d+1;var l=a[d];if(l&&a.length>1){if(!d)for(var i=a.length-1;i>=0;i--)e.unshift(a[i].createBookmark(true));if(j)for(var m=0;a[d+m+1];){for(var n=l.document,j=0,i=n.getById(e[m].endNode),n=n.getById(e[m+
    +1].startNode);;){i=i.getNextSourceNode(false);if(n.equals(i))j=1;else if(c(i)||i.type==CKEDITOR.NODE_ELEMENT&&i.isBlockBoundary())continue;break}if(!j)break;m++}for(l.moveToBookmark(e.shift());m--;){i=a[++d];i.moveToBookmark(e.shift());l.setEnd(i.endContainer,i.endOffset)}}return l}}},createBookmarks:function(b){for(var c=[],e,d=0;db?-1:1}),e=0,f;e
  • ',CKEDITOR.document);a.appendTo(CKEDITOR.document.getHead());try{CKEDITOR.env.hc=a.getComputedStyle("border-top-color")==a.getComputedStyle("border-right-color")}catch(c){CKEDITOR.env.hc=false}a.remove()}if(CKEDITOR.env.hc)CKEDITOR.env.cssClass=CKEDITOR.env.cssClass+" cke_hc";CKEDITOR.document.appendStyleText(".cke{visibility:hidden;}"); +CKEDITOR.status="loaded";CKEDITOR.fireOnce("loaded");if(a=CKEDITOR._.pending){delete CKEDITOR._.pending;for(var b=0;bc;c++){var f=a,h=c,d;d=parseInt(a[c],16);d=("0"+(0>e?0|d*(1+e):0|d+(255-d)*e).toString(16)).slice(-2);f[h]=d}return"#"+a.join("")}}(),c=function(){var b=new CKEDITOR.template("background:#{to};background-image:-webkit-gradient(linear,lefttop,leftbottom,from({from}),to({to}));background-image:-moz-linear-gradient(top,{from},{to});background-image:-webkit-linear-gradient(top,{from},{to});background-image:-o-linear-gradient(top,{from},{to});background-image:-ms-linear-gradient(top,{from},{to});background-image:linear-gradient(top,{from},{to});filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='{from}',endColorstr='{to}');");return function(c, +a){return b.output({from:c,to:a})}}(),f={editor:new CKEDITOR.template("{id}.cke_chrome [border-color:{defaultBorder};] {id} .cke_top [ {defaultGradient}border-bottom-color:{defaultBorder};] {id} .cke_bottom [{defaultGradient}border-top-color:{defaultBorder};] {id} .cke_resizer [border-right-color:{ckeResizer}] {id} .cke_dialog_title [{defaultGradient}border-bottom-color:{defaultBorder};] {id} .cke_dialog_footer [{defaultGradient}outline-color:{defaultBorder};border-top-color:{defaultBorder};] {id} .cke_dialog_tab [{lightGradient}border-color:{defaultBorder};] {id} .cke_dialog_tab:hover [{mediumGradient}] {id} .cke_dialog_contents [border-top-color:{defaultBorder};] {id} .cke_dialog_tab_selected, {id} .cke_dialog_tab_selected:hover [background:{dialogTabSelected};border-bottom-color:{dialogTabSelectedBorder};] {id} .cke_dialog_body [background:{dialogBody};border-color:{defaultBorder};] {id} .cke_toolgroup [{lightGradient}border-color:{defaultBorder};] {id} a.cke_button_off:hover, {id} a.cke_button_off:focus, {id} a.cke_button_off:active [{mediumGradient}] {id} .cke_button_on [{ckeButtonOn}] {id} .cke_toolbar_separator [background-color: {ckeToolbarSeparator};] {id} .cke_combo_button [border-color:{defaultBorder};{lightGradient}] {id} a.cke_combo_button:hover, {id} a.cke_combo_button:focus, {id} .cke_combo_on a.cke_combo_button [border-color:{defaultBorder};{mediumGradient}] {id} .cke_path_item [color:{elementsPathColor};] {id} a.cke_path_item:hover, {id} a.cke_path_item:focus, {id} a.cke_path_item:active [background-color:{elementsPathBg};] {id}.cke_panel [border-color:{defaultBorder};] "), +panel:new CKEDITOR.template(".cke_panel_grouptitle [{lightGradient}border-color:{defaultBorder};] .cke_menubutton_icon [background-color:{menubuttonIcon};] .cke_menubutton:hover .cke_menubutton_icon, .cke_menubutton:focus .cke_menubutton_icon, .cke_menubutton:active .cke_menubutton_icon [background-color:{menubuttonIconHover};] .cke_menuseparator [background-color:{menubuttonIcon};] a:hover.cke_colorbox, a:focus.cke_colorbox, a:active.cke_colorbox [border-color:{defaultBorder};] a:hover.cke_colorauto, a:hover.cke_colormore, a:focus.cke_colorauto, a:focus.cke_colormore, a:active.cke_colorauto, a:active.cke_colormore [background-color:{ckeColorauto};border-color:{defaultBorder};] ")}; +return function(g,e){var a=g.uiColor,a={id:"."+g.id,defaultBorder:b(a,-0.1),defaultGradient:c(b(a,0.9),a),lightGradient:c(b(a,1),b(a,0.7)),mediumGradient:c(b(a,0.8),b(a,0.5)),ckeButtonOn:c(b(a,0.6),b(a,0.7)),ckeResizer:b(a,-0.4),ckeToolbarSeparator:b(a,0.5),ckeColorauto:b(a,0.8),dialogBody:b(a,0.7),dialogTabSelected:c("#FFFFFF","#FFFFFF"),dialogTabSelectedBorder:"#FFF",elementsPathColor:b(a,-0.6),elementsPathBg:a,menubuttonIcon:b(a,0.5),menubuttonIconHover:b(a,0.3)};return f[e].output(a).replace(/\[/g, +"{").replace(/\]/g,"}")}}();CKEDITOR.plugins.add("dialogui",{onLoad:function(){var h=function(b){this._||(this._={});this._["default"]=this._.initValue=b["default"]||"";this._.required=b.required||!1;for(var a=[this._],d=1;darguments.length)){var c=h.call(this,a);c.labelId=CKEDITOR.tools.getNextId()+"_label";this._.children=[];CKEDITOR.ui.dialog.uiElement.call(this,b,a,d,"div",null,{role:"presentation"},function(){var f=[],d=a.required?" cke_required":"";"horizontal"!= +a.labelLayout?f.push('",'"):(d={type:"hbox",widths:a.widths,padding:0,children:[{type:"html",html:'';return C?'Disable SCAYT':'Enable SCAYT';};var Z=function(tooltip,style){this.Command=FCKCommands.GetCommand('Scayt');this.CommandName='Scayt';this.Label=this.GetLabel();this.Tooltip=FCKLang.ScaytTitle;this.Style=1;};Z.prototype=new FCKToolbarSpecialCombo;Z.prototype.CreateItems=function(){this._Combo.AddItem('Trigger','Enable SCAYT');this._Combo.AddItem('Options',FCKLang.ScaytTitleOptions||"Options");this._Combo.AddItem('Langs',FCKLang.ScaytTitleLangs||"Languages");this._Combo.AddItem('About',FCKLang.ScaytTitleAbout||"About");};Z.prototype.GetLabel=function(){var a=FCKConfig.SkinPath+'fck_strip.gif';return FCKBrowserInfo.IsIE?'
    ':'';};function ScaytMessage(m){m&&alert(m);};var b=function(){name='ScaytContext';};b.prototype.Execute=function(contextInfo){var c=contextInfo&&contextInfo.action,g=c&&contextInfo.node,Q=window.scayt_control;if (g){switch (c){case 'Suggestion':Q.replace(g,contextInfo.suggestion);break;case 'Ignore':Q.ignore(g);break;case 'Ignore All':Q.ignoreAll(g);break;case 'Add Word':var E=FCK.EditorWindow.parent.parent;E.scayt.addWordToUserDictionary(g);break;}}};function InitSetup(){FCK.ContextMenu.RegisterListener({AddItems:function(menu){var E=FCK.EditorWindow.parent.parent;var Q=window.scayt_control,P=E.scayt;if (!Q) return;var g=Q.getScaytNode();if (!g) return;var h=P.getSuggestion(Q.getWord(g),Q.getLang());if (!h||!h.length) return;menu.AddSeparator();var j=FCK.Config.ScaytMaxSuggestions||5;var k=(j==-1)?h.length:j;for (var i=0;i';G.open();G.write(''+H+''+document.getElementById('xToolbarSpace').innerHTML+'');G.close();if(FCKBrowserInfo.IsAIR) FCKAdobeAIR.ToolbarSet_InitOutFrame(G);FCKTools.AddEventListener(G,'contextmenu',FCKTools.CancelEvent);FCKTools.AppendStyleSheet(G,FCKConfig.SkinEditorCSS);B=D.__FCKToolbarSet=new FCKToolbarSet(G);B._IFrame=F;if (FCK.IECleanup) FCK.IECleanup.AddItem(D,FCKToolbarSet_Target_Cleanup);};B.CurrentInstance=FCK;if (!B.ToolbarItems) B.ToolbarItems=FCKToolbarItems;FCK.AttachToOnSelectionChange(B.RefreshItemsState);return B;};function FCK_OnBlur(A){var B=A.ToolbarSet;if (B.CurrentInstance==A) B.Disable();};function FCK_OnFocus(A){var B=A.ToolbarSet;var C=A||FCK;B.CurrentInstance.FocusManager.RemoveWindow(B._IFrame.contentWindow);B.CurrentInstance=C;C.FocusManager.AddWindow(B._IFrame.contentWindow,true);B.Enable();};function FCKToolbarSet_Cleanup(){this._TargetElement=null;this._IFrame=null;};function FCKToolbarSet_Target_Cleanup(){this.__FCKToolbarSet=null;};var FCKToolbarSet=function(A){this._Document=A;this._TargetElement=A.getElementById('xToolbar');var B=A.getElementById('xExpandHandle');var C=A.getElementById('xCollapseHandle');B.title=FCKLang.ToolbarExpand;FCKTools.AddEventListener(B,'click',FCKToolbarSet_Expand_OnClick);C.title=FCKLang.ToolbarCollapse;FCKTools.AddEventListener(C,'click',FCKToolbarSet_Collapse_OnClick);if (!FCKConfig.ToolbarCanCollapse||FCKConfig.ToolbarStartExpanded) this.Expand();else this.Collapse();C.style.display=FCKConfig.ToolbarCanCollapse?'':'none';if (FCKConfig.ToolbarCanCollapse) C.style.display='';else A.getElementById('xTBLeftBorder').style.display='';this.Toolbars=[];this.IsLoaded=false;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarSet_Cleanup);};function FCKToolbarSet_Expand_OnClick(){FCK.ToolbarSet.Expand();};function FCKToolbarSet_Collapse_OnClick(){FCK.ToolbarSet.Collapse();};FCKToolbarSet.prototype.Expand=function(){this._ChangeVisibility(false);};FCKToolbarSet.prototype.Collapse=function(){this._ChangeVisibility(true);};FCKToolbarSet.prototype._ChangeVisibility=function(A){this._Document.getElementById('xCollapsed').style.display=A?'':'none';this._Document.getElementById('xExpanded').style.display=A?'none':'';if (window.onresize){FCKTools.RunFunction(window.onresize);}};FCKToolbarSet.prototype.Load=function(A){this.Name=A;this.Items=[];this.ItemsWysiwygOnly=[];this.ItemsContextSensitive=[];this._TargetElement.innerHTML='';var B=FCKConfig.ToolbarSets[A];if (!B){alert(FCKLang.UnknownToolbarSet.replace(/%1/g,A));return;};this.Toolbars=[];for (var x=0;x0) break;}catch (e){break;};D=D.parent;};var E=D.document;var F=function(){if (!B) B=FCKConfig.FloatingPanelsZIndex+999;return++B;};var G=function(){if (!C) return;var H=FCKTools.IsStrictMode(E)?E.documentElement:E.body;FCKDomTools.SetElementStyles(C,{'width':Math.max(H.scrollWidth,H.clientWidth,E.scrollWidth||0)-1+'px','height':Math.max(H.scrollHeight,H.clientHeight,E.scrollHeight||0)-1+'px'});};return {OpenDialog:function(dialogName,dialogTitle,dialogPage,width,height,customValue,resizable){if (!A) this.DisplayMainCover();var I={Title:dialogTitle,Page:dialogPage,Editor:window,CustomValue:customValue,TopWindow:D};FCK.ToolbarSet.CurrentInstance.Selection.Save(true);var J=FCKTools.GetViewPaneSize(D);var K={ 'X':0,'Y':0 };var L=FCKBrowserInfo.IsIE&&(!FCKBrowserInfo.IsIE7||!FCKTools.IsStrictMode(D.document));if (L) K=FCKTools.GetScrollPosition(D);var M=Math.max(K.Y+(J.Height-height-20)/2,0);var N=Math.max(K.X+(J.Width-width-20)/2,0);var O=E.createElement('iframe');FCKTools.ResetStyles(O);O.src=FCKConfig.BasePath+'fckdialog.html';O.frameBorder=0;O.allowTransparency=true;FCKDomTools.SetElementStyles(O,{'position':(L)?'absolute':'fixed','top':M+'px','left':N+'px','width':width+'px','height':height+'px','zIndex':F()});O._DialogArguments=I;E.body.appendChild(O);O._ParentDialog=A;A=O;},OnDialogClose:function(dialogWindow){var O=dialogWindow.frameElement;FCKDomTools.RemoveNode(O);if (O._ParentDialog){A=O._ParentDialog;O._ParentDialog.contentWindow.SetEnabled(true);}else{if (!FCKBrowserInfo.IsIE) FCK.Focus();this.HideMainCover();setTimeout(function(){ A=null;},0);FCK.ToolbarSet.CurrentInstance.Selection.Release();}},DisplayMainCover:function(){C=E.createElement('div');FCKTools.ResetStyles(C);FCKDomTools.SetElementStyles(C,{'position':'absolute','zIndex':F(),'top':'0px','left':'0px','backgroundColor':FCKConfig.BackgroundBlockerColor});FCKDomTools.SetOpacity(C,FCKConfig.BackgroundBlockerOpacity);if (FCKBrowserInfo.IsIE&&!FCKBrowserInfo.IsIE7){var Q=E.createElement('iframe');FCKTools.ResetStyles(Q);Q.hideFocus=true;Q.frameBorder=0;Q.src=FCKTools.GetVoidUrl();FCKDomTools.SetElementStyles(Q,{'width':'100%','height':'100%','position':'absolute','left':'0px','top':'0px','filter':'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'});C.appendChild(Q);};FCKTools.AddEventListener(D,'resize',G);G();E.body.appendChild(C);FCKFocusManager.Lock();var R=FCK.ToolbarSet.CurrentInstance.GetInstanceObject('frameElement');R._fck_originalTabIndex=R.tabIndex;R.tabIndex=-1;},HideMainCover:function(){FCKDomTools.RemoveNode(C);FCKFocusManager.Unlock();var R=FCK.ToolbarSet.CurrentInstance.GetInstanceObject('frameElement');R.tabIndex=R._fck_originalTabIndex;FCKDomTools.ClearElementJSProperty(R,'_fck_originalTabIndex');},GetCover:function(){return C;}};})(); -var FCKMenuItem=function(A,B,C,D,E,F){this.Name=B;this.Label=C||B;this.IsDisabled=E;this.Icon=new FCKIcon(D);this.SubMenu=new FCKMenuBlockPanel();this.SubMenu.Parent=A;this.SubMenu.OnClick=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnClick,this);this.CustomData=F;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuItem_Cleanup);};FCKMenuItem.prototype.AddItem=function(A,B,C,D,E){this.HasSubMenu=true;return this.SubMenu.AddItem(A,B,C,D,E);};FCKMenuItem.prototype.AddSeparator=function(){this.SubMenu.AddSeparator();};FCKMenuItem.prototype.Create=function(A){var B=this.HasSubMenu;var C=FCKTools.GetElementDocument(A);var r=this.MainElement=A.insertRow(-1);r.className=this.IsDisabled?'MN_Item_Disabled':'MN_Item';if (!this.IsDisabled){FCKTools.AddEventListenerEx(r,'mouseover',FCKMenuItem_OnMouseOver,[this]);FCKTools.AddEventListenerEx(r,'click',FCKMenuItem_OnClick,[this]);if (!B) FCKTools.AddEventListenerEx(r,'mouseout',FCKMenuItem_OnMouseOut,[this]);};var D=r.insertCell(-1);D.className='MN_Icon';D.appendChild(this.Icon.CreateIconElement(C));D=r.insertCell(-1);D.className='MN_Label';D.noWrap=true;D.appendChild(C.createTextNode(this.Label));D=r.insertCell(-1);if (B){D.className='MN_Arrow';var E=D.appendChild(C.createElement('IMG'));E.src=FCK_IMAGES_PATH+'arrow_'+FCKLang.Dir+'.gif';E.width=4;E.height=7;this.SubMenu.Create();this.SubMenu.Panel.OnHide=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnHide,this);}};FCKMenuItem.prototype.Activate=function(){this.MainElement.className='MN_Item_Over';if (this.HasSubMenu){this.SubMenu.Show(this.MainElement.offsetWidth+2,-2,this.MainElement);};FCKTools.RunFunction(this.OnActivate,this);};FCKMenuItem.prototype.Deactivate=function(){this.MainElement.className='MN_Item';if (this.HasSubMenu) this.SubMenu.Hide();};function FCKMenuItem_SubMenu_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuItem_SubMenu_OnHide(A){A.Deactivate();};function FCKMenuItem_OnClick(A,B){if (B.HasSubMenu) B.Activate();else{B.Deactivate();FCKTools.RunFunction(B.OnClick,B,[B]);}};function FCKMenuItem_OnMouseOver(A,B){B.Activate();};function FCKMenuItem_OnMouseOut(A,B){B.Deactivate();};function FCKMenuItem_Cleanup(){this.MainElement=null;}; -var FCKMenuBlock=function(){this._Items=[];};FCKMenuBlock.prototype.Count=function(){return this._Items.length;};FCKMenuBlock.prototype.AddItem=function(A,B,C,D,E){var F=new FCKMenuItem(this,A,B,C,D,E);F.OnClick=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnClick,this);F.OnActivate=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnActivate,this);this._Items.push(F);return F;};FCKMenuBlock.prototype.AddSeparator=function(){this._Items.push(new FCKMenuSeparator());};FCKMenuBlock.prototype.RemoveAllItems=function(){this._Items=[];var A=this._ItemsTable;if (A){while (A.rows.length>0) A.deleteRow(0);}};FCKMenuBlock.prototype.Create=function(A){if (!this._ItemsTable){if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuBlock_Cleanup);this._Window=FCKTools.GetElementWindow(A);var B=FCKTools.GetElementDocument(A);var C=A.appendChild(B.createElement('table'));C.cellPadding=0;C.cellSpacing=0;FCKTools.DisableSelection(C);var D=C.insertRow(-1).insertCell(-1);D.className='MN_Menu';var E=this._ItemsTable=D.appendChild(B.createElement('table'));E.cellPadding=0;E.cellSpacing=0;};for (var i=0;i0&&F.href.length==0);if (G) return;menu.AddSeparator();menu.AddItem('VisitLink',FCKLang.VisitLink);menu.AddSeparator();if (E) menu.AddItem('Link',FCKLang.EditLink,34);menu.AddItem('Unlink',FCKLang.RemoveLink,35);}}};case 'Image':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&!tag.getAttribute('_fckfakelement')){menu.AddSeparator();menu.AddItem('Image',FCKLang.ImageProperties,37);}}};case 'Anchor':return {AddItems:function(menu,tag,tagName){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0);if (G||(tagName=='IMG'&&tag.getAttribute('_fckanchor'))){menu.AddSeparator();menu.AddItem('Anchor',FCKLang.AnchorProp,36);menu.AddItem('AnchorDelete',FCKLang.AnchorDelete);}}};case 'Flash':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&tag.getAttribute('_fckflash')){menu.AddSeparator();menu.AddItem('Flash',FCKLang.FlashProperties,38);}}};case 'Form':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('FORM')){menu.AddSeparator();menu.AddItem('Form',FCKLang.FormProp,48);}}};case 'Checkbox':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='checkbox'){menu.AddSeparator();menu.AddItem('Checkbox',FCKLang.CheckboxProp,49);}}};case 'Radio':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='radio'){menu.AddSeparator();menu.AddItem('Radio',FCKLang.RadioButtonProp,50);}}};case 'TextField':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='text'||tag.type=='password')){menu.AddSeparator();menu.AddItem('TextField',FCKLang.TextFieldProp,51);}}};case 'HiddenField':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&tag.getAttribute('_fckinputhidden')){menu.AddSeparator();menu.AddItem('HiddenField',FCKLang.HiddenFieldProp,56);}}};case 'ImageButton':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='image'){menu.AddSeparator();menu.AddItem('ImageButton',FCKLang.ImageButtonProp,55);}}};case 'Button':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='button'||tag.type=='submit'||tag.type=='reset')){menu.AddSeparator();menu.AddItem('Button',FCKLang.ButtonProp,54);}}};case 'Select':return {AddItems:function(menu,tag,tagName){if (tagName=='SELECT'){menu.AddSeparator();menu.AddItem('Select',FCKLang.SelectionFieldProp,53);}}};case 'Textarea':return {AddItems:function(menu,tag,tagName){if (tagName=='TEXTAREA'){menu.AddSeparator();menu.AddItem('Textarea',FCKLang.TextareaProp,52);}}};case 'BulletedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('UL')){menu.AddSeparator();menu.AddItem('BulletedList',FCKLang.BulletedListProp,27);}}};case 'NumberedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('OL')){menu.AddSeparator();menu.AddItem('NumberedList',FCKLang.NumberedListProp,26);}}};case 'DivContainer':return {AddItems:function(menu,tag,tagName){var J=FCKDomTools.GetSelectedDivContainers();if (J.length>0){menu.AddSeparator();menu.AddItem('EditDiv',FCKLang.EditDiv,75);menu.AddItem('DeleteDiv',FCKLang.DeleteDiv,76);}}};};return null;};function FCK_ContextMenu_OnBeforeOpen(){FCK.Events.FireEvent('OnSelectionChange');var A,sTagName;if ((A=FCKSelection.GetSelectedElement())) sTagName=A.tagName;var B=FCK.ContextMenu._InnerContextMenu;B.RemoveAllItems();var C=FCK.ContextMenu.Listeners;for (var i=0;i0){D=A.substr(0,B.index);this._sourceHtml=A.substr(B.index);}else{C=true;D=B[0];this._sourceHtml=A.substr(B[0].length);}}else{D=A;this._sourceHtml=null;};return { 'isTag':C,'value':D };},Each:function(A){var B;while ((B=this.Next())) A(B.isTag,B.value);}};var FCKHtmlIterator=function(A){this._sourceHtml=A;};FCKHtmlIterator.prototype={Next:function(){var A=this._sourceHtml;if (A==null) return null;var B=FCKRegexLib.HtmlTag.exec(A);var C=false;var D="";if (B){if (B.index>0){D=A.substr(0,B.index);this._sourceHtml=A.substr(B.index);}else{C=true;D=B[0];this._sourceHtml=A.substr(B[0].length);}}else{D=A;this._sourceHtml=null;};return { 'isTag':C,'value':D };},Each:function(A){var B;while ((B=this.Next())) A(B.isTag,B.value);}}; -var FCKPlugin=function(A,B,C){this.Name=A;this.BasePath=C?C:FCKConfig.PluginsPath;this.Path=this.BasePath+A+'/';if (!B||B.length==0) this.AvailableLangs=[];else this.AvailableLangs=B.split(',');};FCKPlugin.prototype.Load=function(){if (this.AvailableLangs.length>0){var A;if (this.AvailableLangs.IndexOf(FCKLanguageManager.ActiveLanguage.Code)>=0) A=FCKLanguageManager.ActiveLanguage.Code;else A=this.AvailableLangs[0];LoadScript(this.Path+'lang/'+A+'.js');};LoadScript(this.Path+'fckplugin.js');}; -var FCKPlugins=FCK.Plugins={};FCKPlugins.ItemsCount=0;FCKPlugins.Items={};FCKPlugins.Load=function(){var A=FCKPlugins.Items;for (var i=0;i - - - - - - - - - - - -
    -

    FontFormats Localization

    -

    - IE has some limits when handling the "Font Format". It actually uses localized - strings to retrieve the current format value. This makes it very difficult to - make a system that works on every single computer in the world. -

    -

    - With FCKeditor, this problem impacts in the "Format" toolbar command that - doesn't reflects the format of the current cursor position. -

    -

    - There is only one way to make it work. We must localize FCKeditor using the - strings used by IE. In this way, we will have the expected behavior at least - when using FCKeditor in the same language as the browser. So, when localizing - FCKeditor, go to a computer with IE in the target language, open this page and - use the following string to the "FontFormats" value: -

    -
    - FontFormats : "", -
    -
    -
    -

     

    -
     
    -
     
    -

     

    -

     

    -

     

    -

     

    -
     
    -
     
    -
    - - diff --git a/httemplate/elements/fckeditor/editor/lang/_translationstatus.txt b/httemplate/elements/fckeditor/editor/lang/_translationstatus.txt deleted file mode 100644 index f5eade900..000000000 --- a/httemplate/elements/fckeditor/editor/lang/_translationstatus.txt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Translations Status. - */ - -af.js Found: 396 Missing: 36 -ar.js Found: 420 Missing: 12 -bg.js Found: 373 Missing: 59 -bn.js Found: 380 Missing: 52 -bs.js Found: 226 Missing: 206 -ca.js Found: 420 Missing: 12 -cs.js Found: 432 Missing: 0 -da.js Found: 419 Missing: 13 -de.js Found: 420 Missing: 12 -el.js Found: 396 Missing: 36 -en-au.js Found: 423 Missing: 9 -en-ca.js Found: 423 Missing: 9 -en-uk.js Found: 423 Missing: 9 -eo.js Found: 346 Missing: 86 -es.js Found: 428 Missing: 4 -et.js Found: 411 Missing: 21 -eu.js Found: 420 Missing: 12 -fa.js Found: 413 Missing: 19 -fi.js Found: 427 Missing: 5 -fo.js Found: 420 Missing: 12 -fr-ca.js Found: 419 Missing: 13 -fr.js Found: 428 Missing: 4 -gl.js Found: 381 Missing: 51 -gu.js Found: 411 Missing: 21 -he.js Found: 428 Missing: 4 -hi.js Found: 420 Missing: 12 -hr.js Found: 420 Missing: 12 -hu.js Found: 411 Missing: 21 -is.js Found: 428 Missing: 4 -it.js Found: 410 Missing: 22 -ja.js Found: 420 Missing: 12 -km.js Found: 370 Missing: 62 -ko.js Found: 391 Missing: 41 -lt.js Found: 428 Missing: 4 -lv.js Found: 381 Missing: 51 -mn.js Found: 411 Missing: 21 -ms.js Found: 352 Missing: 80 -nb.js Found: 414 Missing: 18 -nl.js Found: 420 Missing: 12 -no.js Found: 414 Missing: 18 -pl.js Found: 412 Missing: 20 -pt-br.js Found: 411 Missing: 21 -pt.js Found: 381 Missing: 51 -ro.js Found: 410 Missing: 22 -ru.js Found: 427 Missing: 5 -sk.js Found: 420 Missing: 12 -sl.js Found: 426 Missing: 6 -sr-latn.js Found: 368 Missing: 64 -sr.js Found: 368 Missing: 64 -sv.js Found: 431 Missing: 1 -th.js Found: 393 Missing: 39 -tr.js Found: 428 Missing: 4 -uk.js Found: 419 Missing: 13 -vi.js Found: 419 Missing: 13 -zh-cn.js Found: 428 Missing: 4 -zh.js Found: 423 Missing: 9 diff --git a/httemplate/elements/fckeditor/editor/lang/af.js b/httemplate/elements/fckeditor/editor/lang/af.js deleted file mode 100644 index ea233858a..000000000 --- a/httemplate/elements/fckeditor/editor/lang/af.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Afrikaans language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Vou Gereedskaps balk toe", -ToolbarExpand : "Vou Gereedskaps balk oop", - -// Toolbar Items and Context Menu -Save : "Bewaar", -NewPage : "Nuwe Bladsy", -Preview : "Voorskou", -Cut : "Uitsny ", -Copy : "Kopieer", -Paste : "Byvoeg", -PasteText : "Slegs inhoud byvoeg", -PasteWord : "Van Word af byvoeg", -Print : "Druk", -SelectAll : "Selekteer alles", -RemoveFormat : "Formaat verweider", -InsertLinkLbl : "Skakel", -InsertLink : "Skakel byvoeg/verander", -RemoveLink : "Skakel verweider", -VisitLink : "Open Link", //MISSING -Anchor : "Plekhouer byvoeg/verander", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "Beeld", -InsertImage : "Beeld byvoeg/verander", -InsertFlashLbl : "Flash", -InsertFlash : "Flash byvoeg/verander", -InsertTableLbl : "Tabel", -InsertTable : "Tabel byvoeg/verander", -InsertLineLbl : "Lyn", -InsertLine : "Horisontale lyn byvoeg", -InsertSpecialCharLbl: "Spesiaale karakter", -InsertSpecialChar : "Spesiaale Karakter byvoeg", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Smiley byvoeg", -About : "Meer oor FCKeditor", -Bold : "Vet", -Italic : "Skuins", -Underline : "Onderstreep", -StrikeThrough : "Gestreik", -Subscript : "Subscript", -Superscript : "Superscript", -LeftJustify : "Links rig", -CenterJustify : "Rig Middel", -RightJustify : "Regs rig", -BlockJustify : "Blok paradeer", -DecreaseIndent : "Paradeering verkort", -IncreaseIndent : "Paradeering verleng", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Ont-skep", -Redo : "Her-skep", -NumberedListLbl : "Genommerde lys", -NumberedList : "Genommerde lys byvoeg/verweider", -BulletedListLbl : "Gepunkte lys", -BulletedList : "Gepunkte lys byvoeg/verweider", -ShowTableBorders : "Wys tabel kante", -ShowDetails : "Wys informasie", -Style : "Styl", -FontFormat : "Karakter formaat", -Font : "Karakters", -FontSize : "Karakter grote", -TextColor : "Karakter kleur", -BGColor : "Agtergrond kleur", -Source : "Source", -Find : "Vind", -Replace : "Vervang", -SpellCheck : "Spelling nagaan", -UniversalKeyboard : "Universeele Sleutelbord", -PageBreakLbl : "Bladsy breek", -PageBreak : "Bladsy breek byvoeg", - -Form : "Form", -Checkbox : "HakBox", -RadioButton : "PuntBox", -TextField : "Byvoegbare karakter strook", -Textarea : "Byvoegbare karakter area", -HiddenField : "Blinde strook", -Button : "Knop", -SelectionField : "Opklapbare keuse strook", -ImageButton : "Beeld knop", - -FitWindow : "Maksimaliseer venster grote", -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "Verander skakel", -CellCM : "Cell", -RowCM : "Ry", -ColumnCM : "Kolom", -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "Ry verweider", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "Kolom verweider", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "Cell verweider", -MergeCells : "Cell verenig", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "Tabel verweider", -CellProperties : "Cell eienskappe", -TableProperties : "Tabel eienskappe", -ImageProperties : "Beeld eienskappe", -FlashProperties : "Flash eienskappe", - -AnchorProp : "Plekhouer eienskappe", -ButtonProp : "Knop eienskappe", -CheckboxProp : "HakBox eienskappe", -HiddenFieldProp : "Blinde strook eienskappe", -RadioButtonProp : "PuntBox eienskappe", -ImageButtonProp : "Beeld knop eienskappe", -TextFieldProp : "Karakter strook eienskappe", -SelectionFieldProp : "Opklapbare keuse strook eienskappe", -TextareaProp : "Karakter area eienskappe", -FormProp : "Form eienskappe", - -FontFormats : "Normaal;Geformateerd;Adres;Opskrif 1;Opskrif 2;Opskrif 3;Opskrif 4;Opskrif 5;Opskrif 6;Normaal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "XHTML word verarbeit. U geduld asseblief...", -Done : "Kompleet", -PasteWordConfirm : "Die informasie wat U probeer byvoeg is warskynlik van Word. Wil U dit reinig voor die byvoeging?", -NotCompatiblePaste : "Die instruksie is beskikbaar vir Internet Explorer weergawe 5.5 of hor. Wil U dir byvoeg sonder reiniging?", -UnknownToolbarItem : "Unbekende gereedskaps balk item \"%1\"", -UnknownCommand : "Unbekende instruksie naam \"%1\"", -NotImplemented : "Instruksie is nie geimplementeer nie.", -UnknownToolbarSet : "Gereedskaps balk \"%1\" bestaan nie", -NoActiveX : "U browser sekuriteit instellings kan die funksies van die editor behinder. U moet die opsie \"Run ActiveX controls and plug-ins\" aktiveer. U ondervinding mag problematies geskiet of sekere funksionaliteit mag verhinder word.", -BrowseServerBlocked : "Die vorraad venster word geblok! Verseker asseblief dat U die \"popup blocker\" instelling verander.", -DialogBlocked : "Die dialoog venster vir verdere informasie word geblok. De-aktiveer asseblief die \"popup blocker\" instellings wat dit behinder.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Kanseleer", -DlgBtnClose : "Sluit", -DlgBtnBrowseServer : "Server deurblaai", -DlgAdvancedTag : "Ingewikkeld", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Voeg asseblief die URL in", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Taal rigting", -DlgGenLangDirLtr : "Links na regs (LTR)", -DlgGenLangDirRtl : "Regs na links (RTL)", -DlgGenLangCode : "Taal kode", -DlgGenAccessKey : "Toegang sleutel", -DlgGenName : "Naam", -DlgGenTabIndex : "Tab Index", -DlgGenLongDescr : "Lang beskreiwing URL", -DlgGenClass : "Skakel Tiepe", -DlgGenTitle : "Voorbeveelings Titel", -DlgGenContType : "Voorbeveelings inhoud soort", -DlgGenLinkCharset : "Geskakelde voorbeeld karakterstel", -DlgGenStyle : "Styl", - -// Image Dialog -DlgImgTitle : "Beeld eienskappe", -DlgImgInfoTab : "Beeld informasie", -DlgImgBtnUpload : "Stuur dit na die Server", -DlgImgURL : "URL", -DlgImgUpload : "Uplaai", -DlgImgAlt : "Alternatiewe beskrywing", -DlgImgWidth : "Weidte", -DlgImgHeight : "Hoogde", -DlgImgLockRatio : "Behou preporsie", -DlgBtnResetSize : "Herstel groote", -DlgImgBorder : "Kant", -DlgImgHSpace : "HSpasie", -DlgImgVSpace : "VSpasie", -DlgImgAlign : "Paradeer", -DlgImgAlignLeft : "Links", -DlgImgAlignAbsBottom: "Abs Onder", -DlgImgAlignAbsMiddle: "Abs Middel", -DlgImgAlignBaseline : "Baseline", -DlgImgAlignBottom : "Onder", -DlgImgAlignMiddle : "Middel", -DlgImgAlignRight : "Regs", -DlgImgAlignTextTop : "Text Bo", -DlgImgAlignTop : "Bo", -DlgImgPreview : "Voorskou", -DlgImgAlertUrl : "Voeg asseblief Beeld URL in.", -DlgImgLinkTab : "Skakel", - -// Flash Dialog -DlgFlashTitle : "Flash eienskappe", -DlgFlashChkPlay : "Automaties Speel", -DlgFlashChkLoop : "Herhaling", -DlgFlashChkMenu : "Laat Flash Menu toe", -DlgFlashScale : "Scale", -DlgFlashScaleAll : "Wys alles", -DlgFlashScaleNoBorder : "Geen kante", -DlgFlashScaleFit : "Presiese pas", - -// Link Dialog -DlgLnkWindowTitle : "Skakel", -DlgLnkInfoTab : "Skakel informasie", -DlgLnkTargetTab : "Mikpunt", - -DlgLnkType : "Skakel soort", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Skakel na plekhouers in text", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protokol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Kies 'n plekhouer", -DlgLnkAnchorByName : "Volgens plekhouer naam", -DlgLnkAnchorById : "Volgens element Id", -DlgLnkNoAnchors : "(Geen plekhouers beskikbaar in dokument}", -DlgLnkEMail : "E-Mail Adres", -DlgLnkEMailSubject : "Boodskap Opskrif", -DlgLnkEMailBody : "Boodskap Inhoud", -DlgLnkUpload : "Oplaai", -DlgLnkBtnUpload : "Stuur na Server", - -DlgLnkTarget : "Mikpunt", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nuwe Venster (_blank)", -DlgLnkTargetParent : "Vorige Venster (_parent)", -DlgLnkTargetSelf : "Selfde Venster (_self)", -DlgLnkTargetTop : "Boonste Venster (_top)", -DlgLnkTargetFrameName : "Mikpunt Venster Naam", -DlgLnkPopWinName : "Popup Venster Naam", -DlgLnkPopWinFeat : "Popup Venster Geaartheid", -DlgLnkPopResize : "Verstelbare Groote", -DlgLnkPopLocation : "Adres Balk", -DlgLnkPopMenu : "Menu Balk", -DlgLnkPopScroll : "Gleibalkstuk", -DlgLnkPopStatus : "Status Balk", -DlgLnkPopToolbar : "Gereedskap Balk", -DlgLnkPopFullScrn : "Voll Skerm (IE)", -DlgLnkPopDependent : "Afhanklik (Netscape)", -DlgLnkPopWidth : "Weite", -DlgLnkPopHeight : "Hoogde", -DlgLnkPopLeft : "Links Posisie", -DlgLnkPopTop : "Bo Posisie", - -DlnLnkMsgNoUrl : "Voeg asseblief die URL in", -DlnLnkMsgNoEMail : "Voeg asseblief die e-mail adres in", -DlnLnkMsgNoAnchor : "Kies asseblief 'n plekhouer", -DlnLnkMsgInvPopName : "Die popup naam moet begin met alphabetiese karakters sonder spasies.", - -// Color Dialog -DlgColorTitle : "Kies Kleur", -DlgColorBtnClear : "Maak skoon", -DlgColorHighlight : "Highlight", -DlgColorSelected : "Geselekteer", - -// Smiley Dialog -DlgSmileyTitle : "Voeg Smiley by", - -// Special Character Dialog -DlgSpecialCharTitle : "Kies spesiale karakter", - -// Table Dialog -DlgTableTitle : "Tabel eienskappe", -DlgTableRows : "Reie", -DlgTableColumns : "Kolome", -DlgTableBorder : "Kant groote", -DlgTableAlign : "Parideering", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Links", -DlgTableAlignCenter : "Middel", -DlgTableAlignRight : "Regs", -DlgTableWidth : "Weite", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "percent", -DlgTableHeight : "Hoogde", -DlgTableCellSpace : "Cell spasieering", -DlgTableCellPad : "Cell buffer", -DlgTableCaption : "Beskreiwing", -DlgTableSummary : "Opsomming", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Cell eienskappe", -DlgCellWidth : "Weite", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "percent", -DlgCellHeight : "Hoogde", -DlgCellWordWrap : "Woord Wrap", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Ja", -DlgCellWordWrapNo : "Nee", -DlgCellHorAlign : "Horisontale rigting", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Links", -DlgCellHorAlignCenter : "Middel", -DlgCellHorAlignRight: "Regs", -DlgCellVerAlign : "Vertikale rigting", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Bo", -DlgCellVerAlignMiddle : "Middel", -DlgCellVerAlignBottom : "Onder", -DlgCellVerAlignBaseline : "Baseline", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Rei strekking", -DlgCellCollSpan : "Kolom strekking", -DlgCellBackColor : "Agtergrond Kleur", -DlgCellBorderColor : "Kant Kleur", -DlgCellBtnSelect : "Keuse...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", //MISSING - -// Find Dialog -DlgFindTitle : "Vind", -DlgFindFindBtn : "Vind", -DlgFindNotFoundMsg : "Die gespesifiseerde karakters word nie gevind nie.", - -// Replace Dialog -DlgReplaceTitle : "Vervang", -DlgReplaceFindLbl : "Soek wat:", -DlgReplaceReplaceLbl : "Vervang met:", -DlgReplaceCaseChk : "Vergelyk karakter skryfweise", -DlgReplaceReplaceBtn : "Vervang", -DlgReplaceReplAllBtn : "Vervang alles", -DlgReplaceWordChk : "Vergelyk komplete woord", - -// Paste Operations / Dialog -PasteErrorCut : "U browser se sekuriteit instelling behinder die uitsny aksie. Gebruik asseblief die sleutel kombenasie(Ctrl+X).", -PasteErrorCopy : "U browser se sekuriteit instelling behinder die kopieerings aksie. Gebruik asseblief die sleutel kombenasie(Ctrl+C).", - -PasteAsText : "Voeg slegs karakters by", -PasteFromWord : "Byvoeging uit Word", - -DlgPasteMsg2 : "Voeg asseblief die inhoud in die gegewe box by met sleutel kombenasie(Ctrl+V) en druk OK.", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", //MISSING -DlgPasteIgnoreFont : "Ignoreer karakter soort defenisies", -DlgPasteRemoveStyles : "Verweider Styl defenisies", - -// Color Picker -ColorAutomatic : "Automaties", -ColorMoreColors : "Meer Kleure...", - -// Document Properties -DocProps : "Dokument Eienskappe", - -// Anchor Dialog -DlgAnchorTitle : "Plekhouer Eienskappe", -DlgAnchorName : "Plekhouer Naam", -DlgAnchorErrorName : "Voltooi die plekhouer naam asseblief", - -// Speller Pages Dialog -DlgSpellNotInDic : "Nie in woordeboek nie", -DlgSpellChangeTo : "Verander na", -DlgSpellBtnIgnore : "Ignoreer", -DlgSpellBtnIgnoreAll : "Ignoreer na-volgende", -DlgSpellBtnReplace : "Vervang", -DlgSpellBtnReplaceAll : "vervang na-volgende", -DlgSpellBtnUndo : "Ont-skep", -DlgSpellNoSuggestions : "- Geen voorstel -", -DlgSpellProgress : "Spelling word beproef...", -DlgSpellNoMispell : "Spellproef kompleet: Geen foute", -DlgSpellNoChanges : "Spellproef kompleet: Geen woord veranderings", -DlgSpellOneChange : "Spellproef kompleet: Een woord verander", -DlgSpellManyChanges : "Spellproef kompleet: %1 woorde verander", - -IeSpellDownload : "Geen Spellproefer geinstaleer nie. Wil U dit aflaai?", - -// Button Dialog -DlgButtonText : "Karakters (Waarde)", -DlgButtonType : "Soort", -DlgButtonTypeBtn : "Knop", -DlgButtonTypeSbm : "Indien", -DlgButtonTypeRst : "Reset", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Naam", -DlgCheckboxValue : "Waarde", -DlgCheckboxSelected : "Uitgekies", - -// Form Dialog -DlgFormName : "Naam", -DlgFormAction : "Aksie", -DlgFormMethod : "Metode", - -// Select Field Dialog -DlgSelectName : "Naam", -DlgSelectValue : "Waarde", -DlgSelectSize : "Grote", -DlgSelectLines : "lyne", -DlgSelectChkMulti : "Laat meerere keuses toe", -DlgSelectOpAvail : "Beskikbare Opsies", -DlgSelectOpText : "Karakters", -DlgSelectOpValue : "Waarde", -DlgSelectBtnAdd : "Byvoeg", -DlgSelectBtnModify : "Verander", -DlgSelectBtnUp : "Op", -DlgSelectBtnDown : "Af", -DlgSelectBtnSetValue : "Stel as uitgekiesde waarde", -DlgSelectBtnDelete : "Verweider", - -// Textarea Dialog -DlgTextareaName : "Naam", -DlgTextareaCols : "Kolom", -DlgTextareaRows : "Reie", - -// Text Field Dialog -DlgTextName : "Naam", -DlgTextValue : "Waarde", -DlgTextCharWidth : "Karakter weite", -DlgTextMaxChars : "Maximale karakters", -DlgTextType : "Soort", -DlgTextTypeText : "Karakters", -DlgTextTypePass : "Wagwoord", - -// Hidden Field Dialog -DlgHiddenName : "Naam", -DlgHiddenValue : "Waarde", - -// Bulleted List Dialog -BulletedListProp : "Gepunkte lys eienskappe", -NumberedListProp : "Genommerde lys eienskappe", -DlgLstStart : "Begin", -DlgLstType : "Soort", -DlgLstTypeCircle : "Sirkel", -DlgLstTypeDisc : "Skyf", -DlgLstTypeSquare : "Vierkant", -DlgLstTypeNumbers : "Nommer (1, 2, 3)", -DlgLstTypeLCase : "Klein Letters (a, b, c)", -DlgLstTypeUCase : "Hoof Letters (A, B, C)", -DlgLstTypeSRoman : "Klein Romeinse nommers (i, ii, iii)", -DlgLstTypeLRoman : "Groot Romeinse nommers (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Algemeen", -DlgDocBackTab : "Agtergrond", -DlgDocColorsTab : "Kleure en Rante", -DlgDocMetaTab : "Meta Data", - -DlgDocPageTitle : "Bladsy Opskrif", -DlgDocLangDir : "Taal rigting", -DlgDocLangDirLTR : "Link na Regs (LTR)", -DlgDocLangDirRTL : "Regs na Links (RTL)", -DlgDocLangCode : "Taal Kode", -DlgDocCharSet : "Karakterstel Kodeering", -DlgDocCharSetCE : "Sentraal Europa", -DlgDocCharSetCT : "Chinees Traditioneel (Big5)", -DlgDocCharSetCR : "Cyrillic", -DlgDocCharSetGR : "Grieks", -DlgDocCharSetJP : "Japanees", -DlgDocCharSetKR : "Koreans", -DlgDocCharSetTR : "Turks", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Western European", -DlgDocCharSetOther : "Ander Karakterstel Kodeering", - -DlgDocDocType : "Dokument Opskrif Soort", -DlgDocDocTypeOther : "Ander Dokument Opskrif Soort", -DlgDocIncXHTML : "Voeg XHTML verklaring by", -DlgDocBgColor : "Agtergrond kleur", -DlgDocBgImage : "Agtergrond Beeld URL", -DlgDocBgNoScroll : "Vasgeklemde Agtergrond", -DlgDocCText : "Karakters", -DlgDocCLink : "Skakel", -DlgDocCVisited : "Besoekte Skakel", -DlgDocCActive : "Aktiewe Skakel", -DlgDocMargins : "Bladsy Rante", -DlgDocMaTop : "Bo", -DlgDocMaLeft : "Links", -DlgDocMaRight : "Regs", -DlgDocMaBottom : "Onder", -DlgDocMeIndex : "Dokument Index Sleutelwoorde(comma verdeelt)", -DlgDocMeDescr : "Dokument Beskrywing", -DlgDocMeAuthor : "Skrywer", -DlgDocMeCopy : "Kopiereg", -DlgDocPreview : "Voorskou", - -// Templates Dialog -Templates : "Templates", -DlgTemplatesTitle : "Inhoud Templates", -DlgTemplatesSelMsg : "Kies die template om te gebruik in die editor
    (Inhoud word vervang!):", -DlgTemplatesLoading : "Templates word gelaai. U geduld asseblief...", -DlgTemplatesNoTpl : "(Geen templates gedefinieerd)", -DlgTemplatesReplace : "Vervang bestaande inhoud", - -// About Dialog -DlgAboutAboutTab : "Meer oor", -DlgAboutBrowserInfoTab : "Blaai Informasie deur", -DlgAboutLicenseTab : "Lesensie", -DlgAboutVersion : "weergawe", -DlgAboutInfo : "Vir meer informasie gaan na ", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/ar.js b/httemplate/elements/fckeditor/editor/lang/ar.js deleted file mode 100644 index 8bbbca6e1..000000000 --- a/httemplate/elements/fckeditor/editor/lang/ar.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Arabic language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "rtl", - -ToolbarCollapse : "ضم شريط الأدوات", -ToolbarExpand : "تمدد شريط الأدوات", - -// Toolbar Items and Context Menu -Save : "حفظ", -NewPage : "صفحة جديدة", -Preview : "معاينة الصفحة", -Cut : "قص", -Copy : "نسخ", -Paste : "لصق", -PasteText : "لصق كنص بسيط", -PasteWord : "لصق من وورد", -Print : "طباعة", -SelectAll : "تحديد الكل", -RemoveFormat : "إزالة التنسيقات", -InsertLinkLbl : "رابط", -InsertLink : "إدراج/تحرير رابط", -RemoveLink : "إزالة رابط", -VisitLink : "افتح الرابط", -Anchor : "إدراج/تحرير إشارة مرجعية", -AnchorDelete : "إزالة إشارة مرجعية", -InsertImageLbl : "صورة", -InsertImage : "إدراج/تحرير صورة", -InsertFlashLbl : "فلاش", -InsertFlash : "إدراج/تحرير فيلم فلاش", -InsertTableLbl : "جدول", -InsertTable : "إدراج/تحرير جدول", -InsertLineLbl : "خط فاصل", -InsertLine : "إدراج خط فاصل", -InsertSpecialCharLbl: "رموز", -InsertSpecialChar : "إدراج رموز..ِ", -InsertSmileyLbl : "ابتسامات", -InsertSmiley : "إدراج ابتسامات", -About : "حول FCKeditor", -Bold : "غامق", -Italic : "مائل", -Underline : "تسطير", -StrikeThrough : "يتوسطه خط", -Subscript : "منخفض", -Superscript : "مرتفع", -LeftJustify : "محاذاة إلى اليسار", -CenterJustify : "توسيط", -RightJustify : "محاذاة إلى اليمين", -BlockJustify : "ضبط", -DecreaseIndent : "إنقاص المسافة البادئة", -IncreaseIndent : "زيادة المسافة البادئة", -Blockquote : "اقتباس", -CreateDiv : "إنشاء حاوية Div", -EditDiv : "تعديل حاوية Div", -DeleteDiv : "إزالة حاوية Div", -Undo : "تراجع", -Redo : "إعادة", -NumberedListLbl : "تعداد رقمي", -NumberedList : "إدراج/إلغاء تعداد رقمي", -BulletedListLbl : "تعداد نقطي", -BulletedList : "إدراج/إلغاء تعداد نقطي", -ShowTableBorders : "معاينة حدود الجداول", -ShowDetails : "معاينة التفاصيل", -Style : "نمط", -FontFormat : "تنسيق", -Font : "خط", -FontSize : "حجم الخط", -TextColor : "لون النص", -BGColor : "لون الخلفية", -Source : "شفرة المصدر", -Find : "بحث", -Replace : "إستبدال", -SpellCheck : "تدقيق إملائي", -UniversalKeyboard : "لوحة المفاتيح العالمية", -PageBreakLbl : "فصل الصفحة", -PageBreak : "إدخال صفحة جديدة", - -Form : "نموذج", -Checkbox : "خانة إختيار", -RadioButton : "زر خيار", -TextField : "مربع نص", -Textarea : "ناحية نص", -HiddenField : "إدراج حقل خفي", -Button : "زر ضغط", -SelectionField : "قائمة منسدلة", -ImageButton : "زر صورة", - -FitWindow : "تكبير حجم المحرر", -ShowBlocks : "مخطط تفصيلي", - -// Context Menu -EditLink : "تحرير رابط", -CellCM : "خلية", -RowCM : "صف", -ColumnCM : "عمود", -InsertRowAfter : "إدراج صف بعد", -InsertRowBefore : "إدراج صف قبل", -DeleteRows : "حذف صفوف", -InsertColumnAfter : "إدراج عمود بعد", -InsertColumnBefore : "إدراج عمود قبل", -DeleteColumns : "حذف أعمدة", -InsertCellAfter : "إدراج خلية بعد", -InsertCellBefore : "إدراج خلية قبل", -DeleteCells : "حذف خلايا", -MergeCells : "دمج خلايا", -MergeRight : "دمج لليمين", -MergeDown : "دمج للأسفل", -HorizontalSplitCell : "تقسيم الخلية أفقياً", -VerticalSplitCell : "تقسيم الخلية عمودياً", -TableDelete : "حذف الجدول", -CellProperties : "خصائص الخلية", -TableProperties : "خصائص الجدول", -ImageProperties : "خصائص الصورة", -FlashProperties : "خصائص فيلم الفلاش", - -AnchorProp : "خصائص الإشارة المرجعية", -ButtonProp : "خصائص زر الضغط", -CheckboxProp : "خصائص خانة الإختيار", -HiddenFieldProp : "خصائص الحقل الخفي", -RadioButtonProp : "خصائص زر الخيار", -ImageButtonProp : "خصائص زر الصورة", -TextFieldProp : "خصائص مربع النص", -SelectionFieldProp : "خصائص القائمة المنسدلة", -TextareaProp : "خصائص ناحية النص", -FormProp : "خصائص النموذج", - -FontFormats : "عادي;منسّق;دوس;العنوان 1;العنوان 2;العنوان 3;العنوان 4;العنوان 5;العنوان 6", - -// Alerts and Messages -ProcessingXHTML : "إنتظر قليلاً ريثما تتم معالَجة‏ XHTML. لن يستغرق طويلاً...", -Done : "تم", -PasteWordConfirm : "يبدو أن النص المراد لصقه منسوخ من برنامج وورد. هل تود تنظيفه قبل الشروع في عملية اللصق؟", -NotCompatiblePaste : "هذه الميزة تحتاج لمتصفح من النوعInternet Explorer إصدار 5.5 فما فوق. هل تود اللصق دون تنظيف الكود؟", -UnknownToolbarItem : "عنصر شريط أدوات غير معروف \"%1\"", -UnknownCommand : "أمر غير معروف \"%1\"", -NotImplemented : "لم يتم دعم هذا الأمر", -UnknownToolbarSet : "لم أتمكن من العثور على طقم الأدوات \"%1\" ", -NoActiveX : "لتأمين متصفحك يجب أن تحدد بعض مميزات المحرر. يتوجب عليك تمكين الخيار \"Run ActiveX controls and plug-ins\". قد تواجة أخطاء وتلاحظ مميزات مفقودة", -BrowseServerBlocked : "لايمكن فتح مصدر المتصفح. فضلا يجب التأكد بأن جميع موانع النوافذ المنبثقة معطلة", -DialogBlocked : "لايمكن فتح نافذة الحوار . فضلا تأكد من أن مانع النوافذ المنبثة معطل .", -VisitLinkBlocked : "لا يمكن فتح نافذة جديدة. تأكد من إيقاف كل مانعي فتح النوافذ من العمل.", - -// Dialogs -DlgBtnOK : "موافق", -DlgBtnCancel : "إلغاء الأمر", -DlgBtnClose : "إغلاق", -DlgBtnBrowseServer : "تصفح الخادم", -DlgAdvancedTag : "متقدم", -DlgOpOther : "<أخرى>", -DlgInfoTab : "معلومات", -DlgAlertUrl : "الرجاء كتابة عنوان الإنترنت", - -// General Dialogs Labels -DlgGenNotSet : "<بدون تحديد>", -DlgGenId : "الرقم", -DlgGenLangDir : "إتجاه النص", -DlgGenLangDirLtr : "اليسار لليمين (LTR)", -DlgGenLangDirRtl : "اليمين لليسار (RTL)", -DlgGenLangCode : "رمز اللغة", -DlgGenAccessKey : "مفاتيح الإختصار", -DlgGenName : "الاسم", -DlgGenTabIndex : "الترتيب", -DlgGenLongDescr : "عنوان الوصف المفصّل", -DlgGenClass : "فئات التنسيق", -DlgGenTitle : "تلميح الشاشة", -DlgGenContType : "نوع التلميح", -DlgGenLinkCharset : "ترميز المادة المطلوبة", -DlgGenStyle : "نمط", - -// Image Dialog -DlgImgTitle : "خصائص الصورة", -DlgImgInfoTab : "معلومات الصورة", -DlgImgBtnUpload : "أرسلها للخادم", -DlgImgURL : "موقع الصورة", -DlgImgUpload : "رفع", -DlgImgAlt : "الوصف", -DlgImgWidth : "العرض", -DlgImgHeight : "الإرتفاع", -DlgImgLockRatio : "تناسق الحجم", -DlgBtnResetSize : "إستعادة الحجم الأصلي", -DlgImgBorder : "سمك الحدود", -DlgImgHSpace : "تباعد أفقي", -DlgImgVSpace : "تباعد عمودي", -DlgImgAlign : "محاذاة", -DlgImgAlignLeft : "يسار", -DlgImgAlignAbsBottom: "أسفل النص", -DlgImgAlignAbsMiddle: "وسط السطر", -DlgImgAlignBaseline : "على السطر", -DlgImgAlignBottom : "أسفل", -DlgImgAlignMiddle : "وسط", -DlgImgAlignRight : "يمين", -DlgImgAlignTextTop : "أعلى النص", -DlgImgAlignTop : "أعلى", -DlgImgPreview : "معاينة", -DlgImgAlertUrl : "فضلاً أكتب الموقع الذي توجد عليه هذه الصورة.", -DlgImgLinkTab : "الرابط", - -// Flash Dialog -DlgFlashTitle : "خصائص فيلم الفلاش", -DlgFlashChkPlay : "تشغيل تلقائي", -DlgFlashChkLoop : "تكرار", -DlgFlashChkMenu : "تمكين قائمة فيلم الفلاش", -DlgFlashScale : "الحجم", -DlgFlashScaleAll : "إظهار الكل", -DlgFlashScaleNoBorder : "بلا حدود", -DlgFlashScaleFit : "ضبط تام", - -// Link Dialog -DlgLnkWindowTitle : "إرتباط تشعبي", -DlgLnkInfoTab : "معلومات الرابط", -DlgLnkTargetTab : "الهدف", - -DlgLnkType : "نوع الربط", -DlgLnkTypeURL : "العنوان", -DlgLnkTypeAnchor : "مكان في هذا المستند", -DlgLnkTypeEMail : "بريد إلكتروني", -DlgLnkProto : "البروتوكول", -DlgLnkProtoOther : "<أخرى>", -DlgLnkURL : "الموقع", -DlgLnkAnchorSel : "اختر علامة مرجعية", -DlgLnkAnchorByName : "حسب اسم العلامة", -DlgLnkAnchorById : "حسب تعريف العنصر", -DlgLnkNoAnchors : "(لا يوجد علامات مرجعية في هذا المستند)", -DlgLnkEMail : "عنوان بريد إلكتروني", -DlgLnkEMailSubject : "موضوع الرسالة", -DlgLnkEMailBody : "محتوى الرسالة", -DlgLnkUpload : "رفع", -DlgLnkBtnUpload : "أرسلها للخادم", - -DlgLnkTarget : "الهدف", -DlgLnkTargetFrame : "<إطار>", -DlgLnkTargetPopup : "<نافذة منبثقة>", -DlgLnkTargetBlank : "إطار جديد (_blank)", -DlgLnkTargetParent : "الإطار الأصل (_parent)", -DlgLnkTargetSelf : "نفس الإطار (_self)", -DlgLnkTargetTop : "صفحة كاملة (_top)", -DlgLnkTargetFrameName : "اسم الإطار الهدف", -DlgLnkPopWinName : "تسمية النافذة المنبثقة", -DlgLnkPopWinFeat : "خصائص النافذة المنبثقة", -DlgLnkPopResize : "قابلة للتحجيم", -DlgLnkPopLocation : "شريط العنوان", -DlgLnkPopMenu : "القوائم الرئيسية", -DlgLnkPopScroll : "أشرطة التمرير", -DlgLnkPopStatus : "شريط الحالة السفلي", -DlgLnkPopToolbar : "شريط الأدوات", -DlgLnkPopFullScrn : "ملئ الشاشة (IE)", -DlgLnkPopDependent : "تابع (Netscape)", -DlgLnkPopWidth : "العرض", -DlgLnkPopHeight : "الإرتفاع", -DlgLnkPopLeft : "التمركز لليسار", -DlgLnkPopTop : "التمركز للأعلى", - -DlnLnkMsgNoUrl : "فضلاً أدخل عنوان الموقع الذي يشير إليه الرابط", -DlnLnkMsgNoEMail : "فضلاً أدخل عنوان البريد الإلكتروني", -DlnLnkMsgNoAnchor : "فضلاً حدد العلامة المرجعية المرغوبة", -DlnLnkMsgInvPopName : "اسم النافذة المنبثقة يجب أن يبدأ بحرف أبجدي دون مسافات", - -// Color Dialog -DlgColorTitle : "اختر لوناً", -DlgColorBtnClear : "مسح", -DlgColorHighlight : "تحديد", -DlgColorSelected : "إختيار", - -// Smiley Dialog -DlgSmileyTitle : "إدراج إبتسامات ", - -// Special Character Dialog -DlgSpecialCharTitle : "إدراج رمز", - -// Table Dialog -DlgTableTitle : "إدراج جدول", -DlgTableRows : "صفوف", -DlgTableColumns : "أعمدة", -DlgTableBorder : "سمك الحدود", -DlgTableAlign : "المحاذاة", -DlgTableAlignNotSet : "<بدون تحديد>", -DlgTableAlignLeft : "يسار", -DlgTableAlignCenter : "وسط", -DlgTableAlignRight : "يمين", -DlgTableWidth : "العرض", -DlgTableWidthPx : "بكسل", -DlgTableWidthPc : "بالمئة", -DlgTableHeight : "الإرتفاع", -DlgTableCellSpace : "تباعد الخلايا", -DlgTableCellPad : "المسافة البادئة", -DlgTableCaption : "الوصف", -DlgTableSummary : "الخلاصة", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "خصائص الخلية", -DlgCellWidth : "العرض", -DlgCellWidthPx : "بكسل", -DlgCellWidthPc : "بالمئة", -DlgCellHeight : "الإرتفاع", -DlgCellWordWrap : "التفاف النص", -DlgCellWordWrapNotSet : "<بدون تحديد>", -DlgCellWordWrapYes : "نعم", -DlgCellWordWrapNo : "لا", -DlgCellHorAlign : "المحاذاة الأفقية", -DlgCellHorAlignNotSet : "<بدون تحديد>", -DlgCellHorAlignLeft : "يسار", -DlgCellHorAlignCenter : "وسط", -DlgCellHorAlignRight: "يمين", -DlgCellVerAlign : "المحاذاة العمودية", -DlgCellVerAlignNotSet : "<بدون تحديد>", -DlgCellVerAlignTop : "أعلى", -DlgCellVerAlignMiddle : "وسط", -DlgCellVerAlignBottom : "أسفل", -DlgCellVerAlignBaseline : "على السطر", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "إمتداد الصفوف", -DlgCellCollSpan : "إمتداد الأعمدة", -DlgCellBackColor : "لون الخلفية", -DlgCellBorderColor : "لون الحدود", -DlgCellBtnSelect : "حدّد...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "بحث واستبدال", - -// Find Dialog -DlgFindTitle : "بحث", -DlgFindFindBtn : "ابحث", -DlgFindNotFoundMsg : "لم يتم العثور على النص المحدد.", - -// Replace Dialog -DlgReplaceTitle : "إستبدال", -DlgReplaceFindLbl : "البحث عن:", -DlgReplaceReplaceLbl : "إستبدال بـ:", -DlgReplaceCaseChk : "مطابقة حالة الأحرف", -DlgReplaceReplaceBtn : "إستبدال", -DlgReplaceReplAllBtn : "إستبدال الكل", -DlgReplaceWordChk : "الكلمة بالكامل فقط", - -// Paste Operations / Dialog -PasteErrorCut : "الإعدادات الأمنية للمتصفح الذي تستخدمه تمنع القص التلقائي. فضلاً إستخدم لوحة المفاتيح لفعل ذلك (Ctrl+X).", -PasteErrorCopy : "الإعدادات الأمنية للمتصفح الذي تستخدمه تمنع النسخ التلقائي. فضلاً إستخدم لوحة المفاتيح لفعل ذلك (Ctrl+C).", - -PasteAsText : "لصق كنص بسيط", -PasteFromWord : "لصق من وورد", - -DlgPasteMsg2 : "الصق داخل الصندوق بإستخدام زرّي (Ctrl+V) في لوحة المفاتيح، ثم اضغط زر موافق.", -DlgPasteSec : "نظراً لإعدادات الأمان الخاصة بمتصفحك، لن يتمكن هذا المحرر من الوصول لمحتوى حافظتك، لذا وجب عليك لصق المحتوى مرة أخرى في هذه النافذة.", -DlgPasteIgnoreFont : "تجاهل تعريفات أسماء الخطوط", -DlgPasteRemoveStyles : "إزالة تعريفات الأنماط", - -// Color Picker -ColorAutomatic : "تلقائي", -ColorMoreColors : "ألوان إضافية...", - -// Document Properties -DocProps : "خصائص الصفحة", - -// Anchor Dialog -DlgAnchorTitle : "خصائص إشارة مرجعية", -DlgAnchorName : "اسم الإشارة المرجعية", -DlgAnchorErrorName : "الرجاء كتابة اسم الإشارة المرجعية", - -// Speller Pages Dialog -DlgSpellNotInDic : "ليست في القاموس", -DlgSpellChangeTo : "التغيير إلى", -DlgSpellBtnIgnore : "تجاهل", -DlgSpellBtnIgnoreAll : "تجاهل الكل", -DlgSpellBtnReplace : "تغيير", -DlgSpellBtnReplaceAll : "تغيير الكل", -DlgSpellBtnUndo : "تراجع", -DlgSpellNoSuggestions : "- لا توجد إقتراحات -", -DlgSpellProgress : "جاري التدقيق إملائياً", -DlgSpellNoMispell : "تم إكمال التدقيق الإملائي: لم يتم العثور على أي أخطاء إملائية", -DlgSpellNoChanges : "تم إكمال التدقيق الإملائي: لم يتم تغيير أي كلمة", -DlgSpellOneChange : "تم إكمال التدقيق الإملائي: تم تغيير كلمة واحدة فقط", -DlgSpellManyChanges : "تم إكمال التدقيق الإملائي: تم تغيير %1 كلمات\كلمة", - -IeSpellDownload : "المدقق الإملائي (الإنجليزي) غير مثبّت. هل تود تحميله الآن؟", - -// Button Dialog -DlgButtonText : "القيمة/التسمية", -DlgButtonType : "نوع الزر", -DlgButtonTypeBtn : "زر", -DlgButtonTypeSbm : "إرسال", -DlgButtonTypeRst : "إعادة تعيين", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "الاسم", -DlgCheckboxValue : "القيمة", -DlgCheckboxSelected : "محدد", - -// Form Dialog -DlgFormName : "الاسم", -DlgFormAction : "اسم الملف", -DlgFormMethod : "الأسلوب", - -// Select Field Dialog -DlgSelectName : "الاسم", -DlgSelectValue : "القيمة", -DlgSelectSize : "الحجم", -DlgSelectLines : "الأسطر", -DlgSelectChkMulti : "السماح بتحديدات متعددة", -DlgSelectOpAvail : "الخيارات المتاحة", -DlgSelectOpText : "النص", -DlgSelectOpValue : "القيمة", -DlgSelectBtnAdd : "إضافة", -DlgSelectBtnModify : "تعديل", -DlgSelectBtnUp : "تحريك لأعلى", -DlgSelectBtnDown : "تحريك لأسفل", -DlgSelectBtnSetValue : "إجعلها محددة", -DlgSelectBtnDelete : "إزالة", - -// Textarea Dialog -DlgTextareaName : "الاسم", -DlgTextareaCols : "الأعمدة", -DlgTextareaRows : "الصفوف", - -// Text Field Dialog -DlgTextName : "الاسم", -DlgTextValue : "القيمة", -DlgTextCharWidth : "العرض بالأحرف", -DlgTextMaxChars : "عدد الحروف الأقصى", -DlgTextType : "نوع المحتوى", -DlgTextTypeText : "نص", -DlgTextTypePass : "كلمة مرور", - -// Hidden Field Dialog -DlgHiddenName : "الاسم", -DlgHiddenValue : "القيمة", - -// Bulleted List Dialog -BulletedListProp : "خصائص التعداد النقطي", -NumberedListProp : "خصائص التعداد الرقمي", -DlgLstStart : "البدء عند", -DlgLstType : "النوع", -DlgLstTypeCircle : "دائرة", -DlgLstTypeDisc : "قرص", -DlgLstTypeSquare : "مربع", -DlgLstTypeNumbers : "أرقام (1، 2، 3)َ", -DlgLstTypeLCase : "حروف صغيرة (a, b, c)َ", -DlgLstTypeUCase : "حروف كبيرة (A, B, C)َ", -DlgLstTypeSRoman : "ترقيم روماني صغير (i, ii, iii)َ", -DlgLstTypeLRoman : "ترقيم روماني كبير (I, II, III)َ", - -// Document Properties Dialog -DlgDocGeneralTab : "عام", -DlgDocBackTab : "الخلفية", -DlgDocColorsTab : "الألوان والهوامش", -DlgDocMetaTab : "المعرّفات الرأسية", - -DlgDocPageTitle : "عنوان الصفحة", -DlgDocLangDir : "إتجاه اللغة", -DlgDocLangDirLTR : "اليسار لليمين (LTR)", -DlgDocLangDirRTL : "اليمين لليسار (RTL)", -DlgDocLangCode : "رمز اللغة", -DlgDocCharSet : "ترميز الحروف", -DlgDocCharSetCE : "أوروبا الوسطى", -DlgDocCharSetCT : "الصينية التقليدية (Big5)", -DlgDocCharSetCR : "السيريلية", -DlgDocCharSetGR : "اليونانية", -DlgDocCharSetJP : "اليابانية", -DlgDocCharSetKR : "الكورية", -DlgDocCharSetTR : "التركية", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "أوروبا الغربية", -DlgDocCharSetOther : "ترميز آخر", - -DlgDocDocType : "ترويسة نوع الصفحة", -DlgDocDocTypeOther : "ترويسة نوع صفحة أخرى", -DlgDocIncXHTML : "تضمين إعلانات‏ لغة XHTMLَ", -DlgDocBgColor : "لون الخلفية", -DlgDocBgImage : "رابط الصورة الخلفية", -DlgDocBgNoScroll : "جعلها علامة مائية", -DlgDocCText : "النص", -DlgDocCLink : "الروابط", -DlgDocCVisited : "المزارة", -DlgDocCActive : "النشطة", -DlgDocMargins : "هوامش الصفحة", -DlgDocMaTop : "علوي", -DlgDocMaLeft : "أيسر", -DlgDocMaRight : "أيمن", -DlgDocMaBottom : "سفلي", -DlgDocMeIndex : "الكلمات الأساسية (مفصولة بفواصل)َ", -DlgDocMeDescr : "وصف الصفحة", -DlgDocMeAuthor : "الكاتب", -DlgDocMeCopy : "المالك", -DlgDocPreview : "معاينة", - -// Templates Dialog -Templates : "القوالب", -DlgTemplatesTitle : "قوالب المحتوى", -DlgTemplatesSelMsg : "اختر القالب الذي تود وضعه في المحرر
    (سيتم فقدان المحتوى الحالي):", -DlgTemplatesLoading : "جاري تحميل قائمة القوالب، الرجاء الإنتظار...", -DlgTemplatesNoTpl : "(لم يتم تعريف أي قالب)", -DlgTemplatesReplace : "استبدال المحتوى", - -// About Dialog -DlgAboutAboutTab : "نبذة", -DlgAboutBrowserInfoTab : "معلومات متصفحك", -DlgAboutLicenseTab : "الترخيص", -DlgAboutVersion : "الإصدار", -DlgAboutInfo : "لمزيد من المعلومات تفضل بزيارة", - -// Div Dialog -DlgDivGeneralTab : "عام", -DlgDivAdvancedTab : "متقدم", -DlgDivStyle : "المظهر", -DlgDivInlineStyle : "المظهر المضمن", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/bg.js b/httemplate/elements/fckeditor/editor/lang/bg.js deleted file mode 100644 index 0a9022f0f..000000000 --- a/httemplate/elements/fckeditor/editor/lang/bg.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Bulgarian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Скрий панела с инструментите", -ToolbarExpand : "Покажи панела с инструментите", - -// Toolbar Items and Context Menu -Save : "Запази", -NewPage : "Нова страница", -Preview : "Предварителен изглед", -Cut : "Изрежи", -Copy : "Запамети", -Paste : "Вмъкни", -PasteText : "Вмъкни само текст", -PasteWord : "Вмъкни от MS Word", -Print : "Печат", -SelectAll : "Селектирай всичко", -RemoveFormat : "Изтрий форматирането", -InsertLinkLbl : "Връзка", -InsertLink : "Добави/Редактирай връзка", -RemoveLink : "Изтрий връзка", -VisitLink : "Open Link", //MISSING -Anchor : "Добави/Редактирай котва", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "Изображение", -InsertImage : "Добави/Редактирай изображение", -InsertFlashLbl : "Flash", -InsertFlash : "Добави/Редактиай Flash обект", -InsertTableLbl : "Таблица", -InsertTable : "Добави/Редактирай таблица", -InsertLineLbl : "Линия", -InsertLine : "Вмъкни хоризонтална линия", -InsertSpecialCharLbl: "Специален символ", -InsertSpecialChar : "Вмъкни специален символ", -InsertSmileyLbl : "Усмивка", -InsertSmiley : "Добави усмивка", -About : "За FCKeditor", -Bold : "Удебелен", -Italic : "Курсив", -Underline : "Подчертан", -StrikeThrough : "Зачертан", -Subscript : "Индекс за база", -Superscript : "Индекс за степен", -LeftJustify : "Подравняване в ляво", -CenterJustify : "Подравнявне в средата", -RightJustify : "Подравняване в дясно", -BlockJustify : "Двустранно подравняване", -DecreaseIndent : "Намали отстъпа", -IncreaseIndent : "Увеличи отстъпа", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Отмени", -Redo : "Повтори", -NumberedListLbl : "Нумериран списък", -NumberedList : "Добави/Изтрий нумериран списък", -BulletedListLbl : "Ненумериран списък", -BulletedList : "Добави/Изтрий ненумериран списък", -ShowTableBorders : "Покажи рамките на таблицата", -ShowDetails : "Покажи подробности", -Style : "Стил", -FontFormat : "Формат", -Font : "Шрифт", -FontSize : "Размер", -TextColor : "Цвят на текста", -BGColor : "Цвят на фона", -Source : "Код", -Find : "Търси", -Replace : "Замести", -SpellCheck : "Провери правописа", -UniversalKeyboard : "Универсална клавиатура", -PageBreakLbl : "Нов ред", -PageBreak : "Вмъкни нов ред", - -Form : "Формуляр", -Checkbox : "Поле за отметка", -RadioButton : "Поле за опция", -TextField : "Текстово поле", -Textarea : "Текстова област", -HiddenField : "Скрито поле", -Button : "Бутон", -SelectionField : "Падащо меню с опции", -ImageButton : "Бутон-изображение", - -FitWindow : "Maximize the editor size", //MISSING -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "Редактирай връзка", -CellCM : "Cell", //MISSING -RowCM : "Row", //MISSING -ColumnCM : "Column", //MISSING -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "Изтрий редовете", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "Изтрий колоните", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "Изтрий клетките", -MergeCells : "Обедини клетките", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "Изтрий таблицата", -CellProperties : "Параметри на клетката", -TableProperties : "Параметри на таблицата", -ImageProperties : "Параметри на изображението", -FlashProperties : "Параметри на Flash обекта", - -AnchorProp : "Параметри на котвата", -ButtonProp : "Параметри на бутона", -CheckboxProp : "Параметри на полето за отметка", -HiddenFieldProp : "Параметри на скритото поле", -RadioButtonProp : "Параметри на полето за опция", -ImageButtonProp : "Параметри на бутона-изображение", -TextFieldProp : "Параметри на текстовото-поле", -SelectionFieldProp : "Параметри на падащото меню с опции", -TextareaProp : "Параметри на текстовата област", -FormProp : "Параметри на формуляра", - -FontFormats : "Нормален;Форматиран;Адрес;Заглавие 1;Заглавие 2;Заглавие 3;Заглавие 4;Заглавие 5;Заглавие 6;Параграф (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Обработка на XHTML. Моля изчакайте...", -Done : "Готово", -PasteWordConfirm : "Текстът, който искате да вмъкнете е копиран от MS Word. Желаете ли да бъде изчистен преди вмъкването?", -NotCompatiblePaste : "Тази операция изисква MS Internet Explorer версия 5.5 или по-висока. Желаете ли да вмъкнете запаметеното без изчистване?", -UnknownToolbarItem : "Непознат инструмент \"%1\"", -UnknownCommand : "Непозната команда \"%1\"", -NotImplemented : "Командата не е имплементирана", -UnknownToolbarSet : "Панелът \"%1\" не съществува", -NoActiveX : "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.", //MISSING -BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.", //MISSING -DialogBlocked : "It was not possible to open the dialog window. Make sure all popup blockers are disabled.", //MISSING -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "ОК", -DlgBtnCancel : "Отказ", -DlgBtnClose : "Затвори", -DlgBtnBrowseServer : "Разгледай сървъра", -DlgAdvancedTag : "Подробности...", -DlgOpOther : "<Друго>", -DlgInfoTab : "Информация", -DlgAlertUrl : "Моля, въведете пълния път (URL)", - -// General Dialogs Labels -DlgGenNotSet : "<не е настроен>", -DlgGenId : "Идентификатор", -DlgGenLangDir : "посока на речта", -DlgGenLangDirLtr : "От ляво на дясно", -DlgGenLangDirRtl : "От дясно на ляво", -DlgGenLangCode : "Код на езика", -DlgGenAccessKey : "Бърз клавиш", -DlgGenName : "Име", -DlgGenTabIndex : "Ред на достъп", -DlgGenLongDescr : "Описание на връзката", -DlgGenClass : "Клас от стиловите таблици", -DlgGenTitle : "Препоръчително заглавие", -DlgGenContType : "Препоръчителен тип на съдържанието", -DlgGenLinkCharset : "Тип на свързания ресурс", -DlgGenStyle : "Стил", - -// Image Dialog -DlgImgTitle : "Параметри на изображението", -DlgImgInfoTab : "Информация за изображението", -DlgImgBtnUpload : "Прати към сървъра", -DlgImgURL : "Пълен път (URL)", -DlgImgUpload : "Качи", -DlgImgAlt : "Алтернативен текст", -DlgImgWidth : "Ширина", -DlgImgHeight : "Височина", -DlgImgLockRatio : "Запази пропорцията", -DlgBtnResetSize : "Възстанови размера", -DlgImgBorder : "Рамка", -DlgImgHSpace : "Хоризонтален отстъп", -DlgImgVSpace : "Вертикален отстъп", -DlgImgAlign : "Подравняване", -DlgImgAlignLeft : "Ляво", -DlgImgAlignAbsBottom: "Най-долу", -DlgImgAlignAbsMiddle: "Точно по средата", -DlgImgAlignBaseline : "По базовата линия", -DlgImgAlignBottom : "Долу", -DlgImgAlignMiddle : "По средата", -DlgImgAlignRight : "Дясно", -DlgImgAlignTextTop : "Върху текста", -DlgImgAlignTop : "Отгоре", -DlgImgPreview : "Изглед", -DlgImgAlertUrl : "Моля, въведете пълния път до изображението", -DlgImgLinkTab : "Връзка", - -// Flash Dialog -DlgFlashTitle : "Параметри на Flash обекта", -DlgFlashChkPlay : "Автоматично стартиране", -DlgFlashChkLoop : "Ново стартиране след завършването", -DlgFlashChkMenu : "Разрешено Flash меню", -DlgFlashScale : "Оразмеряване", -DlgFlashScaleAll : "Покажи целия обект", -DlgFlashScaleNoBorder : "Без рамка", -DlgFlashScaleFit : "Според мястото", - -// Link Dialog -DlgLnkWindowTitle : "Връзка", -DlgLnkInfoTab : "Информация за връзката", -DlgLnkTargetTab : "Цел", - -DlgLnkType : "Вид на връзката", -DlgLnkTypeURL : "Пълен път (URL)", -DlgLnkTypeAnchor : "Котва в текущата страница", -DlgLnkTypeEMail : "Е-поща", -DlgLnkProto : "Протокол", -DlgLnkProtoOther : "<друго>", -DlgLnkURL : "Пълен път (URL)", -DlgLnkAnchorSel : "Изберете котва", -DlgLnkAnchorByName : "По име на котвата", -DlgLnkAnchorById : "По идентификатор на елемент", -DlgLnkNoAnchors : "(Няма котви в текущия документ)", -DlgLnkEMail : "Адрес за е-поща", -DlgLnkEMailSubject : "Тема на писмото", -DlgLnkEMailBody : "Текст на писмото", -DlgLnkUpload : "Качи", -DlgLnkBtnUpload : "Прати на сървъра", - -DlgLnkTarget : "Цел", -DlgLnkTargetFrame : "<рамка>", -DlgLnkTargetPopup : "<дъщерен прозорец>", -DlgLnkTargetBlank : "Нов прозорец (_blank)", -DlgLnkTargetParent : "Родителски прозорец (_parent)", -DlgLnkTargetSelf : "Активния прозорец (_self)", -DlgLnkTargetTop : "Целия прозорец (_top)", -DlgLnkTargetFrameName : "Име на целевия прозорец", -DlgLnkPopWinName : "Име на дъщерния прозорец", -DlgLnkPopWinFeat : "Параметри на дъщерния прозорец", -DlgLnkPopResize : "С променливи размери", -DlgLnkPopLocation : "Поле за адрес", -DlgLnkPopMenu : "Меню", -DlgLnkPopScroll : "Плъзгач", -DlgLnkPopStatus : "Поле за статус", -DlgLnkPopToolbar : "Панел с бутони", -DlgLnkPopFullScrn : "Голям екран (MS IE)", -DlgLnkPopDependent : "Зависим (Netscape)", -DlgLnkPopWidth : "Ширина", -DlgLnkPopHeight : "Височина", -DlgLnkPopLeft : "Координати - X", -DlgLnkPopTop : "Координати - Y", - -DlnLnkMsgNoUrl : "Моля, напишете пълния път (URL)", -DlnLnkMsgNoEMail : "Моля, напишете адреса за е-поща", -DlnLnkMsgNoAnchor : "Моля, изберете котва", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", //MISSING - -// Color Dialog -DlgColorTitle : "Изберете цвят", -DlgColorBtnClear : "Изчисти", -DlgColorHighlight : "Текущ", -DlgColorSelected : "Избран", - -// Smiley Dialog -DlgSmileyTitle : "Добави усмивка", - -// Special Character Dialog -DlgSpecialCharTitle : "Изберете специален символ", - -// Table Dialog -DlgTableTitle : "Параметри на таблицата", -DlgTableRows : "Редове", -DlgTableColumns : "Колони", -DlgTableBorder : "Размер на рамката", -DlgTableAlign : "Подравняване", -DlgTableAlignNotSet : "<Не е избрано>", -DlgTableAlignLeft : "Ляво", -DlgTableAlignCenter : "Център", -DlgTableAlignRight : "Дясно", -DlgTableWidth : "Ширина", -DlgTableWidthPx : "пиксели", -DlgTableWidthPc : "проценти", -DlgTableHeight : "Височина", -DlgTableCellSpace : "Разстояние между клетките", -DlgTableCellPad : "Отстъп на съдържанието в клетките", -DlgTableCaption : "Заглавие", -DlgTableSummary : "Резюме", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Параметри на клетката", -DlgCellWidth : "Ширина", -DlgCellWidthPx : "пиксели", -DlgCellWidthPc : "проценти", -DlgCellHeight : "Височина", -DlgCellWordWrap : "пренасяне на нов ред", -DlgCellWordWrapNotSet : "<Не е настроено>", -DlgCellWordWrapYes : "Да", -DlgCellWordWrapNo : "не", -DlgCellHorAlign : "Хоризонтално подравняване", -DlgCellHorAlignNotSet : "<Не е настроено>", -DlgCellHorAlignLeft : "Ляво", -DlgCellHorAlignCenter : "Център", -DlgCellHorAlignRight: "Дясно", -DlgCellVerAlign : "Вертикално подравняване", -DlgCellVerAlignNotSet : "<Не е настроено>", -DlgCellVerAlignTop : "Горе", -DlgCellVerAlignMiddle : "По средата", -DlgCellVerAlignBottom : "Долу", -DlgCellVerAlignBaseline : "По базовата линия", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "повече от един ред", -DlgCellCollSpan : "повече от една колона", -DlgCellBackColor : "фонов цвят", -DlgCellBorderColor : "цвят на рамката", -DlgCellBtnSelect : "Изберете...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", //MISSING - -// Find Dialog -DlgFindTitle : "Търси", -DlgFindFindBtn : "Търси", -DlgFindNotFoundMsg : "Указания текст не беше намерен.", - -// Replace Dialog -DlgReplaceTitle : "Замести", -DlgReplaceFindLbl : "Търси:", -DlgReplaceReplaceLbl : "Замести с:", -DlgReplaceCaseChk : "Със същия регистър", -DlgReplaceReplaceBtn : "Замести", -DlgReplaceReplAllBtn : "Замести всички", -DlgReplaceWordChk : "Търси същата дума", - -// Paste Operations / Dialog -PasteErrorCut : "Настройките за сигурност на вашия бразуър не разрешават на редактора да изпълни изрязването. За целта използвайте клавиатурата (Ctrl+X).", -PasteErrorCopy : "Настройките за сигурност на вашия бразуър не разрешават на редактора да изпълни запаметяването. За целта използвайте клавиатурата (Ctrl+C).", - -PasteAsText : "Вмъкни като чист текст", -PasteFromWord : "Вмъкни от MS Word", - -DlgPasteMsg2 : "Вмъкнете тук съдъжанието с клавиатуарата (Ctrl+V) и натиснете OK.", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", //MISSING -DlgPasteIgnoreFont : "Игнорирай шрифтовите дефиниции", -DlgPasteRemoveStyles : "Изтрий стиловите дефиниции", - -// Color Picker -ColorAutomatic : "По подразбиране", -ColorMoreColors : "Други цветове...", - -// Document Properties -DocProps : "Параметри на документа", - -// Anchor Dialog -DlgAnchorTitle : "Параметри на котвата", -DlgAnchorName : "Име на котвата", -DlgAnchorErrorName : "Моля, въведете име на котвата", - -// Speller Pages Dialog -DlgSpellNotInDic : "Липсва в речника", -DlgSpellChangeTo : "Промени на", -DlgSpellBtnIgnore : "Игнорирай", -DlgSpellBtnIgnoreAll : "Игнорирай всички", -DlgSpellBtnReplace : "Замести", -DlgSpellBtnReplaceAll : "Замести всички", -DlgSpellBtnUndo : "Отмени", -DlgSpellNoSuggestions : "- Няма предложения -", -DlgSpellProgress : "Извършване на проверката за правопис...", -DlgSpellNoMispell : "Проверката за правопис завършена: не са открити правописни грешки", -DlgSpellNoChanges : "Проверката за правопис завършена: няма променени думи", -DlgSpellOneChange : "Проверката за правопис завършена: една дума е променена", -DlgSpellManyChanges : "Проверката за правопис завършена: %1 думи са променени", - -IeSpellDownload : "Инструментът за проверка на правопис не е инсталиран. Желаете ли да го инсталирате ?", - -// Button Dialog -DlgButtonText : "Текст (Стойност)", -DlgButtonType : "Тип", -DlgButtonTypeBtn : "Button", //MISSING -DlgButtonTypeSbm : "Submit", //MISSING -DlgButtonTypeRst : "Reset", //MISSING - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Име", -DlgCheckboxValue : "Стойност", -DlgCheckboxSelected : "Отметнато", - -// Form Dialog -DlgFormName : "Име", -DlgFormAction : "Действие", -DlgFormMethod : "Метод", - -// Select Field Dialog -DlgSelectName : "Име", -DlgSelectValue : "Стойност", -DlgSelectSize : "Размер", -DlgSelectLines : "линии", -DlgSelectChkMulti : "Разрешено множествено селектиране", -DlgSelectOpAvail : "Възможни опции", -DlgSelectOpText : "Текст", -DlgSelectOpValue : "Стойност", -DlgSelectBtnAdd : "Добави", -DlgSelectBtnModify : "Промени", -DlgSelectBtnUp : "Нагоре", -DlgSelectBtnDown : "Надолу", -DlgSelectBtnSetValue : "Настрой като избрана стойност", -DlgSelectBtnDelete : "Изтрий", - -// Textarea Dialog -DlgTextareaName : "Име", -DlgTextareaCols : "Колони", -DlgTextareaRows : "Редове", - -// Text Field Dialog -DlgTextName : "Име", -DlgTextValue : "Стойност", -DlgTextCharWidth : "Ширина на символите", -DlgTextMaxChars : "Максимум символи", -DlgTextType : "Тип", -DlgTextTypeText : "Текст", -DlgTextTypePass : "Парола", - -// Hidden Field Dialog -DlgHiddenName : "Име", -DlgHiddenValue : "Стойност", - -// Bulleted List Dialog -BulletedListProp : "Параметри на ненумерирания списък", -NumberedListProp : "Параметри на нумерирания списък", -DlgLstStart : "Start", //MISSING -DlgLstType : "Тип", -DlgLstTypeCircle : "Окръжност", -DlgLstTypeDisc : "Кръг", -DlgLstTypeSquare : "Квадрат", -DlgLstTypeNumbers : "Числа (1, 2, 3)", -DlgLstTypeLCase : "Малки букви (a, b, c)", -DlgLstTypeUCase : "Големи букви (A, B, C)", -DlgLstTypeSRoman : "Малки римски числа (i, ii, iii)", -DlgLstTypeLRoman : "Големи римски числа (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Общи", -DlgDocBackTab : "Фон", -DlgDocColorsTab : "Цветове и отстъпи", -DlgDocMetaTab : "Мета данни", - -DlgDocPageTitle : "Заглавие на страницата", -DlgDocLangDir : "Посока на речта", -DlgDocLangDirLTR : "От ляво на дясно", -DlgDocLangDirRTL : "От дясно на ляво", -DlgDocLangCode : "Код на езика", -DlgDocCharSet : "Кодиране на символите", -DlgDocCharSetCE : "Central European", //MISSING -DlgDocCharSetCT : "Chinese Traditional (Big5)", //MISSING -DlgDocCharSetCR : "Cyrillic", //MISSING -DlgDocCharSetGR : "Greek", //MISSING -DlgDocCharSetJP : "Japanese", //MISSING -DlgDocCharSetKR : "Korean", //MISSING -DlgDocCharSetTR : "Turkish", //MISSING -DlgDocCharSetUN : "Unicode (UTF-8)", //MISSING -DlgDocCharSetWE : "Western European", //MISSING -DlgDocCharSetOther : "Друго кодиране на символите", - -DlgDocDocType : "Тип на документа", -DlgDocDocTypeOther : "Друг тип на документа", -DlgDocIncXHTML : "Включи XHTML декларация", -DlgDocBgColor : "Цвят на фона", -DlgDocBgImage : "Пълен път до фоновото изображение", -DlgDocBgNoScroll : "Не-повтарящо се фоново изображение", -DlgDocCText : "Текст", -DlgDocCLink : "Връзка", -DlgDocCVisited : "Посетена връзка", -DlgDocCActive : "Активна връзка", -DlgDocMargins : "Отстъпи на страницата", -DlgDocMaTop : "Горе", -DlgDocMaLeft : "Ляво", -DlgDocMaRight : "Дясно", -DlgDocMaBottom : "Долу", -DlgDocMeIndex : "Ключови думи за документа (разделени със запетаи)", -DlgDocMeDescr : "Описание на документа", -DlgDocMeAuthor : "Автор", -DlgDocMeCopy : "Авторски права", -DlgDocPreview : "Изглед", - -// Templates Dialog -Templates : "Шаблони", -DlgTemplatesTitle : "Шаблони", -DlgTemplatesSelMsg : "Изберете шаблон
    (текущото съдържание на редактора ще бъде загубено):", -DlgTemplatesLoading : "Зареждане на списъка с шаблоните. Моля изчакайте...", -DlgTemplatesNoTpl : "(Няма дефинирани шаблони)", -DlgTemplatesReplace : "Replace actual contents", //MISSING - -// About Dialog -DlgAboutAboutTab : "За", -DlgAboutBrowserInfoTab : "Информация за браузъра", -DlgAboutLicenseTab : "License", //MISSING -DlgAboutVersion : "версия", -DlgAboutInfo : "За повече информация посетете", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/bn.js b/httemplate/elements/fckeditor/editor/lang/bn.js deleted file mode 100644 index a919b987b..000000000 --- a/httemplate/elements/fckeditor/editor/lang/bn.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Bengali/Bangla language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "টূলবার গুটিয়ে দাও", -ToolbarExpand : "টূলবার ছড়িয়ে দাও", - -// Toolbar Items and Context Menu -Save : "সংরক্ষন কর", -NewPage : "নতুন পেজ", -Preview : "প্রিভিউ", -Cut : "কাট", -Copy : "কপি", -Paste : "পেস্ট", -PasteText : "পেস্ট (সাদা টেক্সট)", -PasteWord : "পেস্ট (শব্দ)", -Print : "প্রিন্ট", -SelectAll : "সব সিলেক্ট কর", -RemoveFormat : "ফরমেট সরাও", -InsertLinkLbl : "লিংকের যুক্ত করার লেবেল", -InsertLink : "লিংক যুক্ত কর", -RemoveLink : "লিংক সরাও", -VisitLink : "Open Link", //MISSING -Anchor : "নোঙ্গর", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "ছবির লেবেল যুক্ত কর", -InsertImage : "ছবি যুক্ত কর", -InsertFlashLbl : "ফ্লাশ লেবেল যুক্ত কর", -InsertFlash : "ফ্লাশ যুক্ত কর", -InsertTableLbl : "টেবিলের লেবেল যুক্ত কর", -InsertTable : "টেবিল যুক্ত কর", -InsertLineLbl : "রেখা যুক্ত কর", -InsertLine : "রেখা যুক্ত কর", -InsertSpecialCharLbl: "বিশেষ অক্ষরের লেবেল যুক্ত কর", -InsertSpecialChar : "বিশেষ অক্ষর যুক্ত কর", -InsertSmileyLbl : "স্মাইলী", -InsertSmiley : "স্মাইলী যুক্ত কর", -About : "FCKeditor কে বানিয়েছে", -Bold : "বোল্ড", -Italic : "ইটালিক", -Underline : "আন্ডারলাইন", -StrikeThrough : "স্ট্রাইক থ্রু", -Subscript : "অধোলেখ", -Superscript : "অভিলেখ", -LeftJustify : "বা দিকে ঘেঁষা", -CenterJustify : "মাঝ বরাবর ঘেষা", -RightJustify : "ডান দিকে ঘেঁষা", -BlockJustify : "ব্লক জাস্টিফাই", -DecreaseIndent : "ইনডেন্ট কমাও", -IncreaseIndent : "ইনডেন্ট বাড়াও", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "আনডু", -Redo : "রি-ডু", -NumberedListLbl : "সাংখ্যিক লিস্টের লেবেল", -NumberedList : "সাংখ্যিক লিস্ট", -BulletedListLbl : "বুলেট লিস্ট লেবেল", -BulletedList : "বুলেটেড লিস্ট", -ShowTableBorders : "টেবিল বর্ডার", -ShowDetails : "সবটুকু দেখাও", -Style : "স্টাইল", -FontFormat : "ফন্ট ফরমেট", -Font : "ফন্ট", -FontSize : "সাইজ", -TextColor : "টেক্স্ট রং", -BGColor : "বেকগ্রাউন্ড রং", -Source : "সোর্স", -Find : "খোজো", -Replace : "রিপ্লেস", -SpellCheck : "বানান চেক", -UniversalKeyboard : "সার্বজনীন কিবোর্ড", -PageBreakLbl : "পেজ ব্রেক লেবেল", -PageBreak : "পেজ ব্রেক", - -Form : "ফর্ম", -Checkbox : "চেক বাক্স", -RadioButton : "রেডিও বাটন", -TextField : "টেক্সট ফীল্ড", -Textarea : "টেক্সট এরিয়া", -HiddenField : "গুপ্ত ফীল্ড", -Button : "বাটন", -SelectionField : "বাছাই ফীল্ড", -ImageButton : "ছবির বাটন", - -FitWindow : "উইন্ডো ফিট কর", -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "লিংক সম্পাদন", -CellCM : "সেল", -RowCM : "রো", -ColumnCM : "কলাম", -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "রো মুছে দাও", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "কলাম মুছে দাও", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "সেল মুছে দাও", -MergeCells : "সেল জোড়া দাও", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "টেবিল ডিলীট কর", -CellProperties : "সেলের প্রোপার্টিজ", -TableProperties : "টেবিল প্রোপার্টি", -ImageProperties : "ছবি প্রোপার্টি", -FlashProperties : "ফ্লাশ প্রোপার্টি", - -AnchorProp : "নোঙর প্রোপার্টি", -ButtonProp : "বাটন প্রোপার্টি", -CheckboxProp : "চেক বক্স প্রোপার্টি", -HiddenFieldProp : "গুপ্ত ফীল্ড প্রোপার্টি", -RadioButtonProp : "রেডিও বাটন প্রোপার্টি", -ImageButtonProp : "ছবি বাটন প্রোপার্টি", -TextFieldProp : "টেক্সট ফীল্ড প্রোপার্টি", -SelectionFieldProp : "বাছাই ফীল্ড প্রোপার্টি", -TextareaProp : "টেক্সট এরিয়া প্রোপার্টি", -FormProp : "ফর্ম প্রোপার্টি", - -FontFormats : "সাধারণ;ফর্মেটেড;ঠিকানা;শীর্ষক ১;শীর্ষক ২;শীর্ষক ৩;শীর্ষক ৪;শীর্ষক ৫;শীর্ষক ৬;শীর্ষক (DIV)", - -// Alerts and Messages -ProcessingXHTML : "XHTML প্রসেস করা হচ্ছে", -Done : "শেষ হয়েছে", -PasteWordConfirm : "যে টেকস্টটি আপনি পেস্ট করতে চাচ্ছেন মনে হচ্ছে সেটি ওয়ার্ড থেকে কপি করা। আপনি কি পেস্ট করার আগে একে পরিষ্কার করতে চান?", -NotCompatiblePaste : "এই কমান্ডটি শুধুমাত্র ইন্টারনেট এক্সপ্লোরার ৫.০ বা তার পরের ভার্সনে পাওয়া সম্ভব। আপনি কি পরিষ্কার না করেই পেস্ট করতে চান?", -UnknownToolbarItem : "অজানা টুলবার আইটেম \"%1\"", -UnknownCommand : "অজানা কমান্ড \"%1\"", -NotImplemented : "কমান্ড ইমপ্লিমেন্ট করা হয়নি", -UnknownToolbarSet : "টুলবার সেট \"%1\" এর অস্তিত্ব নেই", -NoActiveX : "আপনার ব্রাউজারের সুরক্ষা সেটিংস কারনে এডিটরের কিছু ফিচার পাওয়া নাও যেতে পারে। আপনাকে অবশ্যই \"Run ActiveX controls and plug-ins\" এনাবেল করে নিতে হবে। আপনি ভুলভ্রান্তি কিছু কিছু ফিচারের অনুপস্থিতি উপলব্ধি করতে পারেন।", -BrowseServerBlocked : "রিসোর্স ব্রাউজার খোলা গেল না। নিশ্চিত করুন যে সব পপআপ ব্লকার বন্ধ করা আছে।", -DialogBlocked : "ডায়ালগ ইউন্ডো খোলা গেল না। নিশ্চিত করুন যে সব পপআপ ব্লকার বন্ধ করা আছে।", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "ওকে", -DlgBtnCancel : "বাতিল", -DlgBtnClose : "বন্ধ কর", -DlgBtnBrowseServer : "ব্রাউজ সার্ভার", -DlgAdvancedTag : "এডভান্সড", -DlgOpOther : "<অন্য>", -DlgInfoTab : "তথ্য", -DlgAlertUrl : "দয়া করে URL যুক্ত করুন", - -// General Dialogs Labels -DlgGenNotSet : "<সেট নেই>", -DlgGenId : "আইডি", -DlgGenLangDir : "ভাষা লেখার দিক", -DlgGenLangDirLtr : "বাম থেকে ডান (LTR)", -DlgGenLangDirRtl : "ডান থেকে বাম (RTL)", -DlgGenLangCode : "ভাষা কোড", -DlgGenAccessKey : "এক্সেস কী", -DlgGenName : "নাম", -DlgGenTabIndex : "ট্যাব ইন্ডেক্স", -DlgGenLongDescr : "URL এর লম্বা বর্ণনা", -DlgGenClass : "স্টাইল-শীট ক্লাস", -DlgGenTitle : "পরামর্শ শীর্ষক", -DlgGenContType : "পরামর্শ কন্টেন্টের প্রকার", -DlgGenLinkCharset : "লিংক রিসোর্স ক্যারেক্টর সেট", -DlgGenStyle : "স্টাইল", - -// Image Dialog -DlgImgTitle : "ছবির প্রোপার্টি", -DlgImgInfoTab : "ছবির তথ্য", -DlgImgBtnUpload : "ইহাকে সার্ভারে প্রেরন কর", -DlgImgURL : "URL", -DlgImgUpload : "আপলোড", -DlgImgAlt : "বিকল্প টেক্সট", -DlgImgWidth : "প্রস্থ", -DlgImgHeight : "দৈর্ঘ্য", -DlgImgLockRatio : "অনুপাত লক কর", -DlgBtnResetSize : "সাইজ পূর্বাবস্থায় ফিরিয়ে দাও", -DlgImgBorder : "বর্ডার", -DlgImgHSpace : "হরাইজন্টাল স্পেস", -DlgImgVSpace : "ভার্টিকেল স্পেস", -DlgImgAlign : "এলাইন", -DlgImgAlignLeft : "বামে", -DlgImgAlignAbsBottom: "Abs নীচে", -DlgImgAlignAbsMiddle: "Abs উপর", -DlgImgAlignBaseline : "মূল রেখা", -DlgImgAlignBottom : "নীচে", -DlgImgAlignMiddle : "মধ্য", -DlgImgAlignRight : "ডানে", -DlgImgAlignTextTop : "টেক্সট উপর", -DlgImgAlignTop : "উপর", -DlgImgPreview : "প্রীভিউ", -DlgImgAlertUrl : "অনুগ্রহক করে ছবির URL টাইপ করুন", -DlgImgLinkTab : "লিংক", - -// Flash Dialog -DlgFlashTitle : "ফ্ল্যাশ প্রোপার্টি", -DlgFlashChkPlay : "অটো প্লে", -DlgFlashChkLoop : "লূপ", -DlgFlashChkMenu : "ফ্ল্যাশ মেনু এনাবল কর", -DlgFlashScale : "স্কেল", -DlgFlashScaleAll : "সব দেখাও", -DlgFlashScaleNoBorder : "কোনো বর্ডার নেই", -DlgFlashScaleFit : "নিখুঁত ফিট", - -// Link Dialog -DlgLnkWindowTitle : "লিংক", -DlgLnkInfoTab : "লিংক তথ্য", -DlgLnkTargetTab : "টার্গেট", - -DlgLnkType : "লিংক প্রকার", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "এই পেজে নোঙর কর", -DlgLnkTypeEMail : "ইমেইল", -DlgLnkProto : "প্রোটোকল", -DlgLnkProtoOther : "<অন্য>", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "নোঙর বাছাই", -DlgLnkAnchorByName : "নোঙরের নাম দিয়ে", -DlgLnkAnchorById : "নোঙরের আইডি দিয়ে", -DlgLnkNoAnchors : "(No anchors available in the document)", //MISSING -DlgLnkEMail : "ইমেইল ঠিকানা", -DlgLnkEMailSubject : "মেসেজের বিষয়", -DlgLnkEMailBody : "মেসেজের দেহ", -DlgLnkUpload : "আপলোড", -DlgLnkBtnUpload : "একে সার্ভারে পাঠাও", - -DlgLnkTarget : "টার্গেট", -DlgLnkTargetFrame : "<ফ্রেম>", -DlgLnkTargetPopup : "<পপআপ উইন্ডো>", -DlgLnkTargetBlank : "নতুন উইন্ডো (_blank)", -DlgLnkTargetParent : "মূল উইন্ডো (_parent)", -DlgLnkTargetSelf : "এই উইন্ডো (_self)", -DlgLnkTargetTop : "শীর্ষ উইন্ডো (_top)", -DlgLnkTargetFrameName : "টার্গেট ফ্রেমের নাম", -DlgLnkPopWinName : "পপআপ উইন্ডোর নাম", -DlgLnkPopWinFeat : "পপআপ উইন্ডো ফীচার সমূহ", -DlgLnkPopResize : "রিসাইজ করা সম্ভব", -DlgLnkPopLocation : "লোকেশন বার", -DlgLnkPopMenu : "মেন্যু বার", -DlgLnkPopScroll : "স্ক্রল বার", -DlgLnkPopStatus : "স্ট্যাটাস বার", -DlgLnkPopToolbar : "টুল বার", -DlgLnkPopFullScrn : "পূর্ণ পর্দা জুড়ে (IE)", -DlgLnkPopDependent : "ডিপেন্ডেন্ট (Netscape)", -DlgLnkPopWidth : "প্রস্থ", -DlgLnkPopHeight : "দৈর্ঘ্য", -DlgLnkPopLeft : "বামের পজিশন", -DlgLnkPopTop : "ডানের পজিশন", - -DlnLnkMsgNoUrl : "অনুগ্রহ করে URL লিংক টাইপ করুন", -DlnLnkMsgNoEMail : "অনুগ্রহ করে ইমেইল এড্রেস টাইপ করুন", -DlnLnkMsgNoAnchor : "অনুগ্রহ করে নোঙর বাছাই করুন", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", //MISSING - -// Color Dialog -DlgColorTitle : "রং বাছাই কর", -DlgColorBtnClear : "পরিষ্কার কর", -DlgColorHighlight : "হাইলাইট", -DlgColorSelected : "সিলেক্টেড", - -// Smiley Dialog -DlgSmileyTitle : "স্মাইলী যুক্ত কর", - -// Special Character Dialog -DlgSpecialCharTitle : "বিশেষ ক্যারেক্টার বাছাই কর", - -// Table Dialog -DlgTableTitle : "টেবিল প্রোপার্টি", -DlgTableRows : "রো", -DlgTableColumns : "কলাম", -DlgTableBorder : "বর্ডার সাইজ", -DlgTableAlign : "এলাইনমেন্ট", -DlgTableAlignNotSet : "<সেট নেই>", -DlgTableAlignLeft : "বামে", -DlgTableAlignCenter : "মাঝখানে", -DlgTableAlignRight : "ডানে", -DlgTableWidth : "প্রস্থ", -DlgTableWidthPx : "পিক্সেল", -DlgTableWidthPc : "শতকরা", -DlgTableHeight : "দৈর্ঘ্য", -DlgTableCellSpace : "সেল স্পেস", -DlgTableCellPad : "সেল প্যাডিং", -DlgTableCaption : "শীর্ষক", -DlgTableSummary : "সারাংশ", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "সেল প্রোপার্টি", -DlgCellWidth : "প্রস্থ", -DlgCellWidthPx : "পিক্সেল", -DlgCellWidthPc : "শতকরা", -DlgCellHeight : "দৈর্ঘ্য", -DlgCellWordWrap : "ওয়ার্ড রেপ", -DlgCellWordWrapNotSet : "<সেট নেই>", -DlgCellWordWrapYes : "হাঁ", -DlgCellWordWrapNo : "না", -DlgCellHorAlign : "হরাইজন্টাল এলাইনমেন্ট", -DlgCellHorAlignNotSet : "<সেট নেই>", -DlgCellHorAlignLeft : "বামে", -DlgCellHorAlignCenter : "মাঝখানে", -DlgCellHorAlignRight: "ডানে", -DlgCellVerAlign : "ভার্টিক্যাল এলাইনমেন্ট", -DlgCellVerAlignNotSet : "<সেট নেই>", -DlgCellVerAlignTop : "উপর", -DlgCellVerAlignMiddle : "মধ্য", -DlgCellVerAlignBottom : "নীচে", -DlgCellVerAlignBaseline : "মূলরেখা", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "রো স্প্যান", -DlgCellCollSpan : "কলাম স্প্যান", -DlgCellBackColor : "ব্যাকগ্রাউন্ড রং", -DlgCellBorderColor : "বর্ডারের রং", -DlgCellBtnSelect : "বাছাই কর", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", //MISSING - -// Find Dialog -DlgFindTitle : "খোঁজো", -DlgFindFindBtn : "খোঁজো", -DlgFindNotFoundMsg : "আপনার উল্লেখিত টেকস্ট পাওয়া যায়নি", - -// Replace Dialog -DlgReplaceTitle : "বদলে দাও", -DlgReplaceFindLbl : "যা খুঁজতে হবে:", -DlgReplaceReplaceLbl : "যার সাথে বদলাতে হবে:", -DlgReplaceCaseChk : "কেস মিলাও", -DlgReplaceReplaceBtn : "বদলে দাও", -DlgReplaceReplAllBtn : "সব বদলে দাও", -DlgReplaceWordChk : "পুরা শব্দ মেলাও", - -// Paste Operations / Dialog -PasteErrorCut : "আপনার ব্রাউজারের সুরক্ষা সেটিংস এডিটরকে অটোমেটিক কাট করার অনুমতি দেয়নি। দয়া করে এই কাজের জন্য কিবোর্ড ব্যবহার করুন (Ctrl+X)।", -PasteErrorCopy : "আপনার ব্রাউজারের সুরক্ষা সেটিংস এডিটরকে অটোমেটিক কপি করার অনুমতি দেয়নি। দয়া করে এই কাজের জন্য কিবোর্ড ব্যবহার করুন (Ctrl+C)।", - -PasteAsText : "সাদা টেক্সট হিসেবে পেস্ট কর", -PasteFromWord : "ওয়ার্ড থেকে পেস্ট কর", - -DlgPasteMsg2 : "অনুগ্রহ করে নীচের বাক্সে কিবোর্ড ব্যবহার করে (Ctrl+V) পেস্ট করুন এবং OK চাপ দিন", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", //MISSING -DlgPasteIgnoreFont : "ফন্ট ফেস ডেফিনেশন ইগনোর করুন", -DlgPasteRemoveStyles : "স্টাইল ডেফিনেশন সরিয়ে দিন", - -// Color Picker -ColorAutomatic : "অটোমেটিক", -ColorMoreColors : "আরও রং...", - -// Document Properties -DocProps : "ডক্যুমেন্ট প্রোপার্টি", - -// Anchor Dialog -DlgAnchorTitle : "নোঙরের প্রোপার্টি", -DlgAnchorName : "নোঙরের নাম", -DlgAnchorErrorName : "নোঙরের নাম টাইপ করুন", - -// Speller Pages Dialog -DlgSpellNotInDic : "শব্দকোষে নেই", -DlgSpellChangeTo : "এতে বদলাও", -DlgSpellBtnIgnore : "ইগনোর কর", -DlgSpellBtnIgnoreAll : "সব ইগনোর কর", -DlgSpellBtnReplace : "বদলে দাও", -DlgSpellBtnReplaceAll : "সব বদলে দাও", -DlgSpellBtnUndo : "আন্ডু", -DlgSpellNoSuggestions : "- কোন সাজেশন নেই -", -DlgSpellProgress : "বানান পরীক্ষা চলছে...", -DlgSpellNoMispell : "বানান পরীক্ষা শেষ: কোন ভুল বানান পাওয়া যায়নি", -DlgSpellNoChanges : "বানান পরীক্ষা শেষ: কোন শব্দ পরিবর্তন করা হয়নি", -DlgSpellOneChange : "বানান পরীক্ষা শেষ: একটি মাত্র শব্দ পরিবর্তন করা হয়েছে", -DlgSpellManyChanges : "বানান পরীক্ষা শেষ: %1 গুলো শব্দ বদলে গ্যাছে", - -IeSpellDownload : "বানান পরীক্ষক ইনস্টল করা নেই। আপনি কি এখনই এটা ডাউনলোড করতে চান?", - -// Button Dialog -DlgButtonText : "টেক্সট (ভ্যালু)", -DlgButtonType : "প্রকার", -DlgButtonTypeBtn : "Button", //MISSING -DlgButtonTypeSbm : "Submit", //MISSING -DlgButtonTypeRst : "Reset", //MISSING - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "নাম", -DlgCheckboxValue : "ভ্যালু", -DlgCheckboxSelected : "সিলেক্টেড", - -// Form Dialog -DlgFormName : "নাম", -DlgFormAction : "একশ্যন", -DlgFormMethod : "পদ্ধতি", - -// Select Field Dialog -DlgSelectName : "নাম", -DlgSelectValue : "ভ্যালু", -DlgSelectSize : "সাইজ", -DlgSelectLines : "লাইন সমূহ", -DlgSelectChkMulti : "একাধিক সিলেকশন এলাউ কর", -DlgSelectOpAvail : "অন্যান্য বিকল্প", -DlgSelectOpText : "টেক্সট", -DlgSelectOpValue : "ভ্যালু", -DlgSelectBtnAdd : "যুক্ত", -DlgSelectBtnModify : "বদলে দাও", -DlgSelectBtnUp : "উপর", -DlgSelectBtnDown : "নীচে", -DlgSelectBtnSetValue : "বাছাই করা ভ্যালু হিসেবে সেট কর", -DlgSelectBtnDelete : "ডিলীট", - -// Textarea Dialog -DlgTextareaName : "নাম", -DlgTextareaCols : "কলাম", -DlgTextareaRows : "রো", - -// Text Field Dialog -DlgTextName : "নাম", -DlgTextValue : "ভ্যালু", -DlgTextCharWidth : "ক্যারেক্টার প্রশস্ততা", -DlgTextMaxChars : "সর্বাধিক ক্যারেক্টার", -DlgTextType : "টাইপ", -DlgTextTypeText : "টেক্সট", -DlgTextTypePass : "পাসওয়ার্ড", - -// Hidden Field Dialog -DlgHiddenName : "নাম", -DlgHiddenValue : "ভ্যালু", - -// Bulleted List Dialog -BulletedListProp : "বুলেটেড সূচী প্রোপার্টি", -NumberedListProp : "সাংখ্যিক সূচী প্রোপার্টি", -DlgLstStart : "Start", //MISSING -DlgLstType : "প্রকার", -DlgLstTypeCircle : "গোল", -DlgLstTypeDisc : "ডিস্ক", -DlgLstTypeSquare : "চৌকোণা", -DlgLstTypeNumbers : "সংখ্যা (1, 2, 3)", -DlgLstTypeLCase : "ছোট অক্ষর (a, b, c)", -DlgLstTypeUCase : "বড় অক্ষর (A, B, C)", -DlgLstTypeSRoman : "ছোট রোমান সংখ্যা (i, ii, iii)", -DlgLstTypeLRoman : "বড় রোমান সংখ্যা (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "সাধারন", -DlgDocBackTab : "ব্যাকগ্রাউন্ড", -DlgDocColorsTab : "রং এবং মার্জিন", -DlgDocMetaTab : "মেটাডেটা", - -DlgDocPageTitle : "পেজ শীর্ষক", -DlgDocLangDir : "ভাষা লিখার দিক", -DlgDocLangDirLTR : "বাম থেকে ডানে (LTR)", -DlgDocLangDirRTL : "ডান থেকে বামে (RTL)", -DlgDocLangCode : "ভাষা কোড", -DlgDocCharSet : "ক্যারেক্টার সেট এনকোডিং", -DlgDocCharSetCE : "Central European", //MISSING -DlgDocCharSetCT : "Chinese Traditional (Big5)", //MISSING -DlgDocCharSetCR : "Cyrillic", //MISSING -DlgDocCharSetGR : "Greek", //MISSING -DlgDocCharSetJP : "Japanese", //MISSING -DlgDocCharSetKR : "Korean", //MISSING -DlgDocCharSetTR : "Turkish", //MISSING -DlgDocCharSetUN : "Unicode (UTF-8)", //MISSING -DlgDocCharSetWE : "Western European", //MISSING -DlgDocCharSetOther : "অন্য ক্যারেক্টার সেট এনকোডিং", - -DlgDocDocType : "ডক্যুমেন্ট টাইপ হেডিং", -DlgDocDocTypeOther : "অন্য ডক্যুমেন্ট টাইপ হেডিং", -DlgDocIncXHTML : "XHTML ডেক্লারেশন যুক্ত কর", -DlgDocBgColor : "ব্যাকগ্রাউন্ড রং", -DlgDocBgImage : "ব্যাকগ্রাউন্ড ছবির URL", -DlgDocBgNoScroll : "স্ক্রলহীন ব্যাকগ্রাউন্ড", -DlgDocCText : "টেক্সট", -DlgDocCLink : "লিংক", -DlgDocCVisited : "ভিজিট করা লিংক", -DlgDocCActive : "সক্রিয় লিংক", -DlgDocMargins : "পেজ মার্জিন", -DlgDocMaTop : "উপর", -DlgDocMaLeft : "বামে", -DlgDocMaRight : "ডানে", -DlgDocMaBottom : "নীচে", -DlgDocMeIndex : "ডক্যুমেন্ট ইন্ডেক্স কিওয়ার্ড (কমা দ্বারা বিচ্ছিন্ন)", -DlgDocMeDescr : "ডক্যূমেন্ট বর্ণনা", -DlgDocMeAuthor : "লেখক", -DlgDocMeCopy : "কপীরাইট", -DlgDocPreview : "প্রীভিউ", - -// Templates Dialog -Templates : "টেমপ্লেট", -DlgTemplatesTitle : "কনটেন্ট টেমপ্লেট", -DlgTemplatesSelMsg : "অনুগ্রহ করে এডিটরে ওপেন করার জন্য টেমপ্লেট বাছাই করুন
    (আসল কনটেন্ট হারিয়ে যাবে):", -DlgTemplatesLoading : "টেমপ্লেট লিস্ট হারিয়ে যাবে। অনুগ্রহ করে অপেক্ষা করুন...", -DlgTemplatesNoTpl : "(কোন টেমপ্লেট ডিফাইন করা নেই)", -DlgTemplatesReplace : "Replace actual contents", //MISSING - -// About Dialog -DlgAboutAboutTab : "কে বানিয়েছে", -DlgAboutBrowserInfoTab : "ব্রাউজারের ব্যাপারে তথ্য", -DlgAboutLicenseTab : "লাইসেন্স", -DlgAboutVersion : "ভার্সন", -DlgAboutInfo : "আরও তথ্যের জন্য যান", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/bs.js b/httemplate/elements/fckeditor/editor/lang/bs.js deleted file mode 100644 index 361ca5889..000000000 --- a/httemplate/elements/fckeditor/editor/lang/bs.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Bosnian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Skupi trake sa alatima", -ToolbarExpand : "Otvori trake sa alatima", - -// Toolbar Items and Context Menu -Save : "Snimi", -NewPage : "Novi dokument", -Preview : "Prikaži", -Cut : "Izreži", -Copy : "Kopiraj", -Paste : "Zalijepi", -PasteText : "Zalijepi kao obièan tekst", -PasteWord : "Zalijepi iz Word-a", -Print : "Štampaj", -SelectAll : "Selektuj sve", -RemoveFormat : "Poništi format", -InsertLinkLbl : "Link", -InsertLink : "Ubaci/Izmjeni link", -RemoveLink : "Izbriši link", -VisitLink : "Open Link", //MISSING -Anchor : "Insert/Edit Anchor", //MISSING -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "Slika", -InsertImage : "Ubaci/Izmjeni sliku", -InsertFlashLbl : "Flash", //MISSING -InsertFlash : "Insert/Edit Flash", //MISSING -InsertTableLbl : "Tabela", -InsertTable : "Ubaci/Izmjeni tabelu", -InsertLineLbl : "Linija", -InsertLine : "Ubaci horizontalnu liniju", -InsertSpecialCharLbl: "Specijalni karakter", -InsertSpecialChar : "Ubaci specijalni karater", -InsertSmileyLbl : "Smješko", -InsertSmiley : "Ubaci smješka", -About : "O FCKeditor-u", -Bold : "Boldiraj", -Italic : "Ukosi", -Underline : "Podvuci", -StrikeThrough : "Precrtaj", -Subscript : "Subscript", -Superscript : "Superscript", -LeftJustify : "Lijevo poravnanje", -CenterJustify : "Centralno poravnanje", -RightJustify : "Desno poravnanje", -BlockJustify : "Puno poravnanje", -DecreaseIndent : "Smanji uvod", -IncreaseIndent : "Poveæaj uvod", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Vrati", -Redo : "Ponovi", -NumberedListLbl : "Numerisana lista", -NumberedList : "Ubaci/Izmjeni numerisanu listu", -BulletedListLbl : "Lista", -BulletedList : "Ubaci/Izmjeni listu", -ShowTableBorders : "Pokaži okvire tabela", -ShowDetails : "Pokaži detalje", -Style : "Stil", -FontFormat : "Format", -Font : "Font", -FontSize : "Velièina", -TextColor : "Boja teksta", -BGColor : "Boja pozadine", -Source : "HTML kôd", -Find : "Naði", -Replace : "Zamjeni", -SpellCheck : "Check Spelling", //MISSING -UniversalKeyboard : "Universal Keyboard", //MISSING -PageBreakLbl : "Page Break", //MISSING -PageBreak : "Insert Page Break", //MISSING - -Form : "Form", //MISSING -Checkbox : "Checkbox", //MISSING -RadioButton : "Radio Button", //MISSING -TextField : "Text Field", //MISSING -Textarea : "Textarea", //MISSING -HiddenField : "Hidden Field", //MISSING -Button : "Button", //MISSING -SelectionField : "Selection Field", //MISSING -ImageButton : "Image Button", //MISSING - -FitWindow : "Maximize the editor size", //MISSING -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "Izmjeni link", -CellCM : "Cell", //MISSING -RowCM : "Row", //MISSING -ColumnCM : "Column", //MISSING -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "Briši redove", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "Briši kolone", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "Briši æelije", -MergeCells : "Spoji æelije", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "Delete Table", //MISSING -CellProperties : "Svojstva æelije", -TableProperties : "Svojstva tabele", -ImageProperties : "Svojstva slike", -FlashProperties : "Flash Properties", //MISSING - -AnchorProp : "Anchor Properties", //MISSING -ButtonProp : "Button Properties", //MISSING -CheckboxProp : "Checkbox Properties", //MISSING -HiddenFieldProp : "Hidden Field Properties", //MISSING -RadioButtonProp : "Radio Button Properties", //MISSING -ImageButtonProp : "Image Button Properties", //MISSING -TextFieldProp : "Text Field Properties", //MISSING -SelectionFieldProp : "Selection Field Properties", //MISSING -TextareaProp : "Textarea Properties", //MISSING -FormProp : "Form Properties", //MISSING - -FontFormats : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6", - -// Alerts and Messages -ProcessingXHTML : "Procesiram XHTML. Molim saèekajte...", -Done : "Gotovo", -PasteWordConfirm : "Tekst koji želite zalijepiti èini se da je kopiran iz Worda. Da li želite da se prvo oèisti?", -NotCompatiblePaste : "Ova komanda je podržana u Internet Explorer-u verzijama 5.5 ili novijim. Da li želite da izvršite lijepljenje teksta bez èišæenja?", -UnknownToolbarItem : "Nepoznata stavka sa trake sa alatima \"%1\"", -UnknownCommand : "Nepoznata komanda \"%1\"", -NotImplemented : "Komanda nije implementirana", -UnknownToolbarSet : "Traka sa alatima \"%1\" ne postoji", -NoActiveX : "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.", //MISSING -BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.", //MISSING -DialogBlocked : "It was not possible to open the dialog window. Make sure all popup blockers are disabled.", //MISSING -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Odustani", -DlgBtnClose : "Zatvori", -DlgBtnBrowseServer : "Browse Server", //MISSING -DlgAdvancedTag : "Naprednije", -DlgOpOther : "", //MISSING -DlgInfoTab : "Info", //MISSING -DlgAlertUrl : "Please insert the URL", //MISSING - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Smjer pisanja", -DlgGenLangDirLtr : "S lijeva na desno (LTR)", -DlgGenLangDirRtl : "S desna na lijevo (RTL)", -DlgGenLangCode : "Jezièni kôd", -DlgGenAccessKey : "Pristupna tipka", -DlgGenName : "Naziv", -DlgGenTabIndex : "Tab indeks", -DlgGenLongDescr : "Dugaèki opis URL-a", -DlgGenClass : "Klase CSS stilova", -DlgGenTitle : "Advisory title", -DlgGenContType : "Advisory vrsta sadržaja", -DlgGenLinkCharset : "Linked Resource Charset", -DlgGenStyle : "Stil", - -// Image Dialog -DlgImgTitle : "Svojstva slike", -DlgImgInfoTab : "Info slike", -DlgImgBtnUpload : "Šalji na server", -DlgImgURL : "URL", -DlgImgUpload : "Šalji", -DlgImgAlt : "Tekst na slici", -DlgImgWidth : "Širina", -DlgImgHeight : "Visina", -DlgImgLockRatio : "Zakljuèaj odnos", -DlgBtnResetSize : "Resetuj dimenzije", -DlgImgBorder : "Okvir", -DlgImgHSpace : "HSpace", -DlgImgVSpace : "VSpace", -DlgImgAlign : "Poravnanje", -DlgImgAlignLeft : "Lijevo", -DlgImgAlignAbsBottom: "Abs dole", -DlgImgAlignAbsMiddle: "Abs sredina", -DlgImgAlignBaseline : "Bazno", -DlgImgAlignBottom : "Dno", -DlgImgAlignMiddle : "Sredina", -DlgImgAlignRight : "Desno", -DlgImgAlignTextTop : "Vrh teksta", -DlgImgAlignTop : "Vrh", -DlgImgPreview : "Prikaz", -DlgImgAlertUrl : "Molimo ukucajte URL od slike.", -DlgImgLinkTab : "Link", //MISSING - -// Flash Dialog -DlgFlashTitle : "Flash Properties", //MISSING -DlgFlashChkPlay : "Auto Play", //MISSING -DlgFlashChkLoop : "Loop", //MISSING -DlgFlashChkMenu : "Enable Flash Menu", //MISSING -DlgFlashScale : "Scale", //MISSING -DlgFlashScaleAll : "Show all", //MISSING -DlgFlashScaleNoBorder : "No Border", //MISSING -DlgFlashScaleFit : "Exact Fit", //MISSING - -// Link Dialog -DlgLnkWindowTitle : "Link", -DlgLnkInfoTab : "Link info", -DlgLnkTargetTab : "Prozor", - -DlgLnkType : "Tip linka", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Sidro na ovoj stranici", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protokol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Izaberi sidro", -DlgLnkAnchorByName : "Po nazivu sidra", -DlgLnkAnchorById : "Po Id-u elementa", -DlgLnkNoAnchors : "(Nema dostupnih sidra na stranici)", -DlgLnkEMail : "E-Mail Adresa", -DlgLnkEMailSubject : "Subjekt poruke", -DlgLnkEMailBody : "Poruka", -DlgLnkUpload : "Šalji", -DlgLnkBtnUpload : "Šalji na server", - -DlgLnkTarget : "Prozor", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Novi prozor (_blank)", -DlgLnkTargetParent : "Glavni prozor (_parent)", -DlgLnkTargetSelf : "Isti prozor (_self)", -DlgLnkTargetTop : "Najgornji prozor (_top)", -DlgLnkTargetFrameName : "Target Frame Name", //MISSING -DlgLnkPopWinName : "Naziv popup prozora", -DlgLnkPopWinFeat : "Moguænosti popup prozora", -DlgLnkPopResize : "Promjenljive velièine", -DlgLnkPopLocation : "Traka za lokaciju", -DlgLnkPopMenu : "Izborna traka", -DlgLnkPopScroll : "Scroll traka", -DlgLnkPopStatus : "Statusna traka", -DlgLnkPopToolbar : "Traka sa alatima", -DlgLnkPopFullScrn : "Cijeli ekran (IE)", -DlgLnkPopDependent : "Ovisno (Netscape)", -DlgLnkPopWidth : "Širina", -DlgLnkPopHeight : "Visina", -DlgLnkPopLeft : "Lijeva pozicija", -DlgLnkPopTop : "Gornja pozicija", - -DlnLnkMsgNoUrl : "Molimo ukucajte URL link", -DlnLnkMsgNoEMail : "Molimo ukucajte e-mail adresu", -DlnLnkMsgNoAnchor : "Molimo izaberite sidro", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", //MISSING - -// Color Dialog -DlgColorTitle : "Izaberi boju", -DlgColorBtnClear : "Oèisti", -DlgColorHighlight : "Igled", -DlgColorSelected : "Selektovana", - -// Smiley Dialog -DlgSmileyTitle : "Ubaci smješka", - -// Special Character Dialog -DlgSpecialCharTitle : "Izaberi specijalni karakter", - -// Table Dialog -DlgTableTitle : "Svojstva tabele", -DlgTableRows : "Redova", -DlgTableColumns : "Kolona", -DlgTableBorder : "Okvir", -DlgTableAlign : "Poravnanje", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Lijevo", -DlgTableAlignCenter : "Centar", -DlgTableAlignRight : "Desno", -DlgTableWidth : "Širina", -DlgTableWidthPx : "piksela", -DlgTableWidthPc : "posto", -DlgTableHeight : "Visina", -DlgTableCellSpace : "Razmak æelija", -DlgTableCellPad : "Uvod æelija", -DlgTableCaption : "Naslov", -DlgTableSummary : "Summary", //MISSING -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Svojstva æelije", -DlgCellWidth : "Širina", -DlgCellWidthPx : "piksela", -DlgCellWidthPc : "posto", -DlgCellHeight : "Visina", -DlgCellWordWrap : "Vrapuj tekst", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Da", -DlgCellWordWrapNo : "Ne", -DlgCellHorAlign : "Horizontalno poravnanje", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Lijevo", -DlgCellHorAlignCenter : "Centar", -DlgCellHorAlignRight: "Desno", -DlgCellVerAlign : "Vertikalno poravnanje", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Gore", -DlgCellVerAlignMiddle : "Sredina", -DlgCellVerAlignBottom : "Dno", -DlgCellVerAlignBaseline : "Bazno", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Spajanje æelija", -DlgCellCollSpan : "Spajanje kolona", -DlgCellBackColor : "Boja pozadine", -DlgCellBorderColor : "Boja okvira", -DlgCellBtnSelect : "Selektuj...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", //MISSING - -// Find Dialog -DlgFindTitle : "Naði", -DlgFindFindBtn : "Naði", -DlgFindNotFoundMsg : "Traženi tekst nije pronaðen.", - -// Replace Dialog -DlgReplaceTitle : "Zamjeni", -DlgReplaceFindLbl : "Naði šta:", -DlgReplaceReplaceLbl : "Zamjeni sa:", -DlgReplaceCaseChk : "Uporeðuj velika/mala slova", -DlgReplaceReplaceBtn : "Zamjeni", -DlgReplaceReplAllBtn : "Zamjeni sve", -DlgReplaceWordChk : "Uporeðuj samo cijelu rijeè", - -// Paste Operations / Dialog -PasteErrorCut : "Sigurnosne postavke vašeg pretraživaèa ne dozvoljavaju operacije automatskog rezanja. Molimo koristite kraticu na tastaturi (Ctrl+X).", -PasteErrorCopy : "Sigurnosne postavke Vašeg pretraživaèa ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tastaturi (Ctrl+C).", - -PasteAsText : "Zalijepi kao obièan tekst", -PasteFromWord : "Zalijepi iz Word-a", - -DlgPasteMsg2 : "Please paste inside the following box using the keyboard (Ctrl+V) and hit OK.", //MISSING -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", //MISSING -DlgPasteIgnoreFont : "Ignore Font Face definitions", //MISSING -DlgPasteRemoveStyles : "Remove Styles definitions", //MISSING - -// Color Picker -ColorAutomatic : "Automatska", -ColorMoreColors : "Više boja...", - -// Document Properties -DocProps : "Document Properties", //MISSING - -// Anchor Dialog -DlgAnchorTitle : "Anchor Properties", //MISSING -DlgAnchorName : "Anchor Name", //MISSING -DlgAnchorErrorName : "Please type the anchor name", //MISSING - -// Speller Pages Dialog -DlgSpellNotInDic : "Not in dictionary", //MISSING -DlgSpellChangeTo : "Change to", //MISSING -DlgSpellBtnIgnore : "Ignore", //MISSING -DlgSpellBtnIgnoreAll : "Ignore All", //MISSING -DlgSpellBtnReplace : "Replace", //MISSING -DlgSpellBtnReplaceAll : "Replace All", //MISSING -DlgSpellBtnUndo : "Undo", //MISSING -DlgSpellNoSuggestions : "- No suggestions -", //MISSING -DlgSpellProgress : "Spell check in progress...", //MISSING -DlgSpellNoMispell : "Spell check complete: No misspellings found", //MISSING -DlgSpellNoChanges : "Spell check complete: No words changed", //MISSING -DlgSpellOneChange : "Spell check complete: One word changed", //MISSING -DlgSpellManyChanges : "Spell check complete: %1 words changed", //MISSING - -IeSpellDownload : "Spell checker not installed. Do you want to download it now?", //MISSING - -// Button Dialog -DlgButtonText : "Text (Value)", //MISSING -DlgButtonType : "Type", //MISSING -DlgButtonTypeBtn : "Button", //MISSING -DlgButtonTypeSbm : "Submit", //MISSING -DlgButtonTypeRst : "Reset", //MISSING - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Name", //MISSING -DlgCheckboxValue : "Value", //MISSING -DlgCheckboxSelected : "Selected", //MISSING - -// Form Dialog -DlgFormName : "Name", //MISSING -DlgFormAction : "Action", //MISSING -DlgFormMethod : "Method", //MISSING - -// Select Field Dialog -DlgSelectName : "Name", //MISSING -DlgSelectValue : "Value", //MISSING -DlgSelectSize : "Size", //MISSING -DlgSelectLines : "lines", //MISSING -DlgSelectChkMulti : "Allow multiple selections", //MISSING -DlgSelectOpAvail : "Available Options", //MISSING -DlgSelectOpText : "Text", //MISSING -DlgSelectOpValue : "Value", //MISSING -DlgSelectBtnAdd : "Add", //MISSING -DlgSelectBtnModify : "Modify", //MISSING -DlgSelectBtnUp : "Up", //MISSING -DlgSelectBtnDown : "Down", //MISSING -DlgSelectBtnSetValue : "Set as selected value", //MISSING -DlgSelectBtnDelete : "Delete", //MISSING - -// Textarea Dialog -DlgTextareaName : "Name", //MISSING -DlgTextareaCols : "Columns", //MISSING -DlgTextareaRows : "Rows", //MISSING - -// Text Field Dialog -DlgTextName : "Name", //MISSING -DlgTextValue : "Value", //MISSING -DlgTextCharWidth : "Character Width", //MISSING -DlgTextMaxChars : "Maximum Characters", //MISSING -DlgTextType : "Type", //MISSING -DlgTextTypeText : "Text", //MISSING -DlgTextTypePass : "Password", //MISSING - -// Hidden Field Dialog -DlgHiddenName : "Name", //MISSING -DlgHiddenValue : "Value", //MISSING - -// Bulleted List Dialog -BulletedListProp : "Bulleted List Properties", //MISSING -NumberedListProp : "Numbered List Properties", //MISSING -DlgLstStart : "Start", //MISSING -DlgLstType : "Type", //MISSING -DlgLstTypeCircle : "Circle", //MISSING -DlgLstTypeDisc : "Disc", //MISSING -DlgLstTypeSquare : "Square", //MISSING -DlgLstTypeNumbers : "Numbers (1, 2, 3)", //MISSING -DlgLstTypeLCase : "Lowercase Letters (a, b, c)", //MISSING -DlgLstTypeUCase : "Uppercase Letters (A, B, C)", //MISSING -DlgLstTypeSRoman : "Small Roman Numerals (i, ii, iii)", //MISSING -DlgLstTypeLRoman : "Large Roman Numerals (I, II, III)", //MISSING - -// Document Properties Dialog -DlgDocGeneralTab : "General", //MISSING -DlgDocBackTab : "Background", //MISSING -DlgDocColorsTab : "Colors and Margins", //MISSING -DlgDocMetaTab : "Meta Data", //MISSING - -DlgDocPageTitle : "Page Title", //MISSING -DlgDocLangDir : "Language Direction", //MISSING -DlgDocLangDirLTR : "Left to Right (LTR)", //MISSING -DlgDocLangDirRTL : "Right to Left (RTL)", //MISSING -DlgDocLangCode : "Language Code", //MISSING -DlgDocCharSet : "Character Set Encoding", //MISSING -DlgDocCharSetCE : "Central European", //MISSING -DlgDocCharSetCT : "Chinese Traditional (Big5)", //MISSING -DlgDocCharSetCR : "Cyrillic", //MISSING -DlgDocCharSetGR : "Greek", //MISSING -DlgDocCharSetJP : "Japanese", //MISSING -DlgDocCharSetKR : "Korean", //MISSING -DlgDocCharSetTR : "Turkish", //MISSING -DlgDocCharSetUN : "Unicode (UTF-8)", //MISSING -DlgDocCharSetWE : "Western European", //MISSING -DlgDocCharSetOther : "Other Character Set Encoding", //MISSING - -DlgDocDocType : "Document Type Heading", //MISSING -DlgDocDocTypeOther : "Other Document Type Heading", //MISSING -DlgDocIncXHTML : "Include XHTML Declarations", //MISSING -DlgDocBgColor : "Background Color", //MISSING -DlgDocBgImage : "Background Image URL", //MISSING -DlgDocBgNoScroll : "Nonscrolling Background", //MISSING -DlgDocCText : "Text", //MISSING -DlgDocCLink : "Link", //MISSING -DlgDocCVisited : "Visited Link", //MISSING -DlgDocCActive : "Active Link", //MISSING -DlgDocMargins : "Page Margins", //MISSING -DlgDocMaTop : "Top", //MISSING -DlgDocMaLeft : "Left", //MISSING -DlgDocMaRight : "Right", //MISSING -DlgDocMaBottom : "Bottom", //MISSING -DlgDocMeIndex : "Document Indexing Keywords (comma separated)", //MISSING -DlgDocMeDescr : "Document Description", //MISSING -DlgDocMeAuthor : "Author", //MISSING -DlgDocMeCopy : "Copyright", //MISSING -DlgDocPreview : "Preview", //MISSING - -// Templates Dialog -Templates : "Templates", //MISSING -DlgTemplatesTitle : "Content Templates", //MISSING -DlgTemplatesSelMsg : "Please select the template to open in the editor
    (the actual contents will be lost):", //MISSING -DlgTemplatesLoading : "Loading templates list. Please wait...", //MISSING -DlgTemplatesNoTpl : "(No templates defined)", //MISSING -DlgTemplatesReplace : "Replace actual contents", //MISSING - -// About Dialog -DlgAboutAboutTab : "About", //MISSING -DlgAboutBrowserInfoTab : "Browser Info", //MISSING -DlgAboutLicenseTab : "License", //MISSING -DlgAboutVersion : "verzija", -DlgAboutInfo : "Za više informacija posjetite", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/ca.js b/httemplate/elements/fckeditor/editor/lang/ca.js deleted file mode 100644 index 483e042e3..000000000 --- a/httemplate/elements/fckeditor/editor/lang/ca.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Catalan language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Redueix la barra d'eines", -ToolbarExpand : "Amplia la barra d'eines", - -// Toolbar Items and Context Menu -Save : "Desa", -NewPage : "Nova Pàgina", -Preview : "Visualització prèvia", -Cut : "Retalla", -Copy : "Copia", -Paste : "Enganxa", -PasteText : "Enganxa com a text no formatat", -PasteWord : "Enganxa des del Word", -Print : "Imprimeix", -SelectAll : "Selecciona-ho tot", -RemoveFormat : "Elimina Format", -InsertLinkLbl : "Enllaç", -InsertLink : "Insereix/Edita enllaç", -RemoveLink : "Elimina l'enllaç", -VisitLink : "Obre l'enllaç", -Anchor : "Insereix/Edita àncora", -AnchorDelete : "Elimina àncora", -InsertImageLbl : "Imatge", -InsertImage : "Insereix/Edita imatge", -InsertFlashLbl : "Flash", -InsertFlash : "Insereix/Edita Flash", -InsertTableLbl : "Taula", -InsertTable : "Insereix/Edita taula", -InsertLineLbl : "Línia", -InsertLine : "Insereix línia horitzontal", -InsertSpecialCharLbl: "Caràcter Especial", -InsertSpecialChar : "Insereix caràcter especial", -InsertSmileyLbl : "Icona", -InsertSmiley : "Insereix icona", -About : "Quant a l'FCKeditor", -Bold : "Negreta", -Italic : "Cursiva", -Underline : "Subratllat", -StrikeThrough : "Barrat", -Subscript : "Subíndex", -Superscript : "Superíndex", -LeftJustify : "Alinia a l'esquerra", -CenterJustify : "Centrat", -RightJustify : "Alinia a la dreta", -BlockJustify : "Justificat", -DecreaseIndent : "Redueix el sagnat", -IncreaseIndent : "Augmenta el sagnat", -Blockquote : "Bloc de cita", -CreateDiv : "Crea un contenidor Div", -EditDiv : "Edita el contenidor Div", -DeleteDiv : "Elimina el contenidor Div", -Undo : "Desfés", -Redo : "Refés", -NumberedListLbl : "Llista numerada", -NumberedList : "Numeració activada/desactivada", -BulletedListLbl : "Llista de pics", -BulletedList : "Pics activats/descativats", -ShowTableBorders : "Mostra les vores de les taules", -ShowDetails : "Mostra detalls", -Style : "Estil", -FontFormat : "Format", -Font : "Tipus de lletra", -FontSize : "Mida", -TextColor : "Color de Text", -BGColor : "Color de Fons", -Source : "Codi font", -Find : "Cerca", -Replace : "Reemplaça", -SpellCheck : "Revisa l'ortografia", -UniversalKeyboard : "Teclat universal", -PageBreakLbl : "Salt de pàgina", -PageBreak : "Insereix salt de pàgina", - -Form : "Formulari", -Checkbox : "Casella de verificació", -RadioButton : "Botó d'opció", -TextField : "Camp de text", -Textarea : "Àrea de text", -HiddenField : "Camp ocult", -Button : "Botó", -SelectionField : "Camp de selecció", -ImageButton : "Botó d'imatge", - -FitWindow : "Maximiza la mida de l'editor", -ShowBlocks : "Mostra els blocs", - -// Context Menu -EditLink : "Edita l'enllaç", -CellCM : "Cel·la", -RowCM : "Fila", -ColumnCM : "Columna", -InsertRowAfter : "Insereix fila darrera", -InsertRowBefore : "Insereix fila abans de", -DeleteRows : "Suprimeix una fila", -InsertColumnAfter : "Insereix columna darrera", -InsertColumnBefore : "Insereix columna abans de", -DeleteColumns : "Suprimeix una columna", -InsertCellAfter : "Insereix cel·la darrera", -InsertCellBefore : "Insereix cel·la abans de", -DeleteCells : "Suprimeix les cel·les", -MergeCells : "Fusiona les cel·les", -MergeRight : "Fusiona cap a la dreta", -MergeDown : "Fusiona cap avall", -HorizontalSplitCell : "Divideix la cel·la horitzontalment", -VerticalSplitCell : "Divideix la cel·la verticalment", -TableDelete : "Suprimeix la taula", -CellProperties : "Propietats de la cel·la", -TableProperties : "Propietats de la taula", -ImageProperties : "Propietats de la imatge", -FlashProperties : "Propietats del Flash", - -AnchorProp : "Propietats de l'àncora", -ButtonProp : "Propietats del botó", -CheckboxProp : "Propietats de la casella de verificació", -HiddenFieldProp : "Propietats del camp ocult", -RadioButtonProp : "Propietats del botó d'opció", -ImageButtonProp : "Propietats del botó d'imatge", -TextFieldProp : "Propietats del camp de text", -SelectionFieldProp : "Propietats del camp de selecció", -TextareaProp : "Propietats de l'àrea de text", -FormProp : "Propietats del formulari", - -FontFormats : "Normal;Formatejat;Adreça;Encapçalament 1;Encapçalament 2;Encapçalament 3;Encapçalament 4;Encapçalament 5;Encapçalament 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Processant XHTML. Si us plau esperi...", -Done : "Fet", -PasteWordConfirm : "El text que voleu enganxar sembla provenir de Word. Voleu netejar aquest text abans que sigui enganxat?", -NotCompatiblePaste : "Aquesta funció és disponible per a Internet Explorer versió 5.5 o superior. Voleu enganxar sense netejar?", -UnknownToolbarItem : "Element de la barra d'eines desconegut \"%1\"", -UnknownCommand : "Nom de comanda desconegut \"%1\"", -NotImplemented : "Mètode no implementat", -UnknownToolbarSet : "Conjunt de barra d'eines \"%1\" inexistent", -NoActiveX : "Les preferències del navegador poden limitar algunes funcions d'aquest editor. Cal habilitar l'opció \"Executa controls ActiveX i plug-ins\". Poden sorgir errors i poden faltar algunes funcions.", -BrowseServerBlocked : "El visualitzador de recursos no s'ha pogut obrir. Assegura't de que els bloquejos de finestres emergents estan desactivats.", -DialogBlocked : "No ha estat possible obrir una finestra de diàleg. Assegureu-vos que els bloquejos de finestres emergents estan desactivats.", -VisitLinkBlocked : "No ha estat possible obrir una nova finestra. Assegureu-vos que els bloquejos de finestres emergents estan desactivats.", - -// Dialogs -DlgBtnOK : "D'acord", -DlgBtnCancel : "Cancel·la", -DlgBtnClose : "Tanca", -DlgBtnBrowseServer : "Veure servidor", -DlgAdvancedTag : "Avançat", -DlgOpOther : "Altres", -DlgInfoTab : "Info", -DlgAlertUrl : "Si us plau, afegiu la URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Direcció de l'idioma", -DlgGenLangDirLtr : "D'esquerra a dreta (LTR)", -DlgGenLangDirRtl : "De dreta a esquerra (RTL)", -DlgGenLangCode : "Codi d'idioma", -DlgGenAccessKey : "Clau d'accés", -DlgGenName : "Nom", -DlgGenTabIndex : "Index de Tab", -DlgGenLongDescr : "Descripció llarga de la URL", -DlgGenClass : "Classes del full d'estil", -DlgGenTitle : "Títol consultiu", -DlgGenContType : "Tipus de contingut consultiu", -DlgGenLinkCharset : "Conjunt de caràcters font enllaçat", -DlgGenStyle : "Estil", - -// Image Dialog -DlgImgTitle : "Propietats de la imatge", -DlgImgInfoTab : "Informació de la imatge", -DlgImgBtnUpload : "Envia-la al servidor", -DlgImgURL : "URL", -DlgImgUpload : "Puja", -DlgImgAlt : "Text alternatiu", -DlgImgWidth : "Amplada", -DlgImgHeight : "Alçada", -DlgImgLockRatio : "Bloqueja les proporcions", -DlgBtnResetSize : "Restaura la mida", -DlgImgBorder : "Vora", -DlgImgHSpace : "Espaiat horit.", -DlgImgVSpace : "Espaiat vert.", -DlgImgAlign : "Alineació", -DlgImgAlignLeft : "Ajusta a l'esquerra", -DlgImgAlignAbsBottom: "Abs Bottom", -DlgImgAlignAbsMiddle: "Abs Middle", -DlgImgAlignBaseline : "Baseline", -DlgImgAlignBottom : "Bottom", -DlgImgAlignMiddle : "Middle", -DlgImgAlignRight : "Ajusta a la dreta", -DlgImgAlignTextTop : "Text Top", -DlgImgAlignTop : "Top", -DlgImgPreview : "Vista prèvia", -DlgImgAlertUrl : "Si us plau, escriviu la URL de la imatge", -DlgImgLinkTab : "Enllaç", - -// Flash Dialog -DlgFlashTitle : "Propietats del Flash", -DlgFlashChkPlay : "Reprodució automàtica", -DlgFlashChkLoop : "Bucle", -DlgFlashChkMenu : "Habilita menú Flash", -DlgFlashScale : "Escala", -DlgFlashScaleAll : "Mostra-ho tot", -DlgFlashScaleNoBorder : "Sense vores", -DlgFlashScaleFit : "Mida exacta", - -// Link Dialog -DlgLnkWindowTitle : "Enllaç", -DlgLnkInfoTab : "Informació de l'enllaç", -DlgLnkTargetTab : "Destí", - -DlgLnkType : "Tipus d'enllaç", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Àncora en aquesta pàgina", -DlgLnkTypeEMail : "Correu electrònic", -DlgLnkProto : "Protocol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Selecciona una àncora", -DlgLnkAnchorByName : "Per nom d'àncora", -DlgLnkAnchorById : "Per Id d'element", -DlgLnkNoAnchors : "(No hi ha àncores disponibles en aquest document)", -DlgLnkEMail : "Adreça de correu electrònic", -DlgLnkEMailSubject : "Assumpte del missatge", -DlgLnkEMailBody : "Cos del missatge", -DlgLnkUpload : "Puja", -DlgLnkBtnUpload : "Envia al servidor", - -DlgLnkTarget : "Destí", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nova finestra (_blank)", -DlgLnkTargetParent : "Finestra pare (_parent)", -DlgLnkTargetSelf : "Mateixa finestra (_self)", -DlgLnkTargetTop : "Finestra Major (_top)", -DlgLnkTargetFrameName : "Nom del marc de destí", -DlgLnkPopWinName : "Nom finestra popup", -DlgLnkPopWinFeat : "Característiques finestra popup", -DlgLnkPopResize : "Redimensionable", -DlgLnkPopLocation : "Barra d'adreça", -DlgLnkPopMenu : "Barra de menú", -DlgLnkPopScroll : "Barres d'scroll", -DlgLnkPopStatus : "Barra d'estat", -DlgLnkPopToolbar : "Barra d'eines", -DlgLnkPopFullScrn : "Pantalla completa (IE)", -DlgLnkPopDependent : "Depenent (Netscape)", -DlgLnkPopWidth : "Amplada", -DlgLnkPopHeight : "Alçada", -DlgLnkPopLeft : "Posició esquerra", -DlgLnkPopTop : "Posició dalt", - -DlnLnkMsgNoUrl : "Si us plau, escrigui l'enllaç URL", -DlnLnkMsgNoEMail : "Si us plau, escrigui l'adreça correu electrònic", -DlnLnkMsgNoAnchor : "Si us plau, escrigui l'àncora", -DlnLnkMsgInvPopName : "El nom de la finestra emergent ha de començar amb una lletra i no pot tenir espais", - -// Color Dialog -DlgColorTitle : "Selecciona el color", -DlgColorBtnClear : "Neteja", -DlgColorHighlight : "Realça", -DlgColorSelected : "Selecciona", - -// Smiley Dialog -DlgSmileyTitle : "Insereix una icona", - -// Special Character Dialog -DlgSpecialCharTitle : "Selecciona el caràcter especial", - -// Table Dialog -DlgTableTitle : "Propietats de la taula", -DlgTableRows : "Files", -DlgTableColumns : "Columnes", -DlgTableBorder : "Mida vora", -DlgTableAlign : "Alineació", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Esquerra", -DlgTableAlignCenter : "Centre", -DlgTableAlignRight : "Dreta", -DlgTableWidth : "Amplada", -DlgTableWidthPx : "píxels", -DlgTableWidthPc : "percentatge", -DlgTableHeight : "Alçada", -DlgTableCellSpace : "Espaiat de cel·les", -DlgTableCellPad : "Encoixinament de cel·les", -DlgTableCaption : "Títol", -DlgTableSummary : "Resum", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Propietats de la cel·la", -DlgCellWidth : "Amplada", -DlgCellWidthPx : "píxels", -DlgCellWidthPc : "percentatge", -DlgCellHeight : "Alçada", -DlgCellWordWrap : "Ajust de paraula", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Si", -DlgCellWordWrapNo : "No", -DlgCellHorAlign : "Alineació horitzontal", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Esquerra", -DlgCellHorAlignCenter : "Centre", -DlgCellHorAlignRight: "Dreta", -DlgCellVerAlign : "Alineació vertical", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Top", -DlgCellVerAlignMiddle : "Middle", -DlgCellVerAlignBottom : "Bottom", -DlgCellVerAlignBaseline : "Baseline", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Rows Span", -DlgCellCollSpan : "Columns Span", -DlgCellBackColor : "Color de fons", -DlgCellBorderColor : "Color de la vora", -DlgCellBtnSelect : "Seleccioneu...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Cerca i reemplaça", - -// Find Dialog -DlgFindTitle : "Cerca", -DlgFindFindBtn : "Cerca", -DlgFindNotFoundMsg : "El text especificat no s'ha trobat.", - -// Replace Dialog -DlgReplaceTitle : "Reemplaça", -DlgReplaceFindLbl : "Cerca:", -DlgReplaceReplaceLbl : "Remplaça amb:", -DlgReplaceCaseChk : "Distingeix majúscules/minúscules", -DlgReplaceReplaceBtn : "Reemplaça", -DlgReplaceReplAllBtn : "Reemplaça-ho tot", -DlgReplaceWordChk : "Només paraules completes", - -// Paste Operations / Dialog -PasteErrorCut : "La seguretat del vostre navegador no permet executar automàticament les operacions de retallar. Si us plau, utilitzeu el teclat (Ctrl+X).", -PasteErrorCopy : "La seguretat del vostre navegador no permet executar automàticament les operacions de copiar. Si us plau, utilitzeu el teclat (Ctrl+C).", - -PasteAsText : "Enganxa com a text no formatat", -PasteFromWord : "Enganxa com a Word", - -DlgPasteMsg2 : "Si us plau, enganxeu dins del següent camp utilitzant el teclat (Ctrl+V) i premeu OK.", -DlgPasteSec : "A causa de la configuració de seguretat del vostre navegador, l'editor no pot accedir al porta-retalls directament. Enganxeu-ho un altre cop en aquesta finestra.", -DlgPasteIgnoreFont : "Ignora definicions de font", -DlgPasteRemoveStyles : "Elimina definicions d'estil", - -// Color Picker -ColorAutomatic : "Automàtic", -ColorMoreColors : "Més colors...", - -// Document Properties -DocProps : "Propietats del document", - -// Anchor Dialog -DlgAnchorTitle : "Propietats de l'àncora", -DlgAnchorName : "Nom de l'àncora", -DlgAnchorErrorName : "Si us plau, escriviu el nom de l'ancora", - -// Speller Pages Dialog -DlgSpellNotInDic : "No és al diccionari", -DlgSpellChangeTo : "Reemplaça amb", -DlgSpellBtnIgnore : "Ignora", -DlgSpellBtnIgnoreAll : "Ignora-les totes", -DlgSpellBtnReplace : "Canvia", -DlgSpellBtnReplaceAll : "Canvia-les totes", -DlgSpellBtnUndo : "Desfés", -DlgSpellNoSuggestions : "Cap suggeriment", -DlgSpellProgress : "Verificació ortogràfica en curs...", -DlgSpellNoMispell : "Verificació ortogràfica acabada: no hi ha cap paraula mal escrita", -DlgSpellNoChanges : "Verificació ortogràfica: no s'ha canviat cap paraula", -DlgSpellOneChange : "Verificació ortogràfica: s'ha canviat una paraula", -DlgSpellManyChanges : "Verificació ortogràfica: s'han canviat %1 paraules", - -IeSpellDownload : "Verificació ortogràfica no instal·lada. Voleu descarregar-ho ara?", - -// Button Dialog -DlgButtonText : "Text (Valor)", -DlgButtonType : "Tipus", -DlgButtonTypeBtn : "Botó", -DlgButtonTypeSbm : "Transmet formulari", -DlgButtonTypeRst : "Reinicia formulari", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nom", -DlgCheckboxValue : "Valor", -DlgCheckboxSelected : "Seleccionat", - -// Form Dialog -DlgFormName : "Nom", -DlgFormAction : "Acció", -DlgFormMethod : "Mètode", - -// Select Field Dialog -DlgSelectName : "Nom", -DlgSelectValue : "Valor", -DlgSelectSize : "Mida", -DlgSelectLines : "Línies", -DlgSelectChkMulti : "Permet múltiples seleccions", -DlgSelectOpAvail : "Opcions disponibles", -DlgSelectOpText : "Text", -DlgSelectOpValue : "Valor", -DlgSelectBtnAdd : "Afegeix", -DlgSelectBtnModify : "Modifica", -DlgSelectBtnUp : "Amunt", -DlgSelectBtnDown : "Avall", -DlgSelectBtnSetValue : "Selecciona per defecte", -DlgSelectBtnDelete : "Elimina", - -// Textarea Dialog -DlgTextareaName : "Nom", -DlgTextareaCols : "Columnes", -DlgTextareaRows : "Files", - -// Text Field Dialog -DlgTextName : "Nom", -DlgTextValue : "Valor", -DlgTextCharWidth : "Amplada", -DlgTextMaxChars : "Nombre màxim de caràcters", -DlgTextType : "Tipus", -DlgTextTypeText : "Text", -DlgTextTypePass : "Contrasenya", - -// Hidden Field Dialog -DlgHiddenName : "Nom", -DlgHiddenValue : "Valor", - -// Bulleted List Dialog -BulletedListProp : "Propietats de la llista de pics", -NumberedListProp : "Propietats de llista numerada", -DlgLstStart : "Inici", -DlgLstType : "Tipus", -DlgLstTypeCircle : "Cercle", -DlgLstTypeDisc : "Disc", -DlgLstTypeSquare : "Quadrat", -DlgLstTypeNumbers : "Números (1, 2, 3)", -DlgLstTypeLCase : "Lletres minúscules (a, b, c)", -DlgLstTypeUCase : "Lletres majúscules (A, B, C)", -DlgLstTypeSRoman : "Números romans en minúscules (i, ii, iii)", -DlgLstTypeLRoman : "Números romans en majúscules (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "General", -DlgDocBackTab : "Fons", -DlgDocColorsTab : "Colors i marges", -DlgDocMetaTab : "Metadades", - -DlgDocPageTitle : "Títol de la pàgina", -DlgDocLangDir : "Direcció idioma", -DlgDocLangDirLTR : "Esquerra a dreta (LTR)", -DlgDocLangDirRTL : "Dreta a esquerra (RTL)", -DlgDocLangCode : "Codi d'idioma", -DlgDocCharSet : "Codificació de conjunt de caràcters", -DlgDocCharSetCE : "Centreeuropeu", -DlgDocCharSetCT : "Xinès tradicional (Big5)", -DlgDocCharSetCR : "Ciríl·lic", -DlgDocCharSetGR : "Grec", -DlgDocCharSetJP : "Japonès", -DlgDocCharSetKR : "Coreà", -DlgDocCharSetTR : "Turc", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Europeu occidental", -DlgDocCharSetOther : "Una altra codificació de caràcters", - -DlgDocDocType : "Capçalera de tipus de document", -DlgDocDocTypeOther : "Un altra capçalera de tipus de document", -DlgDocIncXHTML : "Incloure declaracions XHTML", -DlgDocBgColor : "Color de fons", -DlgDocBgImage : "URL de la imatge de fons", -DlgDocBgNoScroll : "Fons fixe", -DlgDocCText : "Text", -DlgDocCLink : "Enllaç", -DlgDocCVisited : "Enllaç visitat", -DlgDocCActive : "Enllaç actiu", -DlgDocMargins : "Marges de pàgina", -DlgDocMaTop : "Cap", -DlgDocMaLeft : "Esquerra", -DlgDocMaRight : "Dreta", -DlgDocMaBottom : "Peu", -DlgDocMeIndex : "Mots clau per a indexació (separats per coma)", -DlgDocMeDescr : "Descripció del document", -DlgDocMeAuthor : "Autor", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Vista prèvia", - -// Templates Dialog -Templates : "Plantilles", -DlgTemplatesTitle : "Contingut plantilles", -DlgTemplatesSelMsg : "Si us plau, seleccioneu la plantilla per obrir a l'editor
    (el contingut actual no serà enregistrat):", -DlgTemplatesLoading : "Carregant la llista de plantilles. Si us plau, espereu...", -DlgTemplatesNoTpl : "(No hi ha plantilles definides)", -DlgTemplatesReplace : "Reemplaça el contingut actual", - -// About Dialog -DlgAboutAboutTab : "Quant a", -DlgAboutBrowserInfoTab : "Informació del navegador", -DlgAboutLicenseTab : "Llicència", -DlgAboutVersion : "versió", -DlgAboutInfo : "Per a més informació aneu a", - -// Div Dialog -DlgDivGeneralTab : "General", -DlgDivAdvancedTab : "Avançat", -DlgDivStyle : "Estil", -DlgDivInlineStyle : "Estil en línia", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/cs.js b/httemplate/elements/fckeditor/editor/lang/cs.js deleted file mode 100644 index 10bef9d69..000000000 --- a/httemplate/elements/fckeditor/editor/lang/cs.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Czech language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Skrýt panel nástrojů", -ToolbarExpand : "Zobrazit panel nástrojů", - -// Toolbar Items and Context Menu -Save : "Uložit", -NewPage : "Nová stránka", -Preview : "Náhled", -Cut : "Vyjmout", -Copy : "Kopírovat", -Paste : "Vložit", -PasteText : "Vložit jako čistý text", -PasteWord : "Vložit z Wordu", -Print : "Tisk", -SelectAll : "Vybrat vše", -RemoveFormat : "Odstranit formátování", -InsertLinkLbl : "Odkaz", -InsertLink : "Vložit/změnit odkaz", -RemoveLink : "Odstranit odkaz", -VisitLink : "Otevřít odkaz", -Anchor : "Vložít/změnit záložku", -AnchorDelete : "Odstranit kotvu", -InsertImageLbl : "Obrázek", -InsertImage : "Vložit/změnit obrázek", -InsertFlashLbl : "Flash", -InsertFlash : "Vložit/Upravit Flash", -InsertTableLbl : "Tabulka", -InsertTable : "Vložit/změnit tabulku", -InsertLineLbl : "Linka", -InsertLine : "Vložit vodorovnou linku", -InsertSpecialCharLbl: "Speciální znaky", -InsertSpecialChar : "Vložit speciální znaky", -InsertSmileyLbl : "Smajlíky", -InsertSmiley : "Vložit smajlík", -About : "O aplikaci FCKeditor", -Bold : "Tučné", -Italic : "Kurzíva", -Underline : "Podtržené", -StrikeThrough : "Přeškrtnuté", -Subscript : "Dolní index", -Superscript : "Horní index", -LeftJustify : "Zarovnat vlevo", -CenterJustify : "Zarovnat na střed", -RightJustify : "Zarovnat vpravo", -BlockJustify : "Zarovnat do bloku", -DecreaseIndent : "Zmenšit odsazení", -IncreaseIndent : "Zvětšit odsazení", -Blockquote : "Citace", -CreateDiv : "Vytvořit Div kontejner", -EditDiv : "Upravit Div kontejner", -DeleteDiv : "Odstranit Div kontejner", -Undo : "Zpět", -Redo : "Znovu", -NumberedListLbl : "Číslování", -NumberedList : "Vložit/odstranit číslovaný seznam", -BulletedListLbl : "Odrážky", -BulletedList : "Vložit/odstranit odrážky", -ShowTableBorders : "Zobrazit okraje tabulek", -ShowDetails : "Zobrazit podrobnosti", -Style : "Styl", -FontFormat : "Formát", -Font : "Písmo", -FontSize : "Velikost", -TextColor : "Barva textu", -BGColor : "Barva pozadí", -Source : "Zdroj", -Find : "Hledat", -Replace : "Nahradit", -SpellCheck : "Zkontrolovat pravopis", -UniversalKeyboard : "Univerzální klávesnice", -PageBreakLbl : "Konec stránky", -PageBreak : "Vložit konec stránky", - -Form : "Formulář", -Checkbox : "Zaškrtávací políčko", -RadioButton : "Přepínač", -TextField : "Textové pole", -Textarea : "Textová oblast", -HiddenField : "Skryté pole", -Button : "Tlačítko", -SelectionField : "Seznam", -ImageButton : "Obrázkové tlačítko", - -FitWindow : "Maximalizovat velikost editoru", -ShowBlocks : "Ukázat bloky", - -// Context Menu -EditLink : "Změnit odkaz", -CellCM : "Buňka", -RowCM : "Řádek", -ColumnCM : "Sloupec", -InsertRowAfter : "Vložit řádek za", -InsertRowBefore : "Vložit řádek před", -DeleteRows : "Smazat řádky", -InsertColumnAfter : "Vložit sloupec za", -InsertColumnBefore : "Vložit sloupec před", -DeleteColumns : "Smazat sloupec", -InsertCellAfter : "Vložit buňku za", -InsertCellBefore : "Vložit buňku před", -DeleteCells : "Smazat buňky", -MergeCells : "Sloučit buňky", -MergeRight : "Sloučit doprava", -MergeDown : "Sloučit dolů", -HorizontalSplitCell : "Rozdělit buňky vodorovně", -VerticalSplitCell : "Rozdělit buňky svisle", -TableDelete : "Smazat tabulku", -CellProperties : "Vlastnosti buňky", -TableProperties : "Vlastnosti tabulky", -ImageProperties : "Vlastnosti obrázku", -FlashProperties : "Vlastnosti Flashe", - -AnchorProp : "Vlastnosti záložky", -ButtonProp : "Vlastnosti tlačítka", -CheckboxProp : "Vlastnosti zaškrtávacího políčka", -HiddenFieldProp : "Vlastnosti skrytého pole", -RadioButtonProp : "Vlastnosti přepínače", -ImageButtonProp : "Vlastností obrázkového tlačítka", -TextFieldProp : "Vlastnosti textového pole", -SelectionFieldProp : "Vlastnosti seznamu", -TextareaProp : "Vlastnosti textové oblasti", -FormProp : "Vlastnosti formuláře", - -FontFormats : "Normální;Naformátováno;Adresa;Nadpis 1;Nadpis 2;Nadpis 3;Nadpis 4;Nadpis 5;Nadpis 6;Normální (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Probíhá zpracování XHTML. Prosím čekejte...", -Done : "Hotovo", -PasteWordConfirm : "Jak je vidět, vkládaný text je kopírován z Wordu. Chcete jej před vložením vyčistit?", -NotCompatiblePaste : "Tento příkaz je dostupný pouze v Internet Exploreru verze 5.5 nebo vyšší. Chcete vložit text bez vyčištění?", -UnknownToolbarItem : "Neznámá položka panelu nástrojů \"%1\"", -UnknownCommand : "Neznámý příkaz \"%1\"", -NotImplemented : "Příkaz není implementován", -UnknownToolbarSet : "Panel nástrojů \"%1\" neexistuje", -NoActiveX : "Nastavení bezpečnosti Vašeho prohlížeče omezuje funkčnost některých jeho možností. Je třeba zapnout volbu \"Spouštět ovládáací prvky ActiveX a moduly plug-in\", jinak nebude možné využívat všechny dosputné schopnosti editoru.", -BrowseServerBlocked : "Průzkumník zdrojů nelze otevřít. Prověřte, zda nemáte aktivováno blokování popup oken.", -DialogBlocked : "Nelze otevřít dialogové okno. Prověřte, zda nemáte aktivováno blokování popup oken.", -VisitLinkBlocked : "Není možné otevřít nové okno. Prověřte, zda všechny nástroje pro blokování vyskakovacích oken jsou vypnuty.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Storno", -DlgBtnClose : "Zavřít", -DlgBtnBrowseServer : "Vybrat na serveru", -DlgAdvancedTag : "Rozšířené", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Prosím vložte URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Orientace jazyka", -DlgGenLangDirLtr : "Zleva do prava (LTR)", -DlgGenLangDirRtl : "Zprava do leva (RTL)", -DlgGenLangCode : "Kód jazyka", -DlgGenAccessKey : "Přístupový klíč", -DlgGenName : "Jméno", -DlgGenTabIndex : "Pořadí prvku", -DlgGenLongDescr : "Dlouhý popis URL", -DlgGenClass : "Třída stylu", -DlgGenTitle : "Pomocný titulek", -DlgGenContType : "Pomocný typ obsahu", -DlgGenLinkCharset : "Přiřazená znaková sada", -DlgGenStyle : "Styl", - -// Image Dialog -DlgImgTitle : "Vlastnosti obrázku", -DlgImgInfoTab : "Informace o obrázku", -DlgImgBtnUpload : "Odeslat na server", -DlgImgURL : "URL", -DlgImgUpload : "Odeslat", -DlgImgAlt : "Alternativní text", -DlgImgWidth : "Šířka", -DlgImgHeight : "Výška", -DlgImgLockRatio : "Zámek", -DlgBtnResetSize : "Původní velikost", -DlgImgBorder : "Okraje", -DlgImgHSpace : "H-mezera", -DlgImgVSpace : "V-mezera", -DlgImgAlign : "Zarovnání", -DlgImgAlignLeft : "Vlevo", -DlgImgAlignAbsBottom: "Zcela dolů", -DlgImgAlignAbsMiddle: "Doprostřed", -DlgImgAlignBaseline : "Na účaří", -DlgImgAlignBottom : "Dolů", -DlgImgAlignMiddle : "Na střed", -DlgImgAlignRight : "Vpravo", -DlgImgAlignTextTop : "Na horní okraj textu", -DlgImgAlignTop : "Nahoru", -DlgImgPreview : "Náhled", -DlgImgAlertUrl : "Zadejte prosím URL obrázku", -DlgImgLinkTab : "Odkaz", - -// Flash Dialog -DlgFlashTitle : "Vlastnosti Flashe", -DlgFlashChkPlay : "Automatické spuštění", -DlgFlashChkLoop : "Opakování", -DlgFlashChkMenu : "Nabídka Flash", -DlgFlashScale : "Zobrazit", -DlgFlashScaleAll : "Zobrazit vše", -DlgFlashScaleNoBorder : "Bez okraje", -DlgFlashScaleFit : "Přizpůsobit", - -// Link Dialog -DlgLnkWindowTitle : "Odkaz", -DlgLnkInfoTab : "Informace o odkazu", -DlgLnkTargetTab : "Cíl", - -DlgLnkType : "Typ odkazu", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Kotva v této stránce", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protokol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Vybrat kotvu", -DlgLnkAnchorByName : "Podle jména kotvy", -DlgLnkAnchorById : "Podle Id objektu", -DlgLnkNoAnchors : "(Ve stránce není definována žádná kotva!)", -DlgLnkEMail : "E-Mailová adresa", -DlgLnkEMailSubject : "Předmět zprávy", -DlgLnkEMailBody : "Tělo zprávy", -DlgLnkUpload : "Odeslat", -DlgLnkBtnUpload : "Odeslat na Server", - -DlgLnkTarget : "Cíl", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nové okno (_blank)", -DlgLnkTargetParent : "Rodičovské okno (_parent)", -DlgLnkTargetSelf : "Stejné okno (_self)", -DlgLnkTargetTop : "Hlavní okno (_top)", -DlgLnkTargetFrameName : "Název cílového rámu", -DlgLnkPopWinName : "Název vyskakovacího okna", -DlgLnkPopWinFeat : "Vlastnosti vyskakovacího okna", -DlgLnkPopResize : "Měnitelná velikost", -DlgLnkPopLocation : "Panel umístění", -DlgLnkPopMenu : "Panel nabídky", -DlgLnkPopScroll : "Posuvníky", -DlgLnkPopStatus : "Stavový řádek", -DlgLnkPopToolbar : "Panel nástrojů", -DlgLnkPopFullScrn : "Celá obrazovka (IE)", -DlgLnkPopDependent : "Závislost (Netscape)", -DlgLnkPopWidth : "Šířka", -DlgLnkPopHeight : "Výška", -DlgLnkPopLeft : "Levý okraj", -DlgLnkPopTop : "Horní okraj", - -DlnLnkMsgNoUrl : "Zadejte prosím URL odkazu", -DlnLnkMsgNoEMail : "Zadejte prosím e-mailovou adresu", -DlnLnkMsgNoAnchor : "Vyberte prosím kotvu", -DlnLnkMsgInvPopName : "Název vyskakovacího okna musí začínat písmenem a nesmí obsahovat mezery", - -// Color Dialog -DlgColorTitle : "Výběr barvy", -DlgColorBtnClear : "Vymazat", -DlgColorHighlight : "Zvýrazněná", -DlgColorSelected : "Vybraná", - -// Smiley Dialog -DlgSmileyTitle : "Vkládání smajlíků", - -// Special Character Dialog -DlgSpecialCharTitle : "Výběr speciálního znaku", - -// Table Dialog -DlgTableTitle : "Vlastnosti tabulky", -DlgTableRows : "Řádky", -DlgTableColumns : "Sloupce", -DlgTableBorder : "Ohraničení", -DlgTableAlign : "Zarovnání", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Vlevo", -DlgTableAlignCenter : "Na střed", -DlgTableAlignRight : "Vpravo", -DlgTableWidth : "Šířka", -DlgTableWidthPx : "bodů", -DlgTableWidthPc : "procent", -DlgTableHeight : "Výška", -DlgTableCellSpace : "Vzdálenost buněk", -DlgTableCellPad : "Odsazení obsahu", -DlgTableCaption : "Popis", -DlgTableSummary : "Souhrn", -DlgTableHeaders : "Záhlaví", -DlgTableHeadersNone : "Žádné", -DlgTableHeadersColumn : "První sloupec", -DlgTableHeadersRow : "První řádek", -DlgTableHeadersBoth : "Oboje", - -// Table Cell Dialog -DlgCellTitle : "Vlastnosti buňky", -DlgCellWidth : "Šířka", -DlgCellWidthPx : "bodů", -DlgCellWidthPc : "procent", -DlgCellHeight : "Výška", -DlgCellWordWrap : "Zalamování", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Ano", -DlgCellWordWrapNo : "Ne", -DlgCellHorAlign : "Vodorovné zarovnání", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Vlevo", -DlgCellHorAlignCenter : "Na střed", -DlgCellHorAlignRight: "Vpravo", -DlgCellVerAlign : "Svislé zarovnání", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Nahoru", -DlgCellVerAlignMiddle : "Doprostřed", -DlgCellVerAlignBottom : "Dolů", -DlgCellVerAlignBaseline : "Na účaří", -DlgCellType : "Typ buňky", -DlgCellTypeData : "Data", -DlgCellTypeHeader : "Zálaví", -DlgCellRowSpan : "Sloučené řádky", -DlgCellCollSpan : "Sloučené sloupce", -DlgCellBackColor : "Barva pozadí", -DlgCellBorderColor : "Barva ohraničení", -DlgCellBtnSelect : "Výběr...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Najít a nahradit", - -// Find Dialog -DlgFindTitle : "Hledat", -DlgFindFindBtn : "Hledat", -DlgFindNotFoundMsg : "Hledaný text nebyl nalezen.", - -// Replace Dialog -DlgReplaceTitle : "Nahradit", -DlgReplaceFindLbl : "Co hledat:", -DlgReplaceReplaceLbl : "Čím nahradit:", -DlgReplaceCaseChk : "Rozlišovat velikost písma", -DlgReplaceReplaceBtn : "Nahradit", -DlgReplaceReplAllBtn : "Nahradit vše", -DlgReplaceWordChk : "Pouze celá slova", - -// Paste Operations / Dialog -PasteErrorCut : "Bezpečnostní nastavení Vašeho prohlížeče nedovolují editoru spustit funkci pro vyjmutí zvoleného textu do schránky. Prosím vyjměte zvolený text do schránky pomocí klávesnice (Ctrl+X).", -PasteErrorCopy : "Bezpečnostní nastavení Vašeho prohlížeče nedovolují editoru spustit funkci pro kopírování zvoleného textu do schránky. Prosím zkopírujte zvolený text do schránky pomocí klávesnice (Ctrl+C).", - -PasteAsText : "Vložit jako čistý text", -PasteFromWord : "Vložit text z Wordu", - -DlgPasteMsg2 : "Do následujícího pole vložte požadovaný obsah pomocí klávesnice (Ctrl+V) a stiskněte OK.", -DlgPasteSec : "Z důvodů nastavení bezpečnosti Vašeho prohlížeče nemůže editor přistupovat přímo do schránky. Obsah schránky prosím vložte znovu do tohoto okna.", -DlgPasteIgnoreFont : "Ignorovat písmo", -DlgPasteRemoveStyles : "Odstranit styly", - -// Color Picker -ColorAutomatic : "Automaticky", -ColorMoreColors : "Více barev...", - -// Document Properties -DocProps : "Vlastnosti dokumentu", - -// Anchor Dialog -DlgAnchorTitle : "Vlastnosti záložky", -DlgAnchorName : "Název záložky", -DlgAnchorErrorName : "Zadejte prosím název záložky", - -// Speller Pages Dialog -DlgSpellNotInDic : "Není ve slovníku", -DlgSpellChangeTo : "Změnit na", -DlgSpellBtnIgnore : "Přeskočit", -DlgSpellBtnIgnoreAll : "Přeskakovat vše", -DlgSpellBtnReplace : "Zaměnit", -DlgSpellBtnReplaceAll : "Zaměňovat vše", -DlgSpellBtnUndo : "Zpět", -DlgSpellNoSuggestions : "- žádné návrhy -", -DlgSpellProgress : "Probíhá kontrola pravopisu...", -DlgSpellNoMispell : "Kontrola pravopisu dokončena: Žádné pravopisné chyby nenalezeny", -DlgSpellNoChanges : "Kontrola pravopisu dokončena: Beze změn", -DlgSpellOneChange : "Kontrola pravopisu dokončena: Jedno slovo změněno", -DlgSpellManyChanges : "Kontrola pravopisu dokončena: %1 slov změněno", - -IeSpellDownload : "Kontrola pravopisu není nainstalována. Chcete ji nyní stáhnout?", - -// Button Dialog -DlgButtonText : "Popisek", -DlgButtonType : "Typ", -DlgButtonTypeBtn : "Tlačítko", -DlgButtonTypeSbm : "Odeslat", -DlgButtonTypeRst : "Obnovit", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Název", -DlgCheckboxValue : "Hodnota", -DlgCheckboxSelected : "Zaškrtnuto", - -// Form Dialog -DlgFormName : "Název", -DlgFormAction : "Akce", -DlgFormMethod : "Metoda", - -// Select Field Dialog -DlgSelectName : "Název", -DlgSelectValue : "Hodnota", -DlgSelectSize : "Velikost", -DlgSelectLines : "Řádků", -DlgSelectChkMulti : "Povolit mnohonásobné výběry", -DlgSelectOpAvail : "Dostupná nastavení", -DlgSelectOpText : "Text", -DlgSelectOpValue : "Hodnota", -DlgSelectBtnAdd : "Přidat", -DlgSelectBtnModify : "Změnit", -DlgSelectBtnUp : "Nahoru", -DlgSelectBtnDown : "Dolů", -DlgSelectBtnSetValue : "Nastavit jako vybranou hodnotu", -DlgSelectBtnDelete : "Smazat", - -// Textarea Dialog -DlgTextareaName : "Název", -DlgTextareaCols : "Sloupců", -DlgTextareaRows : "Řádků", - -// Text Field Dialog -DlgTextName : "Název", -DlgTextValue : "Hodnota", -DlgTextCharWidth : "Šířka ve znacích", -DlgTextMaxChars : "Maximální počet znaků", -DlgTextType : "Typ", -DlgTextTypeText : "Text", -DlgTextTypePass : "Heslo", - -// Hidden Field Dialog -DlgHiddenName : "Název", -DlgHiddenValue : "Hodnota", - -// Bulleted List Dialog -BulletedListProp : "Vlastnosti odrážek", -NumberedListProp : "Vlastnosti číslovaného seznamu", -DlgLstStart : "Začátek", -DlgLstType : "Typ", -DlgLstTypeCircle : "Kružnice", -DlgLstTypeDisc : "Kruh", -DlgLstTypeSquare : "Čtverec", -DlgLstTypeNumbers : "Čísla (1, 2, 3)", -DlgLstTypeLCase : "Malá písmena (a, b, c)", -DlgLstTypeUCase : "Velká písmena (A, B, C)", -DlgLstTypeSRoman : "Malé římská číslice (i, ii, iii)", -DlgLstTypeLRoman : "Velké římské číslice (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Obecné", -DlgDocBackTab : "Pozadí", -DlgDocColorsTab : "Barvy a okraje", -DlgDocMetaTab : "Metadata", - -DlgDocPageTitle : "Titulek stránky", -DlgDocLangDir : "Směr jazyku", -DlgDocLangDirLTR : "Zleva do prava ", -DlgDocLangDirRTL : "Zprava doleva", -DlgDocLangCode : "Kód jazyku", -DlgDocCharSet : "Znaková sada", -DlgDocCharSetCE : "Středoevropské jazyky", -DlgDocCharSetCT : "Tradiční čínština (Big5)", -DlgDocCharSetCR : "Cyrilice", -DlgDocCharSetGR : "Řečtina", -DlgDocCharSetJP : "Japonština", -DlgDocCharSetKR : "Korejština", -DlgDocCharSetTR : "Turečtina", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Západoevropské jazyky", -DlgDocCharSetOther : "Další znaková sada", - -DlgDocDocType : "Typ dokumentu", -DlgDocDocTypeOther : "Jiný typ dokumetu", -DlgDocIncXHTML : "Zahrnou deklarace XHTML", -DlgDocBgColor : "Barva pozadí", -DlgDocBgImage : "URL obrázku na pozadí", -DlgDocBgNoScroll : "Nerolovatelné pozadí", -DlgDocCText : "Text", -DlgDocCLink : "Odkaz", -DlgDocCVisited : "Navštívený odkaz", -DlgDocCActive : "Vybraný odkaz", -DlgDocMargins : "Okraje stránky", -DlgDocMaTop : "Horní", -DlgDocMaLeft : "Levý", -DlgDocMaRight : "Pravý", -DlgDocMaBottom : "Dolní", -DlgDocMeIndex : "Klíčová slova (oddělená čárkou)", -DlgDocMeDescr : "Popis dokumentu", -DlgDocMeAuthor : "Autor", -DlgDocMeCopy : "Autorská práva", -DlgDocPreview : "Náhled", - -// Templates Dialog -Templates : "Šablony", -DlgTemplatesTitle : "Šablony obsahu", -DlgTemplatesSelMsg : "Prosím zvolte šablonu pro otevření v editoru
    (aktuální obsah editoru bude ztracen):", -DlgTemplatesLoading : "Nahrávám přeheld šablon. Prosím čekejte...", -DlgTemplatesNoTpl : "(Není definována žádná šablona)", -DlgTemplatesReplace : "Nahradit aktuální obsah", - -// About Dialog -DlgAboutAboutTab : "O aplikaci", -DlgAboutBrowserInfoTab : "Informace o prohlížeči", -DlgAboutLicenseTab : "Licence", -DlgAboutVersion : "verze", -DlgAboutInfo : "Více informací získáte na", - -// Div Dialog -DlgDivGeneralTab : "Obecné", -DlgDivAdvancedTab : "Rozšířené", -DlgDivStyle : "Styl", -DlgDivInlineStyle : "Vložený styl", - -ScaytTitle : "SCAYT", -ScaytTitleOptions : "Nastavení", -ScaytTitleLangs : "Jazyky", -ScaytTitleAbout : "O aplikaci" -}; diff --git a/httemplate/elements/fckeditor/editor/lang/da.js b/httemplate/elements/fckeditor/editor/lang/da.js deleted file mode 100644 index 9e935b84f..000000000 --- a/httemplate/elements/fckeditor/editor/lang/da.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Danish language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Skjul værktøjslinier", -ToolbarExpand : "Vis værktøjslinier", - -// Toolbar Items and Context Menu -Save : "Gem", -NewPage : "Ny side", -Preview : "Vis eksempel", -Cut : "Klip", -Copy : "Kopier", -Paste : "Indsæt", -PasteText : "Indsæt som ikke-formateret tekst", -PasteWord : "Indsæt fra Word", -Print : "Udskriv", -SelectAll : "Vælg alt", -RemoveFormat : "Fjern formatering", -InsertLinkLbl : "Hyperlink", -InsertLink : "Indsæt/rediger hyperlink", -RemoveLink : "Fjern hyperlink", -VisitLink : "Åbn hyperlink", -Anchor : "Indsæt/rediger bogmærke", -AnchorDelete : "Fjern bogmærke", -InsertImageLbl : "Indsæt billede", -InsertImage : "Indsæt/rediger billede", -InsertFlashLbl : "Flash", -InsertFlash : "Indsæt/rediger Flash", -InsertTableLbl : "Table", -InsertTable : "Indsæt/rediger tabel", -InsertLineLbl : "Linie", -InsertLine : "Indsæt vandret linie", -InsertSpecialCharLbl: "Symbol", -InsertSpecialChar : "Indsæt symbol", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Indsæt smiley", -About : "Om FCKeditor", -Bold : "Fed", -Italic : "Kursiv", -Underline : "Understreget", -StrikeThrough : "Overstreget", -Subscript : "Sænket skrift", -Superscript : "Hævet skrift", -LeftJustify : "Venstrestillet", -CenterJustify : "Centreret", -RightJustify : "Højrestillet", -BlockJustify : "Lige margener", -DecreaseIndent : "Formindsk indrykning", -IncreaseIndent : "Forøg indrykning", -Blockquote : "Blokcitat", -CreateDiv : "Opret div container", -EditDiv : "Rediger div container", -DeleteDiv : "Fjern div container", -Undo : "Fortryd", -Redo : "Annuller fortryd", -NumberedListLbl : "Talopstilling", -NumberedList : "Indsæt/fjern talopstilling", -BulletedListLbl : "Punktopstilling", -BulletedList : "Indsæt/fjern punktopstilling", -ShowTableBorders : "Vis tabelkanter", -ShowDetails : "Vis detaljer", -Style : "Typografi", -FontFormat : "Formatering", -Font : "Skrifttype", -FontSize : "Skriftstørrelse", -TextColor : "Tekstfarve", -BGColor : "Baggrundsfarve", -Source : "Kilde", -Find : "Søg", -Replace : "Erstat", -SpellCheck : "Stavekontrol", -UniversalKeyboard : "Universaltastatur", -PageBreakLbl : "Sidskift", -PageBreak : "Indsæt sideskift", - -Form : "Indsæt formular", -Checkbox : "Indsæt afkrydsningsfelt", -RadioButton : "Indsæt alternativknap", -TextField : "Indsæt tekstfelt", -Textarea : "Indsæt tekstboks", -HiddenField : "Indsæt skjult felt", -Button : "Indsæt knap", -SelectionField : "Indsæt liste", -ImageButton : "Indsæt billedknap", - -FitWindow : "Maksimer editor vinduet", -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "Rediger hyperlink", -CellCM : "Celle", -RowCM : "Række", -ColumnCM : "Kolonne", -InsertRowAfter : "Indsæt række efter", -InsertRowBefore : "Indsæt række før", -DeleteRows : "Slet række", -InsertColumnAfter : "Indsæt kolonne efter", -InsertColumnBefore : "Indsæt kolonne før", -DeleteColumns : "Slet kolonne", -InsertCellAfter : "Indsæt celle efter", -InsertCellBefore : "Indsæt celle før", -DeleteCells : "Slet celle", -MergeCells : "Flet celler", -MergeRight : "Flet til højre", -MergeDown : "Flet nedad", -HorizontalSplitCell : "Del celle vandret", -VerticalSplitCell : "Del celle lodret", -TableDelete : "Slet tabel", -CellProperties : "Egenskaber for celle", -TableProperties : "Egenskaber for tabel", -ImageProperties : "Egenskaber for billede", -FlashProperties : "Egenskaber for Flash", - -AnchorProp : "Egenskaber for bogmærke", -ButtonProp : "Egenskaber for knap", -CheckboxProp : "Egenskaber for afkrydsningsfelt", -HiddenFieldProp : "Egenskaber for skjult felt", -RadioButtonProp : "Egenskaber for alternativknap", -ImageButtonProp : "Egenskaber for billedknap", -TextFieldProp : "Egenskaber for tekstfelt", -SelectionFieldProp : "Egenskaber for liste", -TextareaProp : "Egenskaber for tekstboks", -FormProp : "Egenskaber for formular", - -FontFormats : "Normal;Formateret;Adresse;Overskrift 1;Overskrift 2;Overskrift 3;Overskrift 4;Overskrift 5;Overskrift 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Behandler XHTML...", -Done : "Færdig", -PasteWordConfirm : "Den tekst du forsøger at indsætte ser ud til at komme fra Word.
    Vil du rense teksten før den indsættes?", -NotCompatiblePaste : "Denne kommando er tilgændelig i Internet Explorer 5.5 eller senere.
    Vil du indsætte teksten uden at rense den ?", -UnknownToolbarItem : "Ukendt værktøjslinjeobjekt \"%1\"!", -UnknownCommand : "Ukendt kommandonavn \"%1\"!", -NotImplemented : "Kommandoen er ikke implementeret!", -UnknownToolbarSet : "Værktøjslinjen \"%1\" eksisterer ikke!", -NoActiveX : "Din browsers sikkerhedsindstillinger begrænser nogle af editorens muligheder.
    Slå \"Kør ActiveX-objekter og plug-ins\" til, ellers vil du opleve fejl og manglende muligheder.", -BrowseServerBlocked : "Browseren kunne ikke åbne de nødvendige ressourcer!
    Slå pop-up blokering fra.", -DialogBlocked : "Dialogvinduet kunne ikke åbnes!
    Slå pop-up blokering fra.", -VisitLinkBlocked : "Det var ikke muligt at åbne et nyt vindue. Tjek, at ingen popup-blokkere er aktive.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Annuller", -DlgBtnClose : "Luk", -DlgBtnBrowseServer : "Gennemse...", -DlgAdvancedTag : "Avanceret", -DlgOpOther : "", -DlgInfoTab : "Generelt", -DlgAlertUrl : "Indtast URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Tekstretning", -DlgGenLangDirLtr : "Fra venstre mod højre (LTR)", -DlgGenLangDirRtl : "Fra højre mod venstre (RTL)", -DlgGenLangCode : "Sprogkode", -DlgGenAccessKey : "Genvejstast", -DlgGenName : "Navn", -DlgGenTabIndex : "Tabulator indeks", -DlgGenLongDescr : "Udvidet beskrivelse", -DlgGenClass : "Typografiark", -DlgGenTitle : "Titel", -DlgGenContType : "Indholdstype", -DlgGenLinkCharset : "Tegnsæt", -DlgGenStyle : "Typografi", - -// Image Dialog -DlgImgTitle : "Egenskaber for billede", -DlgImgInfoTab : "Generelt", -DlgImgBtnUpload : "Upload", -DlgImgURL : "URL", -DlgImgUpload : "Upload", -DlgImgAlt : "Alternativ tekst", -DlgImgWidth : "Bredde", -DlgImgHeight : "Højde", -DlgImgLockRatio : "Lås størrelsesforhold", -DlgBtnResetSize : "Nulstil størrelse", -DlgImgBorder : "Ramme", -DlgImgHSpace : "HMargen", -DlgImgVSpace : "VMargen", -DlgImgAlign : "Justering", -DlgImgAlignLeft : "Venstre", -DlgImgAlignAbsBottom: "Absolut nederst", -DlgImgAlignAbsMiddle: "Absolut centreret", -DlgImgAlignBaseline : "Grundlinje", -DlgImgAlignBottom : "Nederst", -DlgImgAlignMiddle : "Centreret", -DlgImgAlignRight : "Højre", -DlgImgAlignTextTop : "Toppen af teksten", -DlgImgAlignTop : "Øverst", -DlgImgPreview : "Vis eksempel", -DlgImgAlertUrl : "Indtast stien til billedet", -DlgImgLinkTab : "Hyperlink", - -// Flash Dialog -DlgFlashTitle : "Egenskaber for Flash", -DlgFlashChkPlay : "Automatisk afspilning", -DlgFlashChkLoop : "Gentagelse", -DlgFlashChkMenu : "Vis Flash menu", -DlgFlashScale : "Skalér", -DlgFlashScaleAll : "Vis alt", -DlgFlashScaleNoBorder : "Ingen ramme", -DlgFlashScaleFit : "Tilpas størrelse", - -// Link Dialog -DlgLnkWindowTitle : "Egenskaber for hyperlink", -DlgLnkInfoTab : "Generelt", -DlgLnkTargetTab : "Mål", - -DlgLnkType : "Hyperlink type", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Bogmærke på denne side", -DlgLnkTypeEMail : "E-mail", -DlgLnkProto : "Protokol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Vælg et anker", -DlgLnkAnchorByName : "Efter anker navn", -DlgLnkAnchorById : "Efter element Id", -DlgLnkNoAnchors : "(Ingen bogmærker dokumentet)", -DlgLnkEMail : "E-mailadresse", -DlgLnkEMailSubject : "Emne", -DlgLnkEMailBody : "Brødtekst", -DlgLnkUpload : "Upload", -DlgLnkBtnUpload : "Upload", - -DlgLnkTarget : "Mål", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nyt vindue (_blank)", -DlgLnkTargetParent : "Overordnet ramme (_parent)", -DlgLnkTargetSelf : "Samme vindue (_self)", -DlgLnkTargetTop : "Hele vinduet (_top)", -DlgLnkTargetFrameName : "Destinationsvinduets navn", -DlgLnkPopWinName : "Pop-up vinduets navn", -DlgLnkPopWinFeat : "Egenskaber for pop-up", -DlgLnkPopResize : "Skalering", -DlgLnkPopLocation : "Adresselinje", -DlgLnkPopMenu : "Menulinje", -DlgLnkPopScroll : "Scrollbars", -DlgLnkPopStatus : "Statuslinje", -DlgLnkPopToolbar : "Værktøjslinje", -DlgLnkPopFullScrn : "Fuld skærm (IE)", -DlgLnkPopDependent : "Koblet/dependent (Netscape)", -DlgLnkPopWidth : "Bredde", -DlgLnkPopHeight : "Højde", -DlgLnkPopLeft : "Position fra venstre", -DlgLnkPopTop : "Position fra toppen", - -DlnLnkMsgNoUrl : "Indtast hyperlink URL!", -DlnLnkMsgNoEMail : "Indtast e-mailaddresse!", -DlnLnkMsgNoAnchor : "Vælg bogmærke!", -DlnLnkMsgInvPopName : "Navnet på popup'en skal starte med et bogstav og må ikke indeholde mellemrum", - -// Color Dialog -DlgColorTitle : "Vælg farve", -DlgColorBtnClear : "Nulstil", -DlgColorHighlight : "Markeret", -DlgColorSelected : "Valgt", - -// Smiley Dialog -DlgSmileyTitle : "Vælg smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Vælg symbol", - -// Table Dialog -DlgTableTitle : "Egenskaber for tabel", -DlgTableRows : "Rækker", -DlgTableColumns : "Kolonner", -DlgTableBorder : "Rammebredde", -DlgTableAlign : "Justering", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Venstrestillet", -DlgTableAlignCenter : "Centreret", -DlgTableAlignRight : "Højrestillet", -DlgTableWidth : "Bredde", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "procent", -DlgTableHeight : "Højde", -DlgTableCellSpace : "Celleafstand", -DlgTableCellPad : "Cellemargen", -DlgTableCaption : "Titel", -DlgTableSummary : "Resume", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Egenskaber for celle", -DlgCellWidth : "Bredde", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "procent", -DlgCellHeight : "Højde", -DlgCellWordWrap : "Orddeling", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Ja", -DlgCellWordWrapNo : "Nej", -DlgCellHorAlign : "Vandret justering", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Venstrestillet", -DlgCellHorAlignCenter : "Centreret", -DlgCellHorAlignRight: "Højrestillet", -DlgCellVerAlign : "Lodret justering", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Øverst", -DlgCellVerAlignMiddle : "Centreret", -DlgCellVerAlignBottom : "Nederst", -DlgCellVerAlignBaseline : "Grundlinje", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Højde i antal rækker", -DlgCellCollSpan : "Bredde i antal kolonner", -DlgCellBackColor : "Baggrundsfarve", -DlgCellBorderColor : "Rammefarve", -DlgCellBtnSelect : "Vælg...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Søg og erstat", - -// Find Dialog -DlgFindTitle : "Find", -DlgFindFindBtn : "Find", -DlgFindNotFoundMsg : "Søgeteksten blev ikke fundet!", - -// Replace Dialog -DlgReplaceTitle : "Erstat", -DlgReplaceFindLbl : "Søg efter:", -DlgReplaceReplaceLbl : "Erstat med:", -DlgReplaceCaseChk : "Forskel på store og små bogstaver", -DlgReplaceReplaceBtn : "Erstat", -DlgReplaceReplAllBtn : "Erstat alle", -DlgReplaceWordChk : "Kun hele ord", - -// Paste Operations / Dialog -PasteErrorCut : "Din browsers sikkerhedsindstillinger tillader ikke editoren at klippe tekst automatisk!
    Brug i stedet tastaturet til at klippe teksten (Ctrl+X).", -PasteErrorCopy : "Din browsers sikkerhedsindstillinger tillader ikke editoren at kopiere tekst automatisk!
    Brug i stedet tastaturet til at kopiere teksten (Ctrl+C).", - -PasteAsText : "Indsæt som ikke-formateret tekst", -PasteFromWord : "Indsæt fra Word", - -DlgPasteMsg2 : "Indsæt i feltet herunder (Ctrl+V) og klik OK.", -DlgPasteSec : "På grund af browserens sikkerhedsindstillinger kan editoren ikke tilgå udklipsholderen direkte. Du skal indsætte udklipsholderens indhold i dette vindue igen.", -DlgPasteIgnoreFont : "Ignorer font definitioner", -DlgPasteRemoveStyles : "Ignorer typografi", - -// Color Picker -ColorAutomatic : "Automatisk", -ColorMoreColors : "Flere farver...", - -// Document Properties -DocProps : "Egenskaber for dokument", - -// Anchor Dialog -DlgAnchorTitle : "Egenskaber for bogmærke", -DlgAnchorName : "Bogmærke navn", -DlgAnchorErrorName : "Indtast bogmærke navn!", - -// Speller Pages Dialog -DlgSpellNotInDic : "Ikke i ordbogen", -DlgSpellChangeTo : "Forslag", -DlgSpellBtnIgnore : "Ignorer", -DlgSpellBtnIgnoreAll : "Ignorer alle", -DlgSpellBtnReplace : "Erstat", -DlgSpellBtnReplaceAll : "Erstat alle", -DlgSpellBtnUndo : "Tilbage", -DlgSpellNoSuggestions : "- ingen forslag -", -DlgSpellProgress : "Stavekontrolen arbejder...", -DlgSpellNoMispell : "Stavekontrol færdig: Ingen fejl fundet", -DlgSpellNoChanges : "Stavekontrol færdig: Ingen ord ændret", -DlgSpellOneChange : "Stavekontrol færdig: Et ord ændret", -DlgSpellManyChanges : "Stavekontrol færdig: %1 ord ændret", - -IeSpellDownload : "Stavekontrol ikke installeret.
    Vil du hente den nu?", - -// Button Dialog -DlgButtonText : "Tekst", -DlgButtonType : "Type", -DlgButtonTypeBtn : "Knap", -DlgButtonTypeSbm : "Send", -DlgButtonTypeRst : "Nulstil", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Navn", -DlgCheckboxValue : "Værdi", -DlgCheckboxSelected : "Valgt", - -// Form Dialog -DlgFormName : "Navn", -DlgFormAction : "Handling", -DlgFormMethod : "Metod", - -// Select Field Dialog -DlgSelectName : "Navn", -DlgSelectValue : "Værdi", -DlgSelectSize : "Størrelse", -DlgSelectLines : "linier", -DlgSelectChkMulti : "Tillad flere valg", -DlgSelectOpAvail : "Valgmuligheder", -DlgSelectOpText : "Tekst", -DlgSelectOpValue : "Værdi", -DlgSelectBtnAdd : "Tilføj", -DlgSelectBtnModify : "Rediger", -DlgSelectBtnUp : "Op", -DlgSelectBtnDown : "Ned", -DlgSelectBtnSetValue : "Sæt som valgt", -DlgSelectBtnDelete : "Slet", - -// Textarea Dialog -DlgTextareaName : "Navn", -DlgTextareaCols : "Kolonner", -DlgTextareaRows : "Rækker", - -// Text Field Dialog -DlgTextName : "Navn", -DlgTextValue : "Værdi", -DlgTextCharWidth : "Bredde (tegn)", -DlgTextMaxChars : "Max antal tegn", -DlgTextType : "Type", -DlgTextTypeText : "Tekst", -DlgTextTypePass : "Adgangskode", - -// Hidden Field Dialog -DlgHiddenName : "Navn", -DlgHiddenValue : "Værdi", - -// Bulleted List Dialog -BulletedListProp : "Egenskaber for punktopstilling", -NumberedListProp : "Egenskaber for talopstilling", -DlgLstStart : "Start", -DlgLstType : "Type", -DlgLstTypeCircle : "Cirkel", -DlgLstTypeDisc : "Udfyldt cirkel", -DlgLstTypeSquare : "Firkant", -DlgLstTypeNumbers : "Nummereret (1, 2, 3)", -DlgLstTypeLCase : "Små bogstaver (a, b, c)", -DlgLstTypeUCase : "Store bogstaver (A, B, C)", -DlgLstTypeSRoman : "Små romertal (i, ii, iii)", -DlgLstTypeLRoman : "Store romertal (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Generelt", -DlgDocBackTab : "Baggrund", -DlgDocColorsTab : "Farver og margen", -DlgDocMetaTab : "Metadata", - -DlgDocPageTitle : "Sidetitel", -DlgDocLangDir : "Sprog", -DlgDocLangDirLTR : "Fra venstre mod højre (LTR)", -DlgDocLangDirRTL : "Fra højre mod venstre (RTL)", -DlgDocLangCode : "Landekode", -DlgDocCharSet : "Tegnsæt kode", -DlgDocCharSetCE : "Centraleuropæisk", -DlgDocCharSetCT : "Traditionel kinesisk (Big5)", -DlgDocCharSetCR : "Kyrillisk", -DlgDocCharSetGR : "Græsk", -DlgDocCharSetJP : "Japansk", -DlgDocCharSetKR : "Koreansk", -DlgDocCharSetTR : "Tyrkisk", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Vesteuropæisk", -DlgDocCharSetOther : "Anden tegnsæt kode", - -DlgDocDocType : "Dokumenttype kategori", -DlgDocDocTypeOther : "Anden dokumenttype kategori", -DlgDocIncXHTML : "Inkludere XHTML deklartion", -DlgDocBgColor : "Baggrundsfarve", -DlgDocBgImage : "Baggrundsbillede URL", -DlgDocBgNoScroll : "Fastlåst baggrund", -DlgDocCText : "Tekst", -DlgDocCLink : "Hyperlink", -DlgDocCVisited : "Besøgt hyperlink", -DlgDocCActive : "Aktivt hyperlink", -DlgDocMargins : "Sidemargen", -DlgDocMaTop : "Øverst", -DlgDocMaLeft : "Venstre", -DlgDocMaRight : "Højre", -DlgDocMaBottom : "Nederst", -DlgDocMeIndex : "Dokument index nøgleord (kommasepareret)", -DlgDocMeDescr : "Dokument beskrivelse", -DlgDocMeAuthor : "Forfatter", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Vis", - -// Templates Dialog -Templates : "Skabeloner", -DlgTemplatesTitle : "Indholdsskabeloner", -DlgTemplatesSelMsg : "Vælg den skabelon, som skal åbnes i editoren.
    (Nuværende indhold vil blive overskrevet!):", -DlgTemplatesLoading : "Henter liste over skabeloner...", -DlgTemplatesNoTpl : "(Der er ikke defineret nogen skabelon!)", -DlgTemplatesReplace : "Erstat det faktiske indhold", - -// About Dialog -DlgAboutAboutTab : "Om", -DlgAboutBrowserInfoTab : "Generelt", -DlgAboutLicenseTab : "Licens", -DlgAboutVersion : "version", -DlgAboutInfo : "For yderlig information gå til", - -// Div Dialog -DlgDivGeneralTab : "Generelt", -DlgDivAdvancedTab : "Avanceret", -DlgDivStyle : "Style", -DlgDivInlineStyle : "Inline style", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/de.js b/httemplate/elements/fckeditor/editor/lang/de.js deleted file mode 100644 index 774fcd759..000000000 --- a/httemplate/elements/fckeditor/editor/lang/de.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * German language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Symbolleiste einklappen", -ToolbarExpand : "Symbolleiste ausklappen", - -// Toolbar Items and Context Menu -Save : "Speichern", -NewPage : "Neue Seite", -Preview : "Vorschau", -Cut : "Ausschneiden", -Copy : "Kopieren", -Paste : "Einfügen", -PasteText : "aus Textdatei einfügen", -PasteWord : "aus MS-Word einfügen", -Print : "Drucken", -SelectAll : "Alles auswählen", -RemoveFormat : "Formatierungen entfernen", -InsertLinkLbl : "Link", -InsertLink : "Link einfügen/editieren", -RemoveLink : "Link entfernen", -VisitLink : "Link aufrufen", -Anchor : "Anker einfügen/editieren", -AnchorDelete : "Anker entfernen", -InsertImageLbl : "Bild", -InsertImage : "Bild einfügen/editieren", -InsertFlashLbl : "Flash", -InsertFlash : "Flash einfügen/editieren", -InsertTableLbl : "Tabelle", -InsertTable : "Tabelle einfügen/editieren", -InsertLineLbl : "Linie", -InsertLine : "Horizontale Linie einfügen", -InsertSpecialCharLbl: "Sonderzeichen", -InsertSpecialChar : "Sonderzeichen einfügen/editieren", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Smiley einfügen", -About : "Über FCKeditor", -Bold : "Fett", -Italic : "Kursiv", -Underline : "Unterstrichen", -StrikeThrough : "Durchgestrichen", -Subscript : "Tiefgestellt", -Superscript : "Hochgestellt", -LeftJustify : "Linksbündig", -CenterJustify : "Zentriert", -RightJustify : "Rechtsbündig", -BlockJustify : "Blocksatz", -DecreaseIndent : "Einzug verringern", -IncreaseIndent : "Einzug erhöhen", -Blockquote : "Zitatblock", -CreateDiv : "Erzeuge Div Block", -EditDiv : "Bearbeite Div Block", -DeleteDiv : "Entferne Div Block", -Undo : "Rückgängig", -Redo : "Wiederherstellen", -NumberedListLbl : "Nummerierte Liste", -NumberedList : "Nummerierte Liste einfügen/entfernen", -BulletedListLbl : "Liste", -BulletedList : "Liste einfügen/entfernen", -ShowTableBorders : "Zeige Tabellenrahmen", -ShowDetails : "Zeige Details", -Style : "Stil", -FontFormat : "Format", -Font : "Schriftart", -FontSize : "Größe", -TextColor : "Textfarbe", -BGColor : "Hintergrundfarbe", -Source : "Quellcode", -Find : "Suchen", -Replace : "Ersetzen", -SpellCheck : "Rechtschreibprüfung", -UniversalKeyboard : "Universal-Tastatur", -PageBreakLbl : "Seitenumbruch", -PageBreak : "Seitenumbruch einfügen", - -Form : "Formular", -Checkbox : "Checkbox", -RadioButton : "Radiobutton", -TextField : "Textfeld einzeilig", -Textarea : "Textfeld mehrzeilig", -HiddenField : "verstecktes Feld", -Button : "Klickbutton", -SelectionField : "Auswahlfeld", -ImageButton : "Bildbutton", - -FitWindow : "Editor maximieren", -ShowBlocks : "Blöcke anzeigen", - -// Context Menu -EditLink : "Link editieren", -CellCM : "Zelle", -RowCM : "Zeile", -ColumnCM : "Spalte", -InsertRowAfter : "Zeile unterhalb einfügen", -InsertRowBefore : "Zeile oberhalb einfügen", -DeleteRows : "Zeile entfernen", -InsertColumnAfter : "Spalte rechts danach einfügen", -InsertColumnBefore : "Spalte links davor einfügen", -DeleteColumns : "Spalte löschen", -InsertCellAfter : "Zelle danach einfügen", -InsertCellBefore : "Zelle davor einfügen", -DeleteCells : "Zelle löschen", -MergeCells : "Zellen verbinden", -MergeRight : "nach rechts verbinden", -MergeDown : "nach unten verbinden", -HorizontalSplitCell : "Zelle horizontal teilen", -VerticalSplitCell : "Zelle vertikal teilen", -TableDelete : "Tabelle löschen", -CellProperties : "Zellen-Eigenschaften", -TableProperties : "Tabellen-Eigenschaften", -ImageProperties : "Bild-Eigenschaften", -FlashProperties : "Flash-Eigenschaften", - -AnchorProp : "Anker-Eigenschaften", -ButtonProp : "Button-Eigenschaften", -CheckboxProp : "Checkbox-Eigenschaften", -HiddenFieldProp : "Verstecktes Feld-Eigenschaften", -RadioButtonProp : "Optionsfeld-Eigenschaften", -ImageButtonProp : "Bildbutton-Eigenschaften", -TextFieldProp : "Textfeld (einzeilig) Eigenschaften", -SelectionFieldProp : "Auswahlfeld-Eigenschaften", -TextareaProp : "Textfeld (mehrzeilig) Eigenschaften", -FormProp : "Formular-Eigenschaften", - -FontFormats : "Normal;Formatiert;Addresse;Überschrift 1;Überschrift 2;Überschrift 3;Überschrift 4;Überschrift 5;Überschrift 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Bearbeite XHTML. Bitte warten...", -Done : "Fertig", -PasteWordConfirm : "Der Text, den Sie einfügen möchten, scheint aus MS-Word kopiert zu sein. Möchten Sie ihn zuvor bereinigen lassen?", -NotCompatiblePaste : "Diese Funktion steht nur im Internet Explorer ab Version 5.5 zur Verfügung. Möchten Sie den Text unbereinigt einfügen?", -UnknownToolbarItem : "Unbekanntes Menüleisten-Objekt \"%1\"", -UnknownCommand : "Unbekannter Befehl \"%1\"", -NotImplemented : "Befehl nicht implementiert", -UnknownToolbarSet : "Menüleiste \"%1\" existiert nicht", -NoActiveX : "Die Sicherheitseinstellungen Ihres Browsers beschränken evtl. einige Funktionen des Editors. Aktivieren Sie die Option \"ActiveX-Steuerelemente und Plugins ausführen\" in den Sicherheitseinstellungen, um diese Funktionen nutzen zu können", -BrowseServerBlocked : "Ein Auswahlfenster konnte nicht geöffnet werden. Stellen Sie sicher, das alle Popup-Blocker ausgeschaltet sind.", -DialogBlocked : "Das Dialog-Fenster konnte nicht geöffnet werden. Stellen Sie sicher, das alle Popup-Blocker ausgeschaltet sind.", -VisitLinkBlocked : "Es war leider nicht möglich ein neues Fenster zu öffnen. Bitte versichern Sie sich das der Popup-Blocker ausgeschaltet ist.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Abbrechen", -DlgBtnClose : "Schließen", -DlgBtnBrowseServer : "Server durchsuchen", -DlgAdvancedTag : "Erweitert", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Bitte tragen Sie die URL ein", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "ID", -DlgGenLangDir : "Schreibrichtung", -DlgGenLangDirLtr : "Links nach Rechts (LTR)", -DlgGenLangDirRtl : "Rechts nach Links (RTL)", -DlgGenLangCode : "Sprachenkürzel", -DlgGenAccessKey : "Zugriffstaste", -DlgGenName : "Name", -DlgGenTabIndex : "Tab-Index", -DlgGenLongDescr : "Langform URL", -DlgGenClass : "Stylesheet Klasse", -DlgGenTitle : "Titel Beschreibung", -DlgGenContType : "Inhaltstyp", -DlgGenLinkCharset : "Ziel-Zeichensatz", -DlgGenStyle : "Style", - -// Image Dialog -DlgImgTitle : "Bild-Eigenschaften", -DlgImgInfoTab : "Bild-Info", -DlgImgBtnUpload : "Zum Server senden", -DlgImgURL : "Bildauswahl", -DlgImgUpload : "Upload", -DlgImgAlt : "Alternativer Text", -DlgImgWidth : "Breite", -DlgImgHeight : "Höhe", -DlgImgLockRatio : "Größenverhältniss beibehalten", -DlgBtnResetSize : "Größe zurücksetzen", -DlgImgBorder : "Rahmen", -DlgImgHSpace : "Horizontal-Abstand", -DlgImgVSpace : "Vertikal-Abstand", -DlgImgAlign : "Ausrichtung", -DlgImgAlignLeft : "Links", -DlgImgAlignAbsBottom: "Abs Unten", -DlgImgAlignAbsMiddle: "Abs Mitte", -DlgImgAlignBaseline : "Baseline", -DlgImgAlignBottom : "Unten", -DlgImgAlignMiddle : "Mitte", -DlgImgAlignRight : "Rechts", -DlgImgAlignTextTop : "Text Oben", -DlgImgAlignTop : "Oben", -DlgImgPreview : "Vorschau", -DlgImgAlertUrl : "Bitte geben Sie die Bild-URL an", -DlgImgLinkTab : "Link", - -// Flash Dialog -DlgFlashTitle : "Flash-Eigenschaften", -DlgFlashChkPlay : "autom. Abspielen", -DlgFlashChkLoop : "Endlosschleife", -DlgFlashChkMenu : "Flash-Menü aktivieren", -DlgFlashScale : "Skalierung", -DlgFlashScaleAll : "Alles anzeigen", -DlgFlashScaleNoBorder : "ohne Rand", -DlgFlashScaleFit : "Passgenau", - -// Link Dialog -DlgLnkWindowTitle : "Link", -DlgLnkInfoTab : "Link-Info", -DlgLnkTargetTab : "Zielseite", - -DlgLnkType : "Link-Typ", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Anker in dieser Seite", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protokoll", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Anker auswählen", -DlgLnkAnchorByName : "nach Anker Name", -DlgLnkAnchorById : "nach Element Id", -DlgLnkNoAnchors : "(keine Anker im Dokument vorhanden)", -DlgLnkEMail : "E-Mail Addresse", -DlgLnkEMailSubject : "Betreffzeile", -DlgLnkEMailBody : "Nachrichtentext", -DlgLnkUpload : "Upload", -DlgLnkBtnUpload : "Zum Server senden", - -DlgLnkTarget : "Zielseite", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Neues Fenster (_blank)", -DlgLnkTargetParent : "Oberes Fenster (_parent)", -DlgLnkTargetSelf : "Gleiches Fenster (_self)", -DlgLnkTargetTop : "Oberstes Fenster (_top)", -DlgLnkTargetFrameName : "Ziel-Fenster-Name", -DlgLnkPopWinName : "Pop-up Fenster-Name", -DlgLnkPopWinFeat : "Pop-up Fenster-Eigenschaften", -DlgLnkPopResize : "Vergrößerbar", -DlgLnkPopLocation : "Adress-Leiste", -DlgLnkPopMenu : "Menü-Leiste", -DlgLnkPopScroll : "Rollbalken", -DlgLnkPopStatus : "Statusleiste", -DlgLnkPopToolbar : "Werkzeugleiste", -DlgLnkPopFullScrn : "Vollbild (IE)", -DlgLnkPopDependent : "Abhängig (Netscape)", -DlgLnkPopWidth : "Breite", -DlgLnkPopHeight : "Höhe", -DlgLnkPopLeft : "Linke Position", -DlgLnkPopTop : "Obere Position", - -DlnLnkMsgNoUrl : "Bitte geben Sie die Link-URL an", -DlnLnkMsgNoEMail : "Bitte geben Sie e-Mail Adresse an", -DlnLnkMsgNoAnchor : "Bitte wählen Sie einen Anker aus", -DlnLnkMsgInvPopName : "Der Name des Popups muss mit einem Buchstaben beginnen und darf keine Leerzeichen enthalten", - -// Color Dialog -DlgColorTitle : "Farbauswahl", -DlgColorBtnClear : "Keine Farbe", -DlgColorHighlight : "Vorschau", -DlgColorSelected : "Ausgewählt", - -// Smiley Dialog -DlgSmileyTitle : "Smiley auswählen", - -// Special Character Dialog -DlgSpecialCharTitle : "Sonderzeichen auswählen", - -// Table Dialog -DlgTableTitle : "Tabellen-Eigenschaften", -DlgTableRows : "Zeile", -DlgTableColumns : "Spalte", -DlgTableBorder : "Rahmen", -DlgTableAlign : "Ausrichtung", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Links", -DlgTableAlignCenter : "Zentriert", -DlgTableAlignRight : "Rechts", -DlgTableWidth : "Breite", -DlgTableWidthPx : "Pixel", -DlgTableWidthPc : "%", -DlgTableHeight : "Höhe", -DlgTableCellSpace : "Zellenabstand außen", -DlgTableCellPad : "Zellenabstand innen", -DlgTableCaption : "Überschrift", -DlgTableSummary : "Inhaltsübersicht", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Zellen-Eigenschaften", -DlgCellWidth : "Breite", -DlgCellWidthPx : "Pixel", -DlgCellWidthPc : "%", -DlgCellHeight : "Höhe", -DlgCellWordWrap : "Umbruch", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Ja", -DlgCellWordWrapNo : "Nein", -DlgCellHorAlign : "Horizontale Ausrichtung", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Links", -DlgCellHorAlignCenter : "Zentriert", -DlgCellHorAlignRight: "Rechts", -DlgCellVerAlign : "Vertikale Ausrichtung", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Oben", -DlgCellVerAlignMiddle : "Mitte", -DlgCellVerAlignBottom : "Unten", -DlgCellVerAlignBaseline : "Grundlinie", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Zeilen zusammenfassen", -DlgCellCollSpan : "Spalten zusammenfassen", -DlgCellBackColor : "Hintergrundfarbe", -DlgCellBorderColor : "Rahmenfarbe", -DlgCellBtnSelect : "Auswahl...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Suchen und Ersetzen", - -// Find Dialog -DlgFindTitle : "Finden", -DlgFindFindBtn : "Finden", -DlgFindNotFoundMsg : "Der gesuchte Text wurde nicht gefunden.", - -// Replace Dialog -DlgReplaceTitle : "Ersetzen", -DlgReplaceFindLbl : "Suche nach:", -DlgReplaceReplaceLbl : "Ersetze mit:", -DlgReplaceCaseChk : "Groß-Kleinschreibung beachten", -DlgReplaceReplaceBtn : "Ersetzen", -DlgReplaceReplAllBtn : "Alle Ersetzen", -DlgReplaceWordChk : "Nur ganze Worte suchen", - -// Paste Operations / Dialog -PasteErrorCut : "Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch auszuschneiden. Bitte benutzen Sie die System-Zwischenablage über STRG-X (ausschneiden) und STRG-V (einfügen).", -PasteErrorCopy : "Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch kopieren. Bitte benutzen Sie die System-Zwischenablage über STRG-C (kopieren).", - -PasteAsText : "Als Text einfügen", -PasteFromWord : "Aus Word einfügen", - -DlgPasteMsg2 : "Bitte fügen Sie den Text in der folgenden Box über die Tastatur (mit Strg+V) ein und bestätigen Sie mit OK.", -DlgPasteSec : "Aufgrund von Sicherheitsbeschränkungen Ihres Browsers kann der Editor nicht direkt auf die Zwischenablage zugreifen. Bitte fügen Sie den Inhalt erneut in diesem Fenster ein.", -DlgPasteIgnoreFont : "Ignoriere Schriftart-Definitionen", -DlgPasteRemoveStyles : "Entferne Style-Definitionen", - -// Color Picker -ColorAutomatic : "Automatisch", -ColorMoreColors : "Weitere Farben...", - -// Document Properties -DocProps : "Dokument-Eigenschaften", - -// Anchor Dialog -DlgAnchorTitle : "Anker-Eigenschaften", -DlgAnchorName : "Anker Name", -DlgAnchorErrorName : "Bitte geben Sie den Namen des Ankers ein", - -// Speller Pages Dialog -DlgSpellNotInDic : "Nicht im Wörterbuch", -DlgSpellChangeTo : "Ändern in", -DlgSpellBtnIgnore : "Ignorieren", -DlgSpellBtnIgnoreAll : "Alle Ignorieren", -DlgSpellBtnReplace : "Ersetzen", -DlgSpellBtnReplaceAll : "Alle Ersetzen", -DlgSpellBtnUndo : "Rückgängig", -DlgSpellNoSuggestions : " - keine Vorschläge - ", -DlgSpellProgress : "Rechtschreibprüfung läuft...", -DlgSpellNoMispell : "Rechtschreibprüfung abgeschlossen - keine Fehler gefunden", -DlgSpellNoChanges : "Rechtschreibprüfung abgeschlossen - keine Worte geändert", -DlgSpellOneChange : "Rechtschreibprüfung abgeschlossen - ein Wort geändert", -DlgSpellManyChanges : "Rechtschreibprüfung abgeschlossen - %1 Wörter geändert", - -IeSpellDownload : "Rechtschreibprüfung nicht installiert. Möchten Sie sie jetzt herunterladen?", - -// Button Dialog -DlgButtonText : "Text (Wert)", -DlgButtonType : "Typ", -DlgButtonTypeBtn : "Button", -DlgButtonTypeSbm : "Absenden", -DlgButtonTypeRst : "Zurücksetzen", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Name", -DlgCheckboxValue : "Wert", -DlgCheckboxSelected : "ausgewählt", - -// Form Dialog -DlgFormName : "Name", -DlgFormAction : "Action", -DlgFormMethod : "Method", - -// Select Field Dialog -DlgSelectName : "Name", -DlgSelectValue : "Wert", -DlgSelectSize : "Größe", -DlgSelectLines : "Linien", -DlgSelectChkMulti : "Erlaube Mehrfachauswahl", -DlgSelectOpAvail : "Mögliche Optionen", -DlgSelectOpText : "Text", -DlgSelectOpValue : "Wert", -DlgSelectBtnAdd : "Hinzufügen", -DlgSelectBtnModify : "Ändern", -DlgSelectBtnUp : "Hoch", -DlgSelectBtnDown : "Runter", -DlgSelectBtnSetValue : "Setze als Standardwert", -DlgSelectBtnDelete : "Entfernen", - -// Textarea Dialog -DlgTextareaName : "Name", -DlgTextareaCols : "Spalten", -DlgTextareaRows : "Reihen", - -// Text Field Dialog -DlgTextName : "Name", -DlgTextValue : "Wert", -DlgTextCharWidth : "Zeichenbreite", -DlgTextMaxChars : "Max. Zeichen", -DlgTextType : "Typ", -DlgTextTypeText : "Text", -DlgTextTypePass : "Passwort", - -// Hidden Field Dialog -DlgHiddenName : "Name", -DlgHiddenValue : "Wert", - -// Bulleted List Dialog -BulletedListProp : "Listen-Eigenschaften", -NumberedListProp : "Nummerierte Listen-Eigenschaften", -DlgLstStart : "Start", -DlgLstType : "Typ", -DlgLstTypeCircle : "Ring", -DlgLstTypeDisc : "Kreis", -DlgLstTypeSquare : "Quadrat", -DlgLstTypeNumbers : "Nummern (1, 2, 3)", -DlgLstTypeLCase : "Kleinbuchstaben (a, b, c)", -DlgLstTypeUCase : "Großbuchstaben (A, B, C)", -DlgLstTypeSRoman : "Kleine römische Zahlen (i, ii, iii)", -DlgLstTypeLRoman : "Große römische Zahlen (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Allgemein", -DlgDocBackTab : "Hintergrund", -DlgDocColorsTab : "Farben und Abstände", -DlgDocMetaTab : "Metadaten", - -DlgDocPageTitle : "Seitentitel", -DlgDocLangDir : "Schriftrichtung", -DlgDocLangDirLTR : "Links nach Rechts", -DlgDocLangDirRTL : "Rechts nach Links", -DlgDocLangCode : "Sprachkürzel", -DlgDocCharSet : "Zeichenkodierung", -DlgDocCharSetCE : "Zentraleuropäisch", -DlgDocCharSetCT : "traditionell Chinesisch (Big5)", -DlgDocCharSetCR : "Kyrillisch", -DlgDocCharSetGR : "Griechisch", -DlgDocCharSetJP : "Japanisch", -DlgDocCharSetKR : "Koreanisch", -DlgDocCharSetTR : "Türkisch", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Westeuropäisch", -DlgDocCharSetOther : "Andere Zeichenkodierung", - -DlgDocDocType : "Dokumententyp", -DlgDocDocTypeOther : "Anderer Dokumententyp", -DlgDocIncXHTML : "Beziehe XHTML Deklarationen ein", -DlgDocBgColor : "Hintergrundfarbe", -DlgDocBgImage : "Hintergrundbild URL", -DlgDocBgNoScroll : "feststehender Hintergrund", -DlgDocCText : "Text", -DlgDocCLink : "Link", -DlgDocCVisited : "Besuchter Link", -DlgDocCActive : "Aktiver Link", -DlgDocMargins : "Seitenränder", -DlgDocMaTop : "Oben", -DlgDocMaLeft : "Links", -DlgDocMaRight : "Rechts", -DlgDocMaBottom : "Unten", -DlgDocMeIndex : "Schlüsselwörter (durch Komma getrennt)", -DlgDocMeDescr : "Dokument-Beschreibung", -DlgDocMeAuthor : "Autor", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Vorschau", - -// Templates Dialog -Templates : "Vorlagen", -DlgTemplatesTitle : "Vorlagen", -DlgTemplatesSelMsg : "Klicken Sie auf eine Vorlage, um sie im Editor zu öffnen (der aktuelle Inhalt wird dabei gelöscht!):", -DlgTemplatesLoading : "Liste der Vorlagen wird geladen. Bitte warten...", -DlgTemplatesNoTpl : "(keine Vorlagen definiert)", -DlgTemplatesReplace : "Aktuellen Inhalt ersetzen", - -// About Dialog -DlgAboutAboutTab : "Über", -DlgAboutBrowserInfoTab : "Browser-Info", -DlgAboutLicenseTab : "Lizenz", -DlgAboutVersion : "Version", -DlgAboutInfo : "Für weitere Informationen siehe", - -// Div Dialog -DlgDivGeneralTab : "Allgemein", -DlgDivAdvancedTab : "Erweitert", -DlgDivStyle : "Style", -DlgDivInlineStyle : "Inline Style", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/el.js b/httemplate/elements/fckeditor/editor/lang/el.js deleted file mode 100644 index b5e42686e..000000000 --- a/httemplate/elements/fckeditor/editor/lang/el.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Greek language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Απόκρυψη Μπάρας Εργαλείων", -ToolbarExpand : "Εμφάνιση Μπάρας Εργαλείων", - -// Toolbar Items and Context Menu -Save : "Αποθήκευση", -NewPage : "Νέα Σελίδα", -Preview : "Προεπισκόπιση", -Cut : "Αποκοπή", -Copy : "Αντιγραφή", -Paste : "Επικόλληση", -PasteText : "Επικόλληση (απλό κείμενο)", -PasteWord : "Επικόλληση από το Word", -Print : "Εκτύπωση", -SelectAll : "Επιλογή όλων", -RemoveFormat : "Αφαίρεση Μορφοποίησης", -InsertLinkLbl : "Σύνδεσμος (Link)", -InsertLink : "Εισαγωγή/Μεταβολή Συνδέσμου (Link)", -RemoveLink : "Αφαίρεση Συνδέσμου (Link)", -VisitLink : "Open Link", //MISSING -Anchor : "Εισαγωγή/επεξεργασία Anchor", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "Εικόνα", -InsertImage : "Εισαγωγή/Μεταβολή Εικόνας", -InsertFlashLbl : "Εισαγωγή Flash", -InsertFlash : "Εισαγωγή/επεξεργασία Flash", -InsertTableLbl : "Πίνακας", -InsertTable : "Εισαγωγή/Μεταβολή Πίνακα", -InsertLineLbl : "Γραμμή", -InsertLine : "Εισαγωγή Οριζόντιας Γραμμής", -InsertSpecialCharLbl: "Ειδικό Σύμβολο", -InsertSpecialChar : "Εισαγωγή Ειδικού Συμβόλου", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Εισαγωγή Smiley", -About : "Περί του FCKeditor", -Bold : "Έντονα", -Italic : "Πλάγια", -Underline : "Υπογράμμιση", -StrikeThrough : "Διαγράμμιση", -Subscript : "Δείκτης", -Superscript : "Εκθέτης", -LeftJustify : "Στοίχιση Αριστερά", -CenterJustify : "Στοίχιση στο Κέντρο", -RightJustify : "Στοίχιση Δεξιά", -BlockJustify : "Πλήρης Στοίχιση (Block)", -DecreaseIndent : "Μείωση Εσοχής", -IncreaseIndent : "Αύξηση Εσοχής", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Αναίρεση", -Redo : "Επαναφορά", -NumberedListLbl : "Λίστα με Αριθμούς", -NumberedList : "Εισαγωγή/Διαγραφή Λίστας με Αριθμούς", -BulletedListLbl : "Λίστα με Bullets", -BulletedList : "Εισαγωγή/Διαγραφή Λίστας με Bullets", -ShowTableBorders : "Προβολή Ορίων Πίνακα", -ShowDetails : "Προβολή Λεπτομερειών", -Style : "Στυλ", -FontFormat : "Μορφή Γραμματοσειράς", -Font : "Γραμματοσειρά", -FontSize : "Μέγεθος", -TextColor : "Χρώμα Γραμμάτων", -BGColor : "Χρώμα Υποβάθρου", -Source : "HTML κώδικας", -Find : "Αναζήτηση", -Replace : "Αντικατάσταση", -SpellCheck : "Ορθογραφικός έλεγχος", -UniversalKeyboard : "Διεθνής πληκτρολόγιο", -PageBreakLbl : "Τέλος σελίδας", -PageBreak : "Εισαγωγή τέλους σελίδας", - -Form : "Φόρμα", -Checkbox : "Κουτί επιλογής", -RadioButton : "Κουμπί Radio", -TextField : "Πεδίο κειμένου", -Textarea : "Περιοχή κειμένου", -HiddenField : "Κρυφό πεδίο", -Button : "Κουμπί", -SelectionField : "Πεδίο επιλογής", -ImageButton : "Κουμπί εικόνας", - -FitWindow : "Μεγιστοποίηση προγράμματος", -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "Μεταβολή Συνδέσμου (Link)", -CellCM : "Κελί", -RowCM : "Σειρά", -ColumnCM : "Στήλη", -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "Διαγραφή Γραμμών", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "Διαγραφή Κολωνών", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "Διαγραφή Κελιών", -MergeCells : "Ενοποίηση Κελιών", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "Διαγραφή πίνακα", -CellProperties : "Ιδιότητες Κελιού", -TableProperties : "Ιδιότητες Πίνακα", -ImageProperties : "Ιδιότητες Εικόνας", -FlashProperties : "Ιδιότητες Flash", - -AnchorProp : "Ιδιότητες άγκυρας", -ButtonProp : "Ιδιότητες κουμπιού", -CheckboxProp : "Ιδιότητες κουμπιού επιλογής", -HiddenFieldProp : "Ιδιότητες κρυφού πεδίου", -RadioButtonProp : "Ιδιότητες κουμπιού radio", -ImageButtonProp : "Ιδιότητες κουμπιού εικόνας", -TextFieldProp : "Ιδιότητες πεδίου κειμένου", -SelectionFieldProp : "Ιδιότητες πεδίου επιλογής", -TextareaProp : "Ιδιότητες περιοχής κειμένου", -FormProp : "Ιδιότητες φόρμας", - -FontFormats : "Κανονικό;Μορφοποιημένο;Διεύθυνση;Επικεφαλίδα 1;Επικεφαλίδα 2;Επικεφαλίδα 3;Επικεφαλίδα 4;Επικεφαλίδα 5;Επικεφαλίδα 6", - -// Alerts and Messages -ProcessingXHTML : "Επεξεργασία XHTML. Παρακαλώ περιμένετε...", -Done : "Έτοιμο", -PasteWordConfirm : "Το κείμενο που θέλετε να επικολήσετε, φαίνεται πως προέρχεται από το Word. Θέλετε να καθαριστεί πριν επικοληθεί;", -NotCompatiblePaste : "Αυτή η επιλογή είναι διαθέσιμη στον Internet Explorer έκδοση 5.5+. Θέλετε να γίνει η επικόλληση χωρίς καθαρισμό;", -UnknownToolbarItem : "Άγνωστο αντικείμενο της μπάρας εργαλείων \"%1\"", -UnknownCommand : "Άγνωστή εντολή \"%1\"", -NotImplemented : "Η εντολή δεν έχει ενεργοποιηθεί", -UnknownToolbarSet : "Η μπάρα εργαλείων \"%1\" δεν υπάρχει", -NoActiveX : "Οι ρυθμίσεις ασφαλείας του browser σας μπορεί να περιορίσουν κάποιες ρυθμίσεις του προγράμματος. Χρειάζεται να ενεργοποιήσετε την επιλογή \"Run ActiveX controls and plug-ins\". Ίσως παρουσιαστούν λάθη και παρατηρήσετε ελειπείς λειτουργίες.", -BrowseServerBlocked : "Οι πόροι του browser σας δεν είναι προσπελάσιμοι. Σιγουρευτείτε ότι δεν υπάρχουν ενεργοί popup blockers.", -DialogBlocked : "Δεν ήταν δυνατό να ανοίξει το παράθυρο διαλόγου. Σιγουρευτείτε ότι δεν υπάρχουν ενεργοί popup blockers.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Ακύρωση", -DlgBtnClose : "Κλείσιμο", -DlgBtnBrowseServer : "Εξερεύνηση διακομιστή", -DlgAdvancedTag : "Για προχωρημένους", -DlgOpOther : "<Άλλα>", -DlgInfoTab : "Πληροφορίες", -DlgAlertUrl : "Παρακαλώ εισάγετε URL", - -// General Dialogs Labels -DlgGenNotSet : "<χωρίς>", -DlgGenId : "Id", -DlgGenLangDir : "Κατεύθυνση κειμένου", -DlgGenLangDirLtr : "Αριστερά προς Δεξιά (LTR)", -DlgGenLangDirRtl : "Δεξιά προς Αριστερά (RTL)", -DlgGenLangCode : "Κωδικός Γλώσσας", -DlgGenAccessKey : "Συντόμευση (Access Key)", -DlgGenName : "Όνομα", -DlgGenTabIndex : "Tab Index", -DlgGenLongDescr : "Αναλυτική περιγραφή URL", -DlgGenClass : "Stylesheet Classes", -DlgGenTitle : "Συμβουλευτικός τίτλος", -DlgGenContType : "Συμβουλευτικός τίτλος περιεχομένου", -DlgGenLinkCharset : "Linked Resource Charset", -DlgGenStyle : "Στύλ", - -// Image Dialog -DlgImgTitle : "Ιδιότητες Εικόνας", -DlgImgInfoTab : "Πληροφορίες Εικόνας", -DlgImgBtnUpload : "Αποστολή στον Διακομιστή", -DlgImgURL : "URL", -DlgImgUpload : "Αποστολή", -DlgImgAlt : "Εναλλακτικό Κείμενο (ALT)", -DlgImgWidth : "Πλάτος", -DlgImgHeight : "Ύψος", -DlgImgLockRatio : "Κλείδωμα Αναλογίας", -DlgBtnResetSize : "Επαναφορά Αρχικού Μεγέθους", -DlgImgBorder : "Περιθώριο", -DlgImgHSpace : "Οριζόντιος Χώρος (HSpace)", -DlgImgVSpace : "Κάθετος Χώρος (VSpace)", -DlgImgAlign : "Ευθυγράμμιση (Align)", -DlgImgAlignLeft : "Αριστερά", -DlgImgAlignAbsBottom: "Απόλυτα Κάτω (Abs Bottom)", -DlgImgAlignAbsMiddle: "Απόλυτα στη Μέση (Abs Middle)", -DlgImgAlignBaseline : "Γραμμή Βάσης (Baseline)", -DlgImgAlignBottom : "Κάτω (Bottom)", -DlgImgAlignMiddle : "Μέση (Middle)", -DlgImgAlignRight : "Δεξιά (Right)", -DlgImgAlignTextTop : "Κορυφή Κειμένου (Text Top)", -DlgImgAlignTop : "Πάνω (Top)", -DlgImgPreview : "Προεπισκόπιση", -DlgImgAlertUrl : "Εισάγετε την τοποθεσία (URL) της εικόνας", -DlgImgLinkTab : "Σύνδεσμος", - -// Flash Dialog -DlgFlashTitle : "Ιδιότητες flash", -DlgFlashChkPlay : "Αυτόματη έναρξη", -DlgFlashChkLoop : "Επανάληψη", -DlgFlashChkMenu : "Ενεργοποίηση Flash Menu", -DlgFlashScale : "Κλίμακα", -DlgFlashScaleAll : "Εμφάνιση όλων", -DlgFlashScaleNoBorder : "Χωρίς όρια", -DlgFlashScaleFit : "Ακριβής εφαρμογή", - -// Link Dialog -DlgLnkWindowTitle : "Σύνδεσμος (Link)", -DlgLnkInfoTab : "Link", -DlgLnkTargetTab : "Παράθυρο Στόχος (Target)", - -DlgLnkType : "Τύπος συνδέσμου (Link)", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Άγκυρα σε αυτή τη σελίδα", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Προτόκολο", -DlgLnkProtoOther : "<άλλο>", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Επιλέξτε μια άγκυρα", -DlgLnkAnchorByName : "Βάσει του Ονόματος (Name) της άγκυρας", -DlgLnkAnchorById : "Βάσει του Element Id", -DlgLnkNoAnchors : "(Δεν υπάρχουν άγκυρες στο κείμενο)", -DlgLnkEMail : "Διεύθυνση Ηλεκτρονικού Ταχυδρομείου", -DlgLnkEMailSubject : "Θέμα Μηνύματος", -DlgLnkEMailBody : "Κείμενο Μηνύματος", -DlgLnkUpload : "Αποστολή", -DlgLnkBtnUpload : "Αποστολή στον Διακομιστή", - -DlgLnkTarget : "Παράθυρο Στόχος (Target)", -DlgLnkTargetFrame : "<πλαίσιο>", -DlgLnkTargetPopup : "<παράθυρο popup>", -DlgLnkTargetBlank : "Νέο Παράθυρο (_blank)", -DlgLnkTargetParent : "Γονικό Παράθυρο (_parent)", -DlgLnkTargetSelf : "Ίδιο Παράθυρο (_self)", -DlgLnkTargetTop : "Ανώτατο Παράθυρο (_top)", -DlgLnkTargetFrameName : "Όνομα πλαισίου στόχου", -DlgLnkPopWinName : "Όνομα Popup Window", -DlgLnkPopWinFeat : "Επιλογές Popup Window", -DlgLnkPopResize : "Με αλλαγή Μεγέθους", -DlgLnkPopLocation : "Μπάρα Τοποθεσίας", -DlgLnkPopMenu : "Μπάρα Menu", -DlgLnkPopScroll : "Μπάρες Κύλισης", -DlgLnkPopStatus : "Μπάρα Status", -DlgLnkPopToolbar : "Μπάρα Εργαλείων", -DlgLnkPopFullScrn : "Ολόκληρη η Οθόνη (IE)", -DlgLnkPopDependent : "Dependent (Netscape)", -DlgLnkPopWidth : "Πλάτος", -DlgLnkPopHeight : "Ύψος", -DlgLnkPopLeft : "Τοποθεσία Αριστερής Άκρης", -DlgLnkPopTop : "Τοποθεσία Πάνω Άκρης", - -DlnLnkMsgNoUrl : "Εισάγετε την τοποθεσία (URL) του υπερσυνδέσμου (Link)", -DlnLnkMsgNoEMail : "Εισάγετε την διεύθυνση ηλεκτρονικού ταχυδρομείου", -DlnLnkMsgNoAnchor : "Επιλέξτε ένα Anchor", -DlnLnkMsgInvPopName : "Το όνομα του popup πρέπει να αρχίζει με χαρακτήρα της αλφαβήτου και να μην περιέχει κενά", - -// Color Dialog -DlgColorTitle : "Επιλογή χρώματος", -DlgColorBtnClear : "Καθαρισμός", -DlgColorHighlight : "Προεπισκόπιση", -DlgColorSelected : "Επιλεγμένο", - -// Smiley Dialog -DlgSmileyTitle : "Επιλέξτε ένα Smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Επιλέξτε ένα Ειδικό Σύμβολο", - -// Table Dialog -DlgTableTitle : "Ιδιότητες Πίνακα", -DlgTableRows : "Γραμμές", -DlgTableColumns : "Κολώνες", -DlgTableBorder : "Μέγεθος Περιθωρίου", -DlgTableAlign : "Στοίχιση", -DlgTableAlignNotSet : "<χωρίς>", -DlgTableAlignLeft : "Αριστερά", -DlgTableAlignCenter : "Κέντρο", -DlgTableAlignRight : "Δεξιά", -DlgTableWidth : "Πλάτος", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "\%", -DlgTableHeight : "Ύψος", -DlgTableCellSpace : "Απόσταση κελιών", -DlgTableCellPad : "Γέμισμα κελιών", -DlgTableCaption : "Υπέρτιτλος", -DlgTableSummary : "Περίληψη", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Ιδιότητες Κελιού", -DlgCellWidth : "Πλάτος", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "\%", -DlgCellHeight : "Ύψος", -DlgCellWordWrap : "Με αλλαγή γραμμής", -DlgCellWordWrapNotSet : "<χωρίς>", -DlgCellWordWrapYes : "Ναι", -DlgCellWordWrapNo : "Όχι", -DlgCellHorAlign : "Οριζόντια Στοίχιση", -DlgCellHorAlignNotSet : "<χωρίς>", -DlgCellHorAlignLeft : "Αριστερά", -DlgCellHorAlignCenter : "Κέντρο", -DlgCellHorAlignRight: "Δεξιά", -DlgCellVerAlign : "Κάθετη Στοίχιση", -DlgCellVerAlignNotSet : "<χωρίς>", -DlgCellVerAlignTop : "Πάνω (Top)", -DlgCellVerAlignMiddle : "Μέση (Middle)", -DlgCellVerAlignBottom : "Κάτω (Bottom)", -DlgCellVerAlignBaseline : "Γραμμή Βάσης (Baseline)", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Αριθμός Γραμμών (Rows Span)", -DlgCellCollSpan : "Αριθμός Κολωνών (Columns Span)", -DlgCellBackColor : "Χρώμα Υποβάθρου", -DlgCellBorderColor : "Χρώμα Περιθωρίου", -DlgCellBtnSelect : "Επιλογή...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", //MISSING - -// Find Dialog -DlgFindTitle : "Αναζήτηση", -DlgFindFindBtn : "Αναζήτηση", -DlgFindNotFoundMsg : "Το κείμενο δεν βρέθηκε.", - -// Replace Dialog -DlgReplaceTitle : "Αντικατάσταση", -DlgReplaceFindLbl : "Αναζήτηση:", -DlgReplaceReplaceLbl : "Αντικατάσταση με:", -DlgReplaceCaseChk : "Έλεγχος πεζών/κεφαλαίων", -DlgReplaceReplaceBtn : "Αντικατάσταση", -DlgReplaceReplAllBtn : "Αντικατάσταση Όλων", -DlgReplaceWordChk : "Εύρεση πλήρους λέξης", - -// Paste Operations / Dialog -PasteErrorCut : "Οι ρυθμίσεις ασφαλείας του φυλλομετρητή σας δεν επιτρέπουν την επιλεγμένη εργασία αποκοπής. Χρησιμοποιείστε το πληκτρολόγιο (Ctrl+X).", -PasteErrorCopy : "Οι ρυθμίσεις ασφαλείας του φυλλομετρητή σας δεν επιτρέπουν την επιλεγμένη εργασία αντιγραφής. Χρησιμοποιείστε το πληκτρολόγιο (Ctrl+C).", - -PasteAsText : "Επικόλληση ως Απλό Κείμενο", -PasteFromWord : "Επικόλληση από το Word", - -DlgPasteMsg2 : "Παρακαλώ επικολήστε στο ακόλουθο κουτί χρησιμοποιόντας το πληκτρολόγιο (Ctrl+V) και πατήστε OK.", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", //MISSING -DlgPasteIgnoreFont : "Αγνόηση προδιαγραφών γραμματοσειράς", -DlgPasteRemoveStyles : "Αφαίρεση προδιαγραφών στύλ", - -// Color Picker -ColorAutomatic : "Αυτόματο", -ColorMoreColors : "Περισσότερα χρώματα...", - -// Document Properties -DocProps : "Ιδιότητες εγγράφου", - -// Anchor Dialog -DlgAnchorTitle : "Ιδιότητες άγκυρας", -DlgAnchorName : "Όνομα άγκυρας", -DlgAnchorErrorName : "Παρακαλούμε εισάγετε όνομα άγκυρας", - -// Speller Pages Dialog -DlgSpellNotInDic : "Δεν υπάρχει στο λεξικό", -DlgSpellChangeTo : "Αλλαγή σε", -DlgSpellBtnIgnore : "Αγνόηση", -DlgSpellBtnIgnoreAll : "Αγνόηση όλων", -DlgSpellBtnReplace : "Αντικατάσταση", -DlgSpellBtnReplaceAll : "Αντικατάσταση όλων", -DlgSpellBtnUndo : "Αναίρεση", -DlgSpellNoSuggestions : "- Δεν υπάρχουν προτάσεις -", -DlgSpellProgress : "Ορθογραφικός έλεγχος σε εξέλιξη...", -DlgSpellNoMispell : "Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Δεν βρέθηκαν λάθη", -DlgSpellNoChanges : "Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Δεν άλλαξαν λέξεις", -DlgSpellOneChange : "Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Μια λέξη άλλαξε", -DlgSpellManyChanges : "Ο ορθογραφικός έλεγχος ολοκληρώθηκε: %1 λέξεις άλλαξαν", - -IeSpellDownload : "Δεν υπάρχει εγκατεστημένος ορθογράφος. Θέλετε να τον κατεβάσετε τώρα;", - -// Button Dialog -DlgButtonText : "Κείμενο (Τιμή)", -DlgButtonType : "Τύπος", -DlgButtonTypeBtn : "Κουμπί", -DlgButtonTypeSbm : "Καταχώρηση", -DlgButtonTypeRst : "Επαναφορά", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Όνομα", -DlgCheckboxValue : "Τιμή", -DlgCheckboxSelected : "Επιλεγμένο", - -// Form Dialog -DlgFormName : "Όνομα", -DlgFormAction : "Δράση", -DlgFormMethod : "Μάθοδος", - -// Select Field Dialog -DlgSelectName : "Όνομα", -DlgSelectValue : "Τιμή", -DlgSelectSize : "Μέγεθος", -DlgSelectLines : "γραμμές", -DlgSelectChkMulti : "Πολλαπλές επιλογές", -DlgSelectOpAvail : "Διαθέσιμες επιλογές", -DlgSelectOpText : "Κείμενο", -DlgSelectOpValue : "Τιμή", -DlgSelectBtnAdd : "Προσθήκη", -DlgSelectBtnModify : "Αλλαγή", -DlgSelectBtnUp : "Πάνω", -DlgSelectBtnDown : "Κάτω", -DlgSelectBtnSetValue : "Προεπιλεγμένη επιλογή", -DlgSelectBtnDelete : "Διαγραφή", - -// Textarea Dialog -DlgTextareaName : "Όνομα", -DlgTextareaCols : "Στήλες", -DlgTextareaRows : "Σειρές", - -// Text Field Dialog -DlgTextName : "Όνομα", -DlgTextValue : "Τιμή", -DlgTextCharWidth : "Μήκος χαρακτήρων", -DlgTextMaxChars : "Μέγιστοι χαρακτήρες", -DlgTextType : "Τύπος", -DlgTextTypeText : "Κείμενο", -DlgTextTypePass : "Κωδικός", - -// Hidden Field Dialog -DlgHiddenName : "Όνομα", -DlgHiddenValue : "Τιμή", - -// Bulleted List Dialog -BulletedListProp : "Ιδιότητες λίστας Bulleted", -NumberedListProp : "Ιδιότητες αριθμημένης λίστας ", -DlgLstStart : "Αρχή", -DlgLstType : "Τύπος", -DlgLstTypeCircle : "Κύκλος", -DlgLstTypeDisc : "Δίσκος", -DlgLstTypeSquare : "Τετράγωνο", -DlgLstTypeNumbers : "Αριθμοί (1, 2, 3)", -DlgLstTypeLCase : "Πεζά γράμματα (a, b, c)", -DlgLstTypeUCase : "Κεφαλαία γράμματα (A, B, C)", -DlgLstTypeSRoman : "Μικρά λατινικά αριθμητικά (i, ii, iii)", -DlgLstTypeLRoman : "Μεγάλα λατινικά αριθμητικά (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Γενικά", -DlgDocBackTab : "Φόντο", -DlgDocColorsTab : "Χρώματα και περιθώρια", -DlgDocMetaTab : "Δεδομένα Meta", - -DlgDocPageTitle : "Τίτλος σελίδας", -DlgDocLangDir : "Κατεύθυνση γραφής", -DlgDocLangDirLTR : "αριστερά προς δεξιά (LTR)", -DlgDocLangDirRTL : "δεξιά προς αριστερά (RTL)", -DlgDocLangCode : "Κωδικός γλώσσας", -DlgDocCharSet : "Κωδικοποίηση χαρακτήρων", -DlgDocCharSetCE : "Κεντρικής Ευρώπης", -DlgDocCharSetCT : "Παραδοσιακά κινέζικα (Big5)", -DlgDocCharSetCR : "Κυριλλική", -DlgDocCharSetGR : "Ελληνική", -DlgDocCharSetJP : "Ιαπωνική", -DlgDocCharSetKR : "Κορεάτικη", -DlgDocCharSetTR : "Τουρκική", -DlgDocCharSetUN : "Διεθνής (UTF-8)", -DlgDocCharSetWE : "Δυτικής Ευρώπης", -DlgDocCharSetOther : "Άλλη κωδικοποίηση χαρακτήρων", - -DlgDocDocType : "Επικεφαλίδα τύπου εγγράφου", -DlgDocDocTypeOther : "Άλλη επικεφαλίδα τύπου εγγράφου", -DlgDocIncXHTML : "Να συμπεριληφθούν οι δηλώσεις XHTML", -DlgDocBgColor : "Χρώμα φόντου", -DlgDocBgImage : "Διεύθυνση εικόνας φόντου", -DlgDocBgNoScroll : "Φόντο χωρίς κύλιση", -DlgDocCText : "Κείμενο", -DlgDocCLink : "Σύνδεσμος", -DlgDocCVisited : "Σύνδεσμος που έχει επισκευθεί", -DlgDocCActive : "Ενεργός σύνδεσμος", -DlgDocMargins : "Περιθώρια σελίδας", -DlgDocMaTop : "Κορυφή", -DlgDocMaLeft : "Αριστερά", -DlgDocMaRight : "Δεξιά", -DlgDocMaBottom : "Κάτω", -DlgDocMeIndex : "Λέξεις κλειδιά δείκτες εγγράφου (διαχωρισμός με κόμμα)", -DlgDocMeDescr : "Περιγραφή εγγράφου", -DlgDocMeAuthor : "Συγγραφέας", -DlgDocMeCopy : "Πνευματικά δικαιώματα", -DlgDocPreview : "Προεπισκόπηση", - -// Templates Dialog -Templates : "Πρότυπα", -DlgTemplatesTitle : "Πρότυπα περιεχομένου", -DlgTemplatesSelMsg : "Παρακαλώ επιλέξτε πρότυπο για εισαγωγή στο πρόγραμμα
    (τα υπάρχοντα περιεχόμενα θα χαθούν):", -DlgTemplatesLoading : "Φόρτωση καταλόγου προτύπων. Παρακαλώ περιμένετε...", -DlgTemplatesNoTpl : "(Δεν έχουν καθοριστεί πρότυπα)", -DlgTemplatesReplace : "Αντικατάσταση υπάρχοντων περιεχομένων", - -// About Dialog -DlgAboutAboutTab : "Σχετικά", -DlgAboutBrowserInfoTab : "Πληροφορίες Browser", -DlgAboutLicenseTab : "Άδεια", -DlgAboutVersion : "έκδοση", -DlgAboutInfo : "Για περισσότερες πληροφορίες", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/en-au.js b/httemplate/elements/fckeditor/editor/lang/en-au.js deleted file mode 100644 index 83d6624f2..000000000 --- a/httemplate/elements/fckeditor/editor/lang/en-au.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * English (Australia) language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Collapse Toolbar", -ToolbarExpand : "Expand Toolbar", - -// Toolbar Items and Context Menu -Save : "Save", -NewPage : "New Page", -Preview : "Preview", -Cut : "Cut", -Copy : "Copy", -Paste : "Paste", -PasteText : "Paste as plain text", -PasteWord : "Paste from Word", -Print : "Print", -SelectAll : "Select All", -RemoveFormat : "Remove Format", -InsertLinkLbl : "Link", -InsertLink : "Insert/Edit Link", -RemoveLink : "Remove Link", -VisitLink : "Open Link", -Anchor : "Insert/Edit Anchor", -AnchorDelete : "Remove Anchor", -InsertImageLbl : "Image", -InsertImage : "Insert/Edit Image", -InsertFlashLbl : "Flash", -InsertFlash : "Insert/Edit Flash", -InsertTableLbl : "Table", -InsertTable : "Insert/Edit Table", -InsertLineLbl : "Line", -InsertLine : "Insert Horizontal Line", -InsertSpecialCharLbl: "Special Character", -InsertSpecialChar : "Insert Special Character", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Insert Smiley", -About : "About FCKeditor", -Bold : "Bold", -Italic : "Italic", -Underline : "Underline", -StrikeThrough : "Strike Through", -Subscript : "Subscript", -Superscript : "Superscript", -LeftJustify : "Left Justify", -CenterJustify : "Centre Justify", -RightJustify : "Right Justify", -BlockJustify : "Block Justify", -DecreaseIndent : "Decrease Indent", -IncreaseIndent : "Increase Indent", -Blockquote : "Blockquote", -CreateDiv : "Create Div Container", -EditDiv : "Edit Div Container", -DeleteDiv : "Remove Div Container", -Undo : "Undo", -Redo : "Redo", -NumberedListLbl : "Numbered List", -NumberedList : "Insert/Remove Numbered List", -BulletedListLbl : "Bulleted List", -BulletedList : "Insert/Remove Bulleted List", -ShowTableBorders : "Show Table Borders", -ShowDetails : "Show Details", -Style : "Style", -FontFormat : "Format", -Font : "Font", -FontSize : "Size", -TextColor : "Text Colour", -BGColor : "Background Colour", -Source : "Source", -Find : "Find", -Replace : "Replace", -SpellCheck : "Check Spelling", -UniversalKeyboard : "Universal Keyboard", -PageBreakLbl : "Page Break", -PageBreak : "Insert Page Break", - -Form : "Form", -Checkbox : "Checkbox", -RadioButton : "Radio Button", -TextField : "Text Field", -Textarea : "Textarea", -HiddenField : "Hidden Field", -Button : "Button", -SelectionField : "Selection Field", -ImageButton : "Image Button", - -FitWindow : "Maximize the editor size", -ShowBlocks : "Show Blocks", - -// Context Menu -EditLink : "Edit Link", -CellCM : "Cell", -RowCM : "Row", -ColumnCM : "Column", -InsertRowAfter : "Insert Row After", -InsertRowBefore : "Insert Row Before", -DeleteRows : "Delete Rows", -InsertColumnAfter : "Insert Column After", -InsertColumnBefore : "Insert Column Before", -DeleteColumns : "Delete Columns", -InsertCellAfter : "Insert Cell After", -InsertCellBefore : "Insert Cell Before", -DeleteCells : "Delete Cells", -MergeCells : "Merge Cells", -MergeRight : "Merge Right", -MergeDown : "Merge Down", -HorizontalSplitCell : "Split Cell Horizontally", -VerticalSplitCell : "Split Cell Vertically", -TableDelete : "Delete Table", -CellProperties : "Cell Properties", -TableProperties : "Table Properties", -ImageProperties : "Image Properties", -FlashProperties : "Flash Properties", - -AnchorProp : "Anchor Properties", -ButtonProp : "Button Properties", -CheckboxProp : "Checkbox Properties", -HiddenFieldProp : "Hidden Field Properties", -RadioButtonProp : "Radio Button Properties", -ImageButtonProp : "Image Button Properties", -TextFieldProp : "Text Field Properties", -SelectionFieldProp : "Selection Field Properties", -TextareaProp : "Textarea Properties", -FormProp : "Form Properties", - -FontFormats : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Processing XHTML. Please wait...", -Done : "Done", -PasteWordConfirm : "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?", -NotCompatiblePaste : "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?", -UnknownToolbarItem : "Unknown toolbar item \"%1\"", -UnknownCommand : "Unknown command name \"%1\"", -NotImplemented : "Command not implemented", -UnknownToolbarSet : "Toolbar set \"%1\" doesn't exist", -NoActiveX : "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.", -BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.", -DialogBlocked : "It was not possible to open the dialog window. Make sure all popup blockers are disabled.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Cancel", -DlgBtnClose : "Close", -DlgBtnBrowseServer : "Browse Server", -DlgAdvancedTag : "Advanced", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Please insert the URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Language Direction", -DlgGenLangDirLtr : "Left to Right (LTR)", -DlgGenLangDirRtl : "Right to Left (RTL)", -DlgGenLangCode : "Language Code", -DlgGenAccessKey : "Access Key", -DlgGenName : "Name", -DlgGenTabIndex : "Tab Index", -DlgGenLongDescr : "Long Description URL", -DlgGenClass : "Stylesheet Classes", -DlgGenTitle : "Advisory Title", -DlgGenContType : "Advisory Content Type", -DlgGenLinkCharset : "Linked Resource Charset", -DlgGenStyle : "Style", - -// Image Dialog -DlgImgTitle : "Image Properties", -DlgImgInfoTab : "Image Info", -DlgImgBtnUpload : "Send it to the Server", -DlgImgURL : "URL", -DlgImgUpload : "Upload", -DlgImgAlt : "Alternative Text", -DlgImgWidth : "Width", -DlgImgHeight : "Height", -DlgImgLockRatio : "Lock Ratio", -DlgBtnResetSize : "Reset Size", -DlgImgBorder : "Border", -DlgImgHSpace : "HSpace", -DlgImgVSpace : "VSpace", -DlgImgAlign : "Align", -DlgImgAlignLeft : "Left", -DlgImgAlignAbsBottom: "Abs Bottom", -DlgImgAlignAbsMiddle: "Abs Middle", -DlgImgAlignBaseline : "Baseline", -DlgImgAlignBottom : "Bottom", -DlgImgAlignMiddle : "Middle", -DlgImgAlignRight : "Right", -DlgImgAlignTextTop : "Text Top", -DlgImgAlignTop : "Top", -DlgImgPreview : "Preview", -DlgImgAlertUrl : "Please type the image URL", -DlgImgLinkTab : "Link", - -// Flash Dialog -DlgFlashTitle : "Flash Properties", -DlgFlashChkPlay : "Auto Play", -DlgFlashChkLoop : "Loop", -DlgFlashChkMenu : "Enable Flash Menu", -DlgFlashScale : "Scale", -DlgFlashScaleAll : "Show all", -DlgFlashScaleNoBorder : "No Border", -DlgFlashScaleFit : "Exact Fit", - -// Link Dialog -DlgLnkWindowTitle : "Link", -DlgLnkInfoTab : "Link Info", -DlgLnkTargetTab : "Target", - -DlgLnkType : "Link Type", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Link to anchor in the text", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Select an Anchor", -DlgLnkAnchorByName : "By Anchor Name", -DlgLnkAnchorById : "By Element Id", -DlgLnkNoAnchors : "(No anchors available in the document)", -DlgLnkEMail : "E-Mail Address", -DlgLnkEMailSubject : "Message Subject", -DlgLnkEMailBody : "Message Body", -DlgLnkUpload : "Upload", -DlgLnkBtnUpload : "Send it to the Server", - -DlgLnkTarget : "Target", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "New Window (_blank)", -DlgLnkTargetParent : "Parent Window (_parent)", -DlgLnkTargetSelf : "Same Window (_self)", -DlgLnkTargetTop : "Topmost Window (_top)", -DlgLnkTargetFrameName : "Target Frame Name", -DlgLnkPopWinName : "Popup Window Name", -DlgLnkPopWinFeat : "Popup Window Features", -DlgLnkPopResize : "Resizable", -DlgLnkPopLocation : "Location Bar", -DlgLnkPopMenu : "Menu Bar", -DlgLnkPopScroll : "Scroll Bars", -DlgLnkPopStatus : "Status Bar", -DlgLnkPopToolbar : "Toolbar", -DlgLnkPopFullScrn : "Full Screen (IE)", -DlgLnkPopDependent : "Dependent (Netscape)", -DlgLnkPopWidth : "Width", -DlgLnkPopHeight : "Height", -DlgLnkPopLeft : "Left Position", -DlgLnkPopTop : "Top Position", - -DlnLnkMsgNoUrl : "Please type the link URL", -DlnLnkMsgNoEMail : "Please type the e-mail address", -DlnLnkMsgNoAnchor : "Please select an anchor", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", - -// Color Dialog -DlgColorTitle : "Select Colour", -DlgColorBtnClear : "Clear", -DlgColorHighlight : "Highlight", -DlgColorSelected : "Selected", - -// Smiley Dialog -DlgSmileyTitle : "Insert a Smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Select Special Character", - -// Table Dialog -DlgTableTitle : "Table Properties", -DlgTableRows : "Rows", -DlgTableColumns : "Columns", -DlgTableBorder : "Border size", -DlgTableAlign : "Alignment", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Left", -DlgTableAlignCenter : "Centre", -DlgTableAlignRight : "Right", -DlgTableWidth : "Width", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "percent", -DlgTableHeight : "Height", -DlgTableCellSpace : "Cell spacing", -DlgTableCellPad : "Cell padding", -DlgTableCaption : "Caption", -DlgTableSummary : "Summary", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Cell Properties", -DlgCellWidth : "Width", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "percent", -DlgCellHeight : "Height", -DlgCellWordWrap : "Word Wrap", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Yes", -DlgCellWordWrapNo : "No", -DlgCellHorAlign : "Horizontal Alignment", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Left", -DlgCellHorAlignCenter : "Centre", -DlgCellHorAlignRight: "Right", -DlgCellVerAlign : "Vertical Alignment", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Top", -DlgCellVerAlignMiddle : "Middle", -DlgCellVerAlignBottom : "Bottom", -DlgCellVerAlignBaseline : "Baseline", -DlgCellType : "Cell Type", -DlgCellTypeData : "Data", -DlgCellTypeHeader : "Header", -DlgCellRowSpan : "Rows Span", -DlgCellCollSpan : "Columns Span", -DlgCellBackColor : "Background Colour", -DlgCellBorderColor : "Border Colour", -DlgCellBtnSelect : "Select...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", - -// Find Dialog -DlgFindTitle : "Find", -DlgFindFindBtn : "Find", -DlgFindNotFoundMsg : "The specified text was not found.", - -// Replace Dialog -DlgReplaceTitle : "Replace", -DlgReplaceFindLbl : "Find what:", -DlgReplaceReplaceLbl : "Replace with:", -DlgReplaceCaseChk : "Match case", -DlgReplaceReplaceBtn : "Replace", -DlgReplaceReplAllBtn : "Replace All", -DlgReplaceWordChk : "Match whole word", - -// Paste Operations / Dialog -PasteErrorCut : "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).", -PasteErrorCopy : "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).", - -PasteAsText : "Paste as Plain Text", -PasteFromWord : "Paste from Word", - -DlgPasteMsg2 : "Please paste inside the following box using the keyboard (Ctrl+V) and hit OK.", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", -DlgPasteIgnoreFont : "Ignore Font Face definitions", -DlgPasteRemoveStyles : "Remove Styles definitions", - -// Color Picker -ColorAutomatic : "Automatic", -ColorMoreColors : "More Colours...", - -// Document Properties -DocProps : "Document Properties", - -// Anchor Dialog -DlgAnchorTitle : "Anchor Properties", -DlgAnchorName : "Anchor Name", -DlgAnchorErrorName : "Please type the anchor name", - -// Speller Pages Dialog -DlgSpellNotInDic : "Not in dictionary", -DlgSpellChangeTo : "Change to", -DlgSpellBtnIgnore : "Ignore", -DlgSpellBtnIgnoreAll : "Ignore All", -DlgSpellBtnReplace : "Replace", -DlgSpellBtnReplaceAll : "Replace All", -DlgSpellBtnUndo : "Undo", -DlgSpellNoSuggestions : "- No suggestions -", -DlgSpellProgress : "Spell check in progress...", -DlgSpellNoMispell : "Spell check complete: No misspellings found", -DlgSpellNoChanges : "Spell check complete: No words changed", -DlgSpellOneChange : "Spell check complete: One word changed", -DlgSpellManyChanges : "Spell check complete: %1 words changed", - -IeSpellDownload : "Spell checker not installed. Do you want to download it now?", - -// Button Dialog -DlgButtonText : "Text (Value)", -DlgButtonType : "Type", -DlgButtonTypeBtn : "Button", -DlgButtonTypeSbm : "Submit", -DlgButtonTypeRst : "Reset", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Name", -DlgCheckboxValue : "Value", -DlgCheckboxSelected : "Selected", - -// Form Dialog -DlgFormName : "Name", -DlgFormAction : "Action", -DlgFormMethod : "Method", - -// Select Field Dialog -DlgSelectName : "Name", -DlgSelectValue : "Value", -DlgSelectSize : "Size", -DlgSelectLines : "lines", -DlgSelectChkMulti : "Allow multiple selections", -DlgSelectOpAvail : "Available Options", -DlgSelectOpText : "Text", -DlgSelectOpValue : "Value", -DlgSelectBtnAdd : "Add", -DlgSelectBtnModify : "Modify", -DlgSelectBtnUp : "Up", -DlgSelectBtnDown : "Down", -DlgSelectBtnSetValue : "Set as selected value", -DlgSelectBtnDelete : "Delete", - -// Textarea Dialog -DlgTextareaName : "Name", -DlgTextareaCols : "Columns", -DlgTextareaRows : "Rows", - -// Text Field Dialog -DlgTextName : "Name", -DlgTextValue : "Value", -DlgTextCharWidth : "Character Width", -DlgTextMaxChars : "Maximum Characters", -DlgTextType : "Type", -DlgTextTypeText : "Text", -DlgTextTypePass : "Password", - -// Hidden Field Dialog -DlgHiddenName : "Name", -DlgHiddenValue : "Value", - -// Bulleted List Dialog -BulletedListProp : "Bulleted List Properties", -NumberedListProp : "Numbered List Properties", -DlgLstStart : "Start", -DlgLstType : "Type", -DlgLstTypeCircle : "Circle", -DlgLstTypeDisc : "Disc", -DlgLstTypeSquare : "Square", -DlgLstTypeNumbers : "Numbers (1, 2, 3)", -DlgLstTypeLCase : "Lowercase Letters (a, b, c)", -DlgLstTypeUCase : "Uppercase Letters (A, B, C)", -DlgLstTypeSRoman : "Small Roman Numerals (i, ii, iii)", -DlgLstTypeLRoman : "Large Roman Numerals (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "General", -DlgDocBackTab : "Background", -DlgDocColorsTab : "Colours and Margins", -DlgDocMetaTab : "Meta Data", - -DlgDocPageTitle : "Page Title", -DlgDocLangDir : "Language Direction", -DlgDocLangDirLTR : "Left to Right (LTR)", -DlgDocLangDirRTL : "Right to Left (RTL)", -DlgDocLangCode : "Language Code", -DlgDocCharSet : "Character Set Encoding", -DlgDocCharSetCE : "Central European", -DlgDocCharSetCT : "Chinese Traditional (Big5)", -DlgDocCharSetCR : "Cyrillic", -DlgDocCharSetGR : "Greek", -DlgDocCharSetJP : "Japanese", -DlgDocCharSetKR : "Korean", -DlgDocCharSetTR : "Turkish", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Western European", -DlgDocCharSetOther : "Other Character Set Encoding", - -DlgDocDocType : "Document Type Heading", -DlgDocDocTypeOther : "Other Document Type Heading", -DlgDocIncXHTML : "Include XHTML Declarations", -DlgDocBgColor : "Background Colour", -DlgDocBgImage : "Background Image URL", -DlgDocBgNoScroll : "Nonscrolling Background", -DlgDocCText : "Text", -DlgDocCLink : "Link", -DlgDocCVisited : "Visited Link", -DlgDocCActive : "Active Link", -DlgDocMargins : "Page Margins", -DlgDocMaTop : "Top", -DlgDocMaLeft : "Left", -DlgDocMaRight : "Right", -DlgDocMaBottom : "Bottom", -DlgDocMeIndex : "Document Indexing Keywords (comma separated)", -DlgDocMeDescr : "Document Description", -DlgDocMeAuthor : "Author", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Preview", - -// Templates Dialog -Templates : "Templates", -DlgTemplatesTitle : "Content Templates", -DlgTemplatesSelMsg : "Please select the template to open in the editor
    (the actual contents will be lost):", -DlgTemplatesLoading : "Loading templates list. Please wait...", -DlgTemplatesNoTpl : "(No templates defined)", -DlgTemplatesReplace : "Replace actual contents", - -// About Dialog -DlgAboutAboutTab : "About", -DlgAboutBrowserInfoTab : "Browser Info", -DlgAboutLicenseTab : "License", -DlgAboutVersion : "version", -DlgAboutInfo : "For further information go to", - -// Div Dialog -DlgDivGeneralTab : "General", -DlgDivAdvancedTab : "Advanced", -DlgDivStyle : "Style", -DlgDivInlineStyle : "Inline Style", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/en-ca.js b/httemplate/elements/fckeditor/editor/lang/en-ca.js deleted file mode 100644 index 1f82fc870..000000000 --- a/httemplate/elements/fckeditor/editor/lang/en-ca.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * English (Canadian) language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Collapse Toolbar", -ToolbarExpand : "Expand Toolbar", - -// Toolbar Items and Context Menu -Save : "Save", -NewPage : "New Page", -Preview : "Preview", -Cut : "Cut", -Copy : "Copy", -Paste : "Paste", -PasteText : "Paste as plain text", -PasteWord : "Paste from Word", -Print : "Print", -SelectAll : "Select All", -RemoveFormat : "Remove Format", -InsertLinkLbl : "Link", -InsertLink : "Insert/Edit Link", -RemoveLink : "Remove Link", -VisitLink : "Open Link", -Anchor : "Insert/Edit Anchor", -AnchorDelete : "Remove Anchor", -InsertImageLbl : "Image", -InsertImage : "Insert/Edit Image", -InsertFlashLbl : "Flash", -InsertFlash : "Insert/Edit Flash", -InsertTableLbl : "Table", -InsertTable : "Insert/Edit Table", -InsertLineLbl : "Line", -InsertLine : "Insert Horizontal Line", -InsertSpecialCharLbl: "Special Character", -InsertSpecialChar : "Insert Special Character", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Insert Smiley", -About : "About FCKeditor", -Bold : "Bold", -Italic : "Italic", -Underline : "Underline", -StrikeThrough : "Strike Through", -Subscript : "Subscript", -Superscript : "Superscript", -LeftJustify : "Left Justify", -CenterJustify : "Centre Justify", -RightJustify : "Right Justify", -BlockJustify : "Block Justify", -DecreaseIndent : "Decrease Indent", -IncreaseIndent : "Increase Indent", -Blockquote : "Blockquote", -CreateDiv : "Create Div Container", -EditDiv : "Edit Div Container", -DeleteDiv : "Remove Div Container", -Undo : "Undo", -Redo : "Redo", -NumberedListLbl : "Numbered List", -NumberedList : "Insert/Remove Numbered List", -BulletedListLbl : "Bulleted List", -BulletedList : "Insert/Remove Bulleted List", -ShowTableBorders : "Show Table Borders", -ShowDetails : "Show Details", -Style : "Style", -FontFormat : "Format", -Font : "Font", -FontSize : "Size", -TextColor : "Text Colour", -BGColor : "Background Colour", -Source : "Source", -Find : "Find", -Replace : "Replace", -SpellCheck : "Check Spelling", -UniversalKeyboard : "Universal Keyboard", -PageBreakLbl : "Page Break", -PageBreak : "Insert Page Break", - -Form : "Form", -Checkbox : "Checkbox", -RadioButton : "Radio Button", -TextField : "Text Field", -Textarea : "Textarea", -HiddenField : "Hidden Field", -Button : "Button", -SelectionField : "Selection Field", -ImageButton : "Image Button", - -FitWindow : "Maximize the editor size", -ShowBlocks : "Show Blocks", - -// Context Menu -EditLink : "Edit Link", -CellCM : "Cell", -RowCM : "Row", -ColumnCM : "Column", -InsertRowAfter : "Insert Row After", -InsertRowBefore : "Insert Row Before", -DeleteRows : "Delete Rows", -InsertColumnAfter : "Insert Column After", -InsertColumnBefore : "Insert Column Before", -DeleteColumns : "Delete Columns", -InsertCellAfter : "Insert Cell After", -InsertCellBefore : "Insert Cell Before", -DeleteCells : "Delete Cells", -MergeCells : "Merge Cells", -MergeRight : "Merge Right", -MergeDown : "Merge Down", -HorizontalSplitCell : "Split Cell Horizontally", -VerticalSplitCell : "Split Cell Vertically", -TableDelete : "Delete Table", -CellProperties : "Cell Properties", -TableProperties : "Table Properties", -ImageProperties : "Image Properties", -FlashProperties : "Flash Properties", - -AnchorProp : "Anchor Properties", -ButtonProp : "Button Properties", -CheckboxProp : "Checkbox Properties", -HiddenFieldProp : "Hidden Field Properties", -RadioButtonProp : "Radio Button Properties", -ImageButtonProp : "Image Button Properties", -TextFieldProp : "Text Field Properties", -SelectionFieldProp : "Selection Field Properties", -TextareaProp : "Textarea Properties", -FormProp : "Form Properties", - -FontFormats : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Processing XHTML. Please wait...", -Done : "Done", -PasteWordConfirm : "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?", -NotCompatiblePaste : "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?", -UnknownToolbarItem : "Unknown toolbar item \"%1\"", -UnknownCommand : "Unknown command name \"%1\"", -NotImplemented : "Command not implemented", -UnknownToolbarSet : "Toolbar set \"%1\" doesn't exist", -NoActiveX : "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.", -BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.", -DialogBlocked : "It was not possible to open the dialog window. Make sure all popup blockers are disabled.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Cancel", -DlgBtnClose : "Close", -DlgBtnBrowseServer : "Browse Server", -DlgAdvancedTag : "Advanced", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Please insert the URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Language Direction", -DlgGenLangDirLtr : "Left to Right (LTR)", -DlgGenLangDirRtl : "Right to Left (RTL)", -DlgGenLangCode : "Language Code", -DlgGenAccessKey : "Access Key", -DlgGenName : "Name", -DlgGenTabIndex : "Tab Index", -DlgGenLongDescr : "Long Description URL", -DlgGenClass : "Stylesheet Classes", -DlgGenTitle : "Advisory Title", -DlgGenContType : "Advisory Content Type", -DlgGenLinkCharset : "Linked Resource Charset", -DlgGenStyle : "Style", - -// Image Dialog -DlgImgTitle : "Image Properties", -DlgImgInfoTab : "Image Info", -DlgImgBtnUpload : "Send it to the Server", -DlgImgURL : "URL", -DlgImgUpload : "Upload", -DlgImgAlt : "Alternative Text", -DlgImgWidth : "Width", -DlgImgHeight : "Height", -DlgImgLockRatio : "Lock Ratio", -DlgBtnResetSize : "Reset Size", -DlgImgBorder : "Border", -DlgImgHSpace : "HSpace", -DlgImgVSpace : "VSpace", -DlgImgAlign : "Align", -DlgImgAlignLeft : "Left", -DlgImgAlignAbsBottom: "Abs Bottom", -DlgImgAlignAbsMiddle: "Abs Middle", -DlgImgAlignBaseline : "Baseline", -DlgImgAlignBottom : "Bottom", -DlgImgAlignMiddle : "Middle", -DlgImgAlignRight : "Right", -DlgImgAlignTextTop : "Text Top", -DlgImgAlignTop : "Top", -DlgImgPreview : "Preview", -DlgImgAlertUrl : "Please type the image URL", -DlgImgLinkTab : "Link", - -// Flash Dialog -DlgFlashTitle : "Flash Properties", -DlgFlashChkPlay : "Auto Play", -DlgFlashChkLoop : "Loop", -DlgFlashChkMenu : "Enable Flash Menu", -DlgFlashScale : "Scale", -DlgFlashScaleAll : "Show all", -DlgFlashScaleNoBorder : "No Border", -DlgFlashScaleFit : "Exact Fit", - -// Link Dialog -DlgLnkWindowTitle : "Link", -DlgLnkInfoTab : "Link Info", -DlgLnkTargetTab : "Target", - -DlgLnkType : "Link Type", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Link to anchor in the text", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Select an Anchor", -DlgLnkAnchorByName : "By Anchor Name", -DlgLnkAnchorById : "By Element Id", -DlgLnkNoAnchors : "(No anchors available in the document)", -DlgLnkEMail : "E-Mail Address", -DlgLnkEMailSubject : "Message Subject", -DlgLnkEMailBody : "Message Body", -DlgLnkUpload : "Upload", -DlgLnkBtnUpload : "Send it to the Server", - -DlgLnkTarget : "Target", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "New Window (_blank)", -DlgLnkTargetParent : "Parent Window (_parent)", -DlgLnkTargetSelf : "Same Window (_self)", -DlgLnkTargetTop : "Topmost Window (_top)", -DlgLnkTargetFrameName : "Target Frame Name", -DlgLnkPopWinName : "Popup Window Name", -DlgLnkPopWinFeat : "Popup Window Features", -DlgLnkPopResize : "Resizable", -DlgLnkPopLocation : "Location Bar", -DlgLnkPopMenu : "Menu Bar", -DlgLnkPopScroll : "Scroll Bars", -DlgLnkPopStatus : "Status Bar", -DlgLnkPopToolbar : "Toolbar", -DlgLnkPopFullScrn : "Full Screen (IE)", -DlgLnkPopDependent : "Dependent (Netscape)", -DlgLnkPopWidth : "Width", -DlgLnkPopHeight : "Height", -DlgLnkPopLeft : "Left Position", -DlgLnkPopTop : "Top Position", - -DlnLnkMsgNoUrl : "Please type the link URL", -DlnLnkMsgNoEMail : "Please type the e-mail address", -DlnLnkMsgNoAnchor : "Please select an anchor", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", - -// Color Dialog -DlgColorTitle : "Select Colour", -DlgColorBtnClear : "Clear", -DlgColorHighlight : "Highlight", -DlgColorSelected : "Selected", - -// Smiley Dialog -DlgSmileyTitle : "Insert a Smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Select Special Character", - -// Table Dialog -DlgTableTitle : "Table Properties", -DlgTableRows : "Rows", -DlgTableColumns : "Columns", -DlgTableBorder : "Border size", -DlgTableAlign : "Alignment", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Left", -DlgTableAlignCenter : "Centre", -DlgTableAlignRight : "Right", -DlgTableWidth : "Width", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "percent", -DlgTableHeight : "Height", -DlgTableCellSpace : "Cell spacing", -DlgTableCellPad : "Cell padding", -DlgTableCaption : "Caption", -DlgTableSummary : "Summary", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Cell Properties", -DlgCellWidth : "Width", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "percent", -DlgCellHeight : "Height", -DlgCellWordWrap : "Word Wrap", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Yes", -DlgCellWordWrapNo : "No", -DlgCellHorAlign : "Horizontal Alignment", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Left", -DlgCellHorAlignCenter : "Centre", -DlgCellHorAlignRight: "Right", -DlgCellVerAlign : "Vertical Alignment", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Top", -DlgCellVerAlignMiddle : "Middle", -DlgCellVerAlignBottom : "Bottom", -DlgCellVerAlignBaseline : "Baseline", -DlgCellType : "Cell Type", -DlgCellTypeData : "Data", -DlgCellTypeHeader : "Header", -DlgCellRowSpan : "Rows Span", -DlgCellCollSpan : "Columns Span", -DlgCellBackColor : "Background Colour", -DlgCellBorderColor : "Border Colour", -DlgCellBtnSelect : "Select...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", - -// Find Dialog -DlgFindTitle : "Find", -DlgFindFindBtn : "Find", -DlgFindNotFoundMsg : "The specified text was not found.", - -// Replace Dialog -DlgReplaceTitle : "Replace", -DlgReplaceFindLbl : "Find what:", -DlgReplaceReplaceLbl : "Replace with:", -DlgReplaceCaseChk : "Match case", -DlgReplaceReplaceBtn : "Replace", -DlgReplaceReplAllBtn : "Replace All", -DlgReplaceWordChk : "Match whole word", - -// Paste Operations / Dialog -PasteErrorCut : "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).", -PasteErrorCopy : "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).", - -PasteAsText : "Paste as Plain Text", -PasteFromWord : "Paste from Word", - -DlgPasteMsg2 : "Please paste inside the following box using the keyboard (Ctrl+V) and hit OK.", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", -DlgPasteIgnoreFont : "Ignore Font Face definitions", -DlgPasteRemoveStyles : "Remove Styles definitions", - -// Color Picker -ColorAutomatic : "Automatic", -ColorMoreColors : "More Colours...", - -// Document Properties -DocProps : "Document Properties", - -// Anchor Dialog -DlgAnchorTitle : "Anchor Properties", -DlgAnchorName : "Anchor Name", -DlgAnchorErrorName : "Please type the anchor name", - -// Speller Pages Dialog -DlgSpellNotInDic : "Not in dictionary", -DlgSpellChangeTo : "Change to", -DlgSpellBtnIgnore : "Ignore", -DlgSpellBtnIgnoreAll : "Ignore All", -DlgSpellBtnReplace : "Replace", -DlgSpellBtnReplaceAll : "Replace All", -DlgSpellBtnUndo : "Undo", -DlgSpellNoSuggestions : "- No suggestions -", -DlgSpellProgress : "Spell check in progress...", -DlgSpellNoMispell : "Spell check complete: No misspellings found", -DlgSpellNoChanges : "Spell check complete: No words changed", -DlgSpellOneChange : "Spell check complete: One word changed", -DlgSpellManyChanges : "Spell check complete: %1 words changed", - -IeSpellDownload : "Spell checker not installed. Do you want to download it now?", - -// Button Dialog -DlgButtonText : "Text (Value)", -DlgButtonType : "Type", -DlgButtonTypeBtn : "Button", -DlgButtonTypeSbm : "Submit", -DlgButtonTypeRst : "Reset", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Name", -DlgCheckboxValue : "Value", -DlgCheckboxSelected : "Selected", - -// Form Dialog -DlgFormName : "Name", -DlgFormAction : "Action", -DlgFormMethod : "Method", - -// Select Field Dialog -DlgSelectName : "Name", -DlgSelectValue : "Value", -DlgSelectSize : "Size", -DlgSelectLines : "lines", -DlgSelectChkMulti : "Allow multiple selections", -DlgSelectOpAvail : "Available Options", -DlgSelectOpText : "Text", -DlgSelectOpValue : "Value", -DlgSelectBtnAdd : "Add", -DlgSelectBtnModify : "Modify", -DlgSelectBtnUp : "Up", -DlgSelectBtnDown : "Down", -DlgSelectBtnSetValue : "Set as selected value", -DlgSelectBtnDelete : "Delete", - -// Textarea Dialog -DlgTextareaName : "Name", -DlgTextareaCols : "Columns", -DlgTextareaRows : "Rows", - -// Text Field Dialog -DlgTextName : "Name", -DlgTextValue : "Value", -DlgTextCharWidth : "Character Width", -DlgTextMaxChars : "Maximum Characters", -DlgTextType : "Type", -DlgTextTypeText : "Text", -DlgTextTypePass : "Password", - -// Hidden Field Dialog -DlgHiddenName : "Name", -DlgHiddenValue : "Value", - -// Bulleted List Dialog -BulletedListProp : "Bulleted List Properties", -NumberedListProp : "Numbered List Properties", -DlgLstStart : "Start", -DlgLstType : "Type", -DlgLstTypeCircle : "Circle", -DlgLstTypeDisc : "Disc", -DlgLstTypeSquare : "Square", -DlgLstTypeNumbers : "Numbers (1, 2, 3)", -DlgLstTypeLCase : "Lowercase Letters (a, b, c)", -DlgLstTypeUCase : "Uppercase Letters (A, B, C)", -DlgLstTypeSRoman : "Small Roman Numerals (i, ii, iii)", -DlgLstTypeLRoman : "Large Roman Numerals (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "General", -DlgDocBackTab : "Background", -DlgDocColorsTab : "Colours and Margins", -DlgDocMetaTab : "Meta Data", - -DlgDocPageTitle : "Page Title", -DlgDocLangDir : "Language Direction", -DlgDocLangDirLTR : "Left to Right (LTR)", -DlgDocLangDirRTL : "Right to Left (RTL)", -DlgDocLangCode : "Language Code", -DlgDocCharSet : "Character Set Encoding", -DlgDocCharSetCE : "Central European", -DlgDocCharSetCT : "Chinese Traditional (Big5)", -DlgDocCharSetCR : "Cyrillic", -DlgDocCharSetGR : "Greek", -DlgDocCharSetJP : "Japanese", -DlgDocCharSetKR : "Korean", -DlgDocCharSetTR : "Turkish", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Western European", -DlgDocCharSetOther : "Other Character Set Encoding", - -DlgDocDocType : "Document Type Heading", -DlgDocDocTypeOther : "Other Document Type Heading", -DlgDocIncXHTML : "Include XHTML Declarations", -DlgDocBgColor : "Background Colour", -DlgDocBgImage : "Background Image URL", -DlgDocBgNoScroll : "Nonscrolling Background", -DlgDocCText : "Text", -DlgDocCLink : "Link", -DlgDocCVisited : "Visited Link", -DlgDocCActive : "Active Link", -DlgDocMargins : "Page Margins", -DlgDocMaTop : "Top", -DlgDocMaLeft : "Left", -DlgDocMaRight : "Right", -DlgDocMaBottom : "Bottom", -DlgDocMeIndex : "Document Indexing Keywords (comma separated)", -DlgDocMeDescr : "Document Description", -DlgDocMeAuthor : "Author", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Preview", - -// Templates Dialog -Templates : "Templates", -DlgTemplatesTitle : "Content Templates", -DlgTemplatesSelMsg : "Please select the template to open in the editor
    (the actual contents will be lost):", -DlgTemplatesLoading : "Loading templates list. Please wait...", -DlgTemplatesNoTpl : "(No templates defined)", -DlgTemplatesReplace : "Replace actual contents", - -// About Dialog -DlgAboutAboutTab : "About", -DlgAboutBrowserInfoTab : "Browser Info", -DlgAboutLicenseTab : "License", -DlgAboutVersion : "version", -DlgAboutInfo : "For further information go to", - -// Div Dialog -DlgDivGeneralTab : "General", -DlgDivAdvancedTab : "Advanced", -DlgDivStyle : "Style", -DlgDivInlineStyle : "Inline Style", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/en-uk.js b/httemplate/elements/fckeditor/editor/lang/en-uk.js deleted file mode 100644 index d50b51ed1..000000000 --- a/httemplate/elements/fckeditor/editor/lang/en-uk.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * English (United Kingdom) language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Collapse Toolbar", -ToolbarExpand : "Expand Toolbar", - -// Toolbar Items and Context Menu -Save : "Save", -NewPage : "New Page", -Preview : "Preview", -Cut : "Cut", -Copy : "Copy", -Paste : "Paste", -PasteText : "Paste as plain text", -PasteWord : "Paste from Word", -Print : "Print", -SelectAll : "Select All", -RemoveFormat : "Remove Format", -InsertLinkLbl : "Link", -InsertLink : "Insert/Edit Link", -RemoveLink : "Remove Link", -VisitLink : "Open Link", -Anchor : "Insert/Edit Anchor", -AnchorDelete : "Remove Anchor", -InsertImageLbl : "Image", -InsertImage : "Insert/Edit Image", -InsertFlashLbl : "Flash", -InsertFlash : "Insert/Edit Flash", -InsertTableLbl : "Table", -InsertTable : "Insert/Edit Table", -InsertLineLbl : "Line", -InsertLine : "Insert Horizontal Line", -InsertSpecialCharLbl: "Special Character", -InsertSpecialChar : "Insert Special Character", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Insert Smiley", -About : "About FCKeditor", -Bold : "Bold", -Italic : "Italic", -Underline : "Underline", -StrikeThrough : "Strike Through", -Subscript : "Subscript", -Superscript : "Superscript", -LeftJustify : "Left Justify", -CenterJustify : "Centre Justify", -RightJustify : "Right Justify", -BlockJustify : "Block Justify", -DecreaseIndent : "Decrease Indent", -IncreaseIndent : "Increase Indent", -Blockquote : "Blockquote", -CreateDiv : "Create Div Container", -EditDiv : "Edit Div Container", -DeleteDiv : "Remove Div Container", -Undo : "Undo", -Redo : "Redo", -NumberedListLbl : "Numbered List", -NumberedList : "Insert/Remove Numbered List", -BulletedListLbl : "Bulleted List", -BulletedList : "Insert/Remove Bulleted List", -ShowTableBorders : "Show Table Borders", -ShowDetails : "Show Details", -Style : "Style", -FontFormat : "Format", -Font : "Font", -FontSize : "Size", -TextColor : "Text Colour", -BGColor : "Background Colour", -Source : "Source", -Find : "Find", -Replace : "Replace", -SpellCheck : "Check Spelling", -UniversalKeyboard : "Universal Keyboard", -PageBreakLbl : "Page Break", -PageBreak : "Insert Page Break", - -Form : "Form", -Checkbox : "Checkbox", -RadioButton : "Radio Button", -TextField : "Text Field", -Textarea : "Textarea", -HiddenField : "Hidden Field", -Button : "Button", -SelectionField : "Selection Field", -ImageButton : "Image Button", - -FitWindow : "Maximize the editor size", -ShowBlocks : "Show Blocks", - -// Context Menu -EditLink : "Edit Link", -CellCM : "Cell", -RowCM : "Row", -ColumnCM : "Column", -InsertRowAfter : "Insert Row After", -InsertRowBefore : "Insert Row Before", -DeleteRows : "Delete Rows", -InsertColumnAfter : "Insert Column After", -InsertColumnBefore : "Insert Column Before", -DeleteColumns : "Delete Columns", -InsertCellAfter : "Insert Cell After", -InsertCellBefore : "Insert Cell Before", -DeleteCells : "Delete Cells", -MergeCells : "Merge Cells", -MergeRight : "Merge Right", -MergeDown : "Merge Down", -HorizontalSplitCell : "Split Cell Horizontally", -VerticalSplitCell : "Split Cell Vertically", -TableDelete : "Delete Table", -CellProperties : "Cell Properties", -TableProperties : "Table Properties", -ImageProperties : "Image Properties", -FlashProperties : "Flash Properties", - -AnchorProp : "Anchor Properties", -ButtonProp : "Button Properties", -CheckboxProp : "Checkbox Properties", -HiddenFieldProp : "Hidden Field Properties", -RadioButtonProp : "Radio Button Properties", -ImageButtonProp : "Image Button Properties", -TextFieldProp : "Text Field Properties", -SelectionFieldProp : "Selection Field Properties", -TextareaProp : "Textarea Properties", -FormProp : "Form Properties", - -FontFormats : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Processing XHTML. Please wait...", -Done : "Done", -PasteWordConfirm : "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?", -NotCompatiblePaste : "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?", -UnknownToolbarItem : "Unknown toolbar item \"%1\"", -UnknownCommand : "Unknown command name \"%1\"", -NotImplemented : "Command not implemented", -UnknownToolbarSet : "Toolbar set \"%1\" doesn't exist", -NoActiveX : "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.", -BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.", -DialogBlocked : "It was not possible to open the dialog window. Make sure all popup blockers are disabled.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Cancel", -DlgBtnClose : "Close", -DlgBtnBrowseServer : "Browse Server", -DlgAdvancedTag : "Advanced", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Please insert the URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Language Direction", -DlgGenLangDirLtr : "Left to Right (LTR)", -DlgGenLangDirRtl : "Right to Left (RTL)", -DlgGenLangCode : "Language Code", -DlgGenAccessKey : "Access Key", -DlgGenName : "Name", -DlgGenTabIndex : "Tab Index", -DlgGenLongDescr : "Long Description URL", -DlgGenClass : "Stylesheet Classes", -DlgGenTitle : "Advisory Title", -DlgGenContType : "Advisory Content Type", -DlgGenLinkCharset : "Linked Resource Charset", -DlgGenStyle : "Style", - -// Image Dialog -DlgImgTitle : "Image Properties", -DlgImgInfoTab : "Image Info", -DlgImgBtnUpload : "Send it to the Server", -DlgImgURL : "URL", -DlgImgUpload : "Upload", -DlgImgAlt : "Alternative Text", -DlgImgWidth : "Width", -DlgImgHeight : "Height", -DlgImgLockRatio : "Lock Ratio", -DlgBtnResetSize : "Reset Size", -DlgImgBorder : "Border", -DlgImgHSpace : "HSpace", -DlgImgVSpace : "VSpace", -DlgImgAlign : "Align", -DlgImgAlignLeft : "Left", -DlgImgAlignAbsBottom: "Abs Bottom", -DlgImgAlignAbsMiddle: "Abs Middle", -DlgImgAlignBaseline : "Baseline", -DlgImgAlignBottom : "Bottom", -DlgImgAlignMiddle : "Middle", -DlgImgAlignRight : "Right", -DlgImgAlignTextTop : "Text Top", -DlgImgAlignTop : "Top", -DlgImgPreview : "Preview", -DlgImgAlertUrl : "Please type the image URL", -DlgImgLinkTab : "Link", - -// Flash Dialog -DlgFlashTitle : "Flash Properties", -DlgFlashChkPlay : "Auto Play", -DlgFlashChkLoop : "Loop", -DlgFlashChkMenu : "Enable Flash Menu", -DlgFlashScale : "Scale", -DlgFlashScaleAll : "Show all", -DlgFlashScaleNoBorder : "No Border", -DlgFlashScaleFit : "Exact Fit", - -// Link Dialog -DlgLnkWindowTitle : "Link", -DlgLnkInfoTab : "Link Info", -DlgLnkTargetTab : "Target", - -DlgLnkType : "Link Type", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Link to anchor in the text", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Select an Anchor", -DlgLnkAnchorByName : "By Anchor Name", -DlgLnkAnchorById : "By Element Id", -DlgLnkNoAnchors : "(No anchors available in the document)", -DlgLnkEMail : "E-Mail Address", -DlgLnkEMailSubject : "Message Subject", -DlgLnkEMailBody : "Message Body", -DlgLnkUpload : "Upload", -DlgLnkBtnUpload : "Send it to the Server", - -DlgLnkTarget : "Target", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "New Window (_blank)", -DlgLnkTargetParent : "Parent Window (_parent)", -DlgLnkTargetSelf : "Same Window (_self)", -DlgLnkTargetTop : "Topmost Window (_top)", -DlgLnkTargetFrameName : "Target Frame Name", -DlgLnkPopWinName : "Popup Window Name", -DlgLnkPopWinFeat : "Popup Window Features", -DlgLnkPopResize : "Resizable", -DlgLnkPopLocation : "Location Bar", -DlgLnkPopMenu : "Menu Bar", -DlgLnkPopScroll : "Scroll Bars", -DlgLnkPopStatus : "Status Bar", -DlgLnkPopToolbar : "Toolbar", -DlgLnkPopFullScrn : "Full Screen (IE)", -DlgLnkPopDependent : "Dependent (Netscape)", -DlgLnkPopWidth : "Width", -DlgLnkPopHeight : "Height", -DlgLnkPopLeft : "Left Position", -DlgLnkPopTop : "Top Position", - -DlnLnkMsgNoUrl : "Please type the link URL", -DlnLnkMsgNoEMail : "Please type the e-mail address", -DlnLnkMsgNoAnchor : "Please select an anchor", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", - -// Color Dialog -DlgColorTitle : "Select Colour", -DlgColorBtnClear : "Clear", -DlgColorHighlight : "Highlight", -DlgColorSelected : "Selected", - -// Smiley Dialog -DlgSmileyTitle : "Insert a Smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Select Special Character", - -// Table Dialog -DlgTableTitle : "Table Properties", -DlgTableRows : "Rows", -DlgTableColumns : "Columns", -DlgTableBorder : "Border size", -DlgTableAlign : "Alignment", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Left", -DlgTableAlignCenter : "Centre", -DlgTableAlignRight : "Right", -DlgTableWidth : "Width", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "percent", -DlgTableHeight : "Height", -DlgTableCellSpace : "Cell spacing", -DlgTableCellPad : "Cell padding", -DlgTableCaption : "Caption", -DlgTableSummary : "Summary", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Cell Properties", -DlgCellWidth : "Width", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "percent", -DlgCellHeight : "Height", -DlgCellWordWrap : "Word Wrap", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Yes", -DlgCellWordWrapNo : "No", -DlgCellHorAlign : "Horizontal Alignment", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Left", -DlgCellHorAlignCenter : "Centre", -DlgCellHorAlignRight: "Right", -DlgCellVerAlign : "Vertical Alignment", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Top", -DlgCellVerAlignMiddle : "Middle", -DlgCellVerAlignBottom : "Bottom", -DlgCellVerAlignBaseline : "Baseline", -DlgCellType : "Cell Type", -DlgCellTypeData : "Data", -DlgCellTypeHeader : "Header", -DlgCellRowSpan : "Rows Span", -DlgCellCollSpan : "Columns Span", -DlgCellBackColor : "Background Colour", -DlgCellBorderColor : "Border Colour", -DlgCellBtnSelect : "Select...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", - -// Find Dialog -DlgFindTitle : "Find", -DlgFindFindBtn : "Find", -DlgFindNotFoundMsg : "The specified text was not found.", - -// Replace Dialog -DlgReplaceTitle : "Replace", -DlgReplaceFindLbl : "Find what:", -DlgReplaceReplaceLbl : "Replace with:", -DlgReplaceCaseChk : "Match case", -DlgReplaceReplaceBtn : "Replace", -DlgReplaceReplAllBtn : "Replace All", -DlgReplaceWordChk : "Match whole word", - -// Paste Operations / Dialog -PasteErrorCut : "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).", -PasteErrorCopy : "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).", - -PasteAsText : "Paste as Plain Text", -PasteFromWord : "Paste from Word", - -DlgPasteMsg2 : "Please paste inside the following box using the keyboard (Ctrl+V) and hit OK.", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", -DlgPasteIgnoreFont : "Ignore Font Face definitions", -DlgPasteRemoveStyles : "Remove Styles definitions", - -// Color Picker -ColorAutomatic : "Automatic", -ColorMoreColors : "More Colours...", - -// Document Properties -DocProps : "Document Properties", - -// Anchor Dialog -DlgAnchorTitle : "Anchor Properties", -DlgAnchorName : "Anchor Name", -DlgAnchorErrorName : "Please type the anchor name", - -// Speller Pages Dialog -DlgSpellNotInDic : "Not in dictionary", -DlgSpellChangeTo : "Change to", -DlgSpellBtnIgnore : "Ignore", -DlgSpellBtnIgnoreAll : "Ignore All", -DlgSpellBtnReplace : "Replace", -DlgSpellBtnReplaceAll : "Replace All", -DlgSpellBtnUndo : "Undo", -DlgSpellNoSuggestions : "- No suggestions -", -DlgSpellProgress : "Spell check in progress...", -DlgSpellNoMispell : "Spell check complete: No misspellings found", -DlgSpellNoChanges : "Spell check complete: No words changed", -DlgSpellOneChange : "Spell check complete: One word changed", -DlgSpellManyChanges : "Spell check complete: %1 words changed", - -IeSpellDownload : "Spell checker not installed. Do you want to download it now?", - -// Button Dialog -DlgButtonText : "Text (Value)", -DlgButtonType : "Type", -DlgButtonTypeBtn : "Button", -DlgButtonTypeSbm : "Submit", -DlgButtonTypeRst : "Reset", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Name", -DlgCheckboxValue : "Value", -DlgCheckboxSelected : "Selected", - -// Form Dialog -DlgFormName : "Name", -DlgFormAction : "Action", -DlgFormMethod : "Method", - -// Select Field Dialog -DlgSelectName : "Name", -DlgSelectValue : "Value", -DlgSelectSize : "Size", -DlgSelectLines : "lines", -DlgSelectChkMulti : "Allow multiple selections", -DlgSelectOpAvail : "Available Options", -DlgSelectOpText : "Text", -DlgSelectOpValue : "Value", -DlgSelectBtnAdd : "Add", -DlgSelectBtnModify : "Modify", -DlgSelectBtnUp : "Up", -DlgSelectBtnDown : "Down", -DlgSelectBtnSetValue : "Set as selected value", -DlgSelectBtnDelete : "Delete", - -// Textarea Dialog -DlgTextareaName : "Name", -DlgTextareaCols : "Columns", -DlgTextareaRows : "Rows", - -// Text Field Dialog -DlgTextName : "Name", -DlgTextValue : "Value", -DlgTextCharWidth : "Character Width", -DlgTextMaxChars : "Maximum Characters", -DlgTextType : "Type", -DlgTextTypeText : "Text", -DlgTextTypePass : "Password", - -// Hidden Field Dialog -DlgHiddenName : "Name", -DlgHiddenValue : "Value", - -// Bulleted List Dialog -BulletedListProp : "Bulleted List Properties", -NumberedListProp : "Numbered List Properties", -DlgLstStart : "Start", -DlgLstType : "Type", -DlgLstTypeCircle : "Circle", -DlgLstTypeDisc : "Disc", -DlgLstTypeSquare : "Square", -DlgLstTypeNumbers : "Numbers (1, 2, 3)", -DlgLstTypeLCase : "Lowercase Letters (a, b, c)", -DlgLstTypeUCase : "Uppercase Letters (A, B, C)", -DlgLstTypeSRoman : "Small Roman Numerals (i, ii, iii)", -DlgLstTypeLRoman : "Large Roman Numerals (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "General", -DlgDocBackTab : "Background", -DlgDocColorsTab : "Colours and Margins", -DlgDocMetaTab : "Meta Data", - -DlgDocPageTitle : "Page Title", -DlgDocLangDir : "Language Direction", -DlgDocLangDirLTR : "Left to Right (LTR)", -DlgDocLangDirRTL : "Right to Left (RTL)", -DlgDocLangCode : "Language Code", -DlgDocCharSet : "Character Set Encoding", -DlgDocCharSetCE : "Central European", -DlgDocCharSetCT : "Chinese Traditional (Big5)", -DlgDocCharSetCR : "Cyrillic", -DlgDocCharSetGR : "Greek", -DlgDocCharSetJP : "Japanese", -DlgDocCharSetKR : "Korean", -DlgDocCharSetTR : "Turkish", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Western European", -DlgDocCharSetOther : "Other Character Set Encoding", - -DlgDocDocType : "Document Type Heading", -DlgDocDocTypeOther : "Other Document Type Heading", -DlgDocIncXHTML : "Include XHTML Declarations", -DlgDocBgColor : "Background Colour", -DlgDocBgImage : "Background Image URL", -DlgDocBgNoScroll : "Nonscrolling Background", -DlgDocCText : "Text", -DlgDocCLink : "Link", -DlgDocCVisited : "Visited Link", -DlgDocCActive : "Active Link", -DlgDocMargins : "Page Margins", -DlgDocMaTop : "Top", -DlgDocMaLeft : "Left", -DlgDocMaRight : "Right", -DlgDocMaBottom : "Bottom", -DlgDocMeIndex : "Document Indexing Keywords (comma separated)", -DlgDocMeDescr : "Document Description", -DlgDocMeAuthor : "Author", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Preview", - -// Templates Dialog -Templates : "Templates", -DlgTemplatesTitle : "Content Templates", -DlgTemplatesSelMsg : "Please select the template to open in the editor
    (the actual contents will be lost):", -DlgTemplatesLoading : "Loading templates list. Please wait...", -DlgTemplatesNoTpl : "(No templates defined)", -DlgTemplatesReplace : "Replace actual contents", - -// About Dialog -DlgAboutAboutTab : "About", -DlgAboutBrowserInfoTab : "Browser Info", -DlgAboutLicenseTab : "License", -DlgAboutVersion : "version", -DlgAboutInfo : "For further information go to", - -// Div Dialog -DlgDivGeneralTab : "General", -DlgDivAdvancedTab : "Advanced", -DlgDivStyle : "Style", -DlgDivInlineStyle : "Inline Style", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/en.js b/httemplate/elements/fckeditor/editor/lang/en.js deleted file mode 100644 index 2c2f5da11..000000000 --- a/httemplate/elements/fckeditor/editor/lang/en.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * English language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Collapse Toolbar", -ToolbarExpand : "Expand Toolbar", - -// Toolbar Items and Context Menu -Save : "Save", -NewPage : "New Page", -Preview : "Preview", -Cut : "Cut", -Copy : "Copy", -Paste : "Paste", -PasteText : "Paste as plain text", -PasteWord : "Paste from Word", -Print : "Print", -SelectAll : "Select All", -RemoveFormat : "Remove Format", -InsertLinkLbl : "Link", -InsertLink : "Insert/Edit Link", -RemoveLink : "Remove Link", -VisitLink : "Open Link", -Anchor : "Insert/Edit Anchor", -AnchorDelete : "Remove Anchor", -InsertImageLbl : "Image", -InsertImage : "Insert/Edit Image", -InsertFlashLbl : "Flash", -InsertFlash : "Insert/Edit Flash", -InsertTableLbl : "Table", -InsertTable : "Insert/Edit Table", -InsertLineLbl : "Line", -InsertLine : "Insert Horizontal Line", -InsertSpecialCharLbl: "Special Character", -InsertSpecialChar : "Insert Special Character", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Insert Smiley", -About : "About FCKeditor", -Bold : "Bold", -Italic : "Italic", -Underline : "Underline", -StrikeThrough : "Strike Through", -Subscript : "Subscript", -Superscript : "Superscript", -LeftJustify : "Left Justify", -CenterJustify : "Center Justify", -RightJustify : "Right Justify", -BlockJustify : "Block Justify", -DecreaseIndent : "Decrease Indent", -IncreaseIndent : "Increase Indent", -Blockquote : "Blockquote", -CreateDiv : "Create Div Container", -EditDiv : "Edit Div Container", -DeleteDiv : "Remove Div Container", -Undo : "Undo", -Redo : "Redo", -NumberedListLbl : "Numbered List", -NumberedList : "Insert/Remove Numbered List", -BulletedListLbl : "Bulleted List", -BulletedList : "Insert/Remove Bulleted List", -ShowTableBorders : "Show Table Borders", -ShowDetails : "Show Details", -Style : "Style", -FontFormat : "Format", -Font : "Font", -FontSize : "Size", -TextColor : "Text Color", -BGColor : "Background Color", -Source : "Source", -Find : "Find", -Replace : "Replace", -SpellCheck : "Check Spelling", -UniversalKeyboard : "Universal Keyboard", -PageBreakLbl : "Page Break", -PageBreak : "Insert Page Break", - -Form : "Form", -Checkbox : "Checkbox", -RadioButton : "Radio Button", -TextField : "Text Field", -Textarea : "Textarea", -HiddenField : "Hidden Field", -Button : "Button", -SelectionField : "Selection Field", -ImageButton : "Image Button", - -FitWindow : "Maximize the editor size", -ShowBlocks : "Show Blocks", - -// Context Menu -EditLink : "Edit Link", -CellCM : "Cell", -RowCM : "Row", -ColumnCM : "Column", -InsertRowAfter : "Insert Row After", -InsertRowBefore : "Insert Row Before", -DeleteRows : "Delete Rows", -InsertColumnAfter : "Insert Column After", -InsertColumnBefore : "Insert Column Before", -DeleteColumns : "Delete Columns", -InsertCellAfter : "Insert Cell After", -InsertCellBefore : "Insert Cell Before", -DeleteCells : "Delete Cells", -MergeCells : "Merge Cells", -MergeRight : "Merge Right", -MergeDown : "Merge Down", -HorizontalSplitCell : "Split Cell Horizontally", -VerticalSplitCell : "Split Cell Vertically", -TableDelete : "Delete Table", -CellProperties : "Cell Properties", -TableProperties : "Table Properties", -ImageProperties : "Image Properties", -FlashProperties : "Flash Properties", - -AnchorProp : "Anchor Properties", -ButtonProp : "Button Properties", -CheckboxProp : "Checkbox Properties", -HiddenFieldProp : "Hidden Field Properties", -RadioButtonProp : "Radio Button Properties", -ImageButtonProp : "Image Button Properties", -TextFieldProp : "Text Field Properties", -SelectionFieldProp : "Selection Field Properties", -TextareaProp : "Textarea Properties", -FormProp : "Form Properties", - -FontFormats : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Processing XHTML. Please wait...", -Done : "Done", -PasteWordConfirm : "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?", -NotCompatiblePaste : "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?", -UnknownToolbarItem : "Unknown toolbar item \"%1\"", -UnknownCommand : "Unknown command name \"%1\"", -NotImplemented : "Command not implemented", -UnknownToolbarSet : "Toolbar set \"%1\" doesn't exist", -NoActiveX : "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.", -BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.", -DialogBlocked : "It was not possible to open the dialog window. Make sure all popup blockers are disabled.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Cancel", -DlgBtnClose : "Close", -DlgBtnBrowseServer : "Browse Server", -DlgAdvancedTag : "Advanced", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Please insert the URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Language Direction", -DlgGenLangDirLtr : "Left to Right (LTR)", -DlgGenLangDirRtl : "Right to Left (RTL)", -DlgGenLangCode : "Language Code", -DlgGenAccessKey : "Access Key", -DlgGenName : "Name", -DlgGenTabIndex : "Tab Index", -DlgGenLongDescr : "Long Description URL", -DlgGenClass : "Stylesheet Classes", -DlgGenTitle : "Advisory Title", -DlgGenContType : "Advisory Content Type", -DlgGenLinkCharset : "Linked Resource Charset", -DlgGenStyle : "Style", - -// Image Dialog -DlgImgTitle : "Image Properties", -DlgImgInfoTab : "Image Info", -DlgImgBtnUpload : "Send it to the Server", -DlgImgURL : "URL", -DlgImgUpload : "Upload", -DlgImgAlt : "Alternative Text", -DlgImgWidth : "Width", -DlgImgHeight : "Height", -DlgImgLockRatio : "Lock Ratio", -DlgBtnResetSize : "Reset Size", -DlgImgBorder : "Border", -DlgImgHSpace : "HSpace", -DlgImgVSpace : "VSpace", -DlgImgAlign : "Align", -DlgImgAlignLeft : "Left", -DlgImgAlignAbsBottom: "Abs Bottom", -DlgImgAlignAbsMiddle: "Abs Middle", -DlgImgAlignBaseline : "Baseline", -DlgImgAlignBottom : "Bottom", -DlgImgAlignMiddle : "Middle", -DlgImgAlignRight : "Right", -DlgImgAlignTextTop : "Text Top", -DlgImgAlignTop : "Top", -DlgImgPreview : "Preview", -DlgImgAlertUrl : "Please type the image URL", -DlgImgLinkTab : "Link", - -// Flash Dialog -DlgFlashTitle : "Flash Properties", -DlgFlashChkPlay : "Auto Play", -DlgFlashChkLoop : "Loop", -DlgFlashChkMenu : "Enable Flash Menu", -DlgFlashScale : "Scale", -DlgFlashScaleAll : "Show all", -DlgFlashScaleNoBorder : "No Border", -DlgFlashScaleFit : "Exact Fit", - -// Link Dialog -DlgLnkWindowTitle : "Link", -DlgLnkInfoTab : "Link Info", -DlgLnkTargetTab : "Target", - -DlgLnkType : "Link Type", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Link to anchor in the text", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Select an Anchor", -DlgLnkAnchorByName : "By Anchor Name", -DlgLnkAnchorById : "By Element Id", -DlgLnkNoAnchors : "(No anchors available in the document)", -DlgLnkEMail : "E-Mail Address", -DlgLnkEMailSubject : "Message Subject", -DlgLnkEMailBody : "Message Body", -DlgLnkUpload : "Upload", -DlgLnkBtnUpload : "Send it to the Server", - -DlgLnkTarget : "Target", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "New Window (_blank)", -DlgLnkTargetParent : "Parent Window (_parent)", -DlgLnkTargetSelf : "Same Window (_self)", -DlgLnkTargetTop : "Topmost Window (_top)", -DlgLnkTargetFrameName : "Target Frame Name", -DlgLnkPopWinName : "Popup Window Name", -DlgLnkPopWinFeat : "Popup Window Features", -DlgLnkPopResize : "Resizable", -DlgLnkPopLocation : "Location Bar", -DlgLnkPopMenu : "Menu Bar", -DlgLnkPopScroll : "Scroll Bars", -DlgLnkPopStatus : "Status Bar", -DlgLnkPopToolbar : "Toolbar", -DlgLnkPopFullScrn : "Full Screen (IE)", -DlgLnkPopDependent : "Dependent (Netscape)", -DlgLnkPopWidth : "Width", -DlgLnkPopHeight : "Height", -DlgLnkPopLeft : "Left Position", -DlgLnkPopTop : "Top Position", - -DlnLnkMsgNoUrl : "Please type the link URL", -DlnLnkMsgNoEMail : "Please type the e-mail address", -DlnLnkMsgNoAnchor : "Please select an anchor", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", - -// Color Dialog -DlgColorTitle : "Select Color", -DlgColorBtnClear : "Clear", -DlgColorHighlight : "Highlight", -DlgColorSelected : "Selected", - -// Smiley Dialog -DlgSmileyTitle : "Insert a Smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Select Special Character", - -// Table Dialog -DlgTableTitle : "Table Properties", -DlgTableRows : "Rows", -DlgTableColumns : "Columns", -DlgTableBorder : "Border size", -DlgTableAlign : "Alignment", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Left", -DlgTableAlignCenter : "Center", -DlgTableAlignRight : "Right", -DlgTableWidth : "Width", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "percent", -DlgTableHeight : "Height", -DlgTableCellSpace : "Cell spacing", -DlgTableCellPad : "Cell padding", -DlgTableCaption : "Caption", -DlgTableSummary : "Summary", -DlgTableHeaders : "Headers", -DlgTableHeadersNone : "None", -DlgTableHeadersColumn : "First column", -DlgTableHeadersRow : "First Row", -DlgTableHeadersBoth : "Both", - -// Table Cell Dialog -DlgCellTitle : "Cell Properties", -DlgCellWidth : "Width", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "percent", -DlgCellHeight : "Height", -DlgCellWordWrap : "Word Wrap", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Yes", -DlgCellWordWrapNo : "No", -DlgCellHorAlign : "Horizontal Alignment", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Left", -DlgCellHorAlignCenter : "Center", -DlgCellHorAlignRight: "Right", -DlgCellVerAlign : "Vertical Alignment", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Top", -DlgCellVerAlignMiddle : "Middle", -DlgCellVerAlignBottom : "Bottom", -DlgCellVerAlignBaseline : "Baseline", -DlgCellType : "Cell Type", -DlgCellTypeData : "Data", -DlgCellTypeHeader : "Header", -DlgCellRowSpan : "Rows Span", -DlgCellCollSpan : "Columns Span", -DlgCellBackColor : "Background Color", -DlgCellBorderColor : "Border Color", -DlgCellBtnSelect : "Select...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", - -// Find Dialog -DlgFindTitle : "Find", -DlgFindFindBtn : "Find", -DlgFindNotFoundMsg : "The specified text was not found.", - -// Replace Dialog -DlgReplaceTitle : "Replace", -DlgReplaceFindLbl : "Find what:", -DlgReplaceReplaceLbl : "Replace with:", -DlgReplaceCaseChk : "Match case", -DlgReplaceReplaceBtn : "Replace", -DlgReplaceReplAllBtn : "Replace All", -DlgReplaceWordChk : "Match whole word", - -// Paste Operations / Dialog -PasteErrorCut : "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).", -PasteErrorCopy : "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).", - -PasteAsText : "Paste as Plain Text", -PasteFromWord : "Paste from Word", - -DlgPasteMsg2 : "Please paste inside the following box using the keyboard (Ctrl+V) and hit OK.", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", -DlgPasteIgnoreFont : "Ignore Font Face definitions", -DlgPasteRemoveStyles : "Remove Styles definitions", - -// Color Picker -ColorAutomatic : "Automatic", -ColorMoreColors : "More Colors...", - -// Document Properties -DocProps : "Document Properties", - -// Anchor Dialog -DlgAnchorTitle : "Anchor Properties", -DlgAnchorName : "Anchor Name", -DlgAnchorErrorName : "Please type the anchor name", - -// Speller Pages Dialog -DlgSpellNotInDic : "Not in dictionary", -DlgSpellChangeTo : "Change to", -DlgSpellBtnIgnore : "Ignore", -DlgSpellBtnIgnoreAll : "Ignore All", -DlgSpellBtnReplace : "Replace", -DlgSpellBtnReplaceAll : "Replace All", -DlgSpellBtnUndo : "Undo", -DlgSpellNoSuggestions : "- No suggestions -", -DlgSpellProgress : "Spell check in progress...", -DlgSpellNoMispell : "Spell check complete: No misspellings found", -DlgSpellNoChanges : "Spell check complete: No words changed", -DlgSpellOneChange : "Spell check complete: One word changed", -DlgSpellManyChanges : "Spell check complete: %1 words changed", - -IeSpellDownload : "Spell checker not installed. Do you want to download it now?", - -// Button Dialog -DlgButtonText : "Text (Value)", -DlgButtonType : "Type", -DlgButtonTypeBtn : "Button", -DlgButtonTypeSbm : "Submit", -DlgButtonTypeRst : "Reset", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Name", -DlgCheckboxValue : "Value", -DlgCheckboxSelected : "Selected", - -// Form Dialog -DlgFormName : "Name", -DlgFormAction : "Action", -DlgFormMethod : "Method", - -// Select Field Dialog -DlgSelectName : "Name", -DlgSelectValue : "Value", -DlgSelectSize : "Size", -DlgSelectLines : "lines", -DlgSelectChkMulti : "Allow multiple selections", -DlgSelectOpAvail : "Available Options", -DlgSelectOpText : "Text", -DlgSelectOpValue : "Value", -DlgSelectBtnAdd : "Add", -DlgSelectBtnModify : "Modify", -DlgSelectBtnUp : "Up", -DlgSelectBtnDown : "Down", -DlgSelectBtnSetValue : "Set as selected value", -DlgSelectBtnDelete : "Delete", - -// Textarea Dialog -DlgTextareaName : "Name", -DlgTextareaCols : "Columns", -DlgTextareaRows : "Rows", - -// Text Field Dialog -DlgTextName : "Name", -DlgTextValue : "Value", -DlgTextCharWidth : "Character Width", -DlgTextMaxChars : "Maximum Characters", -DlgTextType : "Type", -DlgTextTypeText : "Text", -DlgTextTypePass : "Password", - -// Hidden Field Dialog -DlgHiddenName : "Name", -DlgHiddenValue : "Value", - -// Bulleted List Dialog -BulletedListProp : "Bulleted List Properties", -NumberedListProp : "Numbered List Properties", -DlgLstStart : "Start", -DlgLstType : "Type", -DlgLstTypeCircle : "Circle", -DlgLstTypeDisc : "Disc", -DlgLstTypeSquare : "Square", -DlgLstTypeNumbers : "Numbers (1, 2, 3)", -DlgLstTypeLCase : "Lowercase Letters (a, b, c)", -DlgLstTypeUCase : "Uppercase Letters (A, B, C)", -DlgLstTypeSRoman : "Small Roman Numerals (i, ii, iii)", -DlgLstTypeLRoman : "Large Roman Numerals (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "General", -DlgDocBackTab : "Background", -DlgDocColorsTab : "Colors and Margins", -DlgDocMetaTab : "Meta Data", - -DlgDocPageTitle : "Page Title", -DlgDocLangDir : "Language Direction", -DlgDocLangDirLTR : "Left to Right (LTR)", -DlgDocLangDirRTL : "Right to Left (RTL)", -DlgDocLangCode : "Language Code", -DlgDocCharSet : "Character Set Encoding", -DlgDocCharSetCE : "Central European", -DlgDocCharSetCT : "Chinese Traditional (Big5)", -DlgDocCharSetCR : "Cyrillic", -DlgDocCharSetGR : "Greek", -DlgDocCharSetJP : "Japanese", -DlgDocCharSetKR : "Korean", -DlgDocCharSetTR : "Turkish", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Western European", -DlgDocCharSetOther : "Other Character Set Encoding", - -DlgDocDocType : "Document Type Heading", -DlgDocDocTypeOther : "Other Document Type Heading", -DlgDocIncXHTML : "Include XHTML Declarations", -DlgDocBgColor : "Background Color", -DlgDocBgImage : "Background Image URL", -DlgDocBgNoScroll : "Nonscrolling Background", -DlgDocCText : "Text", -DlgDocCLink : "Link", -DlgDocCVisited : "Visited Link", -DlgDocCActive : "Active Link", -DlgDocMargins : "Page Margins", -DlgDocMaTop : "Top", -DlgDocMaLeft : "Left", -DlgDocMaRight : "Right", -DlgDocMaBottom : "Bottom", -DlgDocMeIndex : "Document Indexing Keywords (comma separated)", -DlgDocMeDescr : "Document Description", -DlgDocMeAuthor : "Author", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Preview", - -// Templates Dialog -Templates : "Templates", -DlgTemplatesTitle : "Content Templates", -DlgTemplatesSelMsg : "Please select the template to open in the editor
    (the actual contents will be lost):", -DlgTemplatesLoading : "Loading templates list. Please wait...", -DlgTemplatesNoTpl : "(No templates defined)", -DlgTemplatesReplace : "Replace actual contents", - -// About Dialog -DlgAboutAboutTab : "About", -DlgAboutBrowserInfoTab : "Browser Info", -DlgAboutLicenseTab : "License", -DlgAboutVersion : "version", -DlgAboutInfo : "For further information go to", - -// Div Dialog -DlgDivGeneralTab : "General", -DlgDivAdvancedTab : "Advanced", -DlgDivStyle : "Style", -DlgDivInlineStyle : "Inline Style", - -ScaytTitle : "SCAYT", -ScaytTitleOptions : "Options", -ScaytTitleLangs : "Languages", -ScaytTitleAbout : "About" -}; diff --git a/httemplate/elements/fckeditor/editor/lang/eo.js b/httemplate/elements/fckeditor/editor/lang/eo.js deleted file mode 100644 index c1897de50..000000000 --- a/httemplate/elements/fckeditor/editor/lang/eo.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Esperanto language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Kaŝi Ilobreton", -ToolbarExpand : "Vidigi Ilojn", - -// Toolbar Items and Context Menu -Save : "Sekurigi", -NewPage : "Nova Paĝo", -Preview : "Vidigi Aspekton", -Cut : "Eltondi", -Copy : "Kopii", -Paste : "Interglui", -PasteText : "Interglui kiel Tekston", -PasteWord : "Interglui el Word", -Print : "Presi", -SelectAll : "Elekti ĉion", -RemoveFormat : "Forigi Formaton", -InsertLinkLbl : "Ligilo", -InsertLink : "Enmeti/Ŝanĝi Ligilon", -RemoveLink : "Forigi Ligilon", -VisitLink : "Open Link", //MISSING -Anchor : "Enmeti/Ŝanĝi Ankron", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "Bildo", -InsertImage : "Enmeti/Ŝanĝi Bildon", -InsertFlashLbl : "Flash", //MISSING -InsertFlash : "Insert/Edit Flash", //MISSING -InsertTableLbl : "Tabelo", -InsertTable : "Enmeti/Ŝanĝi Tabelon", -InsertLineLbl : "Horizonta Linio", -InsertLine : "Enmeti Horizonta Linio", -InsertSpecialCharLbl: "Speciala Signo", -InsertSpecialChar : "Enmeti Specialan Signon", -InsertSmileyLbl : "Mienvinjeto", -InsertSmiley : "Enmeti Mienvinjeton", -About : "Pri FCKeditor", -Bold : "Grasa", -Italic : "Kursiva", -Underline : "Substreko", -StrikeThrough : "Trastreko", -Subscript : "Subskribo", -Superscript : "Superskribo", -LeftJustify : "Maldekstrigi", -CenterJustify : "Centrigi", -RightJustify : "Dekstrigi", -BlockJustify : "Ĝisrandigi Ambaŭflanke", -DecreaseIndent : "Malpligrandigi Krommarĝenon", -IncreaseIndent : "Pligrandigi Krommarĝenon", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Malfari", -Redo : "Refari", -NumberedListLbl : "Numera Listo", -NumberedList : "Enmeti/Forigi Numeran Liston", -BulletedListLbl : "Bula Listo", -BulletedList : "Enmeti/Forigi Bulan Liston", -ShowTableBorders : "Vidigi Borderojn de Tabelo", -ShowDetails : "Vidigi Detalojn", -Style : "Stilo", -FontFormat : "Formato", -Font : "Tiparo", -FontSize : "Grando", -TextColor : "Teksta Koloro", -BGColor : "Fona Koloro", -Source : "Fonto", -Find : "Serĉi", -Replace : "Anstataŭigi", -SpellCheck : "Literumada Kontrolilo", -UniversalKeyboard : "Universala Klavaro", -PageBreakLbl : "Page Break", //MISSING -PageBreak : "Insert Page Break", //MISSING - -Form : "Formularo", -Checkbox : "Markobutono", -RadioButton : "Radiobutono", -TextField : "Teksta kampo", -Textarea : "Teksta Areo", -HiddenField : "Kaŝita Kampo", -Button : "Butono", -SelectionField : "Elekta Kampo", -ImageButton : "Bildbutono", - -FitWindow : "Maximize the editor size", //MISSING -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "Modifier Ligilon", -CellCM : "Cell", //MISSING -RowCM : "Row", //MISSING -ColumnCM : "Column", //MISSING -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "Forigi Liniojn", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "Forigi Kolumnojn", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "Forigi Ĉelojn", -MergeCells : "Kunfandi Ĉelojn", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "Delete Table", //MISSING -CellProperties : "Atributoj de Ĉelo", -TableProperties : "Atributoj de Tabelo", -ImageProperties : "Atributoj de Bildo", -FlashProperties : "Flash Properties", //MISSING - -AnchorProp : "Ankraj Atributoj", -ButtonProp : "Butonaj Atributoj", -CheckboxProp : "Markobutonaj Atributoj", -HiddenFieldProp : "Atributoj de Kaŝita Kampo", -RadioButtonProp : "Radiobutonaj Atributoj", -ImageButtonProp : "Bildbutonaj Atributoj", -TextFieldProp : "Atributoj de Teksta Kampo", -SelectionFieldProp : "Atributoj de Elekta Kampo", -TextareaProp : "Atributoj de Teksta Areo", -FormProp : "Formularaj Atributoj", - -FontFormats : "Normala;Formatita;Adreso;Titolo 1;Titolo 2;Titolo 3;Titolo 4;Titolo 5;Titolo 6;Paragrafo (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Traktado de XHTML. Bonvolu pacienci...", -Done : "Finita", -PasteWordConfirm : "La algluota teksto ŝajnas esti Word-devena. Ĉu vi volas purigi ĝin antaŭ ol interglui?", -NotCompatiblePaste : "Tiu ĉi komando bezonas almenaŭ Internet Explorer 5.5. Ĉu vi volas daŭrigi sen purigado?", -UnknownToolbarItem : "Ilobretero nekonata \"%1\"", -UnknownCommand : "Komandonomo nekonata \"%1\"", -NotImplemented : "Komando ne ankoraŭ realigita", -UnknownToolbarSet : "La ilobreto \"%1\" ne ekzistas", -NoActiveX : "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.", //MISSING -BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.", //MISSING -DialogBlocked : "It was not possible to open the dialog window. Make sure all popup blockers are disabled.", //MISSING -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "Akcepti", -DlgBtnCancel : "Rezigni", -DlgBtnClose : "Fermi", -DlgBtnBrowseServer : "Foliumi en la Servilo", -DlgAdvancedTag : "Speciala", -DlgOpOther : "", -DlgInfoTab : "Info", //MISSING -DlgAlertUrl : "Please insert the URL", //MISSING - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Skribdirekto", -DlgGenLangDirLtr : "De maldekstro dekstren (LTR)", -DlgGenLangDirRtl : "De dekstro maldekstren (RTL)", -DlgGenLangCode : "Lingva Kodo", -DlgGenAccessKey : "Fulmoklavo", -DlgGenName : "Nomo", -DlgGenTabIndex : "Taba Ordo", -DlgGenLongDescr : "URL de Longa Priskribo", -DlgGenClass : "Klasoj de Stilfolioj", -DlgGenTitle : "Indika Titolo", -DlgGenContType : "Indika Enhavotipo", -DlgGenLinkCharset : "Signaro de la Ligita Rimedo", -DlgGenStyle : "Stilo", - -// Image Dialog -DlgImgTitle : "Atributoj de Bildo", -DlgImgInfoTab : "Informoj pri Bildo", -DlgImgBtnUpload : "Sendu al Servilo", -DlgImgURL : "URL", -DlgImgUpload : "Alŝuti", -DlgImgAlt : "Anstataŭiga Teksto", -DlgImgWidth : "Larĝo", -DlgImgHeight : "Alto", -DlgImgLockRatio : "Konservi Proporcion", -DlgBtnResetSize : "Origina Grando", -DlgImgBorder : "Bordero", -DlgImgHSpace : "HSpaco", -DlgImgVSpace : "VSpaco", -DlgImgAlign : "Ĝisrandigo", -DlgImgAlignLeft : "Maldekstre", -DlgImgAlignAbsBottom: "Abs Malsupre", -DlgImgAlignAbsMiddle: "Abs Centre", -DlgImgAlignBaseline : "Je Malsupro de Teksto", -DlgImgAlignBottom : "Malsupre", -DlgImgAlignMiddle : "Centre", -DlgImgAlignRight : "Dekstre", -DlgImgAlignTextTop : "Je Supro de Teksto", -DlgImgAlignTop : "Supre", -DlgImgPreview : "Vidigi Aspekton", -DlgImgAlertUrl : "Bonvolu tajpi la URL de la bildo", -DlgImgLinkTab : "Link", //MISSING - -// Flash Dialog -DlgFlashTitle : "Flash Properties", //MISSING -DlgFlashChkPlay : "Auto Play", //MISSING -DlgFlashChkLoop : "Loop", //MISSING -DlgFlashChkMenu : "Enable Flash Menu", //MISSING -DlgFlashScale : "Scale", //MISSING -DlgFlashScaleAll : "Show all", //MISSING -DlgFlashScaleNoBorder : "No Border", //MISSING -DlgFlashScaleFit : "Exact Fit", //MISSING - -// Link Dialog -DlgLnkWindowTitle : "Ligilo", -DlgLnkInfoTab : "Informoj pri la Ligilo", -DlgLnkTargetTab : "Celo", - -DlgLnkType : "Tipo de Ligilo", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Ankri en tiu ĉi paĝo", -DlgLnkTypeEMail : "Retpoŝto", -DlgLnkProto : "Protokolo", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Elekti Ankron", -DlgLnkAnchorByName : "Per Ankronomo", -DlgLnkAnchorById : "Per Elementidentigilo", -DlgLnkNoAnchors : "", -DlgLnkEMail : "Retadreso", -DlgLnkEMailSubject : "Temlinio", -DlgLnkEMailBody : "Mesaĝa korpo", -DlgLnkUpload : "Alŝuti", -DlgLnkBtnUpload : "Sendi al Servilo", - -DlgLnkTarget : "Celo", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "<ŝprucfenestro>", -DlgLnkTargetBlank : "Nova Fenestro (_blank)", -DlgLnkTargetParent : "Gepatra Fenestro (_parent)", -DlgLnkTargetSelf : "Sama Fenestro (_self)", -DlgLnkTargetTop : "Plej Supra Fenestro (_top)", -DlgLnkTargetFrameName : "Nomo de Kadro", -DlgLnkPopWinName : "Nomo de Ŝprucfenestro", -DlgLnkPopWinFeat : "Atributoj de la Ŝprucfenestro", -DlgLnkPopResize : "Grando Ŝanĝebla", -DlgLnkPopLocation : "Adresobreto", -DlgLnkPopMenu : "Menubreto", -DlgLnkPopScroll : "Rulumlisteloj", -DlgLnkPopStatus : "Statobreto", -DlgLnkPopToolbar : "Ilobreto", -DlgLnkPopFullScrn : "Tutekrane (IE)", -DlgLnkPopDependent : "Dependa (Netscape)", -DlgLnkPopWidth : "Larĝo", -DlgLnkPopHeight : "Alto", -DlgLnkPopLeft : "Pozicio de Maldekstro", -DlgLnkPopTop : "Pozicio de Supro", - -DlnLnkMsgNoUrl : "Bonvolu entajpi la URL-on", -DlnLnkMsgNoEMail : "Bonvolu entajpi la retadreson", -DlnLnkMsgNoAnchor : "Bonvolu elekti ankron", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", //MISSING - -// Color Dialog -DlgColorTitle : "Elekti", -DlgColorBtnClear : "Forigi", -DlgColorHighlight : "Emfazi", -DlgColorSelected : "Elektita", - -// Smiley Dialog -DlgSmileyTitle : "Enmeti Mienvinjeton", - -// Special Character Dialog -DlgSpecialCharTitle : "Enmeti Specialan Signon", - -// Table Dialog -DlgTableTitle : "Atributoj de Tabelo", -DlgTableRows : "Linioj", -DlgTableColumns : "Kolumnoj", -DlgTableBorder : "Bordero", -DlgTableAlign : "Ĝisrandigo", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Maldekstre", -DlgTableAlignCenter : "Centre", -DlgTableAlignRight : "Dekstre", -DlgTableWidth : "Larĝo", -DlgTableWidthPx : "Bitbilderoj", -DlgTableWidthPc : "elcentoj", -DlgTableHeight : "Alto", -DlgTableCellSpace : "Interspacigo de Ĉeloj", -DlgTableCellPad : "Ĉirkaŭenhava Plenigado", -DlgTableCaption : "Titolo", -DlgTableSummary : "Summary", //MISSING -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Atributoj de Celo", -DlgCellWidth : "Larĝo", -DlgCellWidthPx : "bitbilderoj", -DlgCellWidthPc : "elcentoj", -DlgCellHeight : "Alto", -DlgCellWordWrap : "Linifaldo", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Jes", -DlgCellWordWrapNo : "Ne", -DlgCellHorAlign : "Horizonta Ĝisrandigo", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Maldekstre", -DlgCellHorAlignCenter : "Centre", -DlgCellHorAlignRight: "Dekstre", -DlgCellVerAlign : "Vertikala Ĝisrandigo", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Supre", -DlgCellVerAlignMiddle : "Centre", -DlgCellVerAlignBottom : "Malsupre", -DlgCellVerAlignBaseline : "Je Malsupro de Teksto", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Linioj Kunfanditaj", -DlgCellCollSpan : "Kolumnoj Kunfanditaj", -DlgCellBackColor : "Fono", -DlgCellBorderColor : "Bordero", -DlgCellBtnSelect : "Elekti...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", //MISSING - -// Find Dialog -DlgFindTitle : "Serĉi", -DlgFindFindBtn : "Serĉi", -DlgFindNotFoundMsg : "La celteksto ne estas trovita.", - -// Replace Dialog -DlgReplaceTitle : "Anstataŭigi", -DlgReplaceFindLbl : "Serĉi:", -DlgReplaceReplaceLbl : "Anstataŭigi per:", -DlgReplaceCaseChk : "Kongruigi Usklecon", -DlgReplaceReplaceBtn : "Anstataŭigi", -DlgReplaceReplAllBtn : "Anstataŭigi Ĉiun", -DlgReplaceWordChk : "Tuta Vorto", - -// Paste Operations / Dialog -PasteErrorCut : "La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras eltondajn operaciojn. Bonvolu uzi la klavaron por tio (ctrl-X).", -PasteErrorCopy : "La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras kopiajn operaciojn. Bonvolu uzi la klavaron por tio (ctrl-C).", - -PasteAsText : "Interglui kiel Tekston", -PasteFromWord : "Interglui el Word", - -DlgPasteMsg2 : "Please paste inside the following box using the keyboard (Ctrl+V) and hit OK.", //MISSING -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", //MISSING -DlgPasteIgnoreFont : "Ignore Font Face definitions", //MISSING -DlgPasteRemoveStyles : "Remove Styles definitions", //MISSING - -// Color Picker -ColorAutomatic : "Aŭtomata", -ColorMoreColors : "Pli da Koloroj...", - -// Document Properties -DocProps : "Dokumentaj Atributoj", - -// Anchor Dialog -DlgAnchorTitle : "Ankraj Atributoj", -DlgAnchorName : "Ankra Nomo", -DlgAnchorErrorName : "Bv tajpi la ankran nomon", - -// Speller Pages Dialog -DlgSpellNotInDic : "Ne trovita en la vortaro", -DlgSpellChangeTo : "Ŝanĝi al", -DlgSpellBtnIgnore : "Malatenti", -DlgSpellBtnIgnoreAll : "Malatenti Ĉiun", -DlgSpellBtnReplace : "Anstataŭigi", -DlgSpellBtnReplaceAll : "Anstataŭigi Ĉiun", -DlgSpellBtnUndo : "Malfari", -DlgSpellNoSuggestions : "- Neniu propono -", -DlgSpellProgress : "Literumkontrolado daŭras...", -DlgSpellNoMispell : "Literumkontrolado finita: neniu fuŝo trovita", -DlgSpellNoChanges : "Literumkontrolado finita: neniu vorto ŝanĝita", -DlgSpellOneChange : "Literumkontrolado finita: unu vorto ŝanĝita", -DlgSpellManyChanges : "Literumkontrolado finita: %1 vortoj ŝanĝitaj", - -IeSpellDownload : "Literumada Kontrolilo ne instalita. Ĉu vi volas elŝuti ĝin nun?", - -// Button Dialog -DlgButtonText : "Teksto (Valoro)", -DlgButtonType : "Tipo", -DlgButtonTypeBtn : "Button", //MISSING -DlgButtonTypeSbm : "Submit", //MISSING -DlgButtonTypeRst : "Reset", //MISSING - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nomo", -DlgCheckboxValue : "Valoro", -DlgCheckboxSelected : "Elektita", - -// Form Dialog -DlgFormName : "Nomo", -DlgFormAction : "Ago", -DlgFormMethod : "Metodo", - -// Select Field Dialog -DlgSelectName : "Nomo", -DlgSelectValue : "Valoro", -DlgSelectSize : "Grando", -DlgSelectLines : "Linioj", -DlgSelectChkMulti : "Permesi Plurajn Elektojn", -DlgSelectOpAvail : "Elektoj Disponeblaj", -DlgSelectOpText : "Teksto", -DlgSelectOpValue : "Valoro", -DlgSelectBtnAdd : "Aldoni", -DlgSelectBtnModify : "Modifi", -DlgSelectBtnUp : "Supren", -DlgSelectBtnDown : "Malsupren", -DlgSelectBtnSetValue : "Agordi kiel Elektitan Valoron", -DlgSelectBtnDelete : "Forigi", - -// Textarea Dialog -DlgTextareaName : "Nomo", -DlgTextareaCols : "Kolumnoj", -DlgTextareaRows : "Vicoj", - -// Text Field Dialog -DlgTextName : "Nomo", -DlgTextValue : "Valoro", -DlgTextCharWidth : "Signolarĝo", -DlgTextMaxChars : "Maksimuma Nombro da Signoj", -DlgTextType : "Tipo", -DlgTextTypeText : "Teksto", -DlgTextTypePass : "Pasvorto", - -// Hidden Field Dialog -DlgHiddenName : "Nomo", -DlgHiddenValue : "Valoro", - -// Bulleted List Dialog -BulletedListProp : "Atributoj de Bula Listo", -NumberedListProp : "Atributoj de Numera Listo", -DlgLstStart : "Start", //MISSING -DlgLstType : "Tipo", -DlgLstTypeCircle : "Cirklo", -DlgLstTypeDisc : "Disc", //MISSING -DlgLstTypeSquare : "Kvadrato", -DlgLstTypeNumbers : "Ciferoj (1, 2, 3)", -DlgLstTypeLCase : "Minusklaj Literoj (a, b, c)", -DlgLstTypeUCase : "Majusklaj Literoj (A, B, C)", -DlgLstTypeSRoman : "Malgrandaj Romanaj Ciferoj (i, ii, iii)", -DlgLstTypeLRoman : "Grandaj Romanaj Ciferoj (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Ĝeneralaĵoj", -DlgDocBackTab : "Fono", -DlgDocColorsTab : "Koloroj kaj Marĝenoj", -DlgDocMetaTab : "Metadatumoj", - -DlgDocPageTitle : "Paĝotitolo", -DlgDocLangDir : "Skribdirekto de la Lingvo", -DlgDocLangDirLTR : "De maldekstro dekstren (LTR)", -DlgDocLangDirRTL : "De dekstro maldekstren (LTR)", -DlgDocLangCode : "Lingvokodo", -DlgDocCharSet : "Signara Kodo", -DlgDocCharSetCE : "Central European", //MISSING -DlgDocCharSetCT : "Chinese Traditional (Big5)", //MISSING -DlgDocCharSetCR : "Cyrillic", //MISSING -DlgDocCharSetGR : "Greek", //MISSING -DlgDocCharSetJP : "Japanese", //MISSING -DlgDocCharSetKR : "Korean", //MISSING -DlgDocCharSetTR : "Turkish", //MISSING -DlgDocCharSetUN : "Unicode (UTF-8)", //MISSING -DlgDocCharSetWE : "Western European", //MISSING -DlgDocCharSetOther : "Alia Signara Kodo", - -DlgDocDocType : "Dokumenta Tipo", -DlgDocDocTypeOther : "Alia Dokumenta Tipo", -DlgDocIncXHTML : "Inkluzivi XHTML Deklaroj", -DlgDocBgColor : "Fona Koloro", -DlgDocBgImage : "URL de Fona Bildo", -DlgDocBgNoScroll : "Neruluma Fono", -DlgDocCText : "Teksto", -DlgDocCLink : "Ligilo", -DlgDocCVisited : "Vizitita Ligilo", -DlgDocCActive : "Aktiva Ligilo", -DlgDocMargins : "Paĝaj Marĝenoj", -DlgDocMaTop : "Supra", -DlgDocMaLeft : "Maldekstra", -DlgDocMaRight : "Dekstra", -DlgDocMaBottom : "Malsupra", -DlgDocMeIndex : "Ŝlosilvortoj de la Dokumento (apartigita de komoj)", -DlgDocMeDescr : "Dokumenta Priskribo", -DlgDocMeAuthor : "Verkinto", -DlgDocMeCopy : "Kopirajto", -DlgDocPreview : "Aspekto", - -// Templates Dialog -Templates : "Templates", //MISSING -DlgTemplatesTitle : "Content Templates", //MISSING -DlgTemplatesSelMsg : "Please select the template to open in the editor
    (the actual contents will be lost):", //MISSING -DlgTemplatesLoading : "Loading templates list. Please wait...", //MISSING -DlgTemplatesNoTpl : "(No templates defined)", //MISSING -DlgTemplatesReplace : "Replace actual contents", //MISSING - -// About Dialog -DlgAboutAboutTab : "Pri", -DlgAboutBrowserInfoTab : "Informoj pri TTT-legilo", -DlgAboutLicenseTab : "License", //MISSING -DlgAboutVersion : "versio", -DlgAboutInfo : "Por pli da informoj, vizitu", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/es.js b/httemplate/elements/fckeditor/editor/lang/es.js deleted file mode 100644 index d77d38aa7..000000000 --- a/httemplate/elements/fckeditor/editor/lang/es.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Spanish language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Contraer Barra", -ToolbarExpand : "Expandir Barra", - -// Toolbar Items and Context Menu -Save : "Guardar", -NewPage : "Nueva Página", -Preview : "Vista Previa", -Cut : "Cortar", -Copy : "Copiar", -Paste : "Pegar", -PasteText : "Pegar como texto plano", -PasteWord : "Pegar desde Word", -Print : "Imprimir", -SelectAll : "Seleccionar Todo", -RemoveFormat : "Eliminar Formato", -InsertLinkLbl : "Vínculo", -InsertLink : "Insertar/Editar Vínculo", -RemoveLink : "Eliminar Vínculo", -VisitLink : "Abrir enlace", -Anchor : "Referencia", -AnchorDelete : "Eliminar Referencia", -InsertImageLbl : "Imagen", -InsertImage : "Insertar/Editar Imagen", -InsertFlashLbl : "Flash", -InsertFlash : "Insertar/Editar Flash", -InsertTableLbl : "Tabla", -InsertTable : "Insertar/Editar Tabla", -InsertLineLbl : "Línea", -InsertLine : "Insertar Línea Horizontal", -InsertSpecialCharLbl: "Caracter Especial", -InsertSpecialChar : "Insertar Caracter Especial", -InsertSmileyLbl : "Emoticons", -InsertSmiley : "Insertar Emoticons", -About : "Acerca de FCKeditor", -Bold : "Negrita", -Italic : "Cursiva", -Underline : "Subrayado", -StrikeThrough : "Tachado", -Subscript : "Subíndice", -Superscript : "Superíndice", -LeftJustify : "Alinear a Izquierda", -CenterJustify : "Centrar", -RightJustify : "Alinear a Derecha", -BlockJustify : "Justificado", -DecreaseIndent : "Disminuir Sangría", -IncreaseIndent : "Aumentar Sangría", -Blockquote : "Cita", -CreateDiv : "Crear contenedor (div)", -EditDiv : "Editar contenedor (div)", -DeleteDiv : "Eliminar contenedor (div)", -Undo : "Deshacer", -Redo : "Rehacer", -NumberedListLbl : "Numeración", -NumberedList : "Insertar/Eliminar Numeración", -BulletedListLbl : "Viñetas", -BulletedList : "Insertar/Eliminar Viñetas", -ShowTableBorders : "Mostrar Bordes de Tablas", -ShowDetails : "Mostrar saltos de Párrafo", -Style : "Estilo", -FontFormat : "Formato", -Font : "Fuente", -FontSize : "Tamaño", -TextColor : "Color de Texto", -BGColor : "Color de Fondo", -Source : "Fuente HTML", -Find : "Buscar", -Replace : "Reemplazar", -SpellCheck : "Ortografía", -UniversalKeyboard : "Teclado Universal", -PageBreakLbl : "Salto de Página", -PageBreak : "Insertar Salto de Página", - -Form : "Formulario", -Checkbox : "Casilla de Verificación", -RadioButton : "Botones de Radio", -TextField : "Campo de Texto", -Textarea : "Area de Texto", -HiddenField : "Campo Oculto", -Button : "Botón", -SelectionField : "Campo de Selección", -ImageButton : "Botón Imagen", - -FitWindow : "Maximizar el tamaño del editor", -ShowBlocks : "Mostrar bloques", - -// Context Menu -EditLink : "Editar Vínculo", -CellCM : "Celda", -RowCM : "Fila", -ColumnCM : "Columna", -InsertRowAfter : "Insertar fila en la parte inferior", -InsertRowBefore : "Insertar fila en la parte superior", -DeleteRows : "Eliminar Filas", -InsertColumnAfter : "Insertar columna a la derecha", -InsertColumnBefore : "Insertar columna a la izquierda", -DeleteColumns : "Eliminar Columnas", -InsertCellAfter : "Insertar celda a la derecha", -InsertCellBefore : "Insertar celda a la izquierda", -DeleteCells : "Eliminar Celdas", -MergeCells : "Combinar Celdas", -MergeRight : "Combinar a la derecha", -MergeDown : "Combinar hacia abajo", -HorizontalSplitCell : "Dividir la celda horizontalmente", -VerticalSplitCell : "Dividir la celda verticalmente", -TableDelete : "Eliminar Tabla", -CellProperties : "Propiedades de Celda", -TableProperties : "Propiedades de Tabla", -ImageProperties : "Propiedades de Imagen", -FlashProperties : "Propiedades de Flash", - -AnchorProp : "Propiedades de Referencia", -ButtonProp : "Propiedades de Botón", -CheckboxProp : "Propiedades de Casilla", -HiddenFieldProp : "Propiedades de Campo Oculto", -RadioButtonProp : "Propiedades de Botón de Radio", -ImageButtonProp : "Propiedades de Botón de Imagen", -TextFieldProp : "Propiedades de Campo de Texto", -SelectionFieldProp : "Propiedades de Campo de Selección", -TextareaProp : "Propiedades de Area de Texto", -FormProp : "Propiedades de Formulario", - -FontFormats : "Normal;Con formato;Dirección;Encabezado 1;Encabezado 2;Encabezado 3;Encabezado 4;Encabezado 5;Encabezado 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Procesando XHTML. Por favor, espere...", -Done : "Hecho", -PasteWordConfirm : "El texto que desea parece provenir de Word. Desea depurarlo antes de pegarlo?", -NotCompatiblePaste : "Este comando está disponible sólo para Internet Explorer version 5.5 or superior. Desea pegar sin depurar?", -UnknownToolbarItem : "Item de barra desconocido \"%1\"", -UnknownCommand : "Nombre de comando desconocido \"%1\"", -NotImplemented : "Comando no implementado", -UnknownToolbarSet : "Nombre de barra \"%1\" no definido", -NoActiveX : "La configuración de las opciones de seguridad de su navegador puede estar limitando algunas características del editor. Por favor active la opción \"Ejecutar controles y complementos de ActiveX \", de lo contrario puede experimentar errores o ausencia de funcionalidades.", -BrowseServerBlocked : "La ventana de visualización del servidor no pudo ser abierta. Verifique que su navegador no esté bloqueando las ventanas emergentes (pop up).", -DialogBlocked : "No se ha podido abrir la ventana de diálogo. Verifique que su navegador no esté bloqueando las ventanas emergentes (pop up).", -VisitLinkBlocked : "Nose ha podido abrir la ventana. Asegurese de que todos los bloqueadores de popups están deshabilitados.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Cancelar", -DlgBtnClose : "Cerrar", -DlgBtnBrowseServer : "Ver Servidor", -DlgAdvancedTag : "Avanzado", -DlgOpOther : "", -DlgInfoTab : "Información", -DlgAlertUrl : "Inserte el URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Orientación", -DlgGenLangDirLtr : "Izquierda a Derecha (LTR)", -DlgGenLangDirRtl : "Derecha a Izquierda (RTL)", -DlgGenLangCode : "Cód. de idioma", -DlgGenAccessKey : "Clave de Acceso", -DlgGenName : "Nombre", -DlgGenTabIndex : "Indice de tabulación", -DlgGenLongDescr : "Descripción larga URL", -DlgGenClass : "Clases de hojas de estilo", -DlgGenTitle : "Título", -DlgGenContType : "Tipo de Contenido", -DlgGenLinkCharset : "Fuente de caracteres vinculado", -DlgGenStyle : "Estilo", - -// Image Dialog -DlgImgTitle : "Propiedades de Imagen", -DlgImgInfoTab : "Información de Imagen", -DlgImgBtnUpload : "Enviar al Servidor", -DlgImgURL : "URL", -DlgImgUpload : "Cargar", -DlgImgAlt : "Texto Alternativo", -DlgImgWidth : "Anchura", -DlgImgHeight : "Altura", -DlgImgLockRatio : "Proporcional", -DlgBtnResetSize : "Tamaño Original", -DlgImgBorder : "Borde", -DlgImgHSpace : "Esp.Horiz", -DlgImgVSpace : "Esp.Vert", -DlgImgAlign : "Alineación", -DlgImgAlignLeft : "Izquierda", -DlgImgAlignAbsBottom: "Abs inferior", -DlgImgAlignAbsMiddle: "Abs centro", -DlgImgAlignBaseline : "Línea de base", -DlgImgAlignBottom : "Pie", -DlgImgAlignMiddle : "Centro", -DlgImgAlignRight : "Derecha", -DlgImgAlignTextTop : "Tope del texto", -DlgImgAlignTop : "Tope", -DlgImgPreview : "Vista Previa", -DlgImgAlertUrl : "Por favor escriba la URL de la imagen", -DlgImgLinkTab : "Vínculo", - -// Flash Dialog -DlgFlashTitle : "Propiedades de Flash", -DlgFlashChkPlay : "Autoejecución", -DlgFlashChkLoop : "Repetir", -DlgFlashChkMenu : "Activar Menú Flash", -DlgFlashScale : "Escala", -DlgFlashScaleAll : "Mostrar todo", -DlgFlashScaleNoBorder : "Sin Borde", -DlgFlashScaleFit : "Ajustado", - -// Link Dialog -DlgLnkWindowTitle : "Vínculo", -DlgLnkInfoTab : "Información de Vínculo", -DlgLnkTargetTab : "Destino", - -DlgLnkType : "Tipo de vínculo", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Referencia en esta página", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocolo", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Seleccionar una referencia", -DlgLnkAnchorByName : "Por Nombre de Referencia", -DlgLnkAnchorById : "Por ID de elemento", -DlgLnkNoAnchors : "(No hay referencias disponibles en el documento)", -DlgLnkEMail : "Dirección de E-Mail", -DlgLnkEMailSubject : "Título del Mensaje", -DlgLnkEMailBody : "Cuerpo del Mensaje", -DlgLnkUpload : "Cargar", -DlgLnkBtnUpload : "Enviar al Servidor", - -DlgLnkTarget : "Destino", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nueva Ventana(_blank)", -DlgLnkTargetParent : "Ventana Padre (_parent)", -DlgLnkTargetSelf : "Misma Ventana (_self)", -DlgLnkTargetTop : "Ventana primaria (_top)", -DlgLnkTargetFrameName : "Nombre del Marco Destino", -DlgLnkPopWinName : "Nombre de Ventana Emergente", -DlgLnkPopWinFeat : "Características de Ventana Emergente", -DlgLnkPopResize : "Ajustable", -DlgLnkPopLocation : "Barra de ubicación", -DlgLnkPopMenu : "Barra de Menú", -DlgLnkPopScroll : "Barras de desplazamiento", -DlgLnkPopStatus : "Barra de Estado", -DlgLnkPopToolbar : "Barra de Herramientas", -DlgLnkPopFullScrn : "Pantalla Completa (IE)", -DlgLnkPopDependent : "Dependiente (Netscape)", -DlgLnkPopWidth : "Anchura", -DlgLnkPopHeight : "Altura", -DlgLnkPopLeft : "Posición Izquierda", -DlgLnkPopTop : "Posición Derecha", - -DlnLnkMsgNoUrl : "Por favor tipee el vínculo URL", -DlnLnkMsgNoEMail : "Por favor tipee la dirección de e-mail", -DlnLnkMsgNoAnchor : "Por favor seleccione una referencia", -DlnLnkMsgInvPopName : "El nombre debe empezar con un caracter alfanumérico y no debe contener espacios", - -// Color Dialog -DlgColorTitle : "Seleccionar Color", -DlgColorBtnClear : "Ninguno", -DlgColorHighlight : "Resaltado", -DlgColorSelected : "Seleccionado", - -// Smiley Dialog -DlgSmileyTitle : "Insertar un Emoticon", - -// Special Character Dialog -DlgSpecialCharTitle : "Seleccione un caracter especial", - -// Table Dialog -DlgTableTitle : "Propiedades de Tabla", -DlgTableRows : "Filas", -DlgTableColumns : "Columnas", -DlgTableBorder : "Tamaño de Borde", -DlgTableAlign : "Alineación", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Izquierda", -DlgTableAlignCenter : "Centrado", -DlgTableAlignRight : "Derecha", -DlgTableWidth : "Anchura", -DlgTableWidthPx : "pixeles", -DlgTableWidthPc : "porcentaje", -DlgTableHeight : "Altura", -DlgTableCellSpace : "Esp. e/celdas", -DlgTableCellPad : "Esp. interior", -DlgTableCaption : "Título", -DlgTableSummary : "Síntesis", -DlgTableHeaders : "Encabezados", -DlgTableHeadersNone : "Ninguno", -DlgTableHeadersColumn : "Primera columna", -DlgTableHeadersRow : "Primera fila", -DlgTableHeadersBoth : "Ambas", - -// Table Cell Dialog -DlgCellTitle : "Propiedades de Celda", -DlgCellWidth : "Anchura", -DlgCellWidthPx : "pixeles", -DlgCellWidthPc : "porcentaje", -DlgCellHeight : "Altura", -DlgCellWordWrap : "Cortar Línea", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Si", -DlgCellWordWrapNo : "No", -DlgCellHorAlign : "Alineación Horizontal", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Izquierda", -DlgCellHorAlignCenter : "Centrado", -DlgCellHorAlignRight: "Derecha", -DlgCellVerAlign : "Alineación Vertical", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Tope", -DlgCellVerAlignMiddle : "Medio", -DlgCellVerAlignBottom : "ie", -DlgCellVerAlignBaseline : "Línea de Base", -DlgCellType : "Tipo de celda", -DlgCellTypeData : "Datos", -DlgCellTypeHeader : "Encabezado", -DlgCellRowSpan : "Abarcar Filas", -DlgCellCollSpan : "Abarcar Columnas", -DlgCellBackColor : "Color de Fondo", -DlgCellBorderColor : "Color de Borde", -DlgCellBtnSelect : "Seleccione...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Buscar y Reemplazar", - -// Find Dialog -DlgFindTitle : "Buscar", -DlgFindFindBtn : "Buscar", -DlgFindNotFoundMsg : "El texto especificado no ha sido encontrado.", - -// Replace Dialog -DlgReplaceTitle : "Reemplazar", -DlgReplaceFindLbl : "Texto a buscar:", -DlgReplaceReplaceLbl : "Reemplazar con:", -DlgReplaceCaseChk : "Coincidir may/min", -DlgReplaceReplaceBtn : "Reemplazar", -DlgReplaceReplAllBtn : "Reemplazar Todo", -DlgReplaceWordChk : "Coincidir toda la palabra", - -// Paste Operations / Dialog -PasteErrorCut : "La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de cortado. Por favor use el teclado (Ctrl+X).", -PasteErrorCopy : "La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de copiado. Por favor use el teclado (Ctrl+C).", - -PasteAsText : "Pegar como Texto Plano", -PasteFromWord : "Pegar desde Word", - -DlgPasteMsg2 : "Por favor pegue dentro del cuadro utilizando el teclado (Ctrl+V); luego presione OK.", -DlgPasteSec : "Debido a la configuración de seguridad de su navegador, el editor no tiene acceso al portapapeles. Es necesario que lo pegue de nuevo en esta ventana.", -DlgPasteIgnoreFont : "Ignorar definiciones de fuentes", -DlgPasteRemoveStyles : "Remover definiciones de estilo", - -// Color Picker -ColorAutomatic : "Automático", -ColorMoreColors : "Más Colores...", - -// Document Properties -DocProps : "Propiedades del Documento", - -// Anchor Dialog -DlgAnchorTitle : "Propiedades de la Referencia", -DlgAnchorName : "Nombre de la Referencia", -DlgAnchorErrorName : "Por favor, complete el nombre de la Referencia", - -// Speller Pages Dialog -DlgSpellNotInDic : "No se encuentra en el Diccionario", -DlgSpellChangeTo : "Cambiar a", -DlgSpellBtnIgnore : "Ignorar", -DlgSpellBtnIgnoreAll : "Ignorar Todo", -DlgSpellBtnReplace : "Reemplazar", -DlgSpellBtnReplaceAll : "Reemplazar Todo", -DlgSpellBtnUndo : "Deshacer", -DlgSpellNoSuggestions : "- No hay sugerencias -", -DlgSpellProgress : "Control de Ortografía en progreso...", -DlgSpellNoMispell : "Control finalizado: no se encontraron errores", -DlgSpellNoChanges : "Control finalizado: no se ha cambiado ninguna palabra", -DlgSpellOneChange : "Control finalizado: se ha cambiado una palabra", -DlgSpellManyChanges : "Control finalizado: se ha cambiado %1 palabras", - -IeSpellDownload : "Módulo de Control de Ortografía no instalado. ¿Desea descargarlo ahora?", - -// Button Dialog -DlgButtonText : "Texto (Valor)", -DlgButtonType : "Tipo", -DlgButtonTypeBtn : "Boton", -DlgButtonTypeSbm : "Enviar", -DlgButtonTypeRst : "Reestablecer", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nombre", -DlgCheckboxValue : "Valor", -DlgCheckboxSelected : "Seleccionado", - -// Form Dialog -DlgFormName : "Nombre", -DlgFormAction : "Acción", -DlgFormMethod : "Método", - -// Select Field Dialog -DlgSelectName : "Nombre", -DlgSelectValue : "Valor", -DlgSelectSize : "Tamaño", -DlgSelectLines : "Lineas", -DlgSelectChkMulti : "Permitir múltiple selección", -DlgSelectOpAvail : "Opciones disponibles", -DlgSelectOpText : "Texto", -DlgSelectOpValue : "Valor", -DlgSelectBtnAdd : "Agregar", -DlgSelectBtnModify : "Modificar", -DlgSelectBtnUp : "Subir", -DlgSelectBtnDown : "Bajar", -DlgSelectBtnSetValue : "Establecer como predeterminado", -DlgSelectBtnDelete : "Eliminar", - -// Textarea Dialog -DlgTextareaName : "Nombre", -DlgTextareaCols : "Columnas", -DlgTextareaRows : "Filas", - -// Text Field Dialog -DlgTextName : "Nombre", -DlgTextValue : "Valor", -DlgTextCharWidth : "Caracteres de ancho", -DlgTextMaxChars : "Máximo caracteres", -DlgTextType : "Tipo", -DlgTextTypeText : "Texto", -DlgTextTypePass : "Contraseña", - -// Hidden Field Dialog -DlgHiddenName : "Nombre", -DlgHiddenValue : "Valor", - -// Bulleted List Dialog -BulletedListProp : "Propiedades de Viñetas", -NumberedListProp : "Propiedades de Numeraciones", -DlgLstStart : "Inicio", -DlgLstType : "Tipo", -DlgLstTypeCircle : "Círculo", -DlgLstTypeDisc : "Disco", -DlgLstTypeSquare : "Cuadrado", -DlgLstTypeNumbers : "Números (1, 2, 3)", -DlgLstTypeLCase : "letras en minúsculas (a, b, c)", -DlgLstTypeUCase : "letras en mayúsculas (A, B, C)", -DlgLstTypeSRoman : "Números Romanos (i, ii, iii)", -DlgLstTypeLRoman : "Números Romanos (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "General", -DlgDocBackTab : "Fondo", -DlgDocColorsTab : "Colores y Márgenes", -DlgDocMetaTab : "Meta Información", - -DlgDocPageTitle : "Título de Página", -DlgDocLangDir : "Orientación de idioma", -DlgDocLangDirLTR : "Izq. a Derecha (LTR)", -DlgDocLangDirRTL : "Der. a Izquierda (RTL)", -DlgDocLangCode : "Código de Idioma", -DlgDocCharSet : "Codif. de Conjunto de Caracteres", -DlgDocCharSetCE : "Centro Europeo", -DlgDocCharSetCT : "Chino Tradicional (Big5)", -DlgDocCharSetCR : "Cirílico", -DlgDocCharSetGR : "Griego", -DlgDocCharSetJP : "Japonés", -DlgDocCharSetKR : "Coreano", -DlgDocCharSetTR : "Turco", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Europeo occidental", -DlgDocCharSetOther : "Otra Codificación", - -DlgDocDocType : "Encabezado de Tipo de Documento", -DlgDocDocTypeOther : "Otro Encabezado", -DlgDocIncXHTML : "Incluir Declaraciones XHTML", -DlgDocBgColor : "Color de Fondo", -DlgDocBgImage : "URL de Imagen de Fondo", -DlgDocBgNoScroll : "Fondo sin rolido", -DlgDocCText : "Texto", -DlgDocCLink : "Vínculo", -DlgDocCVisited : "Vínculo Visitado", -DlgDocCActive : "Vínculo Activo", -DlgDocMargins : "Márgenes de Página", -DlgDocMaTop : "Tope", -DlgDocMaLeft : "Izquierda", -DlgDocMaRight : "Derecha", -DlgDocMaBottom : "Pie", -DlgDocMeIndex : "Claves de indexación del Documento (separados por comas)", -DlgDocMeDescr : "Descripción del Documento", -DlgDocMeAuthor : "Autor", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Vista Previa", - -// Templates Dialog -Templates : "Plantillas", -DlgTemplatesTitle : "Contenido de Plantillas", -DlgTemplatesSelMsg : "Por favor selecciona la plantilla a abrir en el editor
    (el contenido actual se perderá):", -DlgTemplatesLoading : "Cargando lista de Plantillas. Por favor, aguarde...", -DlgTemplatesNoTpl : "(No hay plantillas definidas)", -DlgTemplatesReplace : "Reemplazar el contenido actual", - -// About Dialog -DlgAboutAboutTab : "Acerca de", -DlgAboutBrowserInfoTab : "Información de Navegador", -DlgAboutLicenseTab : "Licencia", -DlgAboutVersion : "versión", -DlgAboutInfo : "Para mayor información por favor dirigirse a", - -// Div Dialog -DlgDivGeneralTab : "General", -DlgDivAdvancedTab : "Avanzado", -DlgDivStyle : "Estilo", -DlgDivInlineStyle : "Estilos CSS", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/et.js b/httemplate/elements/fckeditor/editor/lang/et.js deleted file mode 100644 index 3756cadf6..000000000 --- a/httemplate/elements/fckeditor/editor/lang/et.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Estonian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Voldi tööriistariba", -ToolbarExpand : "Laienda tööriistariba", - -// Toolbar Items and Context Menu -Save : "Salvesta", -NewPage : "Uus leht", -Preview : "Eelvaade", -Cut : "Lõika", -Copy : "Kopeeri", -Paste : "Kleebi", -PasteText : "Kleebi tavalise tekstina", -PasteWord : "Kleebi Wordist", -Print : "Prindi", -SelectAll : "Vali kõik", -RemoveFormat : "Eemalda vorming", -InsertLinkLbl : "Link", -InsertLink : "Sisesta link / Muuda linki", -RemoveLink : "Eemalda link", -VisitLink : "Open Link", //MISSING -Anchor : "Sisesta ankur / Muuda ankrut", -AnchorDelete : "Eemalda ankur", -InsertImageLbl : "Pilt", -InsertImage : "Sisesta pilt / Muuda pilti", -InsertFlashLbl : "Flash", -InsertFlash : "Sisesta flash / Muuda flashi", -InsertTableLbl : "Tabel", -InsertTable : "Sisesta tabel / Muuda tabelit", -InsertLineLbl : "Joon", -InsertLine : "Sisesta horisontaaljoon", -InsertSpecialCharLbl: "Erimärgid", -InsertSpecialChar : "Sisesta erimärk", -InsertSmileyLbl : "Emotikon", -InsertSmiley : "Sisesta emotikon", -About : "FCKeditor teave", -Bold : "Paks", -Italic : "Kursiiv", -Underline : "Allajoonitud", -StrikeThrough : "Läbijoonitud", -Subscript : "Allindeks", -Superscript : "Ülaindeks", -LeftJustify : "Vasakjoondus", -CenterJustify : "Keskjoondus", -RightJustify : "Paremjoondus", -BlockJustify : "Rööpjoondus", -DecreaseIndent : "Vähenda taanet", -IncreaseIndent : "Suurenda taanet", -Blockquote : "Blokktsitaat", -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Võta tagasi", -Redo : "Korda toimingut", -NumberedListLbl : "Nummerdatud loetelu", -NumberedList : "Sisesta/Eemalda nummerdatud loetelu", -BulletedListLbl : "Punktiseeritud loetelu", -BulletedList : "Sisesta/Eemalda punktiseeritud loetelu", -ShowTableBorders : "Näita tabeli jooni", -ShowDetails : "Näita üksikasju", -Style : "Laad", -FontFormat : "Vorming", -Font : "Kiri", -FontSize : "Suurus", -TextColor : "Teksti värv", -BGColor : "Tausta värv", -Source : "Lähtekood", -Find : "Otsi", -Replace : "Asenda", -SpellCheck : "Kontrolli õigekirja", -UniversalKeyboard : "Universaalne klaviatuur", -PageBreakLbl : "Lehepiir", -PageBreak : "Sisesta lehevahetuskoht", - -Form : "Vorm", -Checkbox : "Märkeruut", -RadioButton : "Raadionupp", -TextField : "Tekstilahter", -Textarea : "Tekstiala", -HiddenField : "Varjatud lahter", -Button : "Nupp", -SelectionField : "Valiklahter", -ImageButton : "Piltnupp", - -FitWindow : "Maksimeeri redaktori mõõtmed", -ShowBlocks : "Näita blokke", - -// Context Menu -EditLink : "Muuda linki", -CellCM : "Lahter", -RowCM : "Rida", -ColumnCM : "Veerg", -InsertRowAfter : "Sisesta rida peale", -InsertRowBefore : "Sisesta rida enne", -DeleteRows : "Eemalda read", -InsertColumnAfter : "Sisesta veerg peale", -InsertColumnBefore : "Sisesta veerg enne", -DeleteColumns : "Eemalda veerud", -InsertCellAfter : "Sisesta lahter peale", -InsertCellBefore : "Sisesta lahter enne", -DeleteCells : "Eemalda lahtrid", -MergeCells : "Ühenda lahtrid", -MergeRight : "Ühenda paremale", -MergeDown : "Ühenda alla", -HorizontalSplitCell : "Poolita lahter horisontaalselt", -VerticalSplitCell : "Poolita lahter vertikaalselt", -TableDelete : "Kustuta tabel", -CellProperties : "Lahtri atribuudid", -TableProperties : "Tabeli atribuudid", -ImageProperties : "Pildi atribuudid", -FlashProperties : "Flash omadused", - -AnchorProp : "Ankru omadused", -ButtonProp : "Nupu omadused", -CheckboxProp : "Märkeruudu omadused", -HiddenFieldProp : "Varjatud lahtri omadused", -RadioButtonProp : "Raadionupu omadused", -ImageButtonProp : "Piltnupu omadused", -TextFieldProp : "Tekstilahtri omadused", -SelectionFieldProp : "Valiklahtri omadused", -TextareaProp : "Tekstiala omadused", -FormProp : "Vormi omadused", - -FontFormats : "Tavaline;Vormindatud;Aadress;Pealkiri 1;Pealkiri 2;Pealkiri 3;Pealkiri 4;Pealkiri 5;Pealkiri 6;Tavaline (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Töötlen XHTML'i. Palun oota...", -Done : "Tehtud", -PasteWordConfirm : "Tekst, mida soovid lisada paistab pärinevat Word'ist. Kas soovid seda enne kleepimist puhastada?", -NotCompatiblePaste : "See käsk on saadaval ainult Internet Explorer versioon 5.5 või uuema puhul. Kas soovid kleepida ilma puhastamata?", -UnknownToolbarItem : "Tundmatu tööriistarea üksus \"%1\"", -UnknownCommand : "Tundmatu käsunimi \"%1\"", -NotImplemented : "Käsku ei täidetud", -UnknownToolbarSet : "Tööriistariba \"%1\" ei eksisteeri", -NoActiveX : "Sinu veebisirvija turvalisuse seaded võivad limiteerida mõningaid tekstirdaktori kasutusvõimalusi. Sa peaksid võimaldama valiku \"Run ActiveX controls and plug-ins\" oma veebisirvija seadetes. Muidu võid sa täheldada vigu tekstiredaktori töös ja märgata puuduvaid funktsioone.", -BrowseServerBlocked : "Ressursside sirvija avamine ebaõnnestus. Võimalda pop-up akende avanemine.", -DialogBlocked : "Ei olenud võimalik avada dialoogi akent. Võimalda pop-up akende avanemine.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Loobu", -DlgBtnClose : "Sulge", -DlgBtnBrowseServer : "Sirvi serverit", -DlgAdvancedTag : "Täpsemalt", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Palun sisesta URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Keele suund", -DlgGenLangDirLtr : "Vasakult paremale (LTR)", -DlgGenLangDirRtl : "Paremalt vasakule (RTL)", -DlgGenLangCode : "Keele kood", -DlgGenAccessKey : "Juurdepääsu võti", -DlgGenName : "Nimi", -DlgGenTabIndex : "Tab indeks", -DlgGenLongDescr : "Pikk kirjeldus URL", -DlgGenClass : "Stiilistiku klassid", -DlgGenTitle : "Juhendav tiitel", -DlgGenContType : "Juhendava sisu tüüp", -DlgGenLinkCharset : "Lingitud ressurssi märgistik", -DlgGenStyle : "Laad", - -// Image Dialog -DlgImgTitle : "Pildi atribuudid", -DlgImgInfoTab : "Pildi info", -DlgImgBtnUpload : "Saada serverissee", -DlgImgURL : "URL", -DlgImgUpload : "Lae üles", -DlgImgAlt : "Alternatiivne tekst", -DlgImgWidth : "Laius", -DlgImgHeight : "Kõrgus", -DlgImgLockRatio : "Lukusta kuvasuhe", -DlgBtnResetSize : "Lähtesta suurus", -DlgImgBorder : "Joon", -DlgImgHSpace : "H. vaheruum", -DlgImgVSpace : "V. vaheruum", -DlgImgAlign : "Joondus", -DlgImgAlignLeft : "Vasak", -DlgImgAlignAbsBottom: "Abs alla", -DlgImgAlignAbsMiddle: "Abs keskele", -DlgImgAlignBaseline : "Baasjoonele", -DlgImgAlignBottom : "Alla", -DlgImgAlignMiddle : "Keskele", -DlgImgAlignRight : "Paremale", -DlgImgAlignTextTop : "Tekstit üles", -DlgImgAlignTop : "Üles", -DlgImgPreview : "Eelvaade", -DlgImgAlertUrl : "Palun kirjuta pildi URL", -DlgImgLinkTab : "Link", - -// Flash Dialog -DlgFlashTitle : "Flash omadused", -DlgFlashChkPlay : "Automaatne start ", -DlgFlashChkLoop : "Korduv", -DlgFlashChkMenu : "Võimalda flash menüü", -DlgFlashScale : "Mastaap", -DlgFlashScaleAll : "Näita kõike", -DlgFlashScaleNoBorder : "Äärist ei ole", -DlgFlashScaleFit : "Täpne sobivus", - -// Link Dialog -DlgLnkWindowTitle : "Link", -DlgLnkInfoTab : "Lingi info", -DlgLnkTargetTab : "Sihtkoht", - -DlgLnkType : "Lingi tüüp", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Ankur sellel lehel", -DlgLnkTypeEMail : "E-post", -DlgLnkProto : "Protokoll", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Vali ankur", -DlgLnkAnchorByName : "Ankru nime järgi", -DlgLnkAnchorById : "Elemendi id järgi", -DlgLnkNoAnchors : "(Selles dokumendis ei ole ankruid)", -DlgLnkEMail : "E-posti aadress", -DlgLnkEMailSubject : "Sõnumi teema", -DlgLnkEMailBody : "Sõnumi tekst", -DlgLnkUpload : "Lae üles", -DlgLnkBtnUpload : "Saada serverisse", - -DlgLnkTarget : "Sihtkoht", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Uus aken (_blank)", -DlgLnkTargetParent : "Esivanem aken (_parent)", -DlgLnkTargetSelf : "Sama aken (_self)", -DlgLnkTargetTop : "Pealmine aken (_top)", -DlgLnkTargetFrameName : "Sihtmärk raami nimi", -DlgLnkPopWinName : "Hüpikakna nimi", -DlgLnkPopWinFeat : "Hüpikakna omadused", -DlgLnkPopResize : "Suurendatav", -DlgLnkPopLocation : "Aadressiriba", -DlgLnkPopMenu : "Menüüriba", -DlgLnkPopScroll : "Kerimisribad", -DlgLnkPopStatus : "Olekuriba", -DlgLnkPopToolbar : "Tööriistariba", -DlgLnkPopFullScrn : "Täisekraan (IE)", -DlgLnkPopDependent : "Sõltuv (Netscape)", -DlgLnkPopWidth : "Laius", -DlgLnkPopHeight : "Kõrgus", -DlgLnkPopLeft : "Vasak asukoht", -DlgLnkPopTop : "Ülemine asukoht", - -DlnLnkMsgNoUrl : "Palun kirjuta lingi URL", -DlnLnkMsgNoEMail : "Palun kirjuta E-Posti aadress", -DlnLnkMsgNoAnchor : "Palun vali ankur", -DlnLnkMsgInvPopName : "Hüpikakna nimi peab algama alfabeetilise tähega ja ei tohi sisaldada tühikuid", - -// Color Dialog -DlgColorTitle : "Vali värv", -DlgColorBtnClear : "Tühjenda", -DlgColorHighlight : "Märgi", -DlgColorSelected : "Valitud", - -// Smiley Dialog -DlgSmileyTitle : "Sisesta emotikon", - -// Special Character Dialog -DlgSpecialCharTitle : "Vali erimärk", - -// Table Dialog -DlgTableTitle : "Tabeli atribuudid", -DlgTableRows : "Read", -DlgTableColumns : "Veerud", -DlgTableBorder : "Joone suurus", -DlgTableAlign : "Joondus", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Vasak", -DlgTableAlignCenter : "Kesk", -DlgTableAlignRight : "Parem", -DlgTableWidth : "Laius", -DlgTableWidthPx : "pikslit", -DlgTableWidthPc : "protsenti", -DlgTableHeight : "Kõrgus", -DlgTableCellSpace : "Lahtri vahe", -DlgTableCellPad : "Lahtri täidis", -DlgTableCaption : "Tabeli tiitel", -DlgTableSummary : "Kokkuvõte", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Lahtri atribuudid", -DlgCellWidth : "Laius", -DlgCellWidthPx : "pikslit", -DlgCellWidthPc : "protsenti", -DlgCellHeight : "Kõrgus", -DlgCellWordWrap : "Sõna ülekanne", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Jah", -DlgCellWordWrapNo : "Ei", -DlgCellHorAlign : "Horisontaaljoondus", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Vasak", -DlgCellHorAlignCenter : "Kesk", -DlgCellHorAlignRight: "Parem", -DlgCellVerAlign : "Vertikaaljoondus", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Üles", -DlgCellVerAlignMiddle : "Keskele", -DlgCellVerAlignBottom : "Alla", -DlgCellVerAlignBaseline : "Baasjoonele", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Reaulatus", -DlgCellCollSpan : "Veeruulatus", -DlgCellBackColor : "Tausta värv", -DlgCellBorderColor : "Joone värv", -DlgCellBtnSelect : "Vali...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Otsi ja asenda", - -// Find Dialog -DlgFindTitle : "Otsi", -DlgFindFindBtn : "Otsi", -DlgFindNotFoundMsg : "Valitud teksti ei leitud.", - -// Replace Dialog -DlgReplaceTitle : "Asenda", -DlgReplaceFindLbl : "Leia mida:", -DlgReplaceReplaceLbl : "Asenda millega:", -DlgReplaceCaseChk : "Erista suur- ja väiketähti", -DlgReplaceReplaceBtn : "Asenda", -DlgReplaceReplAllBtn : "Asenda kõik", -DlgReplaceWordChk : "Otsi terviklike sõnu", - -// Paste Operations / Dialog -PasteErrorCut : "Sinu veebisirvija turvaseaded ei luba redaktoril automaatselt lõigata. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl+X).", -PasteErrorCopy : "Sinu veebisirvija turvaseaded ei luba redaktoril automaatselt kopeerida. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl+C).", - -PasteAsText : "Kleebi tavalise tekstina", -PasteFromWord : "Kleebi Wordist", - -DlgPasteMsg2 : "Palun kleebi järgnevasse kasti kasutades klaviatuuri klahvikombinatsiooni (Ctrl+V) ja vajuta seejärel OK.", -DlgPasteSec : "Sinu veebisirvija turvaseadete tõttu, ei oma redaktor otsest ligipääsu lõikelaua andmetele. Sa pead kleepima need uuesti siia aknasse.", -DlgPasteIgnoreFont : "Ignoreeri kirja definitsioone", -DlgPasteRemoveStyles : "Eemalda stiilide definitsioonid", - -// Color Picker -ColorAutomatic : "Automaatne", -ColorMoreColors : "Rohkem värve...", - -// Document Properties -DocProps : "Dokumendi omadused", - -// Anchor Dialog -DlgAnchorTitle : "Ankru omadused", -DlgAnchorName : "Ankru nimi", -DlgAnchorErrorName : "Palun sisest ankru nimi", - -// Speller Pages Dialog -DlgSpellNotInDic : "Puudub sõnastikust", -DlgSpellChangeTo : "Muuda", -DlgSpellBtnIgnore : "Ignoreeri", -DlgSpellBtnIgnoreAll : "Ignoreeri kõiki", -DlgSpellBtnReplace : "Asenda", -DlgSpellBtnReplaceAll : "Asenda kõik", -DlgSpellBtnUndo : "Võta tagasi", -DlgSpellNoSuggestions : "- Soovitused puuduvad -", -DlgSpellProgress : "Toimub õigekirja kontroll...", -DlgSpellNoMispell : "Õigekirja kontroll sooritatud: õigekirjuvigu ei leitud", -DlgSpellNoChanges : "Õigekirja kontroll sooritatud: ühtegi sõna ei muudetud", -DlgSpellOneChange : "Õigekirja kontroll sooritatud: üks sõna muudeti", -DlgSpellManyChanges : "Õigekirja kontroll sooritatud: %1 sõna muudetud", - -IeSpellDownload : "Õigekirja kontrollija ei ole installeeritud. Soovid sa selle alla laadida?", - -// Button Dialog -DlgButtonText : "Tekst (väärtus)", -DlgButtonType : "Tüüp", -DlgButtonTypeBtn : "Nupp", -DlgButtonTypeSbm : "Saada", -DlgButtonTypeRst : "Lähtesta", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nimi", -DlgCheckboxValue : "Väärtus", -DlgCheckboxSelected : "Valitud", - -// Form Dialog -DlgFormName : "Nimi", -DlgFormAction : "Toiming", -DlgFormMethod : "Meetod", - -// Select Field Dialog -DlgSelectName : "Nimi", -DlgSelectValue : "Väärtus", -DlgSelectSize : "Suurus", -DlgSelectLines : "ridu", -DlgSelectChkMulti : "Võimalda mitu valikut", -DlgSelectOpAvail : "Võimalikud valikud", -DlgSelectOpText : "Tekst", -DlgSelectOpValue : "Väärtus", -DlgSelectBtnAdd : "Lisa", -DlgSelectBtnModify : "Muuda", -DlgSelectBtnUp : "Üles", -DlgSelectBtnDown : "Alla", -DlgSelectBtnSetValue : "Sea valitud olekuna", -DlgSelectBtnDelete : "Kustuta", - -// Textarea Dialog -DlgTextareaName : "Nimi", -DlgTextareaCols : "Veerge", -DlgTextareaRows : "Ridu", - -// Text Field Dialog -DlgTextName : "Nimi", -DlgTextValue : "Väärtus", -DlgTextCharWidth : "Laius (tähemärkides)", -DlgTextMaxChars : "Maksimaalselt tähemärke", -DlgTextType : "Tüüp", -DlgTextTypeText : "Tekst", -DlgTextTypePass : "Parool", - -// Hidden Field Dialog -DlgHiddenName : "Nimi", -DlgHiddenValue : "Väärtus", - -// Bulleted List Dialog -BulletedListProp : "Täpitud loetelu omadused", -NumberedListProp : "Nummerdatud loetelu omadused", -DlgLstStart : "Alusta", -DlgLstType : "Tüüp", -DlgLstTypeCircle : "Ring", -DlgLstTypeDisc : "Ketas", -DlgLstTypeSquare : "Ruut", -DlgLstTypeNumbers : "Numbrid (1, 2, 3)", -DlgLstTypeLCase : "Väiketähed (a, b, c)", -DlgLstTypeUCase : "Suurtähed (A, B, C)", -DlgLstTypeSRoman : "Väiksed Rooma numbrid (i, ii, iii)", -DlgLstTypeLRoman : "Suured Rooma numbrid (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Üldine", -DlgDocBackTab : "Taust", -DlgDocColorsTab : "Värvid ja veerised", -DlgDocMetaTab : "Meta andmed", - -DlgDocPageTitle : "Lehekülje tiitel", -DlgDocLangDir : "Kirja suund", -DlgDocLangDirLTR : "Vasakult paremale (LTR)", -DlgDocLangDirRTL : "Paremalt vasakule (RTL)", -DlgDocLangCode : "Keele kood", -DlgDocCharSet : "Märgistiku kodeering", -DlgDocCharSetCE : "Kesk-Euroopa", -DlgDocCharSetCT : "Hiina traditsiooniline (Big5)", -DlgDocCharSetCR : "Kirillisa", -DlgDocCharSetGR : "Kreeka", -DlgDocCharSetJP : "Jaapani", -DlgDocCharSetKR : "Korea", -DlgDocCharSetTR : "Türgi", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Lääne-Euroopa", -DlgDocCharSetOther : "Ülejäänud märgistike kodeeringud", - -DlgDocDocType : "Dokumendi tüüppäis", -DlgDocDocTypeOther : "Teised dokumendi tüüppäised", -DlgDocIncXHTML : "Arva kaasa XHTML deklaratsioonid", -DlgDocBgColor : "Taustavärv", -DlgDocBgImage : "Taustapildi URL", -DlgDocBgNoScroll : "Mittekeritav tagataust", -DlgDocCText : "Tekst", -DlgDocCLink : "Link", -DlgDocCVisited : "Külastatud link", -DlgDocCActive : "Aktiivne link", -DlgDocMargins : "Lehekülje äärised", -DlgDocMaTop : "Ülaserv", -DlgDocMaLeft : "Vasakserv", -DlgDocMaRight : "Paremserv", -DlgDocMaBottom : "Alaserv", -DlgDocMeIndex : "Dokumendi võtmesõnad (eraldatud komadega)", -DlgDocMeDescr : "Dokumendi kirjeldus", -DlgDocMeAuthor : "Autor", -DlgDocMeCopy : "Autoriõigus", -DlgDocPreview : "Eelvaade", - -// Templates Dialog -Templates : "Šabloon", -DlgTemplatesTitle : "Sisu šabloonid", -DlgTemplatesSelMsg : "Palun vali šabloon, et avada see redaktoris
    (praegune sisu läheb kaotsi):", -DlgTemplatesLoading : "Laen šabloonide nimekirja. Palun oota...", -DlgTemplatesNoTpl : "(Ühtegi šablooni ei ole defineeritud)", -DlgTemplatesReplace : "Asenda tegelik sisu", - -// About Dialog -DlgAboutAboutTab : "Teave", -DlgAboutBrowserInfoTab : "Veebisirvija info", -DlgAboutLicenseTab : "Litsents", -DlgAboutVersion : "versioon", -DlgAboutInfo : "Täpsema info saamiseks mine", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/eu.js b/httemplate/elements/fckeditor/editor/lang/eu.js deleted file mode 100644 index 75f91a568..000000000 --- a/httemplate/elements/fckeditor/editor/lang/eu.js +++ /dev/null @@ -1,540 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Basque language file. - * Euskara hizkuntza fitxategia. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Estutu Tresna Barra", -ToolbarExpand : "Hedatu Tresna Barra", - -// Toolbar Items and Context Menu -Save : "Gorde", -NewPage : "Orrialde Berria", -Preview : "Aurrebista", -Cut : "Ebaki", -Copy : "Kopiatu", -Paste : "Itsatsi", -PasteText : "Itsatsi testu bezala", -PasteWord : "Itsatsi Word-etik", -Print : "Inprimatu", -SelectAll : "Hautatu dena", -RemoveFormat : "Kendu Formatua", -InsertLinkLbl : "Esteka", -InsertLink : "Txertatu/Editatu Esteka", -RemoveLink : "Kendu Esteka", -VisitLink : "Ireki Esteka", -Anchor : "Aingura", -AnchorDelete : "Ezabatu Aingura", -InsertImageLbl : "Irudia", -InsertImage : "Txertatu/Editatu Irudia", -InsertFlashLbl : "Flasha", -InsertFlash : "Txertatu/Editatu Flasha", -InsertTableLbl : "Taula", -InsertTable : "Txertatu/Editatu Taula", -InsertLineLbl : "Lerroa", -InsertLine : "Txertatu Marra Horizontala", -InsertSpecialCharLbl: "Karaktere Berezia", -InsertSpecialChar : "Txertatu Karaktere Berezia", -InsertSmileyLbl : "Aurpegierak", -InsertSmiley : "Txertatu Aurpegierak", -About : "FCKeditor-ri buruz", -Bold : "Lodia", -Italic : "Etzana", -Underline : "Azpimarratu", -StrikeThrough : "Marratua", -Subscript : "Azpi-indize", -Superscript : "Goi-indize", -LeftJustify : "Lerrokatu Ezkerrean", -CenterJustify : "Lerrokatu Erdian", -RightJustify : "Lerrokatu Eskuman", -BlockJustify : "Justifikatu", -DecreaseIndent : "Txikitu Koska", -IncreaseIndent : "Handitu Koska", -Blockquote : "Aipamen blokea", -CreateDiv : "Sortu Div Edukitzailea", -EditDiv : "Editatu Div Edukitzailea", -DeleteDiv : "Ezabatu Div Edukitzailea", -Undo : "Desegin", -Redo : "Berregin", -NumberedListLbl : "Zenbakidun Zerrenda", -NumberedList : "Txertatu/Kendu Zenbakidun zerrenda", -BulletedListLbl : "Buletdun Zerrenda", -BulletedList : "Txertatu/Kendu Buletdun zerrenda", -ShowTableBorders : "Erakutsi Taularen Ertzak", -ShowDetails : "Erakutsi Xehetasunak", -Style : "Estiloa", -FontFormat : "Formatua", -Font : "Letra-tipoa", -FontSize : "Tamaina", -TextColor : "Testu Kolorea", -BGColor : "Atzeko kolorea", -Source : "HTML Iturburua", -Find : "Bilatu", -Replace : "Ordezkatu", -SpellCheck : "Ortografia", -UniversalKeyboard : "Teklatu Unibertsala", -PageBreakLbl : "Orrialde-jauzia", -PageBreak : "Txertatu Orrialde-jauzia", - -Form : "Formularioa", -Checkbox : "Kontrol-laukia", -RadioButton : "Aukera-botoia", -TextField : "Testu Eremua", -Textarea : "Testu-area", -HiddenField : "Ezkutuko Eremua", -Button : "Botoia", -SelectionField : "Hautespen Eremua", -ImageButton : "Irudi Botoia", - -FitWindow : "Maximizatu editorearen tamaina", -ShowBlocks : "Blokeak erakutsi", - -// Context Menu -EditLink : "Aldatu Esteka", -CellCM : "Gelaxka", -RowCM : "Errenkada", -ColumnCM : "Zutabea", -InsertRowAfter : "Txertatu Lerroa Ostean", -InsertRowBefore : "Txertatu Lerroa Aurretik", -DeleteRows : "Ezabatu Errenkadak", -InsertColumnAfter : "Txertatu Zutabea Ostean", -InsertColumnBefore : "Txertatu Zutabea Aurretik", -DeleteColumns : "Ezabatu Zutabeak", -InsertCellAfter : "Txertatu Gelaxka Ostean", -InsertCellBefore : "Txertatu Gelaxka Aurretik", -DeleteCells : "Kendu Gelaxkak", -MergeCells : "Batu Gelaxkak", -MergeRight : "Elkartu Eskumara", -MergeDown : "Elkartu Behera", -HorizontalSplitCell : "Banatu Gelaxkak Horizontalki", -VerticalSplitCell : "Banatu Gelaxkak Bertikalki", -TableDelete : "Ezabatu Taula", -CellProperties : "Gelaxkaren Ezaugarriak", -TableProperties : "Taularen Ezaugarriak", -ImageProperties : "Irudiaren Ezaugarriak", -FlashProperties : "Flasharen Ezaugarriak", - -AnchorProp : "Ainguraren Ezaugarriak", -ButtonProp : "Botoiaren Ezaugarriak", -CheckboxProp : "Kontrol-laukiko Ezaugarriak", -HiddenFieldProp : "Ezkutuko Eremuaren Ezaugarriak", -RadioButtonProp : "Aukera-botoiaren Ezaugarriak", -ImageButtonProp : "Irudi Botoiaren Ezaugarriak", -TextFieldProp : "Testu Eremuaren Ezaugarriak", -SelectionFieldProp : "Hautespen Eremuaren Ezaugarriak", -TextareaProp : "Testu-arearen Ezaugarriak", -FormProp : "Formularioaren Ezaugarriak", - -FontFormats : "Arrunta;Formateatua;Helbidea;Izenburua 1;Izenburua 2;Izenburua 3;Izenburua 4;Izenburua 5;Izenburua 6;Paragrafoa (DIV)", - -// Alerts and Messages -ProcessingXHTML : "XHTML Prozesatzen. Itxaron mesedez...", -Done : "Eginda", -PasteWordConfirm : "Itsatsi nahi duzun testua Wordetik hartua dela dirudi. Itsatsi baino lehen garbitu nahi duzu?", -NotCompatiblePaste : "Komando hau Internet Explorer 5.5 bertsiorako edo ondorengoentzako erabilgarria dago. Garbitu gabe itsatsi nahi duzu?", -UnknownToolbarItem : "Ataza barrako elementu ezezaguna \"%1\"", -UnknownCommand : "Komando izen ezezaguna \"%1\"", -NotImplemented : "Komando ez inplementatua", -UnknownToolbarSet : "Ataza barra \"%1\" taldea ez da existitzen", -NoActiveX : "Zure nabigatzailearen segurtasun hobespenak editore honen zenbait ezaugarri mugatu ditzake. \"ActiveX kontrolak eta pluginak\" aktibatu beharko zenituzke, bestela erroreak eta ezaugarrietan mugak egon daitezke.", -BrowseServerBlocked : "Baliabideen arakatzailea ezin da ireki. Ziurtatu popup blokeatzaileak desgaituta dituzula.", -DialogBlocked : "Ezin da elkarrizketa-leihoa ireki. Ziurtatu popup blokeatzaileak desgaituta dituzula.", -VisitLinkBlocked : "Ezin da leiho berri bat ireki. Ziurtatu popup blokeatzaileak desgaituta dituzula.", - -// Dialogs -DlgBtnOK : "Ados", -DlgBtnCancel : "Utzi", -DlgBtnClose : "Itxi", -DlgBtnBrowseServer : "Zerbitzaria arakatu", -DlgAdvancedTag : "Aurreratua", -DlgOpOther : "", -DlgInfoTab : "Informazioa", -DlgAlertUrl : "Mesedez URLa idatzi ezazu", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Hizkuntzaren Norabidea", -DlgGenLangDirLtr : "Ezkerretik Eskumara(LTR)", -DlgGenLangDirRtl : "Eskumatik Ezkerrera (RTL)", -DlgGenLangCode : "Hizkuntza Kodea", -DlgGenAccessKey : "Sarbide-gakoa", -DlgGenName : "Izena", -DlgGenTabIndex : "Tabulazio Indizea", -DlgGenLongDescr : "URL Deskribapen Luzea", -DlgGenClass : "Estilo-orriko Klaseak", -DlgGenTitle : "Izenburua", -DlgGenContType : "Eduki Mota (Content Type)", -DlgGenLinkCharset : "Estekatutako Karaktere Multzoa", -DlgGenStyle : "Estiloa", - -// Image Dialog -DlgImgTitle : "Irudi Ezaugarriak", -DlgImgInfoTab : "Irudi informazioa", -DlgImgBtnUpload : "Zerbitzarira bidalia", -DlgImgURL : "URL", -DlgImgUpload : "Gora Kargatu", -DlgImgAlt : "Ordezko Testua", -DlgImgWidth : "Zabalera", -DlgImgHeight : "Altuera", -DlgImgLockRatio : "Erlazioa Blokeatu", -DlgBtnResetSize : "Tamaina Berrezarri", -DlgImgBorder : "Ertza", -DlgImgHSpace : "HSpace", -DlgImgVSpace : "VSpace", -DlgImgAlign : "Lerrokatu", -DlgImgAlignLeft : "Ezkerrera", -DlgImgAlignAbsBottom: "Abs Behean", -DlgImgAlignAbsMiddle: "Abs Erdian", -DlgImgAlignBaseline : "Oinan", -DlgImgAlignBottom : "Behean", -DlgImgAlignMiddle : "Erdian", -DlgImgAlignRight : "Eskuman", -DlgImgAlignTextTop : "Testua Goian", -DlgImgAlignTop : "Goian", -DlgImgPreview : "Aurrebista", -DlgImgAlertUrl : "Mesedez Irudiaren URLa idatzi", -DlgImgLinkTab : "Esteka", - -// Flash Dialog -DlgFlashTitle : "Flasharen Ezaugarriak", -DlgFlashChkPlay : "Automatikoki Erreproduzitu", -DlgFlashChkLoop : "Begizta", -DlgFlashChkMenu : "Flasharen Menua Gaitu", -DlgFlashScale : "Eskalatu", -DlgFlashScaleAll : "Dena erakutsi", -DlgFlashScaleNoBorder : "Ertzik gabe", -DlgFlashScaleFit : "Doitu", - -// Link Dialog -DlgLnkWindowTitle : "Esteka", -DlgLnkInfoTab : "Estekaren Informazioa", -DlgLnkTargetTab : "Helburua", - -DlgLnkType : "Esteka Mota", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Aingura orrialde honetan", -DlgLnkTypeEMail : "ePosta", -DlgLnkProto : "Protokoloa", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Aingura bat hautatu", -DlgLnkAnchorByName : "Aingura izenagatik", -DlgLnkAnchorById : "Elementuaren ID-gatik", -DlgLnkNoAnchors : "(Ez daude aingurak eskuragarri dokumentuan)", -DlgLnkEMail : "ePosta Helbidea", -DlgLnkEMailSubject : "Mezuaren Gaia", -DlgLnkEMailBody : "Mezuaren Gorputza", -DlgLnkUpload : "Gora kargatu", -DlgLnkBtnUpload : "Zerbitzarira bidali", - -DlgLnkTarget : "Target (Helburua)", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Leiho Berria (_blank)", -DlgLnkTargetParent : "Leiho Gurasoa (_parent)", -DlgLnkTargetSelf : "Leiho Berdina (_self)", -DlgLnkTargetTop : "Goiko Leihoa (_top)", -DlgLnkTargetFrameName : "Marko Helburuaren Izena", -DlgLnkPopWinName : "Popup Leihoaren Izena", -DlgLnkPopWinFeat : "Popup Leihoaren Ezaugarriak", -DlgLnkPopResize : "Tamaina Aldakorra", -DlgLnkPopLocation : "Kokaleku Barra", -DlgLnkPopMenu : "Menu Barra", -DlgLnkPopScroll : "Korritze Barrak", -DlgLnkPopStatus : "Egoera Barra", -DlgLnkPopToolbar : "Tresna Barra", -DlgLnkPopFullScrn : "Pantaila Osoa (IE)", -DlgLnkPopDependent : "Menpekoa (Netscape)", -DlgLnkPopWidth : "Zabalera", -DlgLnkPopHeight : "Altuera", -DlgLnkPopLeft : "Ezkerreko Posizioa", -DlgLnkPopTop : "Goiko Posizioa", - -DlnLnkMsgNoUrl : "Mesedez URL esteka idatzi", -DlnLnkMsgNoEMail : "Mesedez ePosta helbidea idatzi", -DlnLnkMsgNoAnchor : "Mesedez aingura bat aukeratu", -DlnLnkMsgInvPopName : "Popup leihoaren izenak karaktere alfabetiko batekin hasi behar du eta eta ezin du zuriunerik izan", - -// Color Dialog -DlgColorTitle : "Kolore Aukeraketa", -DlgColorBtnClear : "Garbitu", -DlgColorHighlight : "Nabarmendu", -DlgColorSelected : "Aukeratuta", - -// Smiley Dialog -DlgSmileyTitle : "Aurpegiera Sartu", - -// Special Character Dialog -DlgSpecialCharTitle : "Karaktere Berezia Aukeratu", - -// Table Dialog -DlgTableTitle : "Taularen Ezaugarriak", -DlgTableRows : "Lerroak", -DlgTableColumns : "Zutabeak", -DlgTableBorder : "Ertzaren Zabalera", -DlgTableAlign : "Lerrokatu", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Ezkerrean", -DlgTableAlignCenter : "Erdian", -DlgTableAlignRight : "Eskuman", -DlgTableWidth : "Zabalera", -DlgTableWidthPx : "pixel", -DlgTableWidthPc : "ehuneko", -DlgTableHeight : "Altuera", -DlgTableCellSpace : "Gelaxka arteko tartea", -DlgTableCellPad : "Gelaxken betegarria", -DlgTableCaption : "Epigrafea", -DlgTableSummary : "Laburpena", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Gelaxken Ezaugarriak", -DlgCellWidth : "Zabalera", -DlgCellWidthPx : "pixel", -DlgCellWidthPc : "ehuneko", -DlgCellHeight : "Altuera", -DlgCellWordWrap : "Itzulbira", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Bai", -DlgCellWordWrapNo : "Ez", -DlgCellHorAlign : "Lerrokatu Horizontalki", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Ezkerrean", -DlgCellHorAlignCenter : "Erdian", -DlgCellHorAlignRight: "Eskuman", -DlgCellVerAlign : "Lerrokatu Bertikalki", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Goian", -DlgCellVerAlignMiddle : "Erdian", -DlgCellVerAlignBottom : "Behean", -DlgCellVerAlignBaseline : "Oinean", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Lerroak Hedatu", -DlgCellCollSpan : "Zutabeak Hedatu", -DlgCellBackColor : "Atzeko Kolorea", -DlgCellBorderColor : "Ertzako Kolorea", -DlgCellBtnSelect : "Aukeratu...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Bilatu eta Ordeztu", - -// Find Dialog -DlgFindTitle : "Bilaketa", -DlgFindFindBtn : "Bilatu", -DlgFindNotFoundMsg : "Idatzitako testua ez da topatu.", - -// Replace Dialog -DlgReplaceTitle : "Ordeztu", -DlgReplaceFindLbl : "Zer bilatu:", -DlgReplaceReplaceLbl : "Zerekin ordeztu:", -DlgReplaceCaseChk : "Maiuskula/minuskula", -DlgReplaceReplaceBtn : "Ordeztu", -DlgReplaceReplAllBtn : "Ordeztu Guztiak", -DlgReplaceWordChk : "Esaldi osoa bilatu", - -// Paste Operations / Dialog -PasteErrorCut : "Zure web nabigatzailearen segurtasun ezarpenak testuak automatikoki moztea ez dute baimentzen. Mesedez teklatua erabili ezazu (Ctrl+X).", -PasteErrorCopy : "Zure web nabigatzailearen segurtasun ezarpenak testuak automatikoki kopiatzea ez dute baimentzen. Mesedez teklatua erabili ezazu (Ctrl+C).", - -PasteAsText : "Testu Arrunta bezala Itsatsi", -PasteFromWord : "Word-etik itsatsi", - -DlgPasteMsg2 : "Mesedez teklatua erabilita (Ctrl+V) ondorego eremuan testua itsatsi eta OK sakatu.", -DlgPasteSec : "Nabigatzailearen segurtasun ezarpenak direla eta, editoreak ezin du arbela zuzenean erabili. Leiho honetan berriro itsatsi behar duzu.", -DlgPasteIgnoreFont : "Letra Motaren definizioa ezikusi", -DlgPasteRemoveStyles : "Estilo definizioak kendu", - -// Color Picker -ColorAutomatic : "Automatikoa", -ColorMoreColors : "Kolore gehiago...", - -// Document Properties -DocProps : "Dokumentuaren Ezarpenak", - -// Anchor Dialog -DlgAnchorTitle : "Ainguraren Ezaugarriak", -DlgAnchorName : "Ainguraren Izena", -DlgAnchorErrorName : "Idatzi ainguraren izena", - -// Speller Pages Dialog -DlgSpellNotInDic : "Ez dago hiztegian", -DlgSpellChangeTo : "Honekin ordezkatu", -DlgSpellBtnIgnore : "Ezikusi", -DlgSpellBtnIgnoreAll : "Denak Ezikusi", -DlgSpellBtnReplace : "Ordezkatu", -DlgSpellBtnReplaceAll : "Denak Ordezkatu", -DlgSpellBtnUndo : "Desegin", -DlgSpellNoSuggestions : "- Iradokizunik ez -", -DlgSpellProgress : "Zuzenketa ortografikoa martxan...", -DlgSpellNoMispell : "Zuzenketa ortografikoa bukatuta: Akatsik ez", -DlgSpellNoChanges : "Zuzenketa ortografikoa bukatuta: Ez da ezer aldatu", -DlgSpellOneChange : "Zuzenketa ortografikoa bukatuta: Hitz bat aldatu da", -DlgSpellManyChanges : "Zuzenketa ortografikoa bukatuta: %1 hitz aldatu dira", - -IeSpellDownload : "Zuzentzaile ortografikoa ez dago instalatuta. Deskargatu nahi duzu?", - -// Button Dialog -DlgButtonText : "Testua (Balorea)", -DlgButtonType : "Mota", -DlgButtonTypeBtn : "Botoia", -DlgButtonTypeSbm : "Bidali", -DlgButtonTypeRst : "Garbitu", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Izena", -DlgCheckboxValue : "Balorea", -DlgCheckboxSelected : "Hautatuta", - -// Form Dialog -DlgFormName : "Izena", -DlgFormAction : "Ekintza", -DlgFormMethod : "Metodoa", - -// Select Field Dialog -DlgSelectName : "Izena", -DlgSelectValue : "Balorea", -DlgSelectSize : "Tamaina", -DlgSelectLines : "lerro kopurura", -DlgSelectChkMulti : "Hautaketa anitzak baimendu", -DlgSelectOpAvail : "Aukera Eskuragarriak", -DlgSelectOpText : "Testua", -DlgSelectOpValue : "Balorea", -DlgSelectBtnAdd : "Gehitu", -DlgSelectBtnModify : "Aldatu", -DlgSelectBtnUp : "Gora", -DlgSelectBtnDown : "Behera", -DlgSelectBtnSetValue : "Aukeratutako balorea ezarri", -DlgSelectBtnDelete : "Ezabatu", - -// Textarea Dialog -DlgTextareaName : "Izena", -DlgTextareaCols : "Zutabeak", -DlgTextareaRows : "Lerroak", - -// Text Field Dialog -DlgTextName : "Izena", -DlgTextValue : "Balorea", -DlgTextCharWidth : "Zabalera", -DlgTextMaxChars : "Zenbat karaktere gehienez", -DlgTextType : "Mota", -DlgTextTypeText : "Testua", -DlgTextTypePass : "Pasahitza", - -// Hidden Field Dialog -DlgHiddenName : "Izena", -DlgHiddenValue : "Balorea", - -// Bulleted List Dialog -BulletedListProp : "Buletdun Zerrendaren Ezarpenak", -NumberedListProp : "Zenbakidun Zerrendaren Ezarpenak", -DlgLstStart : "Hasiera", -DlgLstType : "Mota", -DlgLstTypeCircle : "Zirkulua", -DlgLstTypeDisc : "Diskoa", -DlgLstTypeSquare : "Karratua", -DlgLstTypeNumbers : "Zenbakiak (1, 2, 3)", -DlgLstTypeLCase : "Letra xeheak (a, b, c)", -DlgLstTypeUCase : "Letra larriak (A, B, C)", -DlgLstTypeSRoman : "Erromatar zenbaki zeheak (i, ii, iii)", -DlgLstTypeLRoman : "Erromatar zenbaki larriak (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Orokorra", -DlgDocBackTab : "Atzealdea", -DlgDocColorsTab : "Koloreak eta Marjinak", -DlgDocMetaTab : "Meta Informazioa", - -DlgDocPageTitle : "Orriaren Izenburua", -DlgDocLangDir : "Hizkuntzaren Norabidea", -DlgDocLangDirLTR : "Ezkerretik eskumara (LTR)", -DlgDocLangDirRTL : "Eskumatik ezkerrera (RTL)", -DlgDocLangCode : "Hizkuntzaren Kodea", -DlgDocCharSet : "Karaktere Multzoaren Kodeketa", -DlgDocCharSetCE : "Erdialdeko Europakoa", -DlgDocCharSetCT : "Txinatar Tradizionala (Big5)", -DlgDocCharSetCR : "Zirilikoa", -DlgDocCharSetGR : "Grekoa", -DlgDocCharSetJP : "Japoniarra", -DlgDocCharSetKR : "Korearra", -DlgDocCharSetTR : "Turkiarra", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Mendebaldeko Europakoa", -DlgDocCharSetOther : "Beste Karaktere Multzoko Kodeketa", - -DlgDocDocType : "Document Type Goiburua", -DlgDocDocTypeOther : "Beste Document Type Goiburua", -DlgDocIncXHTML : "XHTML Ezarpenak", -DlgDocBgColor : "Atzeko Kolorea", -DlgDocBgImage : "Atzeko Irudiaren URL-a", -DlgDocBgNoScroll : "Korritze gabeko Atzealdea", -DlgDocCText : "Testua", -DlgDocCLink : "Estekak", -DlgDocCVisited : "Bisitatutako Estekak", -DlgDocCActive : "Esteka Aktiboa", -DlgDocMargins : "Orrialdearen marjinak", -DlgDocMaTop : "Goian", -DlgDocMaLeft : "Ezkerrean", -DlgDocMaRight : "Eskuman", -DlgDocMaBottom : "Behean", -DlgDocMeIndex : "Dokumentuaren Gako-hitzak (komarekin bananduta)", -DlgDocMeDescr : "Dokumentuaren Deskribapena", -DlgDocMeAuthor : "Egilea", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Aurrebista", - -// Templates Dialog -Templates : "Txantiloiak", -DlgTemplatesTitle : "Eduki Txantiloiak", -DlgTemplatesSelMsg : "Mesedez txantiloia aukeratu editorean kargatzeko
    (orain dauden edukiak galduko dira):", -DlgTemplatesLoading : "Txantiloiak kargatzen. Itxaron mesedez...", -DlgTemplatesNoTpl : "(Ez dago definitutako txantiloirik)", -DlgTemplatesReplace : "Ordeztu oraingo edukiak", - -// About Dialog -DlgAboutAboutTab : "Honi buruz", -DlgAboutBrowserInfoTab : "Nabigatzailearen Informazioa", -DlgAboutLicenseTab : "Lizentzia", -DlgAboutVersion : "bertsioa", -DlgAboutInfo : "Informazio gehiago eskuratzeko hona joan", - -// Div Dialog -DlgDivGeneralTab : "Orokorra", -DlgDivAdvancedTab : "Aurreratua", -DlgDivStyle : "Estiloa", -DlgDivInlineStyle : "Inline Estiloa", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/fa.js b/httemplate/elements/fckeditor/editor/lang/fa.js deleted file mode 100644 index 3ca577c2d..000000000 --- a/httemplate/elements/fckeditor/editor/lang/fa.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Persian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "rtl", - -ToolbarCollapse : "برچیدن نوارابزار", -ToolbarExpand : "گستردن نوارابزار", - -// Toolbar Items and Context Menu -Save : "ذخیره", -NewPage : "برگهٴ تازه", -Preview : "پیش‌نمایش", -Cut : "برش", -Copy : "کپی", -Paste : "چسباندن", -PasteText : "چسباندن به عنوان متن ِساده", -PasteWord : "چسباندن از Word", -Print : "چاپ", -SelectAll : "گزینش همه", -RemoveFormat : "برداشتن فرمت", -InsertLinkLbl : "پیوند", -InsertLink : "گنجاندن/ویرایش ِپیوند", -RemoveLink : "برداشتن پیوند", -VisitLink : "باز کردن پیوند", -Anchor : "گنجاندن/ویرایش ِلنگر", -AnchorDelete : "برداشتن لنگر", -InsertImageLbl : "تصویر", -InsertImage : "گنجاندن/ویرایش ِتصویر", -InsertFlashLbl : "Flash", -InsertFlash : "گنجاندن/ویرایش ِFlash", -InsertTableLbl : "جدول", -InsertTable : "گنجاندن/ویرایش ِجدول", -InsertLineLbl : "خط", -InsertLine : "گنجاندن خط ِافقی", -InsertSpecialCharLbl: "نویسهٴ ویژه", -InsertSpecialChar : "گنجاندن نویسهٴ ویژه", -InsertSmileyLbl : "خندانک", -InsertSmiley : "گنجاندن خندانک", -About : "دربارهٴ FCKeditor", -Bold : "درشت", -Italic : "خمیده", -Underline : "خط‌زیردار", -StrikeThrough : "میان‌خط", -Subscript : "زیرنویس", -Superscript : "بالانویس", -LeftJustify : "چپ‌چین", -CenterJustify : "میان‌چین", -RightJustify : "راست‌چین", -BlockJustify : "بلوک‌چین", -DecreaseIndent : "کاهش تورفتگی", -IncreaseIndent : "افزایش تورفتگی", -Blockquote : "بلوک نقل قول", -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "واچیدن", -Redo : "بازچیدن", -NumberedListLbl : "فهرست شماره‌دار", -NumberedList : "گنجاندن/برداشتن فهرست شماره‌دار", -BulletedListLbl : "فهرست نقطه‌ای", -BulletedList : "گنجاندن/برداشتن فهرست نقطه‌ای", -ShowTableBorders : "نمایش لبهٴ جدول", -ShowDetails : "نمایش جزئیات", -Style : "سبک", -FontFormat : "فرمت", -Font : "قلم", -FontSize : "اندازه", -TextColor : "رنگ متن", -BGColor : "رنگ پس‌زمینه", -Source : "منبع", -Find : "جستجو", -Replace : "جایگزینی", -SpellCheck : "بررسی املا", -UniversalKeyboard : "صفحه‌کلید جهانی", -PageBreakLbl : "شکستگی ِپایان ِبرگه", -PageBreak : "گنجاندن شکستگی ِپایان ِبرگه", - -Form : "فرم", -Checkbox : "خانهٴ گزینه‌ای", -RadioButton : "دکمهٴ رادیویی", -TextField : "فیلد متنی", -Textarea : "ناحیهٴ متنی", -HiddenField : "فیلد پنهان", -Button : "دکمه", -SelectionField : "فیلد چندگزینه‌ای", -ImageButton : "دکمهٴ تصویری", - -FitWindow : "بیشینه‌سازی ِاندازهٴ ویرایشگر", -ShowBlocks : "نمایش بلوک‌ها", - -// Context Menu -EditLink : "ویرایش پیوند", -CellCM : "سلول", -RowCM : "سطر", -ColumnCM : "ستون", -InsertRowAfter : "افزودن سطر بعد از", -InsertRowBefore : "افزودن سطر قبل از", -DeleteRows : "حذف سطرها", -InsertColumnAfter : "افزودن ستون بعد از", -InsertColumnBefore : "افزودن ستون قبل از", -DeleteColumns : "حذف ستونها", -InsertCellAfter : "افزودن سلول بعد از", -InsertCellBefore : "افزودن سلول قبل از", -DeleteCells : "حذف سلولها", -MergeCells : "ادغام سلولها", -MergeRight : "ادغام به راست", -MergeDown : "ادغام به پایین", -HorizontalSplitCell : "جدا کردن افقی سلول", -VerticalSplitCell : "جدا کردن عمودی سلول", -TableDelete : "پاک‌کردن جدول", -CellProperties : "ویژگیهای سلول", -TableProperties : "ویژگیهای جدول", -ImageProperties : "ویژگیهای تصویر", -FlashProperties : "ویژگیهای Flash", - -AnchorProp : "ویژگیهای لنگر", -ButtonProp : "ویژگیهای دکمه", -CheckboxProp : "ویژگیهای خانهٴ گزینه‌ای", -HiddenFieldProp : "ویژگیهای فیلد پنهان", -RadioButtonProp : "ویژگیهای دکمهٴ رادیویی", -ImageButtonProp : "ویژگیهای دکمهٴ تصویری", -TextFieldProp : "ویژگیهای فیلد متنی", -SelectionFieldProp : "ویژگیهای فیلد چندگزینه‌ای", -TextareaProp : "ویژگیهای ناحیهٴ متنی", -FormProp : "ویژگیهای فرم", - -FontFormats : "نرمال;فرمت‌شده;آدرس;سرنویس 1;سرنویس 2;سرنویس 3;سرنویس 4;سرنویس 5;سرنویس 6;بند;(DIV)", - -// Alerts and Messages -ProcessingXHTML : "پردازش XHTML. لطفا صبر کنید...", -Done : "انجام شد", -PasteWordConfirm : "متنی که می‌خواهید بچسبانید به نظر می‌رسد از Word کپی شده است. آیا می‌خواهید قبل از چسباندن آن را پاک‌سازی کنید؟", -NotCompatiblePaste : "این فرمان برای مرورگر Internet Explorer از نگارش 5.5 یا بالاتر در دسترس است. آیا می‌خواهید بدون پاک‌سازی، متن را بچسبانید؟", -UnknownToolbarItem : "فقرهٴ نوارابزار ناشناخته \"%1\"", -UnknownCommand : "نام دستور ناشناخته \"%1\"", -NotImplemented : "دستور پیاده‌سازی‌نشده", -UnknownToolbarSet : "مجموعهٴ نوارابزار \"%1\" وجود ندارد", -NoActiveX : "تنظیمات امنیتی مرورگر شما ممکن است در بعضی از ویژگیهای مرورگر محدودیت ایجاد کند. شما باید گزینهٴ \"Run ActiveX controls and plug-ins\" را فعال کنید. ممکن است شما با خطاهایی روبرو باشید و متوجه کمبود ویژگیهایی شوید.", -BrowseServerBlocked : "توانایی بازگشایی مرورگر منابع فراهم نیست. اطمینان حاصل کنید که تمامی برنامه‌های پیشگیری از نمایش popup را از کار بازداشته‌اید.", -DialogBlocked : "توانایی بازگشایی پنجرهٴ کوچک ِگفتگو فراهم نیست. اطمینان حاصل کنید که تمامی برنامه‌های پیشگیری از نمایش popup را از کار بازداشته‌اید.", -VisitLinkBlocked : "امکان بازکردن یک پنجره جدید نیست. اطمینان حاصل کنید که تمامی برنامه‌های پیشگیری از نمایش popup را از کار بازداشته‌اید.", - -// Dialogs -DlgBtnOK : "پذیرش", -DlgBtnCancel : "انصراف", -DlgBtnClose : "بستن", -DlgBtnBrowseServer : "فهرست‌نمایی سرور", -DlgAdvancedTag : "پیشرفته", -DlgOpOther : "<غیره>", -DlgInfoTab : "اطلاعات", -DlgAlertUrl : "لطفاً URL را بنویسید", - -// General Dialogs Labels -DlgGenNotSet : "<تعین‌نشده>", -DlgGenId : "شناسه", -DlgGenLangDir : "جهت‌نمای زبان", -DlgGenLangDirLtr : "چپ به راست (LTR)", -DlgGenLangDirRtl : "راست به چپ (RTL)", -DlgGenLangCode : "کد زبان", -DlgGenAccessKey : "کلید دستیابی", -DlgGenName : "نام", -DlgGenTabIndex : "نمایهٴ دسترسی با Tab", -DlgGenLongDescr : "URL توصیف طولانی", -DlgGenClass : "کلاسهای شیوه‌نامه(Stylesheet)", -DlgGenTitle : "عنوان کمکی", -DlgGenContType : "نوع محتوای کمکی", -DlgGenLinkCharset : "نویسه‌گان منبع ِپیوندشده", -DlgGenStyle : "شیوه(style)", - -// Image Dialog -DlgImgTitle : "ویژگیهای تصویر", -DlgImgInfoTab : "اطلاعات تصویر", -DlgImgBtnUpload : "به سرور بفرست", -DlgImgURL : "URL", -DlgImgUpload : "انتقال به سرور", -DlgImgAlt : "متن جایگزین", -DlgImgWidth : "پهنا", -DlgImgHeight : "درازا", -DlgImgLockRatio : "قفل‌کردن ِنسبت", -DlgBtnResetSize : "بازنشانی اندازه", -DlgImgBorder : "لبه", -DlgImgHSpace : "فاصلهٴ افقی", -DlgImgVSpace : "فاصلهٴ عمودی", -DlgImgAlign : "چینش", -DlgImgAlignLeft : "چپ", -DlgImgAlignAbsBottom: "پائین مطلق", -DlgImgAlignAbsMiddle: "وسط مطلق", -DlgImgAlignBaseline : "خط‌پایه", -DlgImgAlignBottom : "پائین", -DlgImgAlignMiddle : "وسط", -DlgImgAlignRight : "راست", -DlgImgAlignTextTop : "متن بالا", -DlgImgAlignTop : "بالا", -DlgImgPreview : "پیش‌نمایش", -DlgImgAlertUrl : "لطفا URL تصویر را بنویسید", -DlgImgLinkTab : "پیوند", - -// Flash Dialog -DlgFlashTitle : "ویژگیهای Flash", -DlgFlashChkPlay : "آغاز ِخودکار", -DlgFlashChkLoop : "اجرای پیاپی", -DlgFlashChkMenu : "دردسترس‌بودن منوی Flash", -DlgFlashScale : "مقیاس", -DlgFlashScaleAll : "نمایش همه", -DlgFlashScaleNoBorder : "بدون کران", -DlgFlashScaleFit : "جایگیری کامل", - -// Link Dialog -DlgLnkWindowTitle : "پیوند", -DlgLnkInfoTab : "اطلاعات پیوند", -DlgLnkTargetTab : "مقصد", - -DlgLnkType : "نوع پیوند", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "لنگر در همین صفحه", -DlgLnkTypeEMail : "پست الکترونیکی", -DlgLnkProto : "پروتکل", -DlgLnkProtoOther : "<دیگر>", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "یک لنگر برگزینید", -DlgLnkAnchorByName : "با نام لنگر", -DlgLnkAnchorById : "با شناسهٴ المان", -DlgLnkNoAnchors : "(در این سند لنگری دردسترس نیست)", -DlgLnkEMail : "نشانی پست الکترونیکی", -DlgLnkEMailSubject : "موضوع پیام", -DlgLnkEMailBody : "متن پیام", -DlgLnkUpload : "انتقال به سرور", -DlgLnkBtnUpload : "به سرور بفرست", - -DlgLnkTarget : "مقصد", -DlgLnkTargetFrame : "<فریم>", -DlgLnkTargetPopup : "<پنجرهٴ پاپاپ>", -DlgLnkTargetBlank : "پنجرهٴ دیگر (_blank)", -DlgLnkTargetParent : "پنجرهٴ والد (_parent)", -DlgLnkTargetSelf : "همان پنجره (_self)", -DlgLnkTargetTop : "بالاترین پنجره (_top)", -DlgLnkTargetFrameName : "نام فریم مقصد", -DlgLnkPopWinName : "نام پنجرهٴ پاپاپ", -DlgLnkPopWinFeat : "ویژگیهای پنجرهٴ پاپاپ", -DlgLnkPopResize : "قابل تغییر اندازه", -DlgLnkPopLocation : "نوار موقعیت", -DlgLnkPopMenu : "نوار منو", -DlgLnkPopScroll : "میله‌های پیمایش", -DlgLnkPopStatus : "نوار وضعیت", -DlgLnkPopToolbar : "نوارابزار", -DlgLnkPopFullScrn : "تمام‌صفحه (IE)", -DlgLnkPopDependent : "وابسته (Netscape)", -DlgLnkPopWidth : "پهنا", -DlgLnkPopHeight : "درازا", -DlgLnkPopLeft : "موقعیت ِچپ", -DlgLnkPopTop : "موقعیت ِبالا", - -DlnLnkMsgNoUrl : "لطفا URL پیوند را بنویسید", -DlnLnkMsgNoEMail : "لطفا نشانی پست الکترونیکی را بنویسید", -DlnLnkMsgNoAnchor : "لطفا لنگری را برگزینید", -DlnLnkMsgInvPopName : "نام پنجرهٴ پاپاپ باید با یک نویسهٴ الفبایی آغاز گردد و نباید فاصله‌های خالی در آن باشند", - -// Color Dialog -DlgColorTitle : "گزینش رنگ", -DlgColorBtnClear : "پاک‌کردن", -DlgColorHighlight : "نمونه", -DlgColorSelected : "برگزیده", - -// Smiley Dialog -DlgSmileyTitle : "گنجاندن خندانک", - -// Special Character Dialog -DlgSpecialCharTitle : "گزینش نویسهٴ‌ویژه", - -// Table Dialog -DlgTableTitle : "ویژگیهای جدول", -DlgTableRows : "سطرها", -DlgTableColumns : "ستونها", -DlgTableBorder : "اندازهٴ لبه", -DlgTableAlign : "چینش", -DlgTableAlignNotSet : "<تعین‌نشده>", -DlgTableAlignLeft : "چپ", -DlgTableAlignCenter : "وسط", -DlgTableAlignRight : "راست", -DlgTableWidth : "پهنا", -DlgTableWidthPx : "پیکسل", -DlgTableWidthPc : "درصد", -DlgTableHeight : "درازا", -DlgTableCellSpace : "فاصلهٴ میان سلولها", -DlgTableCellPad : "فاصلهٴ پرشده در سلول", -DlgTableCaption : "عنوان", -DlgTableSummary : "خلاصه", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "ویژگیهای سلول", -DlgCellWidth : "پهنا", -DlgCellWidthPx : "پیکسل", -DlgCellWidthPc : "درصد", -DlgCellHeight : "درازا", -DlgCellWordWrap : "شکستن واژه‌ها", -DlgCellWordWrapNotSet : "<تعین‌نشده>", -DlgCellWordWrapYes : "بله", -DlgCellWordWrapNo : "خیر", -DlgCellHorAlign : "چینش ِافقی", -DlgCellHorAlignNotSet : "<تعین‌نشده>", -DlgCellHorAlignLeft : "چپ", -DlgCellHorAlignCenter : "وسط", -DlgCellHorAlignRight: "راست", -DlgCellVerAlign : "چینش ِعمودی", -DlgCellVerAlignNotSet : "<تعین‌نشده>", -DlgCellVerAlignTop : "بالا", -DlgCellVerAlignMiddle : "میان", -DlgCellVerAlignBottom : "پائین", -DlgCellVerAlignBaseline : "خط‌پایه", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "گستردگی سطرها", -DlgCellCollSpan : "گستردگی ستونها", -DlgCellBackColor : "رنگ پس‌زمینه", -DlgCellBorderColor : "رنگ لبه", -DlgCellBtnSelect : "برگزینید...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "جستجو و جایگزینی", - -// Find Dialog -DlgFindTitle : "یافتن", -DlgFindFindBtn : "یافتن", -DlgFindNotFoundMsg : "متن موردنظر یافت نشد.", - -// Replace Dialog -DlgReplaceTitle : "جایگزینی", -DlgReplaceFindLbl : "چه‌چیز را می‌یابید:", -DlgReplaceReplaceLbl : "جایگزینی با:", -DlgReplaceCaseChk : "همسانی در بزرگی و کوچکی نویسه‌ها", -DlgReplaceReplaceBtn : "جایگزینی", -DlgReplaceReplAllBtn : "جایگزینی همهٴ یافته‌ها", -DlgReplaceWordChk : "همسانی با واژهٴ کامل", - -// Paste Operations / Dialog -PasteErrorCut : "تنظیمات امنیتی مرورگر شما اجازه نمی‌دهد که ویرایشگر به طور خودکار عملکردهای برش را انجام دهد. لطفا با دکمه‌های صفحه‌کلید این کار را انجام دهید (Ctrl+X).", -PasteErrorCopy : "تنظیمات امنیتی مرورگر شما اجازه نمی‌دهد که ویرایشگر به طور خودکار عملکردهای کپی‌کردن را انجام دهد. لطفا با دکمه‌های صفحه‌کلید این کار را انجام دهید (Ctrl+C).", - -PasteAsText : "چسباندن به عنوان متن ِساده", -PasteFromWord : "چسباندن از Word", - -DlgPasteMsg2 : "لطفا متن را با کلیدهای (Ctrl+V) در این جعبهٴ متنی بچسبانید و پذیرش را بزنید.", -DlgPasteSec : "به خاطر تنظیمات امنیتی مرورگر شما، ویرایشگر نمی‌تواند دسترسی مستقیم به داده‌های clipboard داشته باشد. شما باید دوباره آنرا در این پنجره بچسبانید.", -DlgPasteIgnoreFont : "چشم‌پوشی از تعاریف نوع قلم", -DlgPasteRemoveStyles : "چشم‌پوشی از تعاریف سبک (style)", - -// Color Picker -ColorAutomatic : "خودکار", -ColorMoreColors : "رنگهای بیشتر...", - -// Document Properties -DocProps : "ویژگیهای سند", - -// Anchor Dialog -DlgAnchorTitle : "ویژگیهای لنگر", -DlgAnchorName : "نام لنگر", -DlgAnchorErrorName : "لطفا نام لنگر را بنویسید", - -// Speller Pages Dialog -DlgSpellNotInDic : "در واژه‌نامه یافت نشد", -DlgSpellChangeTo : "تغییر به", -DlgSpellBtnIgnore : "چشم‌پوشی", -DlgSpellBtnIgnoreAll : "چشم‌پوشی همه", -DlgSpellBtnReplace : "جایگزینی", -DlgSpellBtnReplaceAll : "جایگزینی همه", -DlgSpellBtnUndo : "واچینش", -DlgSpellNoSuggestions : "- پیشنهادی نیست -", -DlgSpellProgress : "بررسی املا در حال انجام...", -DlgSpellNoMispell : "بررسی املا انجام شد. هیچ غلط‌املائی یافت نشد", -DlgSpellNoChanges : "بررسی املا انجام شد. هیچ واژه‌ای تغییر نیافت", -DlgSpellOneChange : "بررسی املا انجام شد. یک واژه تغییر یافت", -DlgSpellManyChanges : "بررسی املا انجام شد. %1 واژه تغییر یافت", - -IeSpellDownload : "بررسی‌کنندهٴ املا نصب نشده است. آیا می‌خواهید آن را هم‌اکنون دریافت کنید؟", - -// Button Dialog -DlgButtonText : "متن (مقدار)", -DlgButtonType : "نوع", -DlgButtonTypeBtn : "دکمه", -DlgButtonTypeSbm : "Submit", -DlgButtonTypeRst : "بازنشانی (Reset)", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "نام", -DlgCheckboxValue : "مقدار", -DlgCheckboxSelected : "برگزیده", - -// Form Dialog -DlgFormName : "نام", -DlgFormAction : "رویداد", -DlgFormMethod : "متد", - -// Select Field Dialog -DlgSelectName : "نام", -DlgSelectValue : "مقدار", -DlgSelectSize : "اندازه", -DlgSelectLines : "خطوط", -DlgSelectChkMulti : "گزینش چندگانه فراهم باشد", -DlgSelectOpAvail : "گزینه‌های دردسترس", -DlgSelectOpText : "متن", -DlgSelectOpValue : "مقدار", -DlgSelectBtnAdd : "افزودن", -DlgSelectBtnModify : "ویرایش", -DlgSelectBtnUp : "بالا", -DlgSelectBtnDown : "پائین", -DlgSelectBtnSetValue : "تنظیم به عنوان مقدار ِبرگزیده", -DlgSelectBtnDelete : "پاک‌کردن", - -// Textarea Dialog -DlgTextareaName : "نام", -DlgTextareaCols : "ستونها", -DlgTextareaRows : "سطرها", - -// Text Field Dialog -DlgTextName : "نام", -DlgTextValue : "مقدار", -DlgTextCharWidth : "پهنای نویسه", -DlgTextMaxChars : "بیشینهٴ نویسه‌ها", -DlgTextType : "نوع", -DlgTextTypeText : "متن", -DlgTextTypePass : "گذرواژه", - -// Hidden Field Dialog -DlgHiddenName : "نام", -DlgHiddenValue : "مقدار", - -// Bulleted List Dialog -BulletedListProp : "ویژگیهای فهرست نقطه‌ای", -NumberedListProp : "ویژگیهای فهرست شماره‌دار", -DlgLstStart : "آغاز", -DlgLstType : "نوع", -DlgLstTypeCircle : "دایره", -DlgLstTypeDisc : "قرص", -DlgLstTypeSquare : "چهارگوش", -DlgLstTypeNumbers : "شماره‌ها (1، 2، 3)", -DlgLstTypeLCase : "نویسه‌های کوچک (a، b، c)", -DlgLstTypeUCase : "نویسه‌های بزرگ (A، B، C)", -DlgLstTypeSRoman : "شمارگان رومی کوچک (i، ii، iii)", -DlgLstTypeLRoman : "شمارگان رومی بزرگ (I، II، III)", - -// Document Properties Dialog -DlgDocGeneralTab : "عمومی", -DlgDocBackTab : "پس‌زمینه", -DlgDocColorsTab : "رنگها و حاشیه‌ها", -DlgDocMetaTab : "فراداده", - -DlgDocPageTitle : "عنوان صفحه", -DlgDocLangDir : "جهت زبان", -DlgDocLangDirLTR : "چپ به راست (LTR(", -DlgDocLangDirRTL : "راست به چپ (RTL(", -DlgDocLangCode : "کد زبان", -DlgDocCharSet : "رمزگذاری نویسه‌گان", -DlgDocCharSetCE : "اروپای مرکزی", -DlgDocCharSetCT : "چینی رسمی (Big5)", -DlgDocCharSetCR : "سیریلیک", -DlgDocCharSetGR : "یونانی", -DlgDocCharSetJP : "ژاپنی", -DlgDocCharSetKR : "کره‌ای", -DlgDocCharSetTR : "ترکی", -DlgDocCharSetUN : "یونیکُد (UTF-8)", -DlgDocCharSetWE : "اروپای غربی", -DlgDocCharSetOther : "رمزگذاری نویسه‌گان دیگر", - -DlgDocDocType : "عنوان نوع سند", -DlgDocDocTypeOther : "عنوان نوع سند دیگر", -DlgDocIncXHTML : "شامل تعاریف XHTML", -DlgDocBgColor : "رنگ پس‌زمینه", -DlgDocBgImage : "URL تصویر پس‌زمینه", -DlgDocBgNoScroll : "پس‌زمینهٴ پیمایش‌ناپذیر", -DlgDocCText : "متن", -DlgDocCLink : "پیوند", -DlgDocCVisited : "پیوند مشاهده‌شده", -DlgDocCActive : "پیوند فعال", -DlgDocMargins : "حاشیه‌های صفحه", -DlgDocMaTop : "بالا", -DlgDocMaLeft : "چپ", -DlgDocMaRight : "راست", -DlgDocMaBottom : "پایین", -DlgDocMeIndex : "کلیدواژگان نمایه‌گذاری سند (با کاما جدا شوند)", -DlgDocMeDescr : "توصیف سند", -DlgDocMeAuthor : "نویسنده", -DlgDocMeCopy : "کپی‌رایت", -DlgDocPreview : "پیش‌نمایش", - -// Templates Dialog -Templates : "الگوها", -DlgTemplatesTitle : "الگوهای محتویات", -DlgTemplatesSelMsg : "لطفا الگوی موردنظر را برای بازکردن در ویرایشگر برگزینید
    (محتویات کنونی از دست خواهند رفت):", -DlgTemplatesLoading : "بارگذاری فهرست الگوها. لطفا صبر کنید...", -DlgTemplatesNoTpl : "(الگوئی تعریف نشده است)", -DlgTemplatesReplace : "محتویات کنونی جایگزین شوند", - -// About Dialog -DlgAboutAboutTab : "درباره", -DlgAboutBrowserInfoTab : "اطلاعات مرورگر", -DlgAboutLicenseTab : "گواهینامه", -DlgAboutVersion : "نگارش", -DlgAboutInfo : "برای آگاهی بیشتر به این نشانی بروید", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/fi.js b/httemplate/elements/fckeditor/editor/lang/fi.js deleted file mode 100644 index 00f9e1c54..000000000 --- a/httemplate/elements/fckeditor/editor/lang/fi.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Finnish language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Piilota työkalurivi", -ToolbarExpand : "Näytä työkalurivi", - -// Toolbar Items and Context Menu -Save : "Tallenna", -NewPage : "Tyhjennä", -Preview : "Esikatsele", -Cut : "Leikkaa", -Copy : "Kopioi", -Paste : "Liitä", -PasteText : "Liitä tekstinä", -PasteWord : "Liitä Wordista", -Print : "Tulosta", -SelectAll : "Valitse kaikki", -RemoveFormat : "Poista muotoilu", -InsertLinkLbl : "Linkki", -InsertLink : "Lisää linkki/muokkaa linkkiä", -RemoveLink : "Poista linkki", -VisitLink : "Avaa linkki", -Anchor : "Lisää ankkuri/muokkaa ankkuria", -AnchorDelete : "Poista ankkuri", -InsertImageLbl : "Kuva", -InsertImage : "Lisää kuva/muokkaa kuvaa", -InsertFlashLbl : "Flash", -InsertFlash : "Lisää/muokkaa Flashia", -InsertTableLbl : "Taulu", -InsertTable : "Lisää taulu/muokkaa taulua", -InsertLineLbl : "Murtoviiva", -InsertLine : "Lisää murtoviiva", -InsertSpecialCharLbl: "Erikoismerkki", -InsertSpecialChar : "Lisää erikoismerkki", -InsertSmileyLbl : "Hymiö", -InsertSmiley : "Lisää hymiö", -About : "FCKeditorista", -Bold : "Lihavoitu", -Italic : "Kursivoitu", -Underline : "Alleviivattu", -StrikeThrough : "Yliviivattu", -Subscript : "Alaindeksi", -Superscript : "Yläindeksi", -LeftJustify : "Tasaa vasemmat reunat", -CenterJustify : "Keskitä", -RightJustify : "Tasaa oikeat reunat", -BlockJustify : "Tasaa molemmat reunat", -DecreaseIndent : "Pienennä sisennystä", -IncreaseIndent : "Suurenna sisennystä", -Blockquote : "Lainaus", -CreateDiv : "Lisää Div", -EditDiv : "Muokkaa Div:ä", -DeleteDiv : "Poista Div", -Undo : "Kumoa", -Redo : "Toista", -NumberedListLbl : "Numerointi", -NumberedList : "Lisää/poista numerointi", -BulletedListLbl : "Luottelomerkit", -BulletedList : "Lisää/poista luottelomerkit", -ShowTableBorders : "Näytä taulun rajat", -ShowDetails : "Näytä muotoilu", -Style : "Tyyli", -FontFormat : "Muotoilu", -Font : "Fontti", -FontSize : "Koko", -TextColor : "Tekstiväri", -BGColor : "Taustaväri", -Source : "Koodi", -Find : "Etsi", -Replace : "Korvaa", -SpellCheck : "Tarkista oikeinkirjoitus", -UniversalKeyboard : "Universaali näppäimistö", -PageBreakLbl : "Sivun vaihto", -PageBreak : "Lisää sivun vaihto", - -Form : "Lomake", -Checkbox : "Valintaruutu", -RadioButton : "Radiopainike", -TextField : "Tekstikenttä", -Textarea : "Tekstilaatikko", -HiddenField : "Piilokenttä", -Button : "Painike", -SelectionField : "Valintakenttä", -ImageButton : "Kuvapainike", - -FitWindow : "Suurenna editori koko ikkunaan", -ShowBlocks : "Näytä elementit", - -// Context Menu -EditLink : "Muokkaa linkkiä", -CellCM : "Solu", -RowCM : "Rivi", -ColumnCM : "Sarake", -InsertRowAfter : "Lisää rivi alapuolelle", -InsertRowBefore : "Lisää rivi yläpuolelle", -DeleteRows : "Poista rivit", -InsertColumnAfter : "Lisää sarake oikealle", -InsertColumnBefore : "Lisää sarake vasemmalle", -DeleteColumns : "Poista sarakkeet", -InsertCellAfter : "Lisää solu perään", -InsertCellBefore : "Lisää solu eteen", -DeleteCells : "Poista solut", -MergeCells : "Yhdistä solut", -MergeRight : "Yhdistä oikealla olevan kanssa", -MergeDown : "Yhdistä alla olevan kanssa", -HorizontalSplitCell : "Jaa solu vaakasuunnassa", -VerticalSplitCell : "Jaa solu pystysuunnassa", -TableDelete : "Poista taulu", -CellProperties : "Solun ominaisuudet", -TableProperties : "Taulun ominaisuudet", -ImageProperties : "Kuvan ominaisuudet", -FlashProperties : "Flash ominaisuudet", - -AnchorProp : "Ankkurin ominaisuudet", -ButtonProp : "Painikkeen ominaisuudet", -CheckboxProp : "Valintaruudun ominaisuudet", -HiddenFieldProp : "Piilokentän ominaisuudet", -RadioButtonProp : "Radiopainikkeen ominaisuudet", -ImageButtonProp : "Kuvapainikkeen ominaisuudet", -TextFieldProp : "Tekstikentän ominaisuudet", -SelectionFieldProp : "Valintakentän ominaisuudet", -TextareaProp : "Tekstilaatikon ominaisuudet", -FormProp : "Lomakkeen ominaisuudet", - -FontFormats : "Normaali;Muotoiltu;Osoite;Otsikko 1;Otsikko 2;Otsikko 3;Otsikko 4;Otsikko 5;Otsikko 6", - -// Alerts and Messages -ProcessingXHTML : "Prosessoidaan XHTML:ää. Odota hetki...", -Done : "Valmis", -PasteWordConfirm : "Teksti, jonka haluat liittää, näyttää olevan kopioitu Wordista. Haluatko puhdistaa sen ennen liittämistä?", -NotCompatiblePaste : "Tämä komento toimii vain Internet Explorer 5.5:ssa tai uudemmassa. Haluatko liittää ilman puhdistusta?", -UnknownToolbarItem : "Tuntemanton työkalu \"%1\"", -UnknownCommand : "Tuntematon komento \"%1\"", -NotImplemented : "Komentoa ei ole liitetty sovellukseen", -UnknownToolbarSet : "Työkalukokonaisuus \"%1\" ei ole olemassa", -NoActiveX : "Selaimesi turvallisuusasetukset voivat rajoittaa joitain editorin ominaisuuksia. Sinun pitää ottaa käyttöön asetuksista \"Suorita ActiveX komponentit ja -plugin-laajennukset\". Saatat kohdata virheitä ja huomata puuttuvia ominaisuuksia.", -BrowseServerBlocked : "Resurssiselainta ei voitu avata. Varmista, että ponnahdusikkunoiden estäjät eivät ole päällä.", -DialogBlocked : "Apuikkunaa ei voitu avaata. Varmista, että ponnahdusikkunoiden estäjät eivät ole päällä.", -VisitLinkBlocked : "IUutta ikkunaa ei voitu avata. Varmista, että ponnahdusikkunoiden estäjät eivät ole päällä.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Peruuta", -DlgBtnClose : "Sulje", -DlgBtnBrowseServer : "Selaa palvelinta", -DlgAdvancedTag : "Lisäominaisuudet", -DlgOpOther : "Muut", -DlgInfoTab : "Info", -DlgAlertUrl : "Lisää URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Tunniste", -DlgGenLangDir : "Kielen suunta", -DlgGenLangDirLtr : "Vasemmalta oikealle (LTR)", -DlgGenLangDirRtl : "Oikealta vasemmalle (RTL)", -DlgGenLangCode : "Kielikoodi", -DlgGenAccessKey : "Pikanäppäin", -DlgGenName : "Nimi", -DlgGenTabIndex : "Tabulaattori indeksi", -DlgGenLongDescr : "Pitkän kuvauksen URL", -DlgGenClass : "Tyyliluokat", -DlgGenTitle : "Avustava otsikko", -DlgGenContType : "Avustava sisällön tyyppi", -DlgGenLinkCharset : "Linkitetty kirjaimisto", -DlgGenStyle : "Tyyli", - -// Image Dialog -DlgImgTitle : "Kuvan ominaisuudet", -DlgImgInfoTab : "Kuvan tiedot", -DlgImgBtnUpload : "Lähetä palvelimelle", -DlgImgURL : "Osoite", -DlgImgUpload : "Lisää kuva", -DlgImgAlt : "Vaihtoehtoinen teksti", -DlgImgWidth : "Leveys", -DlgImgHeight : "Korkeus", -DlgImgLockRatio : "Lukitse suhteet", -DlgBtnResetSize : "Alkuperäinen koko", -DlgImgBorder : "Raja", -DlgImgHSpace : "Vaakatila", -DlgImgVSpace : "Pystytila", -DlgImgAlign : "Kohdistus", -DlgImgAlignLeft : "Vasemmalle", -DlgImgAlignAbsBottom: "Aivan alas", -DlgImgAlignAbsMiddle: "Aivan keskelle", -DlgImgAlignBaseline : "Alas (teksti)", -DlgImgAlignBottom : "Alas", -DlgImgAlignMiddle : "Keskelle", -DlgImgAlignRight : "Oikealle", -DlgImgAlignTextTop : "Ylös (teksti)", -DlgImgAlignTop : "Ylös", -DlgImgPreview : "Esikatselu", -DlgImgAlertUrl : "Kirjoita kuvan osoite (URL)", -DlgImgLinkTab : "Linkki", - -// Flash Dialog -DlgFlashTitle : "Flash ominaisuudet", -DlgFlashChkPlay : "Automaattinen käynnistys", -DlgFlashChkLoop : "Toisto", -DlgFlashChkMenu : "Näytä Flash-valikko", -DlgFlashScale : "Levitä", -DlgFlashScaleAll : "Näytä kaikki", -DlgFlashScaleNoBorder : "Ei rajaa", -DlgFlashScaleFit : "Tarkka koko", - -// Link Dialog -DlgLnkWindowTitle : "Linkki", -DlgLnkInfoTab : "Linkin tiedot", -DlgLnkTargetTab : "Kohde", - -DlgLnkType : "Linkkityyppi", -DlgLnkTypeURL : "Osoite", -DlgLnkTypeAnchor : "Ankkuri tässä sivussa", -DlgLnkTypeEMail : "Sähköposti", -DlgLnkProto : "Protokolla", -DlgLnkProtoOther : "", -DlgLnkURL : "Osoite", -DlgLnkAnchorSel : "Valitse ankkuri", -DlgLnkAnchorByName : "Ankkurin nimen mukaan", -DlgLnkAnchorById : "Ankkurin ID:n mukaan", -DlgLnkNoAnchors : "(Ei ankkureita tässä dokumentissa)", -DlgLnkEMail : "Sähköpostiosoite", -DlgLnkEMailSubject : "Aihe", -DlgLnkEMailBody : "Viesti", -DlgLnkUpload : "Lisää tiedosto", -DlgLnkBtnUpload : "Lähetä palvelimelle", - -DlgLnkTarget : "Kohde", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Uusi ikkuna (_blank)", -DlgLnkTargetParent : "Emoikkuna (_parent)", -DlgLnkTargetSelf : "Sama ikkuna (_self)", -DlgLnkTargetTop : "Päällimmäisin ikkuna (_top)", -DlgLnkTargetFrameName : "Kohdekehyksen nimi", -DlgLnkPopWinName : "Popup ikkunan nimi", -DlgLnkPopWinFeat : "Popup ikkunan ominaisuudet", -DlgLnkPopResize : "Venytettävä", -DlgLnkPopLocation : "Osoiterivi", -DlgLnkPopMenu : "Valikkorivi", -DlgLnkPopScroll : "Vierityspalkit", -DlgLnkPopStatus : "Tilarivi", -DlgLnkPopToolbar : "Vakiopainikkeet", -DlgLnkPopFullScrn : "Täysi ikkuna (IE)", -DlgLnkPopDependent : "Riippuva (Netscape)", -DlgLnkPopWidth : "Leveys", -DlgLnkPopHeight : "Korkeus", -DlgLnkPopLeft : "Vasemmalta (px)", -DlgLnkPopTop : "Ylhäältä (px)", - -DlnLnkMsgNoUrl : "Linkille on kirjoitettava URL", -DlnLnkMsgNoEMail : "Kirjoita sähköpostiosoite", -DlnLnkMsgNoAnchor : "Valitse ankkuri", -DlnLnkMsgInvPopName : "Popup-ikkunan nimi pitää alkaa aakkosella ja ei saa sisältää välejä", - -// Color Dialog -DlgColorTitle : "Valitse väri", -DlgColorBtnClear : "Tyhjennä", -DlgColorHighlight : "Kohdalla", -DlgColorSelected : "Valittu", - -// Smiley Dialog -DlgSmileyTitle : "Lisää hymiö", - -// Special Character Dialog -DlgSpecialCharTitle : "Valitse erikoismerkki", - -// Table Dialog -DlgTableTitle : "Taulun ominaisuudet", -DlgTableRows : "Rivit", -DlgTableColumns : "Sarakkeet", -DlgTableBorder : "Rajan paksuus", -DlgTableAlign : "Kohdistus", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Vasemmalle", -DlgTableAlignCenter : "Keskelle", -DlgTableAlignRight : "Oikealle", -DlgTableWidth : "Leveys", -DlgTableWidthPx : "pikseliä", -DlgTableWidthPc : "prosenttia", -DlgTableHeight : "Korkeus", -DlgTableCellSpace : "Solujen väli", -DlgTableCellPad : "Solujen sisennys", -DlgTableCaption : "Otsikko", -DlgTableSummary : "Yhteenveto", -DlgTableHeaders : "Ylätunnisteet", -DlgTableHeadersNone : "Ei ylätunnisteita", -DlgTableHeadersColumn : "Ensimmäinen sarake", -DlgTableHeadersRow : "Ensimmäinen rivi", -DlgTableHeadersBoth : "Molemmat", - -// Table Cell Dialog -DlgCellTitle : "Solun ominaisuudet", -DlgCellWidth : "Leveys", -DlgCellWidthPx : "pikseliä", -DlgCellWidthPc : "prosenttia", -DlgCellHeight : "Korkeus", -DlgCellWordWrap : "Tekstikierrätys", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Kyllä", -DlgCellWordWrapNo : "Ei", -DlgCellHorAlign : "Vaakakohdistus", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Vasemmalle", -DlgCellHorAlignCenter : "Keskelle", -DlgCellHorAlignRight: "Oikealle", -DlgCellVerAlign : "Pystykohdistus", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Ylös", -DlgCellVerAlignMiddle : "Keskelle", -DlgCellVerAlignBottom : "Alas", -DlgCellVerAlignBaseline : "Tekstin alas", -DlgCellType : "Solun tyyppi", -DlgCellTypeData : "Sisältö", -DlgCellTypeHeader : "Ylätunniste", -DlgCellRowSpan : "Rivin jatkuvuus", -DlgCellCollSpan : "Sarakkeen jatkuvuus", -DlgCellBackColor : "Taustaväri", -DlgCellBorderColor : "Rajan väri", -DlgCellBtnSelect : "Valitse...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Etsi ja korvaa", - -// Find Dialog -DlgFindTitle : "Etsi", -DlgFindFindBtn : "Etsi", -DlgFindNotFoundMsg : "Etsittyä tekstiä ei löytynyt.", - -// Replace Dialog -DlgReplaceTitle : "Korvaa", -DlgReplaceFindLbl : "Etsi mitä:", -DlgReplaceReplaceLbl : "Korvaa tällä:", -DlgReplaceCaseChk : "Sama kirjainkoko", -DlgReplaceReplaceBtn : "Korvaa", -DlgReplaceReplAllBtn : "Korvaa kaikki", -DlgReplaceWordChk : "Koko sana", - -// Paste Operations / Dialog -PasteErrorCut : "Selaimesi turva-asetukset eivät salli editorin toteuttaa leikkaamista. Käytä näppäimistöä leikkaamiseen (Ctrl+X).", -PasteErrorCopy : "Selaimesi turva-asetukset eivät salli editorin toteuttaa kopioimista. Käytä näppäimistöä kopioimiseen (Ctrl+C).", - -PasteAsText : "Liitä tekstinä", -PasteFromWord : "Liitä Wordista", - -DlgPasteMsg2 : "Liitä painamalla (Ctrl+V) ja painamalla OK.", -DlgPasteSec : "Selaimesi turva-asetukset eivät salli editorin käyttää leikepöytää suoraan. Sinun pitää suorittaa liittäminen tässä ikkunassa.", -DlgPasteIgnoreFont : "Jätä huomioimatta fonttimääritykset", -DlgPasteRemoveStyles : "Poista tyylimääritykset", - -// Color Picker -ColorAutomatic : "Automaattinen", -ColorMoreColors : "Lisää värejä...", - -// Document Properties -DocProps : "Dokumentin ominaisuudet", - -// Anchor Dialog -DlgAnchorTitle : "Ankkurin ominaisuudet", -DlgAnchorName : "Nimi", -DlgAnchorErrorName : "Ankkurille on kirjoitettava nimi", - -// Speller Pages Dialog -DlgSpellNotInDic : "Ei sanakirjassa", -DlgSpellChangeTo : "Vaihda", -DlgSpellBtnIgnore : "Jätä huomioimatta", -DlgSpellBtnIgnoreAll : "Jätä kaikki huomioimatta", -DlgSpellBtnReplace : "Korvaa", -DlgSpellBtnReplaceAll : "Korvaa kaikki", -DlgSpellBtnUndo : "Kumoa", -DlgSpellNoSuggestions : "Ei ehdotuksia", -DlgSpellProgress : "Tarkistus käynnissä...", -DlgSpellNoMispell : "Tarkistus valmis: Ei virheitä", -DlgSpellNoChanges : "Tarkistus valmis: Yhtään sanaa ei muutettu", -DlgSpellOneChange : "Tarkistus valmis: Yksi sana muutettiin", -DlgSpellManyChanges : "Tarkistus valmis: %1 sanaa muutettiin", - -IeSpellDownload : "Oikeinkirjoituksen tarkistusta ei ole asennettu. Haluatko ladata sen nyt?", - -// Button Dialog -DlgButtonText : "Teksti (arvo)", -DlgButtonType : "Tyyppi", -DlgButtonTypeBtn : "Painike", -DlgButtonTypeSbm : "Lähetä", -DlgButtonTypeRst : "Tyhjennä", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nimi", -DlgCheckboxValue : "Arvo", -DlgCheckboxSelected : "Valittu", - -// Form Dialog -DlgFormName : "Nimi", -DlgFormAction : "Toiminto", -DlgFormMethod : "Tapa", - -// Select Field Dialog -DlgSelectName : "Nimi", -DlgSelectValue : "Arvo", -DlgSelectSize : "Koko", -DlgSelectLines : "Rivit", -DlgSelectChkMulti : "Salli usea valinta", -DlgSelectOpAvail : "Ominaisuudet", -DlgSelectOpText : "Teksti", -DlgSelectOpValue : "Arvo", -DlgSelectBtnAdd : "Lisää", -DlgSelectBtnModify : "Muuta", -DlgSelectBtnUp : "Ylös", -DlgSelectBtnDown : "Alas", -DlgSelectBtnSetValue : "Aseta valituksi", -DlgSelectBtnDelete : "Poista", - -// Textarea Dialog -DlgTextareaName : "Nimi", -DlgTextareaCols : "Sarakkeita", -DlgTextareaRows : "Rivejä", - -// Text Field Dialog -DlgTextName : "Nimi", -DlgTextValue : "Arvo", -DlgTextCharWidth : "Leveys", -DlgTextMaxChars : "Maksimi merkkimäärä", -DlgTextType : "Tyyppi", -DlgTextTypeText : "Teksti", -DlgTextTypePass : "Salasana", - -// Hidden Field Dialog -DlgHiddenName : "Nimi", -DlgHiddenValue : "Arvo", - -// Bulleted List Dialog -BulletedListProp : "Luettelon ominaisuudet", -NumberedListProp : "Numeroinnin ominaisuudet", -DlgLstStart : "Alku", -DlgLstType : "Tyyppi", -DlgLstTypeCircle : "Kehä", -DlgLstTypeDisc : "Ympyrä", -DlgLstTypeSquare : "Neliö", -DlgLstTypeNumbers : "Numerot (1, 2, 3)", -DlgLstTypeLCase : "Pienet kirjaimet (a, b, c)", -DlgLstTypeUCase : "Isot kirjaimet (A, B, C)", -DlgLstTypeSRoman : "Pienet roomalaiset numerot (i, ii, iii)", -DlgLstTypeLRoman : "Isot roomalaiset numerot (Ii, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Yleiset", -DlgDocBackTab : "Tausta", -DlgDocColorsTab : "Värit ja marginaalit", -DlgDocMetaTab : "Meta-tieto", - -DlgDocPageTitle : "Sivun nimi", -DlgDocLangDir : "Kielen suunta", -DlgDocLangDirLTR : "Vasemmalta oikealle (LTR)", -DlgDocLangDirRTL : "Oikealta vasemmalle (RTL)", -DlgDocLangCode : "Kielikoodi", -DlgDocCharSet : "Merkistökoodaus", -DlgDocCharSetCE : "Keskieurooppalainen", -DlgDocCharSetCT : "Kiina, perinteinen (Big5)", -DlgDocCharSetCR : "Kyrillinen", -DlgDocCharSetGR : "Kreikka", -DlgDocCharSetJP : "Japani", -DlgDocCharSetKR : "Korealainen", -DlgDocCharSetTR : "Turkkilainen", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Länsieurooppalainen", -DlgDocCharSetOther : "Muu merkistökoodaus", - -DlgDocDocType : "Dokumentin tyyppi", -DlgDocDocTypeOther : "Muu dokumentin tyyppi", -DlgDocIncXHTML : "Lisää XHTML julistukset", -DlgDocBgColor : "Taustaväri", -DlgDocBgImage : "Taustakuva", -DlgDocBgNoScroll : "Paikallaanpysyvä tausta", -DlgDocCText : "Teksti", -DlgDocCLink : "Linkki", -DlgDocCVisited : "Vierailtu linkki", -DlgDocCActive : "Aktiivinen linkki", -DlgDocMargins : "Sivun marginaalit", -DlgDocMaTop : "Ylä", -DlgDocMaLeft : "Vasen", -DlgDocMaRight : "Oikea", -DlgDocMaBottom : "Ala", -DlgDocMeIndex : "Hakusanat (pilkulla erotettuna)", -DlgDocMeDescr : "Kuvaus", -DlgDocMeAuthor : "Tekijä", -DlgDocMeCopy : "Tekijänoikeudet", -DlgDocPreview : "Esikatselu", - -// Templates Dialog -Templates : "Pohjat", -DlgTemplatesTitle : "Sisältöpohjat", -DlgTemplatesSelMsg : "Valitse pohja editoriin
    (aiempi sisältö menetetään):", -DlgTemplatesLoading : "Ladataan listaa pohjista. Hetkinen...", -DlgTemplatesNoTpl : "(Ei määriteltyjä pohjia)", -DlgTemplatesReplace : "Korvaa editorin koko sisältö", - -// About Dialog -DlgAboutAboutTab : "Editorista", -DlgAboutBrowserInfoTab : "Selaimen tiedot", -DlgAboutLicenseTab : "Lisenssi", -DlgAboutVersion : "versio", -DlgAboutInfo : "Lisää tietoa osoitteesta", - -// Div Dialog -DlgDivGeneralTab : "Edistynyt", -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Tyyli", -DlgDivInlineStyle : "Rivin sisäinen tyyli", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/fo.js b/httemplate/elements/fckeditor/editor/lang/fo.js deleted file mode 100644 index e13b667a4..000000000 --- a/httemplate/elements/fckeditor/editor/lang/fo.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Faroese language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Fjal amboðsbjálkan", -ToolbarExpand : "Vís amboðsbjálkan", - -// Toolbar Items and Context Menu -Save : "Goym", -NewPage : "Nýggj síða", -Preview : "Frumsýning", -Cut : "Kvett", -Copy : "Avrita", -Paste : "Innrita", -PasteText : "Innrita reinan tekst", -PasteWord : "Innrita frá Word", -Print : "Prenta", -SelectAll : "Markera alt", -RemoveFormat : "Strika sniðgeving", -InsertLinkLbl : "Tilknýti", -InsertLink : "Ger/broyt tilknýti", -RemoveLink : "Strika tilknýti", -VisitLink : "Opna tilknýti", -Anchor : "Ger/broyt marknastein", -AnchorDelete : "Strika marknastein", -InsertImageLbl : "Myndir", -InsertImage : "Set inn/broyt mynd", -InsertFlashLbl : "Flash", -InsertFlash : "Set inn/broyt Flash", -InsertTableLbl : "Tabell", -InsertTable : "Set inn/broyt tabell", -InsertLineLbl : "Linja", -InsertLine : "Ger vatnrætta linju", -InsertSpecialCharLbl: "Sertekn", -InsertSpecialChar : "Set inn sertekn", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Set inn Smiley", -About : "Um FCKeditor", -Bold : "Feit skrift", -Italic : "Skráskrift", -Underline : "Undirstrikað", -StrikeThrough : "Yvirstrikað", -Subscript : "Lækkað skrift", -Superscript : "Hækkað skrift", -LeftJustify : "Vinstrasett", -CenterJustify : "Miðsett", -RightJustify : "Høgrasett", -BlockJustify : "Javnir tekstkantar", -DecreaseIndent : "Minka reglubrotarinntriv", -IncreaseIndent : "Økja reglubrotarinntriv", -Blockquote : "Blockquote", -CreateDiv : "Ger DIV øki", -EditDiv : "Broyt DIV øki", -DeleteDiv : "Strika DIV øki", -Undo : "Angra", -Redo : "Vend aftur", -NumberedListLbl : "Talmerktur listi", -NumberedList : "Ger/strika talmerktan lista", -BulletedListLbl : "Punktmerktur listi", -BulletedList : "Ger/strika punktmerktan lista", -ShowTableBorders : "Vís tabellbordar", -ShowDetails : "Vís í smálutum", -Style : "Typografi", -FontFormat : "Skriftsnið", -Font : "Skrift", -FontSize : "Skriftstødd", -TextColor : "Tekstlitur", -BGColor : "Bakgrundslitur", -Source : "Kelda", -Find : "Leita", -Replace : "Yvirskriva", -SpellCheck : "Kanna stavseting", -UniversalKeyboard : "Knappaborð", -PageBreakLbl : "Síðuskift", -PageBreak : "Ger síðuskift", - -Form : "Formur", -Checkbox : "Flugubein", -RadioButton : "Radioknøttur", -TextField : "Tekstteigur", -Textarea : "Tekstumráði", -HiddenField : "Fjaldur teigur", -Button : "Knøttur", -SelectionField : "Valskrá", -ImageButton : "Myndaknøttur", - -FitWindow : "Set tekstviðgera til fulla stødd", -ShowBlocks : "Vís blokkar", - -// Context Menu -EditLink : "Broyt tilknýti", -CellCM : "Meski", -RowCM : "Rað", -ColumnCM : "Kolonna", -InsertRowAfter : "Set rað inn aftaná", -InsertRowBefore : "Set rað inn áðrenn", -DeleteRows : "Strika røðir", -InsertColumnAfter : "Set kolonnu inn aftaná", -InsertColumnBefore : "Set kolonnu inn áðrenn", -DeleteColumns : "Strika kolonnur", -InsertCellAfter : "Set meska inn aftaná", -InsertCellBefore : "Set meska inn áðrenn", -DeleteCells : "Strika meskar", -MergeCells : "Flætta meskar", -MergeRight : "Flætta meskar til høgru", -MergeDown : "Flætta saman", -HorizontalSplitCell : "Kloyv meska vatnrætt", -VerticalSplitCell : "Kloyv meska loddrætt", -TableDelete : "Strika tabell", -CellProperties : "Meskueginleikar", -TableProperties : "Tabelleginleikar", -ImageProperties : "Myndaeginleikar", -FlashProperties : "Flash eginleikar", - -AnchorProp : "Eginleikar fyri marknastein", -ButtonProp : "Eginleikar fyri knøtt", -CheckboxProp : "Eginleikar fyri flugubein", -HiddenFieldProp : "Eginleikar fyri fjaldan teig", -RadioButtonProp : "Eginleikar fyri radioknøtt", -ImageButtonProp : "Eginleikar fyri myndaknøtt", -TextFieldProp : "Eginleikar fyri tekstteig", -SelectionFieldProp : "Eginleikar fyri valskrá", -TextareaProp : "Eginleikar fyri tekstumráði", -FormProp : "Eginleikar fyri Form", - -FontFormats : "Vanligt;Sniðgivið;Adressa;Yvirskrift 1;Yvirskrift 2;Yvirskrift 3;Yvirskrift 4;Yvirskrift 5;Yvirskrift 6", - -// Alerts and Messages -ProcessingXHTML : "XHTML verður viðgjørt. Bíða við...", -Done : "Liðugt", -PasteWordConfirm : "Teksturin, royndur verður at seta inn, tykist at stava frá Word. Vilt tú reinsa tekstin, áðrenn hann verður settur inn?", -NotCompatiblePaste : "Hetta er bert tøkt í Internet Explorer 5.5 og nýggjari. Vilt tú seta tekstin inn kortini - óreinsaðan?", -UnknownToolbarItem : "Ókendur lutur í amboðsbjálkanum \"%1\"", -UnknownCommand : "Ókend kommando \"%1\"", -NotImplemented : "Hetta er ikki tøkt í hesi útgávuni", -UnknownToolbarSet : "Amboðsbjálkin \"%1\" finst ikki", -NoActiveX : "Trygdaruppsetingin í alnótskaganum kann sum er avmarka onkrar hentleikar í tekstviðgeranum. Tú mást loyva møguleikanum \"Run/Kør ActiveX controls and plug-ins\". Tú kanst uppliva feilir og ávaringar um tvørrandi hentleikar.", -BrowseServerBlocked : "Ambætarakagin kundi ikki opnast. Tryggja tær, at allar pop-up forðingar eru óvirknar.", -DialogBlocked : "Tað eyðnaðist ikki at opna samskiftisrútin. Tryggja tær, at allar pop-up forðingar eru óvirknar.", -VisitLinkBlocked : "Tað eyðnaðist ikki at opna nýggjan rút. Tryggja tær, at allar pop-up forðingar eru óvirknar.", - -// Dialogs -DlgBtnOK : "Góðkent", -DlgBtnCancel : "Avlýst", -DlgBtnClose : "Lat aftur", -DlgBtnBrowseServer : "Ambætarakagi", -DlgAdvancedTag : "Fjølbroytt", -DlgOpOther : "", -DlgInfoTab : "Upplýsingar", -DlgAlertUrl : "Vinarliga veit ein URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Tekstkós", -DlgGenLangDirLtr : "Frá vinstru til høgru (LTR)", -DlgGenLangDirRtl : "Frá høgru til vinstru (RTL)", -DlgGenLangCode : "Málkoda", -DlgGenAccessKey : "Snarvegisknappur", -DlgGenName : "Navn", -DlgGenTabIndex : "Inntriv indeks", -DlgGenLongDescr : "Víðkað URL frágreiðing", -DlgGenClass : "Typografi klassar", -DlgGenTitle : "Vegleiðandi heiti", -DlgGenContType : "Vegleiðandi innihaldsslag", -DlgGenLinkCharset : "Atknýtt teknsett", -DlgGenStyle : "Typografi", - -// Image Dialog -DlgImgTitle : "Myndaeginleikar", -DlgImgInfoTab : "Myndaupplýsingar", -DlgImgBtnUpload : "Send til ambætaran", -DlgImgURL : "URL", -DlgImgUpload : "Send", -DlgImgAlt : "Alternativur tekstur", -DlgImgWidth : "Breidd", -DlgImgHeight : "Hædd", -DlgImgLockRatio : "Læs lutfallið", -DlgBtnResetSize : "Upprunastødd", -DlgImgBorder : "Bordi", -DlgImgHSpace : "Høgri breddi", -DlgImgVSpace : "Vinstri breddi", -DlgImgAlign : "Justering", -DlgImgAlignLeft : "Vinstra", -DlgImgAlignAbsBottom: "Abs botnur", -DlgImgAlignAbsMiddle: "Abs miðja", -DlgImgAlignBaseline : "Basislinja", -DlgImgAlignBottom : "Botnur", -DlgImgAlignMiddle : "Miðja", -DlgImgAlignRight : "Høgra", -DlgImgAlignTextTop : "Tekst toppur", -DlgImgAlignTop : "Ovast", -DlgImgPreview : "Frumsýning", -DlgImgAlertUrl : "Rita slóðina til myndina", -DlgImgLinkTab : "Tilknýti", - -// Flash Dialog -DlgFlashTitle : "Flash eginleikar", -DlgFlashChkPlay : "Avspælingin byrjar sjálv", -DlgFlashChkLoop : "Endurspæl", -DlgFlashChkMenu : "Ger Flash skrá virkna", -DlgFlashScale : "Skalering", -DlgFlashScaleAll : "Vís alt", -DlgFlashScaleNoBorder : "Eingin bordi", -DlgFlashScaleFit : "Neyv skalering", - -// Link Dialog -DlgLnkWindowTitle : "Tilknýti", -DlgLnkInfoTab : "Tilknýtis upplýsingar", -DlgLnkTargetTab : "Mál", - -DlgLnkType : "Tilknýtisslag", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Tilknýti til marknastein í tekstinum", -DlgLnkTypeEMail : "Teldupostur", -DlgLnkProto : "Protokoll", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Vel ein marknastein", -DlgLnkAnchorByName : "Eftir navni á marknasteini", -DlgLnkAnchorById : "Eftir element Id", -DlgLnkNoAnchors : "(Eingir marknasteinar eru í hesum dokumentið)", -DlgLnkEMail : "Teldupost-adressa", -DlgLnkEMailSubject : "Evni", -DlgLnkEMailBody : "Breyðtekstur", -DlgLnkUpload : "Send til ambætaran", -DlgLnkBtnUpload : "Send til ambætaran", - -DlgLnkTarget : "Mál", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nýtt vindeyga (_blank)", -DlgLnkTargetParent : "Upphavliga vindeygað (_parent)", -DlgLnkTargetSelf : "Sama vindeygað (_self)", -DlgLnkTargetTop : "Alt vindeygað (_top)", -DlgLnkTargetFrameName : "Vís navn vindeygans", -DlgLnkPopWinName : "Popup vindeygans navn", -DlgLnkPopWinFeat : "Popup vindeygans víðkaðu eginleikar", -DlgLnkPopResize : "Kann broyta stødd", -DlgLnkPopLocation : "Adressulinja", -DlgLnkPopMenu : "Skrábjálki", -DlgLnkPopScroll : "Rullibjálki", -DlgLnkPopStatus : "Støðufrágreiðingarbjálki", -DlgLnkPopToolbar : "Amboðsbjálki", -DlgLnkPopFullScrn : "Fullur skermur (IE)", -DlgLnkPopDependent : "Bundið (Netscape)", -DlgLnkPopWidth : "Breidd", -DlgLnkPopHeight : "Hædd", -DlgLnkPopLeft : "Frástøða frá vinstru", -DlgLnkPopTop : "Frástøða frá íerva", - -DlnLnkMsgNoUrl : "Vinarliga skriva tilknýti (URL)", -DlnLnkMsgNoEMail : "Vinarliga skriva teldupost-adressu", -DlnLnkMsgNoAnchor : "Vinarliga vel marknastein", -DlnLnkMsgInvPopName : "Popup navnið má byrja við bókstavi og má ikki hava millumrúm", - -// Color Dialog -DlgColorTitle : "Vel lit", -DlgColorBtnClear : "Strika alt", -DlgColorHighlight : "Framhevja", -DlgColorSelected : "Valt", - -// Smiley Dialog -DlgSmileyTitle : "Vel Smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Vel sertekn", - -// Table Dialog -DlgTableTitle : "Eginleikar fyri tabell", -DlgTableRows : "Røðir", -DlgTableColumns : "Kolonnur", -DlgTableBorder : "Bordabreidd", -DlgTableAlign : "Justering", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Vinstrasett", -DlgTableAlignCenter : "Miðsett", -DlgTableAlignRight : "Høgrasett", -DlgTableWidth : "Breidd", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "prosent", -DlgTableHeight : "Hædd", -DlgTableCellSpace : "Fjarstøða millum meskar", -DlgTableCellPad : "Meskubreddi", -DlgTableCaption : "Tabellfrágreiðing", -DlgTableSummary : "Samandráttur", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Mesku eginleikar", -DlgCellWidth : "Breidd", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "prosent", -DlgCellHeight : "Hædd", -DlgCellWordWrap : "Orðkloyving", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Ja", -DlgCellWordWrapNo : "Nei", -DlgCellHorAlign : "Vatnrøtt justering", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Vinstrasett", -DlgCellHorAlignCenter : "Miðsett", -DlgCellHorAlignRight: "Høgrasett", -DlgCellVerAlign : "Lodrøtt justering", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Ovast", -DlgCellVerAlignMiddle : "Miðjan", -DlgCellVerAlignBottom : "Niðast", -DlgCellVerAlignBaseline : "Basislinja", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Røðir, meskin fevnir um", -DlgCellCollSpan : "Kolonnur, meskin fevnir um", -DlgCellBackColor : "Bakgrundslitur", -DlgCellBorderColor : "Litur á borda", -DlgCellBtnSelect : "Vel...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Finn og broyt", - -// Find Dialog -DlgFindTitle : "Finn", -DlgFindFindBtn : "Finn", -DlgFindNotFoundMsg : "Leititeksturin varð ikki funnin", - -// Replace Dialog -DlgReplaceTitle : "Yvirskriva", -DlgReplaceFindLbl : "Finn:", -DlgReplaceReplaceLbl : "Yvirskriva við:", -DlgReplaceCaseChk : "Munur á stórum og smáðum bókstavum", -DlgReplaceReplaceBtn : "Yvirskriva", -DlgReplaceReplAllBtn : "Yvirskriva alt", -DlgReplaceWordChk : "Bert heil orð", - -// Paste Operations / Dialog -PasteErrorCut : "Trygdaruppseting alnótskagans forðar tekstviðgeranum í at kvetta tekstin. Vinarliga nýt knappaborðið til at kvetta tekstin (CTRL+X).", -PasteErrorCopy : "Trygdaruppseting alnótskagans forðar tekstviðgeranum í at avrita tekstin. Vinarliga nýt knappaborðið til at avrita tekstin (CTRL+C).", - -PasteAsText : "Innrita som reinan tekst", -PasteFromWord : "Innrita fra Word", - -DlgPasteMsg2 : "Vinarliga koyr tekstin í hendan rútin við knappaborðinum (CTRL+V) og klikk á Góðtak.", -DlgPasteSec : "Trygdaruppseting alnótskagans forðar tekstviðgeranum í beinleiðis atgongd til avritingarminnið. Tygum mugu royna aftur í hesum rútinum.", -DlgPasteIgnoreFont : "Forfjóna Font definitiónirnar", -DlgPasteRemoveStyles : "Strika typografi definitiónir", - -// Color Picker -ColorAutomatic : "Automatiskt", -ColorMoreColors : "Fleiri litir...", - -// Document Properties -DocProps : "Eginleikar fyri dokument", - -// Anchor Dialog -DlgAnchorTitle : "Eginleikar fyri marknastein", -DlgAnchorName : "Heiti marknasteinsins", -DlgAnchorErrorName : "Vinarliga rita marknasteinsins heiti", - -// Speller Pages Dialog -DlgSpellNotInDic : "Finst ikki í orðabókini", -DlgSpellChangeTo : "Broyt til", -DlgSpellBtnIgnore : "Forfjóna", -DlgSpellBtnIgnoreAll : "Forfjóna alt", -DlgSpellBtnReplace : "Yvirskriva", -DlgSpellBtnReplaceAll : "Yvirskriva alt", -DlgSpellBtnUndo : "Angra", -DlgSpellNoSuggestions : "- Einki uppskot -", -DlgSpellProgress : "Rættstavarin arbeiðir...", -DlgSpellNoMispell : "Rættstavarain liðugur: Eingin feilur funnin", -DlgSpellNoChanges : "Rættstavarain liðugur: Einki orð varð broytt", -DlgSpellOneChange : "Rættstavarain liðugur: Eitt orð er broytt", -DlgSpellManyChanges : "Rættstavarain liðugur: %1 orð broytt", - -IeSpellDownload : "Rættstavarin er ikki tøkur í tekstviðgeranum. Vilt tú heinta hann nú?", - -// Button Dialog -DlgButtonText : "Tekstur", -DlgButtonType : "Slag", -DlgButtonTypeBtn : "Knøttur", -DlgButtonTypeSbm : "Send", -DlgButtonTypeRst : "Nullstilla", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Navn", -DlgCheckboxValue : "Virði", -DlgCheckboxSelected : "Valt", - -// Form Dialog -DlgFormName : "Navn", -DlgFormAction : "Hending", -DlgFormMethod : "Háttur", - -// Select Field Dialog -DlgSelectName : "Navn", -DlgSelectValue : "Virði", -DlgSelectSize : "Stødd", -DlgSelectLines : "Linjur", -DlgSelectChkMulti : "Loyv fleiri valmøguleikum samstundis", -DlgSelectOpAvail : "Tøkir møguleikar", -DlgSelectOpText : "Tekstur", -DlgSelectOpValue : "Virði", -DlgSelectBtnAdd : "Legg afturat", -DlgSelectBtnModify : "Broyt", -DlgSelectBtnUp : "Upp", -DlgSelectBtnDown : "Niður", -DlgSelectBtnSetValue : "Set sum valt virði", -DlgSelectBtnDelete : "Strika", - -// Textarea Dialog -DlgTextareaName : "Navn", -DlgTextareaCols : "kolonnur", -DlgTextareaRows : "røðir", - -// Text Field Dialog -DlgTextName : "Navn", -DlgTextValue : "Virði", -DlgTextCharWidth : "Breidd (sjónlig tekn)", -DlgTextMaxChars : "Mest loyvdu tekn", -DlgTextType : "Slag", -DlgTextTypeText : "Tekstur", -DlgTextTypePass : "Loyniorð", - -// Hidden Field Dialog -DlgHiddenName : "Navn", -DlgHiddenValue : "Virði", - -// Bulleted List Dialog -BulletedListProp : "Eginleikar fyri punktmerktan lista", -NumberedListProp : "Eginleikar fyri talmerktan lista", -DlgLstStart : "Byrjan", -DlgLstType : "Slag", -DlgLstTypeCircle : "Sirkul", -DlgLstTypeDisc : "Fyltur sirkul", -DlgLstTypeSquare : "Fjórhyrningur", -DlgLstTypeNumbers : "Talmerkt (1, 2, 3)", -DlgLstTypeLCase : "Smáir bókstavir (a, b, c)", -DlgLstTypeUCase : "Stórir bókstavir (A, B, C)", -DlgLstTypeSRoman : "Smá rómaratøl (i, ii, iii)", -DlgLstTypeLRoman : "Stór rómaratøl (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Generelt", -DlgDocBackTab : "Bakgrund", -DlgDocColorsTab : "Litir og breddar", -DlgDocMetaTab : "META-upplýsingar", - -DlgDocPageTitle : "Síðuheiti", -DlgDocLangDir : "Tekstkós", -DlgDocLangDirLTR : "Frá vinstru móti høgru (LTR)", -DlgDocLangDirRTL : "Frá høgru móti vinstru (RTL)", -DlgDocLangCode : "Málkoda", -DlgDocCharSet : "Teknsett koda", -DlgDocCharSetCE : "Miðeuropa", -DlgDocCharSetCT : "Kinesiskt traditionelt (Big5)", -DlgDocCharSetCR : "Cyrilliskt", -DlgDocCharSetGR : "Grikst", -DlgDocCharSetJP : "Japanskt", -DlgDocCharSetKR : "Koreanskt", -DlgDocCharSetTR : "Turkiskt", -DlgDocCharSetUN : "UNICODE (UTF-8)", -DlgDocCharSetWE : "Vestureuropa", -DlgDocCharSetOther : "Onnur teknsett koda", - -DlgDocDocType : "Dokumentslag yvirskrift", -DlgDocDocTypeOther : "Annað dokumentslag yvirskrift", -DlgDocIncXHTML : "Viðfest XHTML deklaratiónir", -DlgDocBgColor : "Bakgrundslitur", -DlgDocBgImage : "Leið til bakgrundsmynd (URL)", -DlgDocBgNoScroll : "Læst bakgrund (rullar ikki)", -DlgDocCText : "Tekstur", -DlgDocCLink : "Tilknýti", -DlgDocCVisited : "Vitjaði tilknýti", -DlgDocCActive : "Virkin tilknýti", -DlgDocMargins : "Síðubreddar", -DlgDocMaTop : "Ovast", -DlgDocMaLeft : "Vinstra", -DlgDocMaRight : "Høgra", -DlgDocMaBottom : "Niðast", -DlgDocMeIndex : "Dokument index lyklaorð (sundurbýtt við komma)", -DlgDocMeDescr : "Dokumentlýsing", -DlgDocMeAuthor : "Høvundur", -DlgDocMeCopy : "Upphavsrættindi", -DlgDocPreview : "Frumsýning", - -// Templates Dialog -Templates : "Skabelónir", -DlgTemplatesTitle : "Innihaldsskabelónir", -DlgTemplatesSelMsg : "Vinarliga vel ta skabelón, ið skal opnast í tekstviðgeranum
    (Hetta yvirskrivar núverandi innihald):", -DlgTemplatesLoading : "Heinti yvirlit yvir skabelónir. Vinarliga bíða við...", -DlgTemplatesNoTpl : "(Ongar skabelónir tøkar)", -DlgTemplatesReplace : "Yvirskriva núverandi innihald", - -// About Dialog -DlgAboutAboutTab : "Um", -DlgAboutBrowserInfoTab : "Upplýsingar um alnótskagan", -DlgAboutLicenseTab : "License", -DlgAboutVersion : "version", -DlgAboutInfo : "Fyri fleiri upplýsingar, far til", - -// Div Dialog -DlgDivGeneralTab : "Generelt", -DlgDivAdvancedTab : "Fjølbroytt", -DlgDivStyle : "Typografi", -DlgDivInlineStyle : "Inline typografi", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/fr-ca.js b/httemplate/elements/fckeditor/editor/lang/fr-ca.js deleted file mode 100644 index 2489bd65a..000000000 --- a/httemplate/elements/fckeditor/editor/lang/fr-ca.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Canadian French language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Masquer Outils", -ToolbarExpand : "Afficher Outils", - -// Toolbar Items and Context Menu -Save : "Sauvegarder", -NewPage : "Nouvelle page", -Preview : "Previsualiser", -Cut : "Couper", -Copy : "Copier", -Paste : "Coller", -PasteText : "Coller en tant que texte", -PasteWord : "Coller en tant que Word (formaté)", -Print : "Imprimer", -SelectAll : "Tout sélectionner", -RemoveFormat : "Supprimer le formatage", -InsertLinkLbl : "Lien", -InsertLink : "Insérer/modifier le lien", -RemoveLink : "Supprimer le lien", -VisitLink : "Suivre le lien", -Anchor : "Insérer/modifier l'ancre", -AnchorDelete : "Supprimer l'ancre", -InsertImageLbl : "Image", -InsertImage : "Insérer/modifier l'image", -InsertFlashLbl : "Animation Flash", -InsertFlash : "Insérer/modifier l'animation Flash", -InsertTableLbl : "Tableau", -InsertTable : "Insérer/modifier le tableau", -InsertLineLbl : "Séparateur", -InsertLine : "Insérer un séparateur", -InsertSpecialCharLbl: "Caractères spéciaux", -InsertSpecialChar : "Insérer un caractère spécial", -InsertSmileyLbl : "Emoticon", -InsertSmiley : "Insérer un Emoticon", -About : "A propos de FCKeditor", -Bold : "Gras", -Italic : "Italique", -Underline : "Souligné", -StrikeThrough : "Barrer", -Subscript : "Indice", -Superscript : "Exposant", -LeftJustify : "Aligner à gauche", -CenterJustify : "Centrer", -RightJustify : "Aligner à Droite", -BlockJustify : "Texte justifié", -DecreaseIndent : "Diminuer le retrait", -IncreaseIndent : "Augmenter le retrait", -Blockquote : "Citation", -CreateDiv : "Créer Balise Div", -EditDiv : "Modifier Balise Div", -DeleteDiv : "Supprimer Balise Div", -Undo : "Annuler", -Redo : "Refaire", -NumberedListLbl : "Liste numérotée", -NumberedList : "Insérer/supprimer la liste numérotée", -BulletedListLbl : "Liste à puces", -BulletedList : "Insérer/supprimer la liste à puces", -ShowTableBorders : "Afficher les bordures du tableau", -ShowDetails : "Afficher les caractères invisibles", -Style : "Style", -FontFormat : "Format", -Font : "Police", -FontSize : "Taille", -TextColor : "Couleur de caractère", -BGColor : "Couleur de fond", -Source : "Source", -Find : "Chercher", -Replace : "Remplacer", -SpellCheck : "Orthographe", -UniversalKeyboard : "Clavier universel", -PageBreakLbl : "Saut de page", -PageBreak : "Insérer un saut de page", - -Form : "Formulaire", -Checkbox : "Case à cocher", -RadioButton : "Bouton radio", -TextField : "Champ texte", -Textarea : "Zone de texte", -HiddenField : "Champ caché", -Button : "Bouton", -SelectionField : "Champ de sélection", -ImageButton : "Bouton image", - -FitWindow : "Edition pleine page", -ShowBlocks : "Afficher les blocs", - -// Context Menu -EditLink : "Modifier le lien", -CellCM : "Cellule", -RowCM : "Ligne", -ColumnCM : "Colonne", -InsertRowAfter : "Insérer une ligne après", -InsertRowBefore : "Insérer une ligne avant", -DeleteRows : "Supprimer des lignes", -InsertColumnAfter : "Insérer une colonne après", -InsertColumnBefore : "Insérer une colonne avant", -DeleteColumns : "Supprimer des colonnes", -InsertCellAfter : "Insérer une cellule après", -InsertCellBefore : "Insérer une cellule avant", -DeleteCells : "Supprimer des cellules", -MergeCells : "Fusionner les cellules", -MergeRight : "Fusionner à droite", -MergeDown : "Fusionner en bas", -HorizontalSplitCell : "Scinder la cellule horizontalement", -VerticalSplitCell : "Scinder la cellule verticalement", -TableDelete : "Supprimer le tableau", -CellProperties : "Propriétés de cellule", -TableProperties : "Propriétés du tableau", -ImageProperties : "Propriétés de l'image", -FlashProperties : "Propriétés de l'animation Flash", - -AnchorProp : "Propriétés de l'ancre", -ButtonProp : "Propriétés du bouton", -CheckboxProp : "Propriétés de la case à cocher", -HiddenFieldProp : "Propriétés du champ caché", -RadioButtonProp : "Propriétés du bouton radio", -ImageButtonProp : "Propriétés du bouton image", -TextFieldProp : "Propriétés du champ texte", -SelectionFieldProp : "Propriétés de la liste/du menu", -TextareaProp : "Propriétés de la zone de texte", -FormProp : "Propriétés du formulaire", - -FontFormats : "Normal;Formaté;Adresse;En-tête 1;En-tête 2;En-tête 3;En-tête 4;En-tête 5;En-tête 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Calcul XHTML. Veuillez patienter...", -Done : "Terminé", -PasteWordConfirm : "Le texte à coller semble provenir de Word. Désirez-vous le nettoyer avant de coller?", -NotCompatiblePaste : "Cette commande nécessite Internet Explorer version 5.5 et plus. Souhaitez-vous coller sans nettoyage?", -UnknownToolbarItem : "Élément de barre d'outil inconnu \"%1\"", -UnknownCommand : "Nom de commande inconnu \"%1\"", -NotImplemented : "Commande indisponible", -UnknownToolbarSet : "La barre d'outils \"%1\" n'existe pas", -NoActiveX : "Les paramètres de sécurité de votre navigateur peuvent limiter quelques fonctionnalités de l'éditeur. Veuillez activer l'option \"Exécuter les contrôles ActiveX et les plug-ins\". Il se peut que vous rencontriez des erreurs et remarquiez quelques limitations.", -BrowseServerBlocked : "Le navigateur n'a pas pu être ouvert. Assurez-vous que les bloqueurs de popups soient désactivés.", -DialogBlocked : "La fenêtre de dialogue n'a pas pu s'ouvrir. Assurez-vous que les bloqueurs de popups soient désactivés.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Annuler", -DlgBtnClose : "Fermer", -DlgBtnBrowseServer : "Parcourir le serveur", -DlgAdvancedTag : "Avancée", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Veuillez saisir l'URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Sens d'écriture", -DlgGenLangDirLtr : "De gauche à droite (LTR)", -DlgGenLangDirRtl : "De droite à gauche (RTL)", -DlgGenLangCode : "Code langue", -DlgGenAccessKey : "Équivalent clavier", -DlgGenName : "Nom", -DlgGenTabIndex : "Ordre de tabulation", -DlgGenLongDescr : "URL de description longue", -DlgGenClass : "Classes de feuilles de style", -DlgGenTitle : "Titre", -DlgGenContType : "Type de contenu", -DlgGenLinkCharset : "Encodage de caractère", -DlgGenStyle : "Style", - -// Image Dialog -DlgImgTitle : "Propriétés de l'image", -DlgImgInfoTab : "Informations sur l'image", -DlgImgBtnUpload : "Envoyer sur le serveur", -DlgImgURL : "URL", -DlgImgUpload : "Télécharger", -DlgImgAlt : "Texte de remplacement", -DlgImgWidth : "Largeur", -DlgImgHeight : "Hauteur", -DlgImgLockRatio : "Garder les proportions", -DlgBtnResetSize : "Taille originale", -DlgImgBorder : "Bordure", -DlgImgHSpace : "Espacement horizontal", -DlgImgVSpace : "Espacement vertical", -DlgImgAlign : "Alignement", -DlgImgAlignLeft : "Gauche", -DlgImgAlignAbsBottom: "Abs Bas", -DlgImgAlignAbsMiddle: "Abs Milieu", -DlgImgAlignBaseline : "Bas du texte", -DlgImgAlignBottom : "Bas", -DlgImgAlignMiddle : "Milieu", -DlgImgAlignRight : "Droite", -DlgImgAlignTextTop : "Haut du texte", -DlgImgAlignTop : "Haut", -DlgImgPreview : "Prévisualisation", -DlgImgAlertUrl : "Veuillez saisir l'URL de l'image", -DlgImgLinkTab : "Lien", - -// Flash Dialog -DlgFlashTitle : "Propriétés de l'animation Flash", -DlgFlashChkPlay : "Lecture automatique", -DlgFlashChkLoop : "Boucle", -DlgFlashChkMenu : "Activer le menu Flash", -DlgFlashScale : "Affichage", -DlgFlashScaleAll : "Par défaut (tout montrer)", -DlgFlashScaleNoBorder : "Sans bordure", -DlgFlashScaleFit : "Ajuster aux dimensions", - -// Link Dialog -DlgLnkWindowTitle : "Propriétés du lien", -DlgLnkInfoTab : "Informations sur le lien", -DlgLnkTargetTab : "Destination", - -DlgLnkType : "Type de lien", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Ancre dans cette page", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocole", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Sélectionner une ancre", -DlgLnkAnchorByName : "Par nom", -DlgLnkAnchorById : "Par id", -DlgLnkNoAnchors : "(Pas d'ancre disponible dans le document)", -DlgLnkEMail : "Adresse E-Mail", -DlgLnkEMailSubject : "Sujet du message", -DlgLnkEMailBody : "Corps du message", -DlgLnkUpload : "Télécharger", -DlgLnkBtnUpload : "Envoyer sur le serveur", - -DlgLnkTarget : "Destination", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nouvelle fenêtre (_blank)", -DlgLnkTargetParent : "Fenêtre mère (_parent)", -DlgLnkTargetSelf : "Même fenêtre (_self)", -DlgLnkTargetTop : "Fenêtre supérieure (_top)", -DlgLnkTargetFrameName : "Nom du cadre de destination", -DlgLnkPopWinName : "Nom de la fenêtre popup", -DlgLnkPopWinFeat : "Caractéristiques de la fenêtre popup", -DlgLnkPopResize : "Taille modifiable", -DlgLnkPopLocation : "Barre d'adresses", -DlgLnkPopMenu : "Barre de menu", -DlgLnkPopScroll : "Barres de défilement", -DlgLnkPopStatus : "Barre d'état", -DlgLnkPopToolbar : "Barre d'outils", -DlgLnkPopFullScrn : "Plein écran (IE)", -DlgLnkPopDependent : "Dépendante (Netscape)", -DlgLnkPopWidth : "Largeur", -DlgLnkPopHeight : "Hauteur", -DlgLnkPopLeft : "Position à partir de la gauche", -DlgLnkPopTop : "Position à partir du haut", - -DlnLnkMsgNoUrl : "Veuillez saisir l'URL", -DlnLnkMsgNoEMail : "Veuillez saisir l'adresse e-mail", -DlnLnkMsgNoAnchor : "Veuillez sélectionner une ancre", -DlnLnkMsgInvPopName : "Le nom de la fenêtre popup doit commencer par une lettre et ne doit pas contenir d'espace", - -// Color Dialog -DlgColorTitle : "Sélectionner", -DlgColorBtnClear : "Effacer", -DlgColorHighlight : "Prévisualisation", -DlgColorSelected : "Sélectionné", - -// Smiley Dialog -DlgSmileyTitle : "Insérer un Emoticon", - -// Special Character Dialog -DlgSpecialCharTitle : "Insérer un caractère spécial", - -// Table Dialog -DlgTableTitle : "Propriétés du tableau", -DlgTableRows : "Lignes", -DlgTableColumns : "Colonnes", -DlgTableBorder : "Taille de la bordure", -DlgTableAlign : "Alignement", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Gauche", -DlgTableAlignCenter : "Centré", -DlgTableAlignRight : "Droite", -DlgTableWidth : "Largeur", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "pourcentage", -DlgTableHeight : "Hauteur", -DlgTableCellSpace : "Espacement", -DlgTableCellPad : "Contour", -DlgTableCaption : "Titre", -DlgTableSummary : "Résumé", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Propriétés de la cellule", -DlgCellWidth : "Largeur", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "pourcentage", -DlgCellHeight : "Hauteur", -DlgCellWordWrap : "Retour à la ligne", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Oui", -DlgCellWordWrapNo : "Non", -DlgCellHorAlign : "Alignement horizontal", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Gauche", -DlgCellHorAlignCenter : "Centré", -DlgCellHorAlignRight: "Droite", -DlgCellVerAlign : "Alignement vertical", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Haut", -DlgCellVerAlignMiddle : "Milieu", -DlgCellVerAlignBottom : "Bas", -DlgCellVerAlignBaseline : "Bas du texte", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Lignes fusionnées", -DlgCellCollSpan : "Colonnes fusionnées", -DlgCellBackColor : "Couleur de fond", -DlgCellBorderColor : "Couleur de bordure", -DlgCellBtnSelect : "Sélectionner...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Chercher et Remplacer", - -// Find Dialog -DlgFindTitle : "Chercher", -DlgFindFindBtn : "Chercher", -DlgFindNotFoundMsg : "Le texte indiqué est introuvable.", - -// Replace Dialog -DlgReplaceTitle : "Remplacer", -DlgReplaceFindLbl : "Rechercher:", -DlgReplaceReplaceLbl : "Remplacer par:", -DlgReplaceCaseChk : "Respecter la casse", -DlgReplaceReplaceBtn : "Remplacer", -DlgReplaceReplAllBtn : "Tout remplacer", -DlgReplaceWordChk : "Mot entier", - -// Paste Operations / Dialog -PasteErrorCut : "Les paramètres de sécurité de votre navigateur empêchent l'éditeur de couper automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl+X).", -PasteErrorCopy : "Les paramètres de sécurité de votre navigateur empêchent l'éditeur de copier automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl+C).", - -PasteAsText : "Coller comme texte", -PasteFromWord : "Coller à partir de Word", - -DlgPasteMsg2 : "Veuillez coller dans la zone ci-dessous en utilisant le clavier (Ctrl+V) et appuyer sur OK.", -DlgPasteSec : "A cause des paramètres de sécurité de votre navigateur, l'éditeur ne peut accéder au presse-papier directement. Vous devez coller à nouveau le contenu dans cette fenêtre.", -DlgPasteIgnoreFont : "Ignorer les polices de caractères", -DlgPasteRemoveStyles : "Supprimer les styles", - -// Color Picker -ColorAutomatic : "Automatique", -ColorMoreColors : "Plus de couleurs...", - -// Document Properties -DocProps : "Propriétés du document", - -// Anchor Dialog -DlgAnchorTitle : "Propriétés de l'ancre", -DlgAnchorName : "Nom de l'ancre", -DlgAnchorErrorName : "Veuillez saisir le nom de l'ancre", - -// Speller Pages Dialog -DlgSpellNotInDic : "Pas dans le dictionnaire", -DlgSpellChangeTo : "Changer en", -DlgSpellBtnIgnore : "Ignorer", -DlgSpellBtnIgnoreAll : "Ignorer tout", -DlgSpellBtnReplace : "Remplacer", -DlgSpellBtnReplaceAll : "Remplacer tout", -DlgSpellBtnUndo : "Annuler", -DlgSpellNoSuggestions : "- Pas de suggestion -", -DlgSpellProgress : "Vérification d'orthographe en cours...", -DlgSpellNoMispell : "Vérification d'orthographe terminée: pas d'erreur trouvée", -DlgSpellNoChanges : "Vérification d'orthographe terminée: Pas de modifications", -DlgSpellOneChange : "Vérification d'orthographe terminée: Un mot modifié", -DlgSpellManyChanges : "Vérification d'orthographe terminée: %1 mots modifiés", - -IeSpellDownload : "Le Correcteur d'orthographe n'est pas installé. Souhaitez-vous le télécharger maintenant?", - -// Button Dialog -DlgButtonText : "Texte (Valeur)", -DlgButtonType : "Type", -DlgButtonTypeBtn : "Bouton", -DlgButtonTypeSbm : "Soumettre", -DlgButtonTypeRst : "Réinitialiser", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nom", -DlgCheckboxValue : "Valeur", -DlgCheckboxSelected : "Sélectionné", - -// Form Dialog -DlgFormName : "Nom", -DlgFormAction : "Action", -DlgFormMethod : "Méthode", - -// Select Field Dialog -DlgSelectName : "Nom", -DlgSelectValue : "Valeur", -DlgSelectSize : "Taille", -DlgSelectLines : "lignes", -DlgSelectChkMulti : "Sélection multiple", -DlgSelectOpAvail : "Options disponibles", -DlgSelectOpText : "Texte", -DlgSelectOpValue : "Valeur", -DlgSelectBtnAdd : "Ajouter", -DlgSelectBtnModify : "Modifier", -DlgSelectBtnUp : "Monter", -DlgSelectBtnDown : "Descendre", -DlgSelectBtnSetValue : "Valeur sélectionnée", -DlgSelectBtnDelete : "Supprimer", - -// Textarea Dialog -DlgTextareaName : "Nom", -DlgTextareaCols : "Colonnes", -DlgTextareaRows : "Lignes", - -// Text Field Dialog -DlgTextName : "Nom", -DlgTextValue : "Valeur", -DlgTextCharWidth : "Largeur en caractères", -DlgTextMaxChars : "Nombre maximum de caractères", -DlgTextType : "Type", -DlgTextTypeText : "Texte", -DlgTextTypePass : "Mot de passe", - -// Hidden Field Dialog -DlgHiddenName : "Nom", -DlgHiddenValue : "Valeur", - -// Bulleted List Dialog -BulletedListProp : "Propriétés de liste à puces", -NumberedListProp : "Propriétés de liste numérotée", -DlgLstStart : "Début", -DlgLstType : "Type", -DlgLstTypeCircle : "Cercle", -DlgLstTypeDisc : "Disque", -DlgLstTypeSquare : "Carré", -DlgLstTypeNumbers : "Nombres (1, 2, 3)", -DlgLstTypeLCase : "Lettres minuscules (a, b, c)", -DlgLstTypeUCase : "Lettres majuscules (A, B, C)", -DlgLstTypeSRoman : "Chiffres romains minuscules (i, ii, iii)", -DlgLstTypeLRoman : "Chiffres romains majuscules (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Général", -DlgDocBackTab : "Fond", -DlgDocColorsTab : "Couleurs et Marges", -DlgDocMetaTab : "Méta-Données", - -DlgDocPageTitle : "Titre de la page", -DlgDocLangDir : "Sens d'écriture", -DlgDocLangDirLTR : "De la gauche vers la droite (LTR)", -DlgDocLangDirRTL : "De la droite vers la gauche (RTL)", -DlgDocLangCode : "Code langue", -DlgDocCharSet : "Encodage de caractère", -DlgDocCharSetCE : "Europe Centrale", -DlgDocCharSetCT : "Chinois Traditionnel (Big5)", -DlgDocCharSetCR : "Cyrillique", -DlgDocCharSetGR : "Grecque", -DlgDocCharSetJP : "Japonais", -DlgDocCharSetKR : "Coréen", -DlgDocCharSetTR : "Turcque", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Occidental", -DlgDocCharSetOther : "Autre encodage de caractère", - -DlgDocDocType : "Type de document", -DlgDocDocTypeOther : "Autre type de document", -DlgDocIncXHTML : "Inclure les déclarations XHTML", -DlgDocBgColor : "Couleur de fond", -DlgDocBgImage : "Image de fond", -DlgDocBgNoScroll : "Image fixe sans défilement", -DlgDocCText : "Texte", -DlgDocCLink : "Lien", -DlgDocCVisited : "Lien visité", -DlgDocCActive : "Lien activé", -DlgDocMargins : "Marges", -DlgDocMaTop : "Haut", -DlgDocMaLeft : "Gauche", -DlgDocMaRight : "Droite", -DlgDocMaBottom : "Bas", -DlgDocMeIndex : "Mots-clés (séparés par des virgules)", -DlgDocMeDescr : "Description", -DlgDocMeAuthor : "Auteur", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Prévisualisation", - -// Templates Dialog -Templates : "Modèles", -DlgTemplatesTitle : "Modèles de contenu", -DlgTemplatesSelMsg : "Sélectionner le modèle à ouvrir dans l'éditeur
    (le contenu actuel sera remplacé):", -DlgTemplatesLoading : "Chargement de la liste des modèles. Veuillez patienter...", -DlgTemplatesNoTpl : "(Aucun modèle disponible)", -DlgTemplatesReplace : "Remplacer tout le contenu actuel", - -// About Dialog -DlgAboutAboutTab : "Á propos de", -DlgAboutBrowserInfoTab : "Navigateur", -DlgAboutLicenseTab : "License", -DlgAboutVersion : "Version", -DlgAboutInfo : "Pour plus d'informations, visiter", - -// Div Dialog -DlgDivGeneralTab : "Général", -DlgDivAdvancedTab : "Avancé", -DlgDivStyle : "Style", -DlgDivInlineStyle : "Attribut Style", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/fr.js b/httemplate/elements/fckeditor/editor/lang/fr.js deleted file mode 100644 index a03558f74..000000000 --- a/httemplate/elements/fckeditor/editor/lang/fr.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * French language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Masquer Outils", -ToolbarExpand : "Afficher Outils", - -// Toolbar Items and Context Menu -Save : "Enregistrer", -NewPage : "Nouvelle page", -Preview : "Prévisualisation", -Cut : "Couper", -Copy : "Copier", -Paste : "Coller", -PasteText : "Coller comme texte", -PasteWord : "Coller de Word", -Print : "Imprimer", -SelectAll : "Tout sélectionner", -RemoveFormat : "Supprimer le format", -InsertLinkLbl : "Lien", -InsertLink : "Insérer/modifier le lien", -RemoveLink : "Supprimer le lien", -VisitLink : "Suivre le lien", -Anchor : "Insérer/modifier l'ancre", -AnchorDelete : "Supprimer l'ancre", -InsertImageLbl : "Image", -InsertImage : "Insérer/modifier l'image", -InsertFlashLbl : "Animation Flash", -InsertFlash : "Insérer/modifier l'animation Flash", -InsertTableLbl : "Tableau", -InsertTable : "Insérer/modifier le tableau", -InsertLineLbl : "Séparateur", -InsertLine : "Insérer un séparateur", -InsertSpecialCharLbl: "Caractères spéciaux", -InsertSpecialChar : "Insérer un caractère spécial", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Insérer un Smiley", -About : "A propos de FCKeditor", -Bold : "Gras", -Italic : "Italique", -Underline : "Souligné", -StrikeThrough : "Barré", -Subscript : "Indice", -Superscript : "Exposant", -LeftJustify : "Aligné à gauche", -CenterJustify : "Centré", -RightJustify : "Aligné à Droite", -BlockJustify : "Texte justifié", -DecreaseIndent : "Diminuer le retrait", -IncreaseIndent : "Augmenter le retrait", -Blockquote : "Citation", -CreateDiv : "Créer Balise Div", -EditDiv : "Modifier Balise Div", -DeleteDiv : "Supprimer Balise Div", -Undo : "Annuler", -Redo : "Refaire", -NumberedListLbl : "Liste numérotée", -NumberedList : "Insérer/supprimer la liste numérotée", -BulletedListLbl : "Liste à puces", -BulletedList : "Insérer/supprimer la liste à puces", -ShowTableBorders : "Afficher les bordures du tableau", -ShowDetails : "Afficher les caractères invisibles", -Style : "Style", -FontFormat : "Format", -Font : "Police", -FontSize : "Taille", -TextColor : "Couleur de caractère", -BGColor : "Couleur de fond", -Source : "Source", -Find : "Chercher", -Replace : "Remplacer", -SpellCheck : "Orthographe", -UniversalKeyboard : "Clavier universel", -PageBreakLbl : "Saut de page", -PageBreak : "Insérer un saut de page", - -Form : "Formulaire", -Checkbox : "Case à cocher", -RadioButton : "Bouton radio", -TextField : "Champ texte", -Textarea : "Zone de texte", -HiddenField : "Champ caché", -Button : "Bouton", -SelectionField : "Liste/menu", -ImageButton : "Bouton image", - -FitWindow : "Edition pleine page", -ShowBlocks : "Afficher les blocs", - -// Context Menu -EditLink : "Modifier le lien", -CellCM : "Cellule", -RowCM : "Ligne", -ColumnCM : "Colonne", -InsertRowAfter : "Insérer une ligne après", -InsertRowBefore : "Insérer une ligne avant", -DeleteRows : "Supprimer des lignes", -InsertColumnAfter : "Insérer une colonne après", -InsertColumnBefore : "Insérer une colonne avant", -DeleteColumns : "Supprimer des colonnes", -InsertCellAfter : "Insérer une cellule après", -InsertCellBefore : "Insérer une cellule avant", -DeleteCells : "Supprimer des cellules", -MergeCells : "Fusionner les cellules", -MergeRight : "Fusionner à droite", -MergeDown : "Fusionner en bas", -HorizontalSplitCell : "Scinder la cellule horizontalement", -VerticalSplitCell : "Scinder la cellule verticalement", -TableDelete : "Supprimer le tableau", -CellProperties : "Propriétés de cellule", -TableProperties : "Propriétés du tableau", -ImageProperties : "Propriétés de l'image", -FlashProperties : "Propriétés de l'animation Flash", - -AnchorProp : "Propriétés de l'ancre", -ButtonProp : "Propriétés du bouton", -CheckboxProp : "Propriétés de la case à cocher", -HiddenFieldProp : "Propriétés du champ caché", -RadioButtonProp : "Propriétés du bouton radio", -ImageButtonProp : "Propriétés du bouton image", -TextFieldProp : "Propriétés du champ texte", -SelectionFieldProp : "Propriétés de la liste/du menu", -TextareaProp : "Propriétés de la zone de texte", -FormProp : "Propriétés du formulaire", - -FontFormats : "Normal;Formaté;Adresse;En-tête 1;En-tête 2;En-tête 3;En-tête 4;En-tête 5;En-tête 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Calcul XHTML. Veuillez patienter...", -Done : "Terminé", -PasteWordConfirm : "Le texte à coller semble provenir de Word. Désirez-vous le nettoyer avant de coller?", -NotCompatiblePaste : "Cette commande nécessite Internet Explorer version 5.5 minimum. Souhaitez-vous coller sans nettoyage?", -UnknownToolbarItem : "Elément de barre d'outil inconnu \"%1\"", -UnknownCommand : "Nom de commande inconnu \"%1\"", -NotImplemented : "Commande non encore écrite", -UnknownToolbarSet : "La barre d'outils \"%1\" n'existe pas", -NoActiveX : "Les paramètres de sécurité de votre navigateur peuvent limiter quelques fonctionnalités de l'éditeur. Veuillez activer l'option \"Exécuter les contrôles ActiveX et les plug-ins\". Il se peut que vous rencontriez des erreurs et remarquiez quelques limitations.", -BrowseServerBlocked : "Le navigateur n'a pas pu être ouvert. Assurez-vous que les bloqueurs de popups soient désactivés.", -DialogBlocked : "La fenêtre de dialogue n'a pas pu s'ouvrir. Assurez-vous que les bloqueurs de popups soient désactivés.", -VisitLinkBlocked : "Impossible d'ouvrir une nouvelle fenêtre. Assurez-vous que les bloqueurs de popups soient désactivés.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Annuler", -DlgBtnClose : "Fermer", -DlgBtnBrowseServer : "Parcourir le serveur", -DlgAdvancedTag : "Avancé", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Veuillez saisir l'URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Sens d'écriture", -DlgGenLangDirLtr : "De gauche à droite (LTR)", -DlgGenLangDirRtl : "De droite à gauche (RTL)", -DlgGenLangCode : "Code langue", -DlgGenAccessKey : "Equivalent clavier", -DlgGenName : "Nom", -DlgGenTabIndex : "Ordre de tabulation", -DlgGenLongDescr : "URL de description longue", -DlgGenClass : "Classes de feuilles de style", -DlgGenTitle : "Titre", -DlgGenContType : "Type de contenu", -DlgGenLinkCharset : "Encodage de caractère", -DlgGenStyle : "Style", - -// Image Dialog -DlgImgTitle : "Propriétés de l'image", -DlgImgInfoTab : "Informations sur l'image", -DlgImgBtnUpload : "Envoyer sur le serveur", -DlgImgURL : "URL", -DlgImgUpload : "Télécharger", -DlgImgAlt : "Texte de remplacement", -DlgImgWidth : "Largeur", -DlgImgHeight : "Hauteur", -DlgImgLockRatio : "Garder les proportions", -DlgBtnResetSize : "Taille originale", -DlgImgBorder : "Bordure", -DlgImgHSpace : "Espacement horizontal", -DlgImgVSpace : "Espacement vertical", -DlgImgAlign : "Alignement", -DlgImgAlignLeft : "Gauche", -DlgImgAlignAbsBottom: "Abs Bas", -DlgImgAlignAbsMiddle: "Abs Milieu", -DlgImgAlignBaseline : "Bas du texte", -DlgImgAlignBottom : "Bas", -DlgImgAlignMiddle : "Milieu", -DlgImgAlignRight : "Droite", -DlgImgAlignTextTop : "Haut du texte", -DlgImgAlignTop : "Haut", -DlgImgPreview : "Prévisualisation", -DlgImgAlertUrl : "Veuillez saisir l'URL de l'image", -DlgImgLinkTab : "Lien", - -// Flash Dialog -DlgFlashTitle : "Propriétés de l'animation Flash", -DlgFlashChkPlay : "Lecture automatique", -DlgFlashChkLoop : "Boucle", -DlgFlashChkMenu : "Activer le menu Flash", -DlgFlashScale : "Affichage", -DlgFlashScaleAll : "Par défaut (tout montrer)", -DlgFlashScaleNoBorder : "Sans bordure", -DlgFlashScaleFit : "Ajuster aux dimensions", - -// Link Dialog -DlgLnkWindowTitle : "Propriétés du lien", -DlgLnkInfoTab : "Informations sur le lien", -DlgLnkTargetTab : "Destination", - -DlgLnkType : "Type de lien", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Ancre dans cette page", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocole", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Sélectionner une ancre", -DlgLnkAnchorByName : "Par nom", -DlgLnkAnchorById : "Par id", -DlgLnkNoAnchors : "(Pas d'ancre disponible dans le document)", -DlgLnkEMail : "Adresse E-Mail", -DlgLnkEMailSubject : "Sujet du message", -DlgLnkEMailBody : "Corps du message", -DlgLnkUpload : "Télécharger", -DlgLnkBtnUpload : "Envoyer sur le serveur", - -DlgLnkTarget : "Destination", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nouvelle fenêtre (_blank)", -DlgLnkTargetParent : "Fenêtre mère (_parent)", -DlgLnkTargetSelf : "Même fenêtre (_self)", -DlgLnkTargetTop : "Fenêtre supérieure (_top)", -DlgLnkTargetFrameName : "Nom du cadre de destination", -DlgLnkPopWinName : "Nom de la fenêtre popup", -DlgLnkPopWinFeat : "Caractéristiques de la fenêtre popup", -DlgLnkPopResize : "Taille modifiable", -DlgLnkPopLocation : "Barre d'adresses", -DlgLnkPopMenu : "Barre de menu", -DlgLnkPopScroll : "Barres de défilement", -DlgLnkPopStatus : "Barre d'état", -DlgLnkPopToolbar : "Barre d'outils", -DlgLnkPopFullScrn : "Plein écran (IE)", -DlgLnkPopDependent : "Dépendante (Netscape)", -DlgLnkPopWidth : "Largeur", -DlgLnkPopHeight : "Hauteur", -DlgLnkPopLeft : "Position à partir de la gauche", -DlgLnkPopTop : "Position à partir du haut", - -DlnLnkMsgNoUrl : "Veuillez saisir l'URL", -DlnLnkMsgNoEMail : "Veuillez saisir l'adresse e-mail", -DlnLnkMsgNoAnchor : "Veuillez sélectionner une ancre", -DlnLnkMsgInvPopName : "Le nom de la fenêtre popup doit commencer par une lettre et ne doit pas contenir d'espace", - -// Color Dialog -DlgColorTitle : "Sélectionner", -DlgColorBtnClear : "Effacer", -DlgColorHighlight : "Prévisualisation", -DlgColorSelected : "Sélectionné", - -// Smiley Dialog -DlgSmileyTitle : "Insérer un Smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Insérer un caractère spécial", - -// Table Dialog -DlgTableTitle : "Propriétés du tableau", -DlgTableRows : "Lignes", -DlgTableColumns : "Colonnes", -DlgTableBorder : "Bordure", -DlgTableAlign : "Alignement", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Gauche", -DlgTableAlignCenter : "Centré", -DlgTableAlignRight : "Droite", -DlgTableWidth : "Largeur", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "pourcentage", -DlgTableHeight : "Hauteur", -DlgTableCellSpace : "Espacement", -DlgTableCellPad : "Contour", -DlgTableCaption : "Titre", -DlgTableSummary : "Résumé", -DlgTableHeaders : "Entêtes", -DlgTableHeadersNone : "Sans", -DlgTableHeadersColumn : "Première colonne", -DlgTableHeadersRow : "Première Ligne", -DlgTableHeadersBoth : "Les 2", - -// Table Cell Dialog -DlgCellTitle : "Propriétés de la cellule", -DlgCellWidth : "Largeur", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "pourcentage", -DlgCellHeight : "Hauteur", -DlgCellWordWrap : "Retour à la ligne", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Oui", -DlgCellWordWrapNo : "Non", -DlgCellHorAlign : "Alignement horizontal", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Gauche", -DlgCellHorAlignCenter : "Centré", -DlgCellHorAlignRight: "Droite", -DlgCellVerAlign : "Alignement vertical", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Haut", -DlgCellVerAlignMiddle : "Milieu", -DlgCellVerAlignBottom : "Bas", -DlgCellVerAlignBaseline : "Bas du texte", -DlgCellType : "Type de Cellule", -DlgCellTypeData : "Données", -DlgCellTypeHeader : "Entête", -DlgCellRowSpan : "Lignes fusionnées", -DlgCellCollSpan : "Colonnes fusionnées", -DlgCellBackColor : "Fond", -DlgCellBorderColor : "Bordure", -DlgCellBtnSelect : "Choisir...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Chercher et Remplacer", - -// Find Dialog -DlgFindTitle : "Chercher", -DlgFindFindBtn : "Chercher", -DlgFindNotFoundMsg : "Le texte indiqué est introuvable.", - -// Replace Dialog -DlgReplaceTitle : "Remplacer", -DlgReplaceFindLbl : "Rechercher:", -DlgReplaceReplaceLbl : "Remplacer par:", -DlgReplaceCaseChk : "Respecter la casse", -DlgReplaceReplaceBtn : "Remplacer", -DlgReplaceReplAllBtn : "Tout remplacer", -DlgReplaceWordChk : "Mot entier", - -// Paste Operations / Dialog -PasteErrorCut : "Les paramètres de sécurité de votre navigateur empêchent l'éditeur de couper automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl+X).", -PasteErrorCopy : "Les paramètres de sécurité de votre navigateur empêchent l'éditeur de copier automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl+C).", - -PasteAsText : "Coller comme texte", -PasteFromWord : "Coller à partir de Word", - -DlgPasteMsg2 : "Veuillez coller dans la zone ci-dessous en utilisant le clavier (Ctrl+V) et cliquez sur OK.", -DlgPasteSec : "A cause des paramètres de sécurité de votre navigateur, l'éditeur ne peut accéder au presse-papier directement. Vous devez coller à nouveau le contenu dans cette fenêtre.", -DlgPasteIgnoreFont : "Ignorer les polices de caractères", -DlgPasteRemoveStyles : "Supprimer les styles", - -// Color Picker -ColorAutomatic : "Automatique", -ColorMoreColors : "Plus de couleurs...", - -// Document Properties -DocProps : "Propriétés du document", - -// Anchor Dialog -DlgAnchorTitle : "Propriétés de l'ancre", -DlgAnchorName : "Nom de l'ancre", -DlgAnchorErrorName : "Veuillez saisir le nom de l'ancre", - -// Speller Pages Dialog -DlgSpellNotInDic : "Pas dans le dictionnaire", -DlgSpellChangeTo : "Changer en", -DlgSpellBtnIgnore : "Ignorer", -DlgSpellBtnIgnoreAll : "Ignorer tout", -DlgSpellBtnReplace : "Remplacer", -DlgSpellBtnReplaceAll : "Remplacer tout", -DlgSpellBtnUndo : "Annuler", -DlgSpellNoSuggestions : "- Aucune suggestion -", -DlgSpellProgress : "Vérification d'orthographe en cours...", -DlgSpellNoMispell : "Vérification d'orthographe terminée: Aucune erreur trouvée", -DlgSpellNoChanges : "Vérification d'orthographe terminée: Pas de modifications", -DlgSpellOneChange : "Vérification d'orthographe terminée: Un mot modifié", -DlgSpellManyChanges : "Vérification d'orthographe terminée: %1 mots modifiés", - -IeSpellDownload : "Le Correcteur n'est pas installé. Souhaitez-vous le télécharger maintenant?", - -// Button Dialog -DlgButtonText : "Texte (valeur)", -DlgButtonType : "Type", -DlgButtonTypeBtn : "Bouton", -DlgButtonTypeSbm : "Envoyer", -DlgButtonTypeRst : "Réinitialiser", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nom", -DlgCheckboxValue : "Valeur", -DlgCheckboxSelected : "Sélectionné", - -// Form Dialog -DlgFormName : "Nom", -DlgFormAction : "Action", -DlgFormMethod : "Méthode", - -// Select Field Dialog -DlgSelectName : "Nom", -DlgSelectValue : "Valeur", -DlgSelectSize : "Taille", -DlgSelectLines : "lignes", -DlgSelectChkMulti : "Sélection multiple", -DlgSelectOpAvail : "Options disponibles", -DlgSelectOpText : "Texte", -DlgSelectOpValue : "Valeur", -DlgSelectBtnAdd : "Ajouter", -DlgSelectBtnModify : "Modifier", -DlgSelectBtnUp : "Monter", -DlgSelectBtnDown : "Descendre", -DlgSelectBtnSetValue : "Valeur sélectionnée", -DlgSelectBtnDelete : "Supprimer", - -// Textarea Dialog -DlgTextareaName : "Nom", -DlgTextareaCols : "Colonnes", -DlgTextareaRows : "Lignes", - -// Text Field Dialog -DlgTextName : "Nom", -DlgTextValue : "Valeur", -DlgTextCharWidth : "Largeur en caractères", -DlgTextMaxChars : "Nombre maximum de caractères", -DlgTextType : "Type", -DlgTextTypeText : "Texte", -DlgTextTypePass : "Mot de passe", - -// Hidden Field Dialog -DlgHiddenName : "Nom", -DlgHiddenValue : "Valeur", - -// Bulleted List Dialog -BulletedListProp : "Propriétés de liste à puces", -NumberedListProp : "Propriétés de liste numérotée", -DlgLstStart : "Début", -DlgLstType : "Type", -DlgLstTypeCircle : "Cercle", -DlgLstTypeDisc : "Disque", -DlgLstTypeSquare : "Carré", -DlgLstTypeNumbers : "Nombres (1, 2, 3)", -DlgLstTypeLCase : "Lettres minuscules (a, b, c)", -DlgLstTypeUCase : "Lettres majuscules (A, B, C)", -DlgLstTypeSRoman : "Chiffres romains minuscules (i, ii, iii)", -DlgLstTypeLRoman : "Chiffres romains majuscules (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Général", -DlgDocBackTab : "Fond", -DlgDocColorsTab : "Couleurs et marges", -DlgDocMetaTab : "Métadonnées", - -DlgDocPageTitle : "Titre de la page", -DlgDocLangDir : "Sens d'écriture", -DlgDocLangDirLTR : "De la gauche vers la droite (LTR)", -DlgDocLangDirRTL : "De la droite vers la gauche (RTL)", -DlgDocLangCode : "Code langue", -DlgDocCharSet : "Encodage de caractère", -DlgDocCharSetCE : "Europe Centrale", -DlgDocCharSetCT : "Chinois Traditionnel (Big5)", -DlgDocCharSetCR : "Cyrillique", -DlgDocCharSetGR : "Grec", -DlgDocCharSetJP : "Japonais", -DlgDocCharSetKR : "Coréen", -DlgDocCharSetTR : "Turc", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Occidental", -DlgDocCharSetOther : "Autre encodage de caractère", - -DlgDocDocType : "Type de document", -DlgDocDocTypeOther : "Autre type de document", -DlgDocIncXHTML : "Inclure les déclarations XHTML", -DlgDocBgColor : "Couleur de fond", -DlgDocBgImage : "Image de fond", -DlgDocBgNoScroll : "Image fixe sans défilement", -DlgDocCText : "Texte", -DlgDocCLink : "Lien", -DlgDocCVisited : "Lien visité", -DlgDocCActive : "Lien activé", -DlgDocMargins : "Marges", -DlgDocMaTop : "Haut", -DlgDocMaLeft : "Gauche", -DlgDocMaRight : "Droite", -DlgDocMaBottom : "Bas", -DlgDocMeIndex : "Mots-clés (séparés par des virgules)", -DlgDocMeDescr : "Description", -DlgDocMeAuthor : "Auteur", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Prévisualisation", - -// Templates Dialog -Templates : "Modèles", -DlgTemplatesTitle : "Modèles de contenu", -DlgTemplatesSelMsg : "Veuillez sélectionner le modèle à ouvrir dans l'éditeur
    (le contenu actuel sera remplacé):", -DlgTemplatesLoading : "Chargement de la liste des modèles. Veuillez patienter...", -DlgTemplatesNoTpl : "(Aucun modèle disponible)", -DlgTemplatesReplace : "Remplacer tout le contenu", - -// About Dialog -DlgAboutAboutTab : "A propos de", -DlgAboutBrowserInfoTab : "Navigateur", -DlgAboutLicenseTab : "Licence", -DlgAboutVersion : "Version", -DlgAboutInfo : "Pour plus d'informations, aller à", - -// Div Dialog -DlgDivGeneralTab : "Général", -DlgDivAdvancedTab : "Avancé", -DlgDivStyle : "Style", -DlgDivInlineStyle : "Attribut Style", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/gl.js b/httemplate/elements/fckeditor/editor/lang/gl.js deleted file mode 100644 index 311bfb457..000000000 --- a/httemplate/elements/fckeditor/editor/lang/gl.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Galician language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Ocultar Ferramentas", -ToolbarExpand : "Mostrar Ferramentas", - -// Toolbar Items and Context Menu -Save : "Gardar", -NewPage : "Nova Páxina", -Preview : "Vista Previa", -Cut : "Cortar", -Copy : "Copiar", -Paste : "Pegar", -PasteText : "Pegar como texto plano", -PasteWord : "Pegar dende Word", -Print : "Imprimir", -SelectAll : "Seleccionar todo", -RemoveFormat : "Eliminar Formato", -InsertLinkLbl : "Ligazón", -InsertLink : "Inserir/Editar Ligazón", -RemoveLink : "Eliminar Ligazón", -VisitLink : "Open Link", //MISSING -Anchor : "Inserir/Editar Referencia", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "Imaxe", -InsertImage : "Inserir/Editar Imaxe", -InsertFlashLbl : "Flash", -InsertFlash : "Inserir/Editar Flash", -InsertTableLbl : "Tabla", -InsertTable : "Inserir/Editar Tabla", -InsertLineLbl : "Liña", -InsertLine : "Inserir Liña Horizontal", -InsertSpecialCharLbl: "Carácter Special", -InsertSpecialChar : "Inserir Carácter Especial", -InsertSmileyLbl : "Smiley", -InsertSmiley : "Inserir Smiley", -About : "Acerca de FCKeditor", -Bold : "Negrita", -Italic : "Cursiva", -Underline : "Sub-raiado", -StrikeThrough : "Tachado", -Subscript : "Subíndice", -Superscript : "Superíndice", -LeftJustify : "Aliñar á Esquerda", -CenterJustify : "Centrado", -RightJustify : "Aliñar á Dereita", -BlockJustify : "Xustificado", -DecreaseIndent : "Disminuir Sangría", -IncreaseIndent : "Aumentar Sangría", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Desfacer", -Redo : "Refacer", -NumberedListLbl : "Lista Numerada", -NumberedList : "Inserir/Eliminar Lista Numerada", -BulletedListLbl : "Marcas", -BulletedList : "Inserir/Eliminar Marcas", -ShowTableBorders : "Mostrar Bordes das Táboas", -ShowDetails : "Mostrar Marcas Parágrafo", -Style : "Estilo", -FontFormat : "Formato", -Font : "Tipo", -FontSize : "Tamaño", -TextColor : "Cor do Texto", -BGColor : "Cor do Fondo", -Source : "Código Fonte", -Find : "Procurar", -Replace : "Substituir", -SpellCheck : "Corrección Ortográfica", -UniversalKeyboard : "Teclado Universal", -PageBreakLbl : "Salto de Páxina", -PageBreak : "Inserir Salto de Páxina", - -Form : "Formulario", -Checkbox : "Cadro de Verificación", -RadioButton : "Botón de Radio", -TextField : "Campo de Texto", -Textarea : "Área de Texto", -HiddenField : "Campo Oculto", -Button : "Botón", -SelectionField : "Campo de Selección", -ImageButton : "Botón de Imaxe", - -FitWindow : "Maximizar o tamaño do editor", -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "Editar Ligazón", -CellCM : "Cela", -RowCM : "Fila", -ColumnCM : "Columna", -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "Borrar Filas", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "Borrar Columnas", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "Borrar Cela", -MergeCells : "Unir Celas", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "Borrar Táboa", -CellProperties : "Propriedades da Cela", -TableProperties : "Propriedades da Táboa", -ImageProperties : "Propriedades Imaxe", -FlashProperties : "Propriedades Flash", - -AnchorProp : "Propriedades da Referencia", -ButtonProp : "Propriedades do Botón", -CheckboxProp : "Propriedades do Cadro de Verificación", -HiddenFieldProp : "Propriedades do Campo Oculto", -RadioButtonProp : "Propriedades do Botón de Radio", -ImageButtonProp : "Propriedades do Botón de Imaxe", -TextFieldProp : "Propriedades do Campo de Texto", -SelectionFieldProp : "Propriedades do Campo de Selección", -TextareaProp : "Propriedades da Área de Texto", -FormProp : "Propriedades do Formulario", - -FontFormats : "Normal;Formateado;Enderezo;Enacabezado 1;Encabezado 2;Encabezado 3;Encabezado 4;Encabezado 5;Encabezado 6;Paragraph (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Procesando XHTML. Por facor, agarde...", -Done : "Feiro", -PasteWordConfirm : "Parece que o texto que quere pegar está copiado do Word.¿Quere limpar o formato antes de pegalo?", -NotCompatiblePaste : "Este comando está disponible para Internet Explorer versión 5.5 ou superior. ¿Quere pegalo sen limpar o formato?", -UnknownToolbarItem : "Ítem de ferramentas descoñecido \"%1\"", -UnknownCommand : "Nome de comando descoñecido \"%1\"", -NotImplemented : "Comando non implementado", -UnknownToolbarSet : "O conxunto de ferramentas \"%1\" non existe", -NoActiveX : "As opcións de seguridade do seu navegador poderían limitar algunha das características de editor. Debe activar a opción \"Executar controis ActiveX e plug-ins\". Pode notar que faltan características e experimentar erros", -BrowseServerBlocked : "Non se poido abrir o navegador de recursos. Asegúrese de que están desactivados os bloqueadores de xanelas emerxentes", -DialogBlocked : "Non foi posible abrir a xanela de diálogo. Asegúrese de que están desactivados os bloqueadores de xanelas emerxentes", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Cancelar", -DlgBtnClose : "Pechar", -DlgBtnBrowseServer : "Navegar no Servidor", -DlgAdvancedTag : "Advanzado", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Por favor, insira a URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Orientación do Idioma", -DlgGenLangDirLtr : "Esquerda a Dereita (LTR)", -DlgGenLangDirRtl : "Dereita a Esquerda (RTL)", -DlgGenLangCode : "Código do Idioma", -DlgGenAccessKey : "Chave de Acceso", -DlgGenName : "Nome", -DlgGenTabIndex : "Índice de Tabulación", -DlgGenLongDescr : "Descrición Completa da URL", -DlgGenClass : "Clases da Folla de Estilos", -DlgGenTitle : "Título", -DlgGenContType : "Tipo de Contido", -DlgGenLinkCharset : "Fonte de Caracteres Vinculado", -DlgGenStyle : "Estilo", - -// Image Dialog -DlgImgTitle : "Propriedades da Imaxe", -DlgImgInfoTab : "Información da Imaxe", -DlgImgBtnUpload : "Enviar ó Servidor", -DlgImgURL : "URL", -DlgImgUpload : "Carregar", -DlgImgAlt : "Texto Alternativo", -DlgImgWidth : "Largura", -DlgImgHeight : "Altura", -DlgImgLockRatio : "Proporcional", -DlgBtnResetSize : "Tamaño Orixinal", -DlgImgBorder : "Límite", -DlgImgHSpace : "Esp. Horiz.", -DlgImgVSpace : "Esp. Vert.", -DlgImgAlign : "Aliñamento", -DlgImgAlignLeft : "Esquerda", -DlgImgAlignAbsBottom: "Abs Inferior", -DlgImgAlignAbsMiddle: "Abs Centro", -DlgImgAlignBaseline : "Liña Base", -DlgImgAlignBottom : "Pé", -DlgImgAlignMiddle : "Centro", -DlgImgAlignRight : "Dereita", -DlgImgAlignTextTop : "Tope do Texto", -DlgImgAlignTop : "Tope", -DlgImgPreview : "Vista Previa", -DlgImgAlertUrl : "Por favor, escriba a URL da imaxe", -DlgImgLinkTab : "Ligazón", - -// Flash Dialog -DlgFlashTitle : "Propriedades Flash", -DlgFlashChkPlay : "Auto Execución", -DlgFlashChkLoop : "Bucle", -DlgFlashChkMenu : "Activar Menú Flash", -DlgFlashScale : "Escalar", -DlgFlashScaleAll : "Amosar Todo", -DlgFlashScaleNoBorder : "Sen Borde", -DlgFlashScaleFit : "Encaixar axustando", - -// Link Dialog -DlgLnkWindowTitle : "Ligazón", -DlgLnkInfoTab : "Información da Ligazón", -DlgLnkTargetTab : "Referencia a esta páxina", - -DlgLnkType : "Tipo de Ligazón", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Referencia nesta páxina", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocolo", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Seleccionar unha Referencia", -DlgLnkAnchorByName : "Por Nome de Referencia", -DlgLnkAnchorById : "Por Element Id", -DlgLnkNoAnchors : "(Non hai referencias disponibles no documento)", -DlgLnkEMail : "Enderezo de E-Mail", -DlgLnkEMailSubject : "Asunto do Mensaxe", -DlgLnkEMailBody : "Corpo do Mensaxe", -DlgLnkUpload : "Carregar", -DlgLnkBtnUpload : "Enviar ó servidor", - -DlgLnkTarget : "Destino", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nova Xanela (_blank)", -DlgLnkTargetParent : "Xanela Pai (_parent)", -DlgLnkTargetSelf : "Mesma Xanela (_self)", -DlgLnkTargetTop : "Xanela Primaria (_top)", -DlgLnkTargetFrameName : "Nome do Marco Destino", -DlgLnkPopWinName : "Nome da Xanela Emerxente", -DlgLnkPopWinFeat : "Características da Xanela Emerxente", -DlgLnkPopResize : "Axustable", -DlgLnkPopLocation : "Barra de Localización", -DlgLnkPopMenu : "Barra de Menú", -DlgLnkPopScroll : "Barras de Desplazamento", -DlgLnkPopStatus : "Barra de Estado", -DlgLnkPopToolbar : "Barra de Ferramentas", -DlgLnkPopFullScrn : "A Toda Pantalla (IE)", -DlgLnkPopDependent : "Dependente (Netscape)", -DlgLnkPopWidth : "Largura", -DlgLnkPopHeight : "Altura", -DlgLnkPopLeft : "Posición Esquerda", -DlgLnkPopTop : "Posición dende Arriba", - -DlnLnkMsgNoUrl : "Por favor, escriba a ligazón URL", -DlnLnkMsgNoEMail : "Por favor, escriba o enderezo de e-mail", -DlnLnkMsgNoAnchor : "Por favor, seleccione un destino", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", //MISSING - -// Color Dialog -DlgColorTitle : "Seleccionar Color", -DlgColorBtnClear : "Nengunha", -DlgColorHighlight : "Destacado", -DlgColorSelected : "Seleccionado", - -// Smiley Dialog -DlgSmileyTitle : "Inserte un Smiley", - -// Special Character Dialog -DlgSpecialCharTitle : "Seleccione Caracter Especial", - -// Table Dialog -DlgTableTitle : "Propiedades da Táboa", -DlgTableRows : "Filas", -DlgTableColumns : "Columnas", -DlgTableBorder : "Tamaño do Borde", -DlgTableAlign : "Aliñamento", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Esquerda", -DlgTableAlignCenter : "Centro", -DlgTableAlignRight : "Ereita", -DlgTableWidth : "Largura", -DlgTableWidthPx : "pixels", -DlgTableWidthPc : "percent", -DlgTableHeight : "Altura", -DlgTableCellSpace : "Marxe entre Celas", -DlgTableCellPad : "Marxe interior", -DlgTableCaption : "Título", -DlgTableSummary : "Sumario", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Propriedades da Cela", -DlgCellWidth : "Largura", -DlgCellWidthPx : "pixels", -DlgCellWidthPc : "percent", -DlgCellHeight : "Altura", -DlgCellWordWrap : "Axustar Liñas", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Si", -DlgCellWordWrapNo : "Non", -DlgCellHorAlign : "Aliñamento Horizontal", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Esquerda", -DlgCellHorAlignCenter : "Centro", -DlgCellHorAlignRight: "Dereita", -DlgCellVerAlign : "Aliñamento Vertical", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Arriba", -DlgCellVerAlignMiddle : "Medio", -DlgCellVerAlignBottom : "Abaixo", -DlgCellVerAlignBaseline : "Liña de Base", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Ocupar Filas", -DlgCellCollSpan : "Ocupar Columnas", -DlgCellBackColor : "Color de Fondo", -DlgCellBorderColor : "Color de Borde", -DlgCellBtnSelect : "Seleccionar...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", //MISSING - -// Find Dialog -DlgFindTitle : "Procurar", -DlgFindFindBtn : "Procurar", -DlgFindNotFoundMsg : "Non te atopou o texto indicado.", - -// Replace Dialog -DlgReplaceTitle : "Substituir", -DlgReplaceFindLbl : "Texto a procurar:", -DlgReplaceReplaceLbl : "Substituir con:", -DlgReplaceCaseChk : "Coincidir Mai./min.", -DlgReplaceReplaceBtn : "Substituir", -DlgReplaceReplAllBtn : "Substitiur Todo", -DlgReplaceWordChk : "Coincidir con toda a palabra", - -// Paste Operations / Dialog -PasteErrorCut : "Os axustes de seguridade do seu navegador non permiten que o editor realice automáticamente as tarefas de corte. Por favor, use o teclado para iso (Ctrl+X).", -PasteErrorCopy : "Os axustes de seguridade do seu navegador non permiten que o editor realice automáticamente as tarefas de copia. Por favor, use o teclado para iso (Ctrl+C).", - -PasteAsText : "Pegar como texto plano", -PasteFromWord : "Pegar dende Word", - -DlgPasteMsg2 : "Por favor, pegue dentro do seguinte cadro usando o teclado (Ctrl+V) e pulse OK.", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", //MISSING -DlgPasteIgnoreFont : "Ignorar as definicións de Tipografía", -DlgPasteRemoveStyles : "Eliminar as definicións de Estilos", - -// Color Picker -ColorAutomatic : "Automático", -ColorMoreColors : "Máis Cores...", - -// Document Properties -DocProps : "Propriedades do Documento", - -// Anchor Dialog -DlgAnchorTitle : "Propriedades da Referencia", -DlgAnchorName : "Nome da Referencia", -DlgAnchorErrorName : "Por favor, escriba o nome da referencia", - -// Speller Pages Dialog -DlgSpellNotInDic : "Non está no diccionario", -DlgSpellChangeTo : "Cambiar a", -DlgSpellBtnIgnore : "Ignorar", -DlgSpellBtnIgnoreAll : "Ignorar Todas", -DlgSpellBtnReplace : "Substituir", -DlgSpellBtnReplaceAll : "Substituir Todas", -DlgSpellBtnUndo : "Desfacer", -DlgSpellNoSuggestions : "- Sen candidatos -", -DlgSpellProgress : "Corrección ortográfica en progreso...", -DlgSpellNoMispell : "Corrección ortográfica rematada: Non se atoparon erros", -DlgSpellNoChanges : "Corrección ortográfica rematada: Non se substituiu nengunha verba", -DlgSpellOneChange : "Corrección ortográfica rematada: Unha verba substituida", -DlgSpellManyChanges : "Corrección ortográfica rematada: %1 verbas substituidas", - -IeSpellDownload : "O corrector ortográfico non está instalado. ¿Quere descargalo agora?", - -// Button Dialog -DlgButtonText : "Texto (Valor)", -DlgButtonType : "Tipo", -DlgButtonTypeBtn : "Button", //MISSING -DlgButtonTypeSbm : "Submit", //MISSING -DlgButtonTypeRst : "Reset", //MISSING - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nome", -DlgCheckboxValue : "Valor", -DlgCheckboxSelected : "Seleccionado", - -// Form Dialog -DlgFormName : "Nome", -DlgFormAction : "Acción", -DlgFormMethod : "Método", - -// Select Field Dialog -DlgSelectName : "Nome", -DlgSelectValue : "Valor", -DlgSelectSize : "Tamaño", -DlgSelectLines : "liñas", -DlgSelectChkMulti : "Permitir múltiples seleccións", -DlgSelectOpAvail : "Opcións Disponibles", -DlgSelectOpText : "Texto", -DlgSelectOpValue : "Valor", -DlgSelectBtnAdd : "Engadir", -DlgSelectBtnModify : "Modificar", -DlgSelectBtnUp : "Subir", -DlgSelectBtnDown : "Baixar", -DlgSelectBtnSetValue : "Definir como valor por defecto", -DlgSelectBtnDelete : "Borrar", - -// Textarea Dialog -DlgTextareaName : "Nome", -DlgTextareaCols : "Columnas", -DlgTextareaRows : "Filas", - -// Text Field Dialog -DlgTextName : "Nome", -DlgTextValue : "Valor", -DlgTextCharWidth : "Tamaño do Caracter", -DlgTextMaxChars : "Máximo de Caracteres", -DlgTextType : "Tipo", -DlgTextTypeText : "Texto", -DlgTextTypePass : "Chave", - -// Hidden Field Dialog -DlgHiddenName : "Nome", -DlgHiddenValue : "Valor", - -// Bulleted List Dialog -BulletedListProp : "Propriedades das Marcas", -NumberedListProp : "Propriedades da Lista de Numeración", -DlgLstStart : "Start", //MISSING -DlgLstType : "Tipo", -DlgLstTypeCircle : "Círculo", -DlgLstTypeDisc : "Disco", -DlgLstTypeSquare : "Cuadrado", -DlgLstTypeNumbers : "Números (1, 2, 3)", -DlgLstTypeLCase : "Letras Minúsculas (a, b, c)", -DlgLstTypeUCase : "Letras Maiúsculas (A, B, C)", -DlgLstTypeSRoman : "Números Romanos en minúscula (i, ii, iii)", -DlgLstTypeLRoman : "Números Romanos en Maiúscula (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Xeral", -DlgDocBackTab : "Fondo", -DlgDocColorsTab : "Cores e Marxes", -DlgDocMetaTab : "Meta Data", - -DlgDocPageTitle : "Título da Páxina", -DlgDocLangDir : "Orientación do Idioma", -DlgDocLangDirLTR : "Esquerda a Dereita (LTR)", -DlgDocLangDirRTL : "Dereita a Esquerda (RTL)", -DlgDocLangCode : "Código de Idioma", -DlgDocCharSet : "Codificación do Xogo de Caracteres", -DlgDocCharSetCE : "Central European", //MISSING -DlgDocCharSetCT : "Chinese Traditional (Big5)", //MISSING -DlgDocCharSetCR : "Cyrillic", //MISSING -DlgDocCharSetGR : "Greek", //MISSING -DlgDocCharSetJP : "Japanese", //MISSING -DlgDocCharSetKR : "Korean", //MISSING -DlgDocCharSetTR : "Turkish", //MISSING -DlgDocCharSetUN : "Unicode (UTF-8)", //MISSING -DlgDocCharSetWE : "Western European", //MISSING -DlgDocCharSetOther : "Outra Codificación do Xogo de Caracteres", - -DlgDocDocType : "Encabezado do Tipo de Documento", -DlgDocDocTypeOther : "Outro Encabezado do Tipo de Documento", -DlgDocIncXHTML : "Incluir Declaracións XHTML", -DlgDocBgColor : "Cor de Fondo", -DlgDocBgImage : "URL da Imaxe de Fondo", -DlgDocBgNoScroll : "Fondo Fixo", -DlgDocCText : "Texto", -DlgDocCLink : "Ligazóns", -DlgDocCVisited : "Ligazón Visitada", -DlgDocCActive : "Ligazón Activa", -DlgDocMargins : "Marxes da Páxina", -DlgDocMaTop : "Arriba", -DlgDocMaLeft : "Esquerda", -DlgDocMaRight : "Dereita", -DlgDocMaBottom : "Abaixo", -DlgDocMeIndex : "Palabras Chave de Indexación do Documento (separadas por comas)", -DlgDocMeDescr : "Descripción do Documento", -DlgDocMeAuthor : "Autor", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Vista Previa", - -// Templates Dialog -Templates : "Plantillas", -DlgTemplatesTitle : "Plantillas de Contido", -DlgTemplatesSelMsg : "Por favor, seleccione a plantilla a abrir no editor
    (o contido actual perderase):", -DlgTemplatesLoading : "Cargando listado de plantillas. Por favor, espere...", -DlgTemplatesNoTpl : "(Non hai plantillas definidas)", -DlgTemplatesReplace : "Replace actual contents", //MISSING - -// About Dialog -DlgAboutAboutTab : "Acerca de", -DlgAboutBrowserInfoTab : "Información do Navegador", -DlgAboutLicenseTab : "Licencia", -DlgAboutVersion : "versión", -DlgAboutInfo : "Para máis información visitar:", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/gu.js b/httemplate/elements/fckeditor/editor/lang/gu.js deleted file mode 100644 index 3e8b6b27a..000000000 --- a/httemplate/elements/fckeditor/editor/lang/gu.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Gujarati language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "ટૂલબાર નાનું કરવું", -ToolbarExpand : "ટૂલબાર મોટું કરવું", - -// Toolbar Items and Context Menu -Save : "સેવ", -NewPage : "નવુ પાનું", -Preview : "પૂર્વદર્શન", -Cut : "કાપવું", -Copy : "નકલ", -Paste : "પેસ્ટ", -PasteText : "પેસ્ટ (સાદી ટેક્સ્ટ)", -PasteWord : "પેસ્ટ (વડૅ ટેક્સ્ટ)", -Print : "પ્રિન્ટ", -SelectAll : "બઘું પસંદ કરવું", -RemoveFormat : "ફૉર્મટ કાઢવું", -InsertLinkLbl : "સંબંધન, લિંક", -InsertLink : "લિંક ઇન્સર્ટ/દાખલ કરવી", -RemoveLink : "લિંક કાઢવી", -VisitLink : "Open Link", //MISSING -Anchor : "ઍંકર ઇન્સર્ટ/દાખલ કરવી", -AnchorDelete : "ઍંકર કાઢવી", -InsertImageLbl : "ચિત્ર", -InsertImage : "ચિત્ર ઇન્સર્ટ/દાખલ કરવું", -InsertFlashLbl : "ફ્લૅશ", -InsertFlash : "ફ્લૅશ ઇન્સર્ટ/દાખલ કરવું", -InsertTableLbl : "ટેબલ, કોઠો", -InsertTable : "ટેબલ, કોઠો ઇન્સર્ટ/દાખલ કરવું", -InsertLineLbl : "રેખા", -InsertLine : "સમસ્તરીય રેખા ઇન્સર્ટ/દાખલ કરવી", -InsertSpecialCharLbl: "વિશિષ્ટ અક્ષર", -InsertSpecialChar : "વિશિષ્ટ અક્ષર ઇન્સર્ટ/દાખલ કરવું", -InsertSmileyLbl : "સ્માઇલી", -InsertSmiley : "સ્માઇલી ઇન્સર્ટ/દાખલ કરવી", -About : "FCKeditorના વિષે", -Bold : "બોલ્ડ/સ્પષ્ટ", -Italic : "ઇટેલિક, ત્રાંસા", -Underline : "અન્ડર્લાઇન, નીચે લીટી", -StrikeThrough : "છેકી નાખવું", -Subscript : "એક ચિહ્નની નીચે કરેલું બીજું ચિહ્ન", -Superscript : "એક ચિહ્ન ઉપર કરેલું બીજું ચિહ્ન.", -LeftJustify : "ડાબી બાજુએ/બાજુ તરફ", -CenterJustify : "સંકેંદ્રણ/સેંટરિંગ", -RightJustify : "જમણી બાજુએ/બાજુ તરફ", -BlockJustify : "બ્લૉક, અંતરાય જસ્ટિફાઇ", -DecreaseIndent : "ઇન્ડેન્ટ લીટીના આરંભમાં જગ્યા ઘટાડવી", -IncreaseIndent : "ઇન્ડેન્ટ, લીટીના આરંભમાં જગ્યા વધારવી", -Blockquote : "બ્લૉક-કોટ, અવતરણચિહ્નો", -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "રદ કરવું; પહેલાં હતી એવી સ્થિતિ પાછી લાવવી", -Redo : "રિડૂ; પછી હતી એવી સ્થિતિ પાછી લાવવી", -NumberedListLbl : "સંખ્યાંકન સૂચિ", -NumberedList : "સંખ્યાંકન સૂચિ ઇન્સર્ટ/દાખલ કરવી", -BulletedListLbl : "બુલેટ સૂચિ", -BulletedList : "બુલેટ સૂચિ ઇન્સર્ટ/દાખલ કરવી", -ShowTableBorders : "ટેબલ, કોઠાની બાજુ(બોર્ડર) બતાવવી", -ShowDetails : "વિસ્તૃત વિગતવાર બતાવવું", -Style : "શૈલી/રીત", -FontFormat : "ફૉન્ટ ફૉર્મટ, રચનાની શૈલી", -Font : "ફૉન્ટ", -FontSize : "ફૉન્ટ સાઇઝ/કદ", -TextColor : "શબ્દનો રંગ", -BGColor : "બૅકગ્રાઉન્ડ રંગ,", -Source : "મૂળ કે પ્રાથમિક દસ્તાવેજ", -Find : "શોધવું", -Replace : "રિપ્લેસ/બદલવું", -SpellCheck : "જોડણી (સ્પેલિંગ) તપાસવી", -UniversalKeyboard : "યૂનિવર્સલ/વિશ્વવ્યાપક કીબૉર્ડ", -PageBreakLbl : "પેજબ્રેક/પાનાને અલગ કરવું", -PageBreak : "ઇન્સર્ટ પેજબ્રેક/પાનાને અલગ કરવું/દાખલ કરવું", - -Form : "ફૉર્મ/પત્રક", -Checkbox : "ચેક બોક્સ", -RadioButton : "રેડિઓ બટન", -TextField : "ટેક્સ્ટ ફીલ્ડ, શબ્દ ક્ષેત્ર", -Textarea : "ટેક્સ્ટ એરિઆ, શબ્દ વિસ્તાર", -HiddenField : "ગુપ્ત ક્ષેત્ર", -Button : "બટન", -SelectionField : "પસંદગી ક્ષેત્ર", -ImageButton : "ચિત્ર બટન", - -FitWindow : "એડિટરની સાઇઝ અધિકતમ કરવી", -ShowBlocks : "બ્લૉક બતાવવું", - -// Context Menu -EditLink : " લિંક એડિટ/માં ફેરફાર કરવો", -CellCM : "કોષના ખાના", -RowCM : "પંક્તિના ખાના", -ColumnCM : "કૉલમ/ઊભી કટાર", -InsertRowAfter : "પછી પંક્તિ ઉમેરવી", -InsertRowBefore : "પહેલાં પંક્તિ ઉમેરવી", -DeleteRows : "પંક્તિઓ ડિલીટ/કાઢી નાખવી", -InsertColumnAfter : "પછી કૉલમ/ઊભી કટાર ઉમેરવી", -InsertColumnBefore : "પહેલાં કૉલમ/ઊભી કટાર ઉમેરવી", -DeleteColumns : "કૉલમ/ઊભી કટાર ડિલીટ/કાઢી નાખવી", -InsertCellAfter : "પછી કોષ ઉમેરવો", -InsertCellBefore : "પહેલાં કોષ ઉમેરવો", -DeleteCells : "કોષ ડિલીટ/કાઢી નાખવો", -MergeCells : "કોષ ભેગા કરવા", -MergeRight : "જમણી બાજુ ભેગા કરવા", -MergeDown : "નીચે ભેગા કરવા", -HorizontalSplitCell : "કોષને સમસ્તરીય વિભાજન કરવું", -VerticalSplitCell : "કોષને સીધું ને ઊભું વિભાજન કરવું", -TableDelete : "કોઠો ડિલીટ/કાઢી નાખવું", -CellProperties : "કોષના ગુણ", -TableProperties : "કોઠાના ગુણ", -ImageProperties : "ચિત્રના ગુણ", -FlashProperties : "ફ્લૅશના ગુણ", - -AnchorProp : "ઍંકરના ગુણ", -ButtonProp : "બટનના ગુણ", -CheckboxProp : "ચેક બોક્સ ગુણ", -HiddenFieldProp : "ગુપ્ત ક્ષેત્રના ગુણ", -RadioButtonProp : "રેડિઓ બટનના ગુણ", -ImageButtonProp : "ચિત્ર બટનના ગુણ", -TextFieldProp : "ટેક્સ્ટ ફીલ્ડ, શબ્દ ક્ષેત્રના ગુણ", -SelectionFieldProp : "પસંદગી ક્ષેત્રના ગુણ", -TextareaProp : "ટેક્સ્ટ એઅરિઆ, શબ્દ વિસ્તારના ગુણ", -FormProp : "ફૉર્મ/પત્રકના ગુણ", - -FontFormats : "સામાન્ય;ફૉર્મટેડ;સરનામું;શીર્ષક 1;શીર્ષક 2;શીર્ષક 3;શીર્ષક 4;શીર્ષક 5;શીર્ષક 6;શીર્ષક (DIV)", - -// Alerts and Messages -ProcessingXHTML : "XHTML પ્રક્રિયા ચાલુ છે. મહેરબાની કરીને રાહ જોવો...", -Done : "પતી ગયું", -PasteWordConfirm : "તમે જે ટેક્સ્ટ પેસ્ટ કરવા માંગો છો, તે વડૅમાંથી કોપી કરેલુ લાગે છે. પેસ્ટ કરતા પહેલાં ટેક્સ્ટ સાફ કરવી છે?", -NotCompatiblePaste : "આ કમાન્ડ ઈનટરનેટ એક્સપ્લોરર(Internet Explorer) 5.5 અથવા એના પછીના વર્ઝન માટેજ છે. ટેક્સ્ટને સાફ કયૅા પહેલાં પેસ્ટ કરવી છે?", -UnknownToolbarItem : "અજાણી ટૂલબાર આઇટમ \"%1\"", -UnknownCommand : "અજાણયો કમાન્ડ \"%1\"", -NotImplemented : "કમાન્ડ ઇમ્પ્લિમન્ટ નથી કરોયો", -UnknownToolbarSet : "ટૂલબાર સેટ \"%1\" ઉપલબ્ધ નથી", -NoActiveX : "તમારા બ્રાઉઝરની સુરક્ષા સેટિંગસ એડિટરના અમુક ફીચરને પરવાનગી આપતી નથી. કૃપયા \"Run ActiveX controls and plug-ins\" વિકલ્પને ઇનેબલ/સમર્થ કરો. તમારા બ્રાઉઝરમાં એરર ઇન્વિઝિબલ ફીચરનો અનુભવ થઈ શકે છે. કૃપયા પૉપ-અપ બ્લૉકર ડિસેબલ કરો.", -BrowseServerBlocked : "રિસૉર્સ બ્રાઉઝર ખોલી ન સકાયું.", -DialogBlocked : "ડાયલૉગ વિન્ડો ખોલી ન સકાયું. કૃપયા પૉપ-અપ બ્લૉકર ડિસેબલ કરો.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "ઠીક છે", -DlgBtnCancel : "રદ કરવું", -DlgBtnClose : "બંધ કરવું", -DlgBtnBrowseServer : "સર્વર બ્રાઉઝ કરો", -DlgAdvancedTag : "અડ્વાન્સડ", -DlgOpOther : "<અન્ય>", -DlgInfoTab : "સૂચના", -DlgAlertUrl : "URL ઇન્સર્ટ કરો", - -// General Dialogs Labels -DlgGenNotSet : "<સેટ નથી>", -DlgGenId : "Id", -DlgGenLangDir : "ભાષા લેખવાની પદ્ધતિ", -DlgGenLangDirLtr : "ડાબે થી જમણે (LTR)", -DlgGenLangDirRtl : "જમણે થી ડાબે (RTL)", -DlgGenLangCode : "ભાષા કોડ", -DlgGenAccessKey : "ઍક્સેસ કી", -DlgGenName : "નામ", -DlgGenTabIndex : "ટૅબ ઇન્ડેક્સ", -DlgGenLongDescr : "વધારે માહિતી માટે URL", -DlgGenClass : "સ્ટાઇલ-શીટ ક્લાસ", -DlgGenTitle : "મુખ્ય મથાળું", -DlgGenContType : "મુખ્ય કન્ટેન્ટ પ્રકાર", -DlgGenLinkCharset : "લિંક રિસૉર્સ કૅરિક્ટર સેટ", -DlgGenStyle : "સ્ટાઇલ", - -// Image Dialog -DlgImgTitle : "ચિત્રના ગુણ", -DlgImgInfoTab : "ચિત્ર ની જાણકારી", -DlgImgBtnUpload : "આ સર્વરને મોકલવું", -DlgImgURL : "URL", -DlgImgUpload : "અપલોડ", -DlgImgAlt : "ઑલ્ટર્નટ ટેક્સ્ટ", -DlgImgWidth : "પહોળાઈ", -DlgImgHeight : "ઊંચાઈ", -DlgImgLockRatio : "લૉક ગુણોત્તર", -DlgBtnResetSize : "રીસેટ સાઇઝ", -DlgImgBorder : "બોર્ડર", -DlgImgHSpace : "સમસ્તરીય જગ્યા", -DlgImgVSpace : "લંબરૂપ જગ્યા", -DlgImgAlign : "લાઇનદોરીમાં ગોઠવવું", -DlgImgAlignLeft : "ડાબી બાજુ ગોઠવવું", -DlgImgAlignAbsBottom: "Abs નીચે", -DlgImgAlignAbsMiddle: "Abs ઉપર", -DlgImgAlignBaseline : "આધાર લીટી", -DlgImgAlignBottom : "નીચે", -DlgImgAlignMiddle : "વચ્ચે", -DlgImgAlignRight : "જમણી", -DlgImgAlignTextTop : "ટેક્સ્ટ ઉપર", -DlgImgAlignTop : "ઉપર", -DlgImgPreview : "પૂર્વદર્શન", -DlgImgAlertUrl : "ચિત્રની URL ટાઇપ કરો", -DlgImgLinkTab : "લિંક", - -// Flash Dialog -DlgFlashTitle : "ફ્લૅશ ગુણ", -DlgFlashChkPlay : "ઑટો/સ્વયં પ્લે", -DlgFlashChkLoop : "લૂપ", -DlgFlashChkMenu : "ફ્લૅશ મેન્યૂ નો પ્રયોગ કરો", -DlgFlashScale : "સ્કેલ", -DlgFlashScaleAll : "સ્કેલ ઓલ/બધુ બતાવો", -DlgFlashScaleNoBorder : "સ્કેલ બોર્ડર વગર", -DlgFlashScaleFit : "સ્કેલ એકદમ ફીટ", - -// Link Dialog -DlgLnkWindowTitle : "લિંક", -DlgLnkInfoTab : "લિંક ઇન્ફૉ ટૅબ", -DlgLnkTargetTab : "ટાર્ગેટ/લક્ષ્ય ટૅબ", - -DlgLnkType : "લિંક પ્રકાર", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "આ પેજનો ઍંકર", -DlgLnkTypeEMail : "ઈ-મેલ", -DlgLnkProto : "પ્રોટોકૉલ", -DlgLnkProtoOther : "<અન્ય>", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "ઍંકર પસંદ કરો", -DlgLnkAnchorByName : "ઍંકર નામથી પસંદ કરો", -DlgLnkAnchorById : "ઍંકર એલિમન્ટ Id થી પસંદ કરો", -DlgLnkNoAnchors : "(ડૉક્યુમન્ટમાં ઍંકરની સંખ્યા)", -DlgLnkEMail : "ઈ-મેલ સરનામું", -DlgLnkEMailSubject : "ઈ-મેલ વિષય", -DlgLnkEMailBody : "સંદેશ", -DlgLnkUpload : "અપલોડ", -DlgLnkBtnUpload : "આ સર્વરને મોકલવું", - -DlgLnkTarget : "ટાર્ગેટ/લક્ષ્ય", -DlgLnkTargetFrame : "<ફ્રેમ>", -DlgLnkTargetPopup : "<પૉપ-અપ વિન્ડો>", -DlgLnkTargetBlank : "નવી વિન્ડો (_blank)", -DlgLnkTargetParent : "મૂળ વિન્ડો (_parent)", -DlgLnkTargetSelf : "આજ વિન્ડો (_self)", -DlgLnkTargetTop : "ઉપરની વિન્ડો (_top)", -DlgLnkTargetFrameName : "ટાર્ગેટ ફ્રેમ નું નામ", -DlgLnkPopWinName : "પૉપ-અપ વિન્ડો નું નામ", -DlgLnkPopWinFeat : "પૉપ-અપ વિન્ડો ફીચરસૅ", -DlgLnkPopResize : "સાઇઝ બદલી સકાય છે", -DlgLnkPopLocation : "લોકેશન બાર", -DlgLnkPopMenu : "મેન્યૂ બાર", -DlgLnkPopScroll : "સ્ક્રોલ બાર", -DlgLnkPopStatus : "સ્ટૅટસ બાર", -DlgLnkPopToolbar : "ટૂલ બાર", -DlgLnkPopFullScrn : "ફુલ સ્ક્રીન (IE)", -DlgLnkPopDependent : "ડિપેન્ડન્ટ (Netscape)", -DlgLnkPopWidth : "પહોળાઈ", -DlgLnkPopHeight : "ઊંચાઈ", -DlgLnkPopLeft : "ડાબી બાજુ", -DlgLnkPopTop : "જમણી બાજુ", - -DlnLnkMsgNoUrl : "લિંક URL ટાઇપ કરો", -DlnLnkMsgNoEMail : "ઈ-મેલ સરનામું ટાઇપ કરો", -DlnLnkMsgNoAnchor : "ઍંકર પસંદ કરો", -DlnLnkMsgInvPopName : "પૉપ-અપ વિન્ડો નું નામ ઍલ્ફબેટથી શરૂ કરવો અને તેમાં સ્પેઇસ ન હોવી જોઈએ", - -// Color Dialog -DlgColorTitle : "રંગ પસંદ કરો", -DlgColorBtnClear : "સાફ કરો", -DlgColorHighlight : "હાઈલાઇટ", -DlgColorSelected : "સિલેક્ટેડ/પસંદ કરવું", - -// Smiley Dialog -DlgSmileyTitle : "સ્માઇલી પસંદ કરો", - -// Special Character Dialog -DlgSpecialCharTitle : "સ્પેશિઅલ વિશિષ્ટ અક્ષર પસંદ કરો", - -// Table Dialog -DlgTableTitle : "ટેબલ, કોઠાનું મથાળું", -DlgTableRows : "પંક્તિના ખાના", -DlgTableColumns : "કૉલમ/ઊભી કટાર", -DlgTableBorder : "કોઠાની બાજુ(બોર્ડર) સાઇઝ", -DlgTableAlign : "અલાઇનમન્ટ/ગોઠવાયેલું ", -DlgTableAlignNotSet : "<સેટ નથી>", -DlgTableAlignLeft : "ડાબી બાજુ", -DlgTableAlignCenter : "મધ્ય સેન્ટર", -DlgTableAlignRight : "જમણી બાજુ", -DlgTableWidth : "પહોળાઈ", -DlgTableWidthPx : "પિકસલ", -DlgTableWidthPc : "પ્રતિશત", -DlgTableHeight : "ઊંચાઈ", -DlgTableCellSpace : "સેલ અંતર", -DlgTableCellPad : "સેલ પૅડિંગ", -DlgTableCaption : "મથાળું/કૅપ્શન ", -DlgTableSummary : "ટૂંકો એહેવાલ", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "પંક્તિના ખાનાના ગુણ", -DlgCellWidth : "પહોળાઈ", -DlgCellWidthPx : "પિકસલ", -DlgCellWidthPc : "પ્રતિશત", -DlgCellHeight : "ઊંચાઈ", -DlgCellWordWrap : "વર્ડ રૅપ", -DlgCellWordWrapNotSet : "<સેટ નથી>", -DlgCellWordWrapYes : "હા", -DlgCellWordWrapNo : "ના", -DlgCellHorAlign : "સમસ્તરીય ગોઠવવું", -DlgCellHorAlignNotSet : "<સેટ નથી>", -DlgCellHorAlignLeft : "ડાબી બાજુ", -DlgCellHorAlignCenter : "મધ્ય સેન્ટર", -DlgCellHorAlignRight: "જમણી બાજુ", -DlgCellVerAlign : "લંબરૂપ ગોઠવવું", -DlgCellVerAlignNotSet : "<સેટ નથી>", -DlgCellVerAlignTop : "ઉપર", -DlgCellVerAlignMiddle : "મધ્ય સેન્ટર", -DlgCellVerAlignBottom : "નીચે", -DlgCellVerAlignBaseline : "મૂળ રેખા", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "પંક્તિ સ્પાન", -DlgCellCollSpan : "કૉલમ/ઊભી કટાર સ્પાન", -DlgCellBackColor : "બૅકગ્રાઉન્ડ રંગ", -DlgCellBorderColor : "બોર્ડરનો રંગ", -DlgCellBtnSelect : "પસંદ કરો...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "શોધવું અને બદલવું", - -// Find Dialog -DlgFindTitle : "શોધવું", -DlgFindFindBtn : "શોધવું", -DlgFindNotFoundMsg : "તમે શોધેલી ટેક્સ્ટ નથી મળી", - -// Replace Dialog -DlgReplaceTitle : "બદલવું", -DlgReplaceFindLbl : "આ શોધો", -DlgReplaceReplaceLbl : "આનાથી બદલો", -DlgReplaceCaseChk : "કેસ સરખા રાખો", -DlgReplaceReplaceBtn : "બદલવું", -DlgReplaceReplAllBtn : "બઘા બદલી ", -DlgReplaceWordChk : "બઘા શબ્દ સરખા રાખો", - -// Paste Operations / Dialog -PasteErrorCut : "તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસ કટ કરવાની પરવાનગી નથી આપતી. (Ctrl+X) નો ઉપયોગ કરો.", -PasteErrorCopy : "તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસ કોપી કરવાની પરવાનગી નથી આપતી. (Ctrl+C) का प्रयोग करें।", - -PasteAsText : "પેસ્ટ (ટેક્સ્ટ)", -PasteFromWord : "પેસ્ટ (વર્ડ થી)", - -DlgPasteMsg2 : "Ctrl+V નો પ્રયોગ કરી પેસ્ટ કરો", -DlgPasteSec : "તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસના કારણે,એડિટર તમારા કિલ્પબોર્ડ ડેટા ને કોપી નથી કરી શકતો. તમારે આ વિન્ડોમાં ફરીથી પેસ્ટ કરવું પડશે.", -DlgPasteIgnoreFont : "ફૉન્ટફેસ વ્યાખ્યાની અવગણના", -DlgPasteRemoveStyles : "સ્ટાઇલ વ્યાખ્યા કાઢી નાખવી", - -// Color Picker -ColorAutomatic : "સ્વચાલિત", -ColorMoreColors : "ઔર રંગ...", - -// Document Properties -DocProps : "ડૉક્યુમન્ટ ગુણ/પ્રૉપર્ટિઝ", - -// Anchor Dialog -DlgAnchorTitle : "ઍંકર ગુણ/પ્રૉપર્ટિઝ", -DlgAnchorName : "ઍંકરનું નામ", -DlgAnchorErrorName : "ઍંકરનું નામ ટાઈપ કરો", - -// Speller Pages Dialog -DlgSpellNotInDic : "શબ્દકોશમાં નથી", -DlgSpellChangeTo : "આનાથી બદલવું", -DlgSpellBtnIgnore : "ઇગ્નોર/અવગણના કરવી", -DlgSpellBtnIgnoreAll : "બધાની ઇગ્નોર/અવગણના કરવી", -DlgSpellBtnReplace : "બદલવું", -DlgSpellBtnReplaceAll : "બધા બદલી કરો", -DlgSpellBtnUndo : "અન્ડૂ", -DlgSpellNoSuggestions : "- કઇ સજેશન નથી -", -DlgSpellProgress : "શબ્દની જોડણી/સ્પેલ ચેક ચાલુ છે...", -DlgSpellNoMispell : "શબ્દની જોડણી/સ્પેલ ચેક પૂર્ણ: ખોટી જોડણી મળી નથી", -DlgSpellNoChanges : "શબ્દની જોડણી/સ્પેલ ચેક પૂર્ણ: એકપણ શબ્દ બદલયો નથી", -DlgSpellOneChange : "શબ્દની જોડણી/સ્પેલ ચેક પૂર્ણ: એક શબ્દ બદલયો છે", -DlgSpellManyChanges : "શબ્દની જોડણી/સ્પેલ ચેક પૂર્ણ: %1 શબ્દ બદલયા છે", - -IeSpellDownload : "સ્પેલ-ચેકર ઇન્સ્ટોલ નથી. શું તમે ડાઉનલોડ કરવા માંગો છો?", - -// Button Dialog -DlgButtonText : "ટેક્સ્ટ (વૅલ્યૂ)", -DlgButtonType : "પ્રકાર", -DlgButtonTypeBtn : "બટન", -DlgButtonTypeSbm : "સબ્મિટ", -DlgButtonTypeRst : "રિસેટ", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "નામ", -DlgCheckboxValue : "વૅલ્યૂ", -DlgCheckboxSelected : "સિલેક્ટેડ", - -// Form Dialog -DlgFormName : "નામ", -DlgFormAction : "ક્રિયા", -DlgFormMethod : "પદ્ધતિ", - -// Select Field Dialog -DlgSelectName : "નામ", -DlgSelectValue : "વૅલ્યૂ", -DlgSelectSize : "સાઇઝ", -DlgSelectLines : "લીટીઓ", -DlgSelectChkMulti : "એકથી વધારે પસંદ કરી શકો", -DlgSelectOpAvail : "ઉપલબ્ધ વિકલ્પ", -DlgSelectOpText : "ટેક્સ્ટ", -DlgSelectOpValue : "વૅલ્યૂ", -DlgSelectBtnAdd : "ઉમેરવું", -DlgSelectBtnModify : "બદલવું", -DlgSelectBtnUp : "ઉપર", -DlgSelectBtnDown : "નીચે", -DlgSelectBtnSetValue : "પસંદ કરલી વૅલ્યૂ સેટ કરો", -DlgSelectBtnDelete : "રદ કરવું", - -// Textarea Dialog -DlgTextareaName : "નામ", -DlgTextareaCols : "કૉલમ/ઊભી કટાર", -DlgTextareaRows : "પંક્તિઓ", - -// Text Field Dialog -DlgTextName : "નામ", -DlgTextValue : "વૅલ્યૂ", -DlgTextCharWidth : "કેરેક્ટરની પહોળાઈ", -DlgTextMaxChars : "અધિકતમ કેરેક્ટર", -DlgTextType : "ટાઇપ", -DlgTextTypeText : "ટેક્સ્ટ", -DlgTextTypePass : "પાસવર્ડ", - -// Hidden Field Dialog -DlgHiddenName : "નામ", -DlgHiddenValue : "વૅલ્યૂ", - -// Bulleted List Dialog -BulletedListProp : "બુલેટ સૂચિ ગુણ", -NumberedListProp : "સંખ્યાંક્તિ સૂચિ ગુણ", -DlgLstStart : "શરૂઆતથી", -DlgLstType : "પ્રકાર", -DlgLstTypeCircle : "વર્તુળ", -DlgLstTypeDisc : "ડિસ્ક", -DlgLstTypeSquare : "ચોરસ", -DlgLstTypeNumbers : "સંખ્યા (1, 2, 3)", -DlgLstTypeLCase : "નાના અક્ષર (a, b, c)", -DlgLstTypeUCase : "મોટા અક્ષર (A, B, C)", -DlgLstTypeSRoman : "નાના રોમન આંક (i, ii, iii)", -DlgLstTypeLRoman : "મોટા રોમન આંક (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "સાધારણ", -DlgDocBackTab : "બૅકગ્રાઉન્ડ", -DlgDocColorsTab : "રંગ અને માર્જિન/કિનાર", -DlgDocMetaTab : "મેટાડૅટા", - -DlgDocPageTitle : "પેજ મથાળું/ટાઇટલ", -DlgDocLangDir : "ભાષા લેખવાની પદ્ધતિ", -DlgDocLangDirLTR : "ડાબે થી જમણે (LTR)", -DlgDocLangDirRTL : "જમણે થી ડાબે (RTL)", -DlgDocLangCode : "ભાષા કોડ", -DlgDocCharSet : "કેરેક્ટર સેટ એન્કોડિંગ", -DlgDocCharSetCE : "મધ્ય યુરોપિઅન (Central European)", -DlgDocCharSetCT : "ચાઇનીઝ (Chinese Traditional Big5)", -DlgDocCharSetCR : "સિરીલિક (Cyrillic)", -DlgDocCharSetGR : "ગ્રીક (Greek)", -DlgDocCharSetJP : "જાપાનિઝ (Japanese)", -DlgDocCharSetKR : "કોરીયન (Korean)", -DlgDocCharSetTR : "ટર્કિ (Turkish)", -DlgDocCharSetUN : "યૂનિકોડ (UTF-8)", -DlgDocCharSetWE : "પશ્ચિમ યુરોપિઅન (Western European)", -DlgDocCharSetOther : "અન્ય કેરેક્ટર સેટ એન્કોડિંગ", - -DlgDocDocType : "ડૉક્યુમન્ટ પ્રકાર શીર્ષક", -DlgDocDocTypeOther : "અન્ય ડૉક્યુમન્ટ પ્રકાર શીર્ષક", -DlgDocIncXHTML : "XHTML સૂચના સમાવિષ્ટ કરવી", -DlgDocBgColor : "બૅકગ્રાઉન્ડ રંગ", -DlgDocBgImage : "બૅકગ્રાઉન્ડ ચિત્ર URL", -DlgDocBgNoScroll : "સ્ક્રોલ ન થાય તેવું બૅકગ્રાઉન્ડ", -DlgDocCText : "ટેક્સ્ટ", -DlgDocCLink : "લિંક", -DlgDocCVisited : "વિઝિટેડ લિંક", -DlgDocCActive : "સક્રિય લિંક", -DlgDocMargins : "પેજ માર્જિન", -DlgDocMaTop : "ઉપર", -DlgDocMaLeft : "ડાબી", -DlgDocMaRight : "જમણી", -DlgDocMaBottom : "નીચે", -DlgDocMeIndex : "ડૉક્યુમન્ટ ઇન્ડેક્સ સંકેતશબ્દ (અલ્પવિરામ (,) થી અલગ કરો)", -DlgDocMeDescr : "ડૉક્યુમન્ટ વર્ણન", -DlgDocMeAuthor : "લેખક", -DlgDocMeCopy : "કૉપિરાઇટ", -DlgDocPreview : "પૂર્વદર્શન", - -// Templates Dialog -Templates : "ટેમ્પ્લેટ", -DlgTemplatesTitle : "કન્ટેન્ટ ટેમ્પ્લેટ", -DlgTemplatesSelMsg : "એડિટરમાં ઓપન કરવા ટેમ્પ્લેટ પસંદ કરો (વર્તમાન કન્ટેન્ટ સેવ નહીં થાય):", -DlgTemplatesLoading : "ટેમ્પ્લેટ સૂચિ લોડ થાય છે. રાહ જુઓ...", -DlgTemplatesNoTpl : "(કોઈ ટેમ્પ્લેટ ડિફાઇન નથી)", -DlgTemplatesReplace : "મૂળ શબ્દને બદલો", - -// About Dialog -DlgAboutAboutTab : "FCKEditor ના વિષે", -DlgAboutBrowserInfoTab : "બ્રાઉઝર ના વિષે", -DlgAboutLicenseTab : "લાઇસન્સ", -DlgAboutVersion : "વર્ઝન", -DlgAboutInfo : "વધારે માહિતી માટે:", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/he.js b/httemplate/elements/fckeditor/editor/lang/he.js deleted file mode 100644 index 4cbbf9550..000000000 --- a/httemplate/elements/fckeditor/editor/lang/he.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Hebrew language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "rtl", - -ToolbarCollapse : "כיווץ סרגל הכלים", -ToolbarExpand : "פתיחת סרגל הכלים", - -// Toolbar Items and Context Menu -Save : "שמירה", -NewPage : "דף חדש", -Preview : "תצוגה מקדימה", -Cut : "גזירה", -Copy : "העתקה", -Paste : "הדבקה", -PasteText : "הדבקה כטקסט פשוט", -PasteWord : "הדבקה מ-וורד", -Print : "הדפסה", -SelectAll : "בחירת הכל", -RemoveFormat : "הסרת העיצוב", -InsertLinkLbl : "קישור", -InsertLink : "הוספת/עריכת קישור", -RemoveLink : "הסרת הקישור", -VisitLink : "פתח קישור", -Anchor : "הוספת/עריכת נקודת עיגון", -AnchorDelete : "הסר נקודת עיגון", -InsertImageLbl : "תמונה", -InsertImage : "הוספת/עריכת תמונה", -InsertFlashLbl : "פלאש", -InsertFlash : "הוסף/ערוך פלאש", -InsertTableLbl : "טבלה", -InsertTable : "הוספת/עריכת טבלה", -InsertLineLbl : "קו", -InsertLine : "הוספת קו אופקי", -InsertSpecialCharLbl: "תו מיוחד", -InsertSpecialChar : "הוספת תו מיוחד", -InsertSmileyLbl : "סמיילי", -InsertSmiley : "הוספת סמיילי", -About : "אודות FCKeditor", -Bold : "מודגש", -Italic : "נטוי", -Underline : "קו תחתון", -StrikeThrough : "כתיב מחוק", -Subscript : "כתיב תחתון", -Superscript : "כתיב עליון", -LeftJustify : "יישור לשמאל", -CenterJustify : "מרכוז", -RightJustify : "יישור לימין", -BlockJustify : "יישור לשוליים", -DecreaseIndent : "הקטנת אינדנטציה", -IncreaseIndent : "הגדלת אינדנטציה", -Blockquote : "בלוק ציטוט", -CreateDiv : "צור מיכל(תג)DIV", -EditDiv : "ערוך מיכל (תג)DIV", -DeleteDiv : "הסר מיכל(תג) DIV", -Undo : "ביטול צעד אחרון", -Redo : "חזרה על צעד אחרון", -NumberedListLbl : "רשימה ממוספרת", -NumberedList : "הוספת/הסרת רשימה ממוספרת", -BulletedListLbl : "רשימת נקודות", -BulletedList : "הוספת/הסרת רשימת נקודות", -ShowTableBorders : "הצגת מסגרת הטבלה", -ShowDetails : "הצגת פרטים", -Style : "סגנון", -FontFormat : "עיצוב", -Font : "גופן", -FontSize : "גודל", -TextColor : "צבע טקסט", -BGColor : "צבע רקע", -Source : "מקור", -Find : "חיפוש", -Replace : "החלפה", -SpellCheck : "בדיקת איות", -UniversalKeyboard : "מקלדת אוניברסלית", -PageBreakLbl : "שבירת דף", -PageBreak : "הוסף שבירת דף", - -Form : "טופס", -Checkbox : "תיבת סימון", -RadioButton : "לחצן אפשרויות", -TextField : "שדה טקסט", -Textarea : "איזור טקסט", -HiddenField : "שדה חבוי", -Button : "כפתור", -SelectionField : "שדה בחירה", -ImageButton : "כפתור תמונה", - -FitWindow : "הגדל את גודל העורך", -ShowBlocks : "הצג בלוקים", - -// Context Menu -EditLink : "עריכת קישור", -CellCM : "תא", -RowCM : "שורה", -ColumnCM : "עמודה", -InsertRowAfter : "הוסף שורה אחרי", -InsertRowBefore : "הוסף שורה לפני", -DeleteRows : "מחיקת שורות", -InsertColumnAfter : "הוסף עמודה אחרי", -InsertColumnBefore : "הוסף עמודה לפני", -DeleteColumns : "מחיקת עמודות", -InsertCellAfter : "הוסף תא אחרי", -InsertCellBefore : "הוסף תא אחרי", -DeleteCells : "מחיקת תאים", -MergeCells : "מיזוג תאים", -MergeRight : "מזג ימינה", -MergeDown : "מזג למטה", -HorizontalSplitCell : "פצל תא אופקית", -VerticalSplitCell : "פצל תא אנכית", -TableDelete : "מחק טבלה", -CellProperties : "תכונות התא", -TableProperties : "תכונות הטבלה", -ImageProperties : "תכונות התמונה", -FlashProperties : "מאפייני פלאש", - -AnchorProp : "מאפייני נקודת עיגון", -ButtonProp : "מאפייני כפתור", -CheckboxProp : "מאפייני תיבת סימון", -HiddenFieldProp : "מאפיני שדה חבוי", -RadioButtonProp : "מאפייני לחצן אפשרויות", -ImageButtonProp : "מאפיני כפתור תמונה", -TextFieldProp : "מאפייני שדה טקסט", -SelectionFieldProp : "מאפייני שדה בחירה", -TextareaProp : "מאפיני איזור טקסט", -FormProp : "מאפיני טופס", - -FontFormats : "נורמלי;קוד;כתובת;כותרת;כותרת 2;כותרת 3;כותרת 4;כותרת 5;כותרת 6", - -// Alerts and Messages -ProcessingXHTML : "מעבד XHTML, נא להמתין...", -Done : "המשימה הושלמה", -PasteWordConfirm : "נראה הטקסט שבכוונתך להדביק מקורו בקובץ וורד. האם ברצונך לנקות אותו טרם ההדבקה?", -NotCompatiblePaste : "פעולה זו זמינה לדפדפן אינטרנט אקספלורר מגירסא 5.5 ומעלה. האם להמשיך בהדבקה ללא הניקוי?", -UnknownToolbarItem : "פריט לא ידוע בסרגל הכלים \"%1\"", -UnknownCommand : "שם פעולה לא ידוע \"%1\"", -NotImplemented : "הפקודה לא מיושמת", -UnknownToolbarSet : "ערכת סרגל הכלים \"%1\" לא קיימת", -NoActiveX : "הגדרות אבטחה של הדפדפן עלולות לגביל את אפשרויות העריכה.יש לאפשר את האופציה \"הרץ פקדים פעילים ותוספות\". תוכל לחוות טעויות וחיווים של אפשרויות שחסרים.", -BrowseServerBlocked : "לא ניתן לגשת לדפדפן משאבים.אנא וודא שחוסם חלונות הקופצים לא פעיל.", -DialogBlocked : "לא היה ניתן לפתוח חלון דיאלוג. אנא וודא שחוסם חלונות קופצים לא פעיל.", -VisitLinkBlocked : "לא ניתן לפתוח חלון חדש.נא לוודא שחוסמי החלונות הקופצים לא פעילים.", - -// Dialogs -DlgBtnOK : "אישור", -DlgBtnCancel : "ביטול", -DlgBtnClose : "סגירה", -DlgBtnBrowseServer : "סייר השרת", -DlgAdvancedTag : "אפשרויות מתקדמות", -DlgOpOther : "<אחר>", -DlgInfoTab : "מידע", -DlgAlertUrl : "אנא הזן URL", - -// General Dialogs Labels -DlgGenNotSet : "<לא נקבע>", -DlgGenId : "זיהוי (Id)", -DlgGenLangDir : "כיוון שפה", -DlgGenLangDirLtr : "שמאל לימין (LTR)", -DlgGenLangDirRtl : "ימין לשמאל (RTL)", -DlgGenLangCode : "קוד שפה", -DlgGenAccessKey : "מקש גישה", -DlgGenName : "שם", -DlgGenTabIndex : "מספר טאב", -DlgGenLongDescr : "קישור לתיאור מפורט", -DlgGenClass : "גיליונות עיצוב קבוצות", -DlgGenTitle : "כותרת מוצעת", -DlgGenContType : "Content Type מוצע", -DlgGenLinkCharset : "קידוד המשאב המקושר", -DlgGenStyle : "סגנון", - -// Image Dialog -DlgImgTitle : "תכונות התמונה", -DlgImgInfoTab : "מידע על התמונה", -DlgImgBtnUpload : "שליחה לשרת", -DlgImgURL : "כתובת (URL)", -DlgImgUpload : "העלאה", -DlgImgAlt : "טקסט חלופי", -DlgImgWidth : "רוחב", -DlgImgHeight : "גובה", -DlgImgLockRatio : "נעילת היחס", -DlgBtnResetSize : "איפוס הגודל", -DlgImgBorder : "מסגרת", -DlgImgHSpace : "מרווח אופקי", -DlgImgVSpace : "מרווח אנכי", -DlgImgAlign : "יישור", -DlgImgAlignLeft : "לשמאל", -DlgImgAlignAbsBottom: "לתחתית האבסולוטית", -DlgImgAlignAbsMiddle: "מרכוז אבסולוטי", -DlgImgAlignBaseline : "לקו התחתית", -DlgImgAlignBottom : "לתחתית", -DlgImgAlignMiddle : "לאמצע", -DlgImgAlignRight : "לימין", -DlgImgAlignTextTop : "לראש הטקסט", -DlgImgAlignTop : "למעלה", -DlgImgPreview : "תצוגה מקדימה", -DlgImgAlertUrl : "נא להקליד את כתובת התמונה", -DlgImgLinkTab : "קישור", - -// Flash Dialog -DlgFlashTitle : "מאפיני פלאש", -DlgFlashChkPlay : "נגן אוטומטי", -DlgFlashChkLoop : "לולאה", -DlgFlashChkMenu : "אפשר תפריט פלאש", -DlgFlashScale : "גודל", -DlgFlashScaleAll : "הצג הכל", -DlgFlashScaleNoBorder : "ללא גבולות", -DlgFlashScaleFit : "התאמה מושלמת", - -// Link Dialog -DlgLnkWindowTitle : "קישור", -DlgLnkInfoTab : "מידע על הקישור", -DlgLnkTargetTab : "מטרה", - -DlgLnkType : "סוג קישור", -DlgLnkTypeURL : "כתובת (URL)", -DlgLnkTypeAnchor : "עוגן בעמוד זה", -DlgLnkTypeEMail : "דוא''ל", -DlgLnkProto : "פרוטוקול", -DlgLnkProtoOther : "<אחר>", -DlgLnkURL : "כתובת (URL)", -DlgLnkAnchorSel : "בחירת עוגן", -DlgLnkAnchorByName : "עפ''י שם העוגן", -DlgLnkAnchorById : "עפ''י זיהוי (Id) הרכיב", -DlgLnkNoAnchors : "(אין עוגנים זמינים בדף)", -DlgLnkEMail : "כתובת הדוא''ל", -DlgLnkEMailSubject : "נושא ההודעה", -DlgLnkEMailBody : "גוף ההודעה", -DlgLnkUpload : "העלאה", -DlgLnkBtnUpload : "שליחה לשרת", - -DlgLnkTarget : "מטרה", -DlgLnkTargetFrame : "<מסגרת>", -DlgLnkTargetPopup : "<חלון קופץ>", -DlgLnkTargetBlank : "חלון חדש (_blank)", -DlgLnkTargetParent : "חלון האב (_parent)", -DlgLnkTargetSelf : "באותו החלון (_self)", -DlgLnkTargetTop : "חלון ראשי (_top)", -DlgLnkTargetFrameName : "שם מסגרת היעד", -DlgLnkPopWinName : "שם החלון הקופץ", -DlgLnkPopWinFeat : "תכונות החלון הקופץ", -DlgLnkPopResize : "בעל גודל ניתן לשינוי", -DlgLnkPopLocation : "סרגל כתובת", -DlgLnkPopMenu : "סרגל תפריט", -DlgLnkPopScroll : "ניתן לגלילה", -DlgLnkPopStatus : "סרגל חיווי", -DlgLnkPopToolbar : "סרגל הכלים", -DlgLnkPopFullScrn : "מסך מלא (IE)", -DlgLnkPopDependent : "תלוי (Netscape)", -DlgLnkPopWidth : "רוחב", -DlgLnkPopHeight : "גובה", -DlgLnkPopLeft : "מיקום צד שמאל", -DlgLnkPopTop : "מיקום צד עליון", - -DlnLnkMsgNoUrl : "נא להקליד את כתובת הקישור (URL)", -DlnLnkMsgNoEMail : "נא להקליד את כתובת הדוא''ל", -DlnLnkMsgNoAnchor : "נא לבחור עוגן במסמך", -DlnLnkMsgInvPopName : "שם החלון הקופץ חייב להתחיל באותיות ואסור לכלול רווחים", - -// Color Dialog -DlgColorTitle : "בחירת צבע", -DlgColorBtnClear : "איפוס", -DlgColorHighlight : "נוכחי", -DlgColorSelected : "נבחר", - -// Smiley Dialog -DlgSmileyTitle : "הוספת סמיילי", - -// Special Character Dialog -DlgSpecialCharTitle : "בחירת תו מיוחד", - -// Table Dialog -DlgTableTitle : "תכונות טבלה", -DlgTableRows : "שורות", -DlgTableColumns : "עמודות", -DlgTableBorder : "גודל מסגרת", -DlgTableAlign : "יישור", -DlgTableAlignNotSet : "<לא נקבע>", -DlgTableAlignLeft : "שמאל", -DlgTableAlignCenter : "מרכז", -DlgTableAlignRight : "ימין", -DlgTableWidth : "רוחב", -DlgTableWidthPx : "פיקסלים", -DlgTableWidthPc : "אחוז", -DlgTableHeight : "גובה", -DlgTableCellSpace : "מרווח תא", -DlgTableCellPad : "ריפוד תא", -DlgTableCaption : "כיתוב", -DlgTableSummary : "סיכום", -DlgTableHeaders : "כותרות", -DlgTableHeadersNone : "אין", -DlgTableHeadersColumn : "עמודה ראשונה", -DlgTableHeadersRow : "שורה ראשונה", -DlgTableHeadersBoth : "שניהם", - -// Table Cell Dialog -DlgCellTitle : "תכונות תא", -DlgCellWidth : "רוחב", -DlgCellWidthPx : "פיקסלים", -DlgCellWidthPc : "אחוז", -DlgCellHeight : "גובה", -DlgCellWordWrap : "גלילת שורות", -DlgCellWordWrapNotSet : "<לא נקבע>", -DlgCellWordWrapYes : "כן", -DlgCellWordWrapNo : "לא", -DlgCellHorAlign : "יישור אופקי", -DlgCellHorAlignNotSet : "<לא נקבע>", -DlgCellHorAlignLeft : "שמאל", -DlgCellHorAlignCenter : "מרכז", -DlgCellHorAlignRight: "ימין", -DlgCellVerAlign : "יישור אנכי", -DlgCellVerAlignNotSet : "<לא נקבע>", -DlgCellVerAlignTop : "למעלה", -DlgCellVerAlignMiddle : "לאמצע", -DlgCellVerAlignBottom : "לתחתית", -DlgCellVerAlignBaseline : "קו תחתית", -DlgCellType : "סוג תא", -DlgCellTypeData : "סוג", -DlgCellTypeHeader : "כותרת", -DlgCellRowSpan : "טווח שורות", -DlgCellCollSpan : "טווח עמודות", -DlgCellBackColor : "צבע רקע", -DlgCellBorderColor : "צבע מסגרת", -DlgCellBtnSelect : "בחירה...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "חפש והחלף", - -// Find Dialog -DlgFindTitle : "חיפוש", -DlgFindFindBtn : "חיפוש", -DlgFindNotFoundMsg : "הטקסט המבוקש לא נמצא.", - -// Replace Dialog -DlgReplaceTitle : "החלפה", -DlgReplaceFindLbl : "חיפוש מחרוזת:", -DlgReplaceReplaceLbl : "החלפה במחרוזת:", -DlgReplaceCaseChk : "התאמת סוג אותיות (Case)", -DlgReplaceReplaceBtn : "החלפה", -DlgReplaceReplAllBtn : "החלפה בכל העמוד", -DlgReplaceWordChk : "התאמה למילה המלאה", - -// Paste Operations / Dialog -PasteErrorCut : "הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות גזירה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl+X).", -PasteErrorCopy : "הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות העתקה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl+C).", - -PasteAsText : "הדבקה כטקסט פשוט", -PasteFromWord : "הדבקה מ-וורד", - -DlgPasteMsg2 : "אנא הדבק בתוך הקופסה באמצעות (Ctrl+V) ולחץ על אישור.", -DlgPasteSec : "עקב הגדרות אבטחה בדפדפן, לא ניתן לגשת אל לוח הגזירים (clipboard) בצורה ישירה.אנא בצע הדבק שוב בחלון זה.", -DlgPasteIgnoreFont : "התעלם מהגדרות סוג פונט", -DlgPasteRemoveStyles : "הסר הגדרות סגנון", - -// Color Picker -ColorAutomatic : "אוטומטי", -ColorMoreColors : "צבעים נוספים...", - -// Document Properties -DocProps : "מאפיני מסמך", - -// Anchor Dialog -DlgAnchorTitle : "מאפיני נקודת עיגון", -DlgAnchorName : "שם לנקודת עיגון", -DlgAnchorErrorName : "אנא הזן שם לנקודת עיגון", - -// Speller Pages Dialog -DlgSpellNotInDic : "לא נמצא במילון", -DlgSpellChangeTo : "שנה ל", -DlgSpellBtnIgnore : "התעלם", -DlgSpellBtnIgnoreAll : "התעלם מהכל", -DlgSpellBtnReplace : "החלף", -DlgSpellBtnReplaceAll : "החלף הכל", -DlgSpellBtnUndo : "החזר", -DlgSpellNoSuggestions : "- אין הצעות -", -DlgSpellProgress : "בדיקות איות בתהליך ....", -DlgSpellNoMispell : "בדיקות איות הסתיימה: לא נמצאו שגיעות כתיב", -DlgSpellNoChanges : "בדיקות איות הסתיימה: לא שונתה אף מילה", -DlgSpellOneChange : "בדיקות איות הסתיימה: שונתה מילה אחת", -DlgSpellManyChanges : "בדיקות איות הסתיימה: %1 מילים שונו", - -IeSpellDownload : "בודק האיות לא מותקן, האם אתה מעוניין להוריד?", - -// Button Dialog -DlgButtonText : "טקסט (ערך)", -DlgButtonType : "סוג", -DlgButtonTypeBtn : "כפתור", -DlgButtonTypeSbm : "שלח", -DlgButtonTypeRst : "אפס", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "שם", -DlgCheckboxValue : "ערך", -DlgCheckboxSelected : "בחור", - -// Form Dialog -DlgFormName : "שם", -DlgFormAction : "שלח אל", -DlgFormMethod : "סוג שליחה", - -// Select Field Dialog -DlgSelectName : "שם", -DlgSelectValue : "ערך", -DlgSelectSize : "גודל", -DlgSelectLines : "שורות", -DlgSelectChkMulti : "אפשר בחירות מרובות", -DlgSelectOpAvail : "אפשרויות זמינות", -DlgSelectOpText : "טקסט", -DlgSelectOpValue : "ערך", -DlgSelectBtnAdd : "הוסף", -DlgSelectBtnModify : "שנה", -DlgSelectBtnUp : "למעלה", -DlgSelectBtnDown : "למטה", -DlgSelectBtnSetValue : "קבע כברירת מחדל", -DlgSelectBtnDelete : "מחק", - -// Textarea Dialog -DlgTextareaName : "שם", -DlgTextareaCols : "עמודות", -DlgTextareaRows : "שורות", - -// Text Field Dialog -DlgTextName : "שם", -DlgTextValue : "ערך", -DlgTextCharWidth : "רוחב באותיות", -DlgTextMaxChars : "מקסימות אותיות", -DlgTextType : "סוג", -DlgTextTypeText : "טקסט", -DlgTextTypePass : "סיסמה", - -// Hidden Field Dialog -DlgHiddenName : "שם", -DlgHiddenValue : "ערך", - -// Bulleted List Dialog -BulletedListProp : "מאפייני רשימה", -NumberedListProp : "מאפייני רשימה ממוספרת", -DlgLstStart : "התחלה", -DlgLstType : "סוג", -DlgLstTypeCircle : "עיגול", -DlgLstTypeDisc : "דיסק", -DlgLstTypeSquare : "מרובע", -DlgLstTypeNumbers : "מספרים (1, 2, 3)", -DlgLstTypeLCase : "אותיות קטנות (a, b, c)", -DlgLstTypeUCase : "אותיות גדולות (A, B, C)", -DlgLstTypeSRoman : "ספרות רומאיות קטנות (i, ii, iii)", -DlgLstTypeLRoman : "ספרות רומאיות גדולות (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "כללי", -DlgDocBackTab : "רקע", -DlgDocColorsTab : "צבעים וגבולות", -DlgDocMetaTab : "נתוני META", - -DlgDocPageTitle : "כותרת דף", -DlgDocLangDir : "כיוון שפה", -DlgDocLangDirLTR : "שמאל לימין (LTR)", -DlgDocLangDirRTL : "ימין לשמאל (RTL)", -DlgDocLangCode : "קוד שפה", -DlgDocCharSet : "קידוד אותיות", -DlgDocCharSetCE : "מרכז אירופה", -DlgDocCharSetCT : "סיני מסורתי (Big5)", -DlgDocCharSetCR : "קירילי", -DlgDocCharSetGR : "יוונית", -DlgDocCharSetJP : "יפנית", -DlgDocCharSetKR : "קוראנית", -DlgDocCharSetTR : "טורקית", -DlgDocCharSetUN : "יוני קוד (UTF-8)", -DlgDocCharSetWE : "מערב אירופה", -DlgDocCharSetOther : "קידוד אותיות אחר", - -DlgDocDocType : "הגדרות סוג מסמך", -DlgDocDocTypeOther : "הגדרות סוג מסמך אחרות", -DlgDocIncXHTML : "כלול הגדרות XHTML", -DlgDocBgColor : "צבע רקע", -DlgDocBgImage : "URL לתמונת רקע", -DlgDocBgNoScroll : "רגע ללא גלילה", -DlgDocCText : "טקסט", -DlgDocCLink : "קישור", -DlgDocCVisited : "קישור שבוקר", -DlgDocCActive : " קישור פעיל", -DlgDocMargins : "גבולות דף", -DlgDocMaTop : "למעלה", -DlgDocMaLeft : "שמאלה", -DlgDocMaRight : "ימינה", -DlgDocMaBottom : "למטה", -DlgDocMeIndex : "מפתח עניינים של המסמך )מופרד בפסיק(", -DlgDocMeDescr : "תאור מסמך", -DlgDocMeAuthor : "מחבר", -DlgDocMeCopy : "זכויות יוצרים", -DlgDocPreview : "תצוגה מקדימה", - -// Templates Dialog -Templates : "תבניות", -DlgTemplatesTitle : "תביות תוכן", -DlgTemplatesSelMsg : "אנא בחר תבנית לפתיחה בעורך
    התוכן המקורי ימחק:", -DlgTemplatesLoading : "מעלה רשימת תבניות אנא המתן", -DlgTemplatesNoTpl : "(לא הוגדרו תבניות)", -DlgTemplatesReplace : "החלפת תוכן ממשי", - -// About Dialog -DlgAboutAboutTab : "אודות", -DlgAboutBrowserInfoTab : "גירסת דפדפן", -DlgAboutLicenseTab : "רשיון", -DlgAboutVersion : "גירסא", -DlgAboutInfo : "מידע נוסף ניתן למצוא כאן:", - -// Div Dialog -DlgDivGeneralTab : "כללי", -DlgDivAdvancedTab : "מתקדם", -DlgDivStyle : "סגנון", -DlgDivInlineStyle : "סגנון בתוך השורה", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/hi.js b/httemplate/elements/fckeditor/editor/lang/hi.js deleted file mode 100644 index b4e88fcff..000000000 --- a/httemplate/elements/fckeditor/editor/lang/hi.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Hindi language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "टूलबार सिमटायें", -ToolbarExpand : "टूलबार का विस्तार करें", - -// Toolbar Items and Context Menu -Save : "सेव", -NewPage : "नया पेज", -Preview : "प्रीव्यू", -Cut : "कट", -Copy : "कॉपी", -Paste : "पेस्ट", -PasteText : "पेस्ट (सादा टॅक्स्ट)", -PasteWord : "पेस्ट (वर्ड से)", -Print : "प्रिन्ट", -SelectAll : "सब सॅलॅक्ट करें", -RemoveFormat : "फ़ॉर्मैट हटायें", -InsertLinkLbl : "लिंक", -InsertLink : "लिंक इन्सर्ट/संपादन", -RemoveLink : "लिंक हटायें", -VisitLink : "लिंक खोलें", -Anchor : "ऐंकर इन्सर्ट/संपादन", -AnchorDelete : "ऐंकर हटायें", -InsertImageLbl : "तस्वीर", -InsertImage : "तस्वीर इन्सर्ट/संपादन", -InsertFlashLbl : "फ़्लैश", -InsertFlash : "फ़्लैश इन्सर्ट/संपादन", -InsertTableLbl : "टेबल", -InsertTable : "टेबल इन्सर्ट/संपादन", -InsertLineLbl : "रेखा", -InsertLine : "हॉरिज़ॉन्टल रेखा इन्सर्ट करें", -InsertSpecialCharLbl: "विशेष करॅक्टर", -InsertSpecialChar : "विशेष करॅक्टर इन्सर्ट करें", -InsertSmileyLbl : "स्माइली", -InsertSmiley : "स्माइली इन्सर्ट करें", -About : "FCKeditor के बारे में", -Bold : "बोल्ड", -Italic : "इटैलिक", -Underline : "रेखांकण", -StrikeThrough : "स्ट्राइक थ्रू", -Subscript : "अधोलेख", -Superscript : "अभिलेख", -LeftJustify : "बायीं तरफ", -CenterJustify : "बीच में", -RightJustify : "दायीं तरफ", -BlockJustify : "ब्लॉक जस्टीफ़ाई", -DecreaseIndent : "इन्डॅन्ट कम करें", -IncreaseIndent : "इन्डॅन्ट बढ़ायें", -Blockquote : "ब्लॉक-कोट", -CreateDiv : "डिव (Div) कन्टेनर बनायें", -EditDiv : "डिव (Div) कन्टेनर बदलें", -DeleteDiv : "डिव कन्टेनर हटायें", -Undo : "अन्डू", -Redo : "रीडू", -NumberedListLbl : "अंकीय सूची", -NumberedList : "अंकीय सूची इन्सर्ट/संपादन", -BulletedListLbl : "बुलॅट सूची", -BulletedList : "बुलॅट सूची इन्सर्ट/संपादन", -ShowTableBorders : "टेबल बॉर्डरयें दिखायें", -ShowDetails : "ज्यादा दिखायें", -Style : "स्टाइल", -FontFormat : "फ़ॉर्मैट", -Font : "फ़ॉन्ट", -FontSize : "साइज़", -TextColor : "टेक्स्ट रंग", -BGColor : "बैक्ग्राउन्ड रंग", -Source : "सोर्स", -Find : "खोजें", -Replace : "रीप्लेस", -SpellCheck : "वर्तनी (स्पेलिंग) जाँच", -UniversalKeyboard : "यूनीवर्सल कीबोर्ड", -PageBreakLbl : "पेज ब्रेक", -PageBreak : "पेज ब्रेक इन्सर्ट् करें", - -Form : "फ़ॉर्म", -Checkbox : "चॅक बॉक्स", -RadioButton : "रेडिओ बटन", -TextField : "टेक्स्ट फ़ील्ड", -Textarea : "टेक्स्ट एरिया", -HiddenField : "गुप्त फ़ील्ड", -Button : "बटन", -SelectionField : "चुनाव फ़ील्ड", -ImageButton : "तस्वीर बटन", - -FitWindow : "एडिटर साइज़ को चरम सीमा तक बढ़ायें", -ShowBlocks : "ब्लॉक दिखायें", - -// Context Menu -EditLink : "लिंक संपादन", -CellCM : "खाना", -RowCM : "पंक्ति", -ColumnCM : "कालम", -InsertRowAfter : "बाद में पंक्ति डालें", -InsertRowBefore : "पहले पंक्ति डालें", -DeleteRows : "पंक्तियाँ डिलीट करें", -InsertColumnAfter : "बाद में कालम डालें", -InsertColumnBefore : "पहले कालम डालें", -DeleteColumns : "कालम डिलीट करें", -InsertCellAfter : "बाद में सैल डालें", -InsertCellBefore : "पहले सैल डालें", -DeleteCells : "सैल डिलीट करें", -MergeCells : "सैल मिलायें", -MergeRight : "बाँया विलय", -MergeDown : "नीचे विलय करें", -HorizontalSplitCell : "सैल को क्षैतिज स्थिति में विभाजित करें", -VerticalSplitCell : "सैल को लम्बाकार में विभाजित करें", -TableDelete : "टेबल डिलीट करें", -CellProperties : "सैल प्रॉपर्टीज़", -TableProperties : "टेबल प्रॉपर्टीज़", -ImageProperties : "तस्वीर प्रॉपर्टीज़", -FlashProperties : "फ़्लैश प्रॉपर्टीज़", - -AnchorProp : "ऐंकर प्रॉपर्टीज़", -ButtonProp : "बटन प्रॉपर्टीज़", -CheckboxProp : "चॅक बॉक्स प्रॉपर्टीज़", -HiddenFieldProp : "गुप्त फ़ील्ड प्रॉपर्टीज़", -RadioButtonProp : "रेडिओ बटन प्रॉपर्टीज़", -ImageButtonProp : "तस्वीर बटन प्रॉपर्टीज़", -TextFieldProp : "टेक्स्ट फ़ील्ड प्रॉपर्टीज़", -SelectionFieldProp : "चुनाव फ़ील्ड प्रॉपर्टीज़", -TextareaProp : "टेक्स्त एरिया प्रॉपर्टीज़", -FormProp : "फ़ॉर्म प्रॉपर्टीज़", - -FontFormats : "साधारण;फ़ॉर्मैटॅड;पता;शीर्षक 1;शीर्षक 2;शीर्षक 3;शीर्षक 4;शीर्षक 5;शीर्षक 6;शीर्षक (DIV)", - -// Alerts and Messages -ProcessingXHTML : "XHTML प्रोसॅस हो रहा है। ज़रा ठहरें...", -Done : "पूरा हुआ", -PasteWordConfirm : "आप जो टेक्स्ट पेस्ट करना चाहते हैं, वह वर्ड से कॉपी किया हुआ लग रहा है। क्या पेस्ट करने से पहले आप इसे साफ़ करना चाहेंगे?", -NotCompatiblePaste : "यह कमांड इन्टरनॅट एक्स्प्लोरर(Internet Explorer) 5.5 या उसके बाद के वर्ज़न के लिए ही उपलब्ध है। क्या आप बिना साफ़ किए पेस्ट करना चाहेंगे?", -UnknownToolbarItem : "अनजान टूलबार आइटम \"%1\"", -UnknownCommand : "अनजान कमान्ड \"%1\"", -NotImplemented : "कमान्ड इम्प्लीमॅन्ट नहीं किया गया है", -UnknownToolbarSet : "टूलबार सॅट \"%1\" उपलब्ध नहीं है", -NoActiveX : "आपके ब्राउज़र् की सुरक्शा सेटिंग्स् एडिटर की कुछ् फ़ीचरों को सीमित कर् सकती हैं। क्रिपया \"Run ActiveX controls and plug-ins\" विकल्प को एनेबल करें. आपको एरर्स् और गायब फ़ीचर्स् का अनुभव हो सकता है।", -BrowseServerBlocked : "रिसोर्सेज़ ब्राउज़र् नहीं खोला जा सका। क्रिपया सभी पॉप्-अप् ब्लॉकर्स् को निष्क्रिय करें।", -DialogBlocked : "डायलग विन्डो नहीं खोला जा सका। क्रिपया सभी पॉप्-अप् ब्लॉकर्स् को निष्क्रिय करें।", -VisitLinkBlocked : "नया विन्डो नहीं खोला जा सका। क्रिपया सभी पॉप्-अप् ब्लॉकर्स् को निष्क्रिय करें।", - -// Dialogs -DlgBtnOK : "ठीक है", -DlgBtnCancel : "रद्द करें", -DlgBtnClose : "बन्द करें", -DlgBtnBrowseServer : "सर्वर ब्राउज़ करें", -DlgAdvancedTag : "ऍड्वान्स्ड", -DlgOpOther : "<अन्य>", -DlgInfoTab : "सूचना", -DlgAlertUrl : "URL इन्सर्ट करें", - -// General Dialogs Labels -DlgGenNotSet : "<सॅट नहीं>", -DlgGenId : "Id", -DlgGenLangDir : "भाषा लिखने की दिशा", -DlgGenLangDirLtr : "बायें से दायें (LTR)", -DlgGenLangDirRtl : "दायें से बायें (RTL)", -DlgGenLangCode : "भाषा कोड", -DlgGenAccessKey : "ऍक्सॅस की", -DlgGenName : "नाम", -DlgGenTabIndex : "टैब इन्डॅक्स", -DlgGenLongDescr : "अधिक विवरण के लिए URL", -DlgGenClass : "स्टाइल-शीट क्लास", -DlgGenTitle : "परामर्श शीर्शक", -DlgGenContType : "परामर्श कन्टॅन्ट प्रकार", -DlgGenLinkCharset : "लिंक रिसोर्स करॅक्टर सॅट", -DlgGenStyle : "स्टाइल", - -// Image Dialog -DlgImgTitle : "तस्वीर प्रॉपर्टीज़", -DlgImgInfoTab : "तस्वीर की जानकारी", -DlgImgBtnUpload : "इसे सर्वर को भेजें", -DlgImgURL : "URL", -DlgImgUpload : "अपलोड", -DlgImgAlt : "वैकल्पिक टेक्स्ट", -DlgImgWidth : "चौड़ाई", -DlgImgHeight : "ऊँचाई", -DlgImgLockRatio : "लॉक अनुपात", -DlgBtnResetSize : "रीसॅट साइज़", -DlgImgBorder : "बॉर्डर", -DlgImgHSpace : "हॉरिज़ॉन्टल स्पेस", -DlgImgVSpace : "वर्टिकल स्पेस", -DlgImgAlign : "ऍलाइन", -DlgImgAlignLeft : "दायें", -DlgImgAlignAbsBottom: "Abs नीचे", -DlgImgAlignAbsMiddle: "Abs ऊपर", -DlgImgAlignBaseline : "मूल रेखा", -DlgImgAlignBottom : "नीचे", -DlgImgAlignMiddle : "मध्य", -DlgImgAlignRight : "दायें", -DlgImgAlignTextTop : "टेक्स्ट ऊपर", -DlgImgAlignTop : "ऊपर", -DlgImgPreview : "प्रीव्यू", -DlgImgAlertUrl : "तस्वीर का URL टाइप करें ", -DlgImgLinkTab : "लिंक", - -// Flash Dialog -DlgFlashTitle : "फ़्लैश प्रॉपर्टीज़", -DlgFlashChkPlay : "ऑटो प्ले", -DlgFlashChkLoop : "लूप", -DlgFlashChkMenu : "फ़्लैश मॅन्यू का प्रयोग करें", -DlgFlashScale : "स्केल", -DlgFlashScaleAll : "सभी दिखायें", -DlgFlashScaleNoBorder : "कोई बॉर्डर नहीं", -DlgFlashScaleFit : "बिल्कुल फ़िट", - -// Link Dialog -DlgLnkWindowTitle : "लिंक", -DlgLnkInfoTab : "लिंक ", -DlgLnkTargetTab : "टार्गेट", - -DlgLnkType : "लिंक प्रकार", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "इस पेज का ऐंकर", -DlgLnkTypeEMail : "ई-मेल", -DlgLnkProto : "प्रोटोकॉल", -DlgLnkProtoOther : "<अन्य>", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "ऐंकर चुनें", -DlgLnkAnchorByName : "ऐंकर नाम से", -DlgLnkAnchorById : "ऍलीमॅन्ट Id से", -DlgLnkNoAnchors : "(डॉक्यूमॅन्ट में ऐंकर्स की संख्या)", -DlgLnkEMail : "ई-मेल पता", -DlgLnkEMailSubject : "संदेश विषय", -DlgLnkEMailBody : "संदेश", -DlgLnkUpload : "अपलोड", -DlgLnkBtnUpload : "इसे सर्वर को भेजें", - -DlgLnkTarget : "टार्गेट", -DlgLnkTargetFrame : "<फ़्रेम>", -DlgLnkTargetPopup : "<पॉप-अप विन्डो>", -DlgLnkTargetBlank : "नया विन्डो (_blank)", -DlgLnkTargetParent : "मूल विन्डो (_parent)", -DlgLnkTargetSelf : "इसी विन्डो (_self)", -DlgLnkTargetTop : "शीर्ष विन्डो (_top)", -DlgLnkTargetFrameName : "टार्गेट फ़्रेम का नाम", -DlgLnkPopWinName : "पॉप-अप विन्डो का नाम", -DlgLnkPopWinFeat : "पॉप-अप विन्डो फ़ीचर्स", -DlgLnkPopResize : "साइज़ बदला जा सकता है", -DlgLnkPopLocation : "लोकेशन बार", -DlgLnkPopMenu : "मॅन्यू बार", -DlgLnkPopScroll : "स्क्रॉल बार", -DlgLnkPopStatus : "स्टेटस बार", -DlgLnkPopToolbar : "टूल बार", -DlgLnkPopFullScrn : "फ़ुल स्क्रीन (IE)", -DlgLnkPopDependent : "डिपेन्डॅन्ट (Netscape)", -DlgLnkPopWidth : "चौड़ाई", -DlgLnkPopHeight : "ऊँचाई", -DlgLnkPopLeft : "बायीं तरफ", -DlgLnkPopTop : "दायीं तरफ", - -DlnLnkMsgNoUrl : "लिंक URL टाइप करें", -DlnLnkMsgNoEMail : "ई-मेल पता टाइप करें", -DlnLnkMsgNoAnchor : "ऐंकर चुनें", -DlnLnkMsgInvPopName : "पॉप-अप का नाम अल्फाबेट से शुरू होना चाहिये और उसमें स्पेस नहीं होने चाहिए", - -// Color Dialog -DlgColorTitle : "रंग चुनें", -DlgColorBtnClear : "साफ़ करें", -DlgColorHighlight : "हाइलाइट", -DlgColorSelected : "सॅलॅक्टॅड", - -// Smiley Dialog -DlgSmileyTitle : "स्माइली इन्सर्ट करें", - -// Special Character Dialog -DlgSpecialCharTitle : "विशेष करॅक्टर चुनें", - -// Table Dialog -DlgTableTitle : "टेबल प्रॉपर्टीज़", -DlgTableRows : "पंक्तियाँ", -DlgTableColumns : "कालम", -DlgTableBorder : "बॉर्डर साइज़", -DlgTableAlign : "ऍलाइन्मॅन्ट", -DlgTableAlignNotSet : "<सॅट नहीं>", -DlgTableAlignLeft : "दायें", -DlgTableAlignCenter : "बीच में", -DlgTableAlignRight : "बायें", -DlgTableWidth : "चौड़ाई", -DlgTableWidthPx : "पिक्सैल", -DlgTableWidthPc : "प्रतिशत", -DlgTableHeight : "ऊँचाई", -DlgTableCellSpace : "सैल अंतर", -DlgTableCellPad : "सैल पैडिंग", -DlgTableCaption : "शीर्षक", -DlgTableSummary : "सारांश", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "सैल प्रॉपर्टीज़", -DlgCellWidth : "चौड़ाई", -DlgCellWidthPx : "पिक्सैल", -DlgCellWidthPc : "प्रतिशत", -DlgCellHeight : "ऊँचाई", -DlgCellWordWrap : "वर्ड रैप", -DlgCellWordWrapNotSet : "<सॅट नहीं>", -DlgCellWordWrapYes : "हाँ", -DlgCellWordWrapNo : "नहीं", -DlgCellHorAlign : "हॉरिज़ॉन्टल ऍलाइन्मॅन्ट", -DlgCellHorAlignNotSet : "<सॅट नहीं>", -DlgCellHorAlignLeft : "दायें", -DlgCellHorAlignCenter : "बीच में", -DlgCellHorAlignRight: "बायें", -DlgCellVerAlign : "वर्टिकल ऍलाइन्मॅन्ट", -DlgCellVerAlignNotSet : "<सॅट नहीं>", -DlgCellVerAlignTop : "ऊपर", -DlgCellVerAlignMiddle : "मध्य", -DlgCellVerAlignBottom : "नीचे", -DlgCellVerAlignBaseline : "मूलरेखा", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "पंक्ति स्पैन", -DlgCellCollSpan : "कालम स्पैन", -DlgCellBackColor : "बैक्ग्राउन्ड रंग", -DlgCellBorderColor : "बॉर्डर का रंग", -DlgCellBtnSelect : "चुनें...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "खोजें और बदलें", - -// Find Dialog -DlgFindTitle : "खोजें", -DlgFindFindBtn : "खोजें", -DlgFindNotFoundMsg : "आपके द्वारा दिया गया टेक्स्ट नहीं मिला", - -// Replace Dialog -DlgReplaceTitle : "रिप्लेस", -DlgReplaceFindLbl : "यह खोजें:", -DlgReplaceReplaceLbl : "इससे रिप्लेस करें:", -DlgReplaceCaseChk : "केस मिलायें", -DlgReplaceReplaceBtn : "रिप्लेस", -DlgReplaceReplAllBtn : "सभी रिप्लेस करें", -DlgReplaceWordChk : "पूरा शब्द मिलायें", - -// Paste Operations / Dialog -PasteErrorCut : "आपके ब्राउज़र की सुरक्षा सॅटिन्ग्स ने कट करने की अनुमति नहीं प्रदान की है। (Ctrl+X) का प्रयोग करें।", -PasteErrorCopy : "आपके ब्राआउज़र की सुरक्षा सॅटिन्ग्स ने कॉपी करने की अनुमति नहीं प्रदान की है। (Ctrl+C) का प्रयोग करें।", - -PasteAsText : "पेस्ट (सादा टॅक्स्ट)", -PasteFromWord : "पेस्ट (वर्ड से)", - -DlgPasteMsg2 : "Ctrl+V का प्रयोग करके पेस्ट करें और ठीक है करें.", -DlgPasteSec : "आपके ब्राउज़र की सुरक्षा आपके ब्राउज़र की सुरKश सैटिंग के कारण, एडिटर आपके क्लिपबोर्ड डेटा को नहीं पा सकता है. आपको उसे इस विन्डो में दोबारा पेस्ट करना होगा.", -DlgPasteIgnoreFont : "फ़ॉन्ट परिभाषा निकालें", -DlgPasteRemoveStyles : "स्टाइल परिभाषा निकालें", - -// Color Picker -ColorAutomatic : "स्वचालित", -ColorMoreColors : "और रंग...", - -// Document Properties -DocProps : "डॉक्यूमॅन्ट प्रॉपर्टीज़", - -// Anchor Dialog -DlgAnchorTitle : "ऐंकर प्रॉपर्टीज़", -DlgAnchorName : "ऐंकर का नाम", -DlgAnchorErrorName : "ऐंकर का नाम टाइप करें", - -// Speller Pages Dialog -DlgSpellNotInDic : "शब्दकोश में नहीं", -DlgSpellChangeTo : "इसमें बदलें", -DlgSpellBtnIgnore : "इग्नोर", -DlgSpellBtnIgnoreAll : "सभी इग्नोर करें", -DlgSpellBtnReplace : "रिप्लेस", -DlgSpellBtnReplaceAll : "सभी रिप्लेस करें", -DlgSpellBtnUndo : "अन्डू", -DlgSpellNoSuggestions : "- कोई सुझाव नहीं -", -DlgSpellProgress : "वर्तनी की जाँच (स्पॅल-चॅक) जारी है...", -DlgSpellNoMispell : "वर्तनी की जाँच : कोई गलत वर्तनी (स्पॅलिंग) नहीं पाई गई", -DlgSpellNoChanges : "वर्तनी की जाँच :कोई शब्द नहीं बदला गया", -DlgSpellOneChange : "वर्तनी की जाँच : एक शब्द बदला गया", -DlgSpellManyChanges : "वर्तनी की जाँच : %1 शब्द बदले गये", - -IeSpellDownload : "स्पॅल-चॅकर इन्स्टाल नहीं किया गया है। क्या आप इसे डा‌उनलोड करना चाहेंगे?", - -// Button Dialog -DlgButtonText : "टेक्स्ट (वैल्यू)", -DlgButtonType : "प्रकार", -DlgButtonTypeBtn : "बटन", -DlgButtonTypeSbm : "सब्मिट", -DlgButtonTypeRst : "रिसेट", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "नाम", -DlgCheckboxValue : "वैल्यू", -DlgCheckboxSelected : "सॅलॅक्टॅड", - -// Form Dialog -DlgFormName : "नाम", -DlgFormAction : "क्रिया", -DlgFormMethod : "तरीका", - -// Select Field Dialog -DlgSelectName : "नाम", -DlgSelectValue : "वैल्यू", -DlgSelectSize : "साइज़", -DlgSelectLines : "पंक्तियाँ", -DlgSelectChkMulti : "एक से ज्यादा विकल्प चुनने दें", -DlgSelectOpAvail : "उपलब्ध विकल्प", -DlgSelectOpText : "टेक्स्ट", -DlgSelectOpValue : "वैल्यू", -DlgSelectBtnAdd : "जोड़ें", -DlgSelectBtnModify : "बदलें", -DlgSelectBtnUp : "ऊपर", -DlgSelectBtnDown : "नीचे", -DlgSelectBtnSetValue : "चुनी गई वैल्यू सॅट करें", -DlgSelectBtnDelete : "डिलीट", - -// Textarea Dialog -DlgTextareaName : "नाम", -DlgTextareaCols : "कालम", -DlgTextareaRows : "पंक्तियां", - -// Text Field Dialog -DlgTextName : "नाम", -DlgTextValue : "वैल्यू", -DlgTextCharWidth : "करॅक्टर की चौढ़ाई", -DlgTextMaxChars : "अधिकतम करॅक्टर", -DlgTextType : "टाइप", -DlgTextTypeText : "टेक्स्ट", -DlgTextTypePass : "पास्वर्ड", - -// Hidden Field Dialog -DlgHiddenName : "नाम", -DlgHiddenValue : "वैल्यू", - -// Bulleted List Dialog -BulletedListProp : "बुलॅट सूची प्रॉपर्टीज़", -NumberedListProp : "अंकीय सूची प्रॉपर्टीज़", -DlgLstStart : "प्रारम्भ", -DlgLstType : "प्रकार", -DlgLstTypeCircle : "गोल", -DlgLstTypeDisc : "डिस्क", -DlgLstTypeSquare : "चौकॊण", -DlgLstTypeNumbers : "अंक (1, 2, 3)", -DlgLstTypeLCase : "छोटे अक्षर (a, b, c)", -DlgLstTypeUCase : "बड़े अक्षर (A, B, C)", -DlgLstTypeSRoman : "छोटे रोमन अंक (i, ii, iii)", -DlgLstTypeLRoman : "बड़े रोमन अंक (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "आम", -DlgDocBackTab : "बैक्ग्राउन्ड", -DlgDocColorsTab : "रंग और मार्जिन", -DlgDocMetaTab : "मॅटाडेटा", - -DlgDocPageTitle : "पेज शीर्षक", -DlgDocLangDir : "भाषा लिखने की दिशा", -DlgDocLangDirLTR : "बायें से दायें (LTR)", -DlgDocLangDirRTL : "दायें से बायें (RTL)", -DlgDocLangCode : "भाषा कोड", -DlgDocCharSet : "करेक्टर सॅट ऍन्कोडिंग", -DlgDocCharSetCE : "मध्य यूरोपीय (Central European)", -DlgDocCharSetCT : "चीनी (Chinese Traditional Big5)", -DlgDocCharSetCR : "सिरीलिक (Cyrillic)", -DlgDocCharSetGR : "यवन (Greek)", -DlgDocCharSetJP : "जापानी (Japanese)", -DlgDocCharSetKR : "कोरीयन (Korean)", -DlgDocCharSetTR : "तुर्की (Turkish)", -DlgDocCharSetUN : "यूनीकोड (UTF-8)", -DlgDocCharSetWE : "पश्चिम यूरोपीय (Western European)", -DlgDocCharSetOther : "अन्य करेक्टर सॅट ऍन्कोडिंग", - -DlgDocDocType : "डॉक्यूमॅन्ट प्रकार शीर्षक", -DlgDocDocTypeOther : "अन्य डॉक्यूमॅन्ट प्रकार शीर्षक", -DlgDocIncXHTML : "XHTML सूचना सम्मिलित करें", -DlgDocBgColor : "बैक्ग्राउन्ड रंग", -DlgDocBgImage : "बैक्ग्राउन्ड तस्वीर URL", -DlgDocBgNoScroll : "स्क्रॉल न करने वाला बैक्ग्राउन्ड", -DlgDocCText : "टेक्स्ट", -DlgDocCLink : "लिंक", -DlgDocCVisited : "विज़िट किया गया लिंक", -DlgDocCActive : "सक्रिय लिंक", -DlgDocMargins : "पेज मार्जिन", -DlgDocMaTop : "ऊपर", -DlgDocMaLeft : "बायें", -DlgDocMaRight : "दायें", -DlgDocMaBottom : "नीचे", -DlgDocMeIndex : "डॉक्युमॅन्ट इन्डेक्स संकेतशब्द (अल्पविराम से अलग करें)", -DlgDocMeDescr : "डॉक्यूमॅन्ट करॅक्टरन", -DlgDocMeAuthor : "लेखक", -DlgDocMeCopy : "कॉपीराइट", -DlgDocPreview : "प्रीव्यू", - -// Templates Dialog -Templates : "टॅम्प्लेट", -DlgTemplatesTitle : "कन्टेन्ट टॅम्प्लेट", -DlgTemplatesSelMsg : "ऍडिटर में ओपन करने हेतु टॅम्प्लेट चुनें(वर्तमान कन्टॅन्ट सेव नहीं होंगे):", -DlgTemplatesLoading : "टॅम्प्लेट सूची लोड की जा रही है। ज़रा ठहरें...", -DlgTemplatesNoTpl : "(कोई टॅम्प्लेट डिफ़ाइन नहीं किया गया है)", -DlgTemplatesReplace : "मूल शब्दों को बदलें", - -// About Dialog -DlgAboutAboutTab : "FCKEditor के बारे में", -DlgAboutBrowserInfoTab : "ब्राउज़र के बारे में", -DlgAboutLicenseTab : "लाइसैन्स", -DlgAboutVersion : "वर्ज़न", -DlgAboutInfo : "अधिक जानकारी के लिये यहाँ जायें:", - -// Div Dialog -DlgDivGeneralTab : "सामान्य", -DlgDivAdvancedTab : "एड्वान्स्ड", -DlgDivStyle : "स्टाइल", -DlgDivInlineStyle : "इनलाइन स्टाइल", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/hr.js b/httemplate/elements/fckeditor/editor/lang/hr.js deleted file mode 100644 index 3a920964f..000000000 --- a/httemplate/elements/fckeditor/editor/lang/hr.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Croatian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Smanji trake s alatima", -ToolbarExpand : "Proširi trake s alatima", - -// Toolbar Items and Context Menu -Save : "Snimi", -NewPage : "Nova stranica", -Preview : "Pregledaj", -Cut : "Izreži", -Copy : "Kopiraj", -Paste : "Zalijepi", -PasteText : "Zalijepi kao čisti tekst", -PasteWord : "Zalijepi iz Worda", -Print : "Ispiši", -SelectAll : "Odaberi sve", -RemoveFormat : "Ukloni formatiranje", -InsertLinkLbl : "Link", -InsertLink : "Ubaci/promijeni link", -RemoveLink : "Ukloni link", -VisitLink : "Otvori link", -Anchor : "Ubaci/promijeni sidro", -AnchorDelete : "Ukloni sidro", -InsertImageLbl : "Slika", -InsertImage : "Ubaci/promijeni sliku", -InsertFlashLbl : "Flash", -InsertFlash : "Ubaci/promijeni Flash", -InsertTableLbl : "Tablica", -InsertTable : "Ubaci/promijeni tablicu", -InsertLineLbl : "Linija", -InsertLine : "Ubaci vodoravnu liniju", -InsertSpecialCharLbl: "Posebni karakteri", -InsertSpecialChar : "Ubaci posebne znakove", -InsertSmileyLbl : "Smješko", -InsertSmiley : "Ubaci smješka", -About : "O FCKeditoru", -Bold : "Podebljaj", -Italic : "Ukosi", -Underline : "Potcrtano", -StrikeThrough : "Precrtano", -Subscript : "Subscript", -Superscript : "Superscript", -LeftJustify : "Lijevo poravnanje", -CenterJustify : "Središnje poravnanje", -RightJustify : "Desno poravnanje", -BlockJustify : "Blok poravnanje", -DecreaseIndent : "Pomakni ulijevo", -IncreaseIndent : "Pomakni udesno", -Blockquote : "Blockquote", -CreateDiv : "Napravi Div kontejner", -EditDiv : "Uredi Div kontejner", -DeleteDiv : "Ukloni Div kontejner", -Undo : "Poništi", -Redo : "Ponovi", -NumberedListLbl : "Brojčana lista", -NumberedList : "Ubaci/ukloni brojčanu listu", -BulletedListLbl : "Obična lista", -BulletedList : "Ubaci/ukloni običnu listu", -ShowTableBorders : "Prikaži okvir tablice", -ShowDetails : "Prikaži detalje", -Style : "Stil", -FontFormat : "Format", -Font : "Font", -FontSize : "Veličina", -TextColor : "Boja teksta", -BGColor : "Boja pozadine", -Source : "Kôd", -Find : "Pronađi", -Replace : "Zamijeni", -SpellCheck : "Provjeri pravopis", -UniversalKeyboard : "Univerzalna tipkovnica", -PageBreakLbl : "Prijelom stranice", -PageBreak : "Ubaci prijelom stranice", - -Form : "Form", -Checkbox : "Checkbox", -RadioButton : "Radio Button", -TextField : "Text Field", -Textarea : "Textarea", -HiddenField : "Hidden Field", -Button : "Button", -SelectionField : "Selection Field", -ImageButton : "Image Button", - -FitWindow : "Povećaj veličinu editora", -ShowBlocks : "Prikaži blokove", - -// Context Menu -EditLink : "Promijeni link", -CellCM : "Ćelija", -RowCM : "Red", -ColumnCM : "Kolona", -InsertRowAfter : "Ubaci red poslije", -InsertRowBefore : "Ubaci red prije", -DeleteRows : "Izbriši redove", -InsertColumnAfter : "Ubaci kolonu poslije", -InsertColumnBefore : "Ubaci kolonu prije", -DeleteColumns : "Izbriši kolone", -InsertCellAfter : "Ubaci ćeliju poslije", -InsertCellBefore : "Ubaci ćeliju prije", -DeleteCells : "Izbriši ćelije", -MergeCells : "Spoji ćelije", -MergeRight : "Spoji desno", -MergeDown : "Spoji dolje", -HorizontalSplitCell : "Podijeli ćeliju vodoravno", -VerticalSplitCell : "Podijeli ćeliju okomito", -TableDelete : "Izbriši tablicu", -CellProperties : "Svojstva ćelije", -TableProperties : "Svojstva tablice", -ImageProperties : "Svojstva slike", -FlashProperties : "Flash svojstva", - -AnchorProp : "Svojstva sidra", -ButtonProp : "Image Button svojstva", -CheckboxProp : "Checkbox svojstva", -HiddenFieldProp : "Hidden Field svojstva", -RadioButtonProp : "Radio Button svojstva", -ImageButtonProp : "Image Button svojstva", -TextFieldProp : "Text Field svojstva", -SelectionFieldProp : "Selection svojstva", -TextareaProp : "Textarea svojstva", -FormProp : "Form svojstva", - -FontFormats : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Obrađujem XHTML. Molimo pričekajte...", -Done : "Završio", -PasteWordConfirm : "Tekst koji želite zalijepiti čini se da je kopiran iz Worda. Želite li prije očistiti tekst?", -NotCompatiblePaste : "Ova naredba je dostupna samo u Internet Exploreru 5.5 ili novijem. Želite li nastaviti bez čišćenja?", -UnknownToolbarItem : "Nepoznati član trake s alatima \"%1\"", -UnknownCommand : "Nepoznata naredba \"%1\"", -NotImplemented : "Naredba nije implementirana", -UnknownToolbarSet : "Traka s alatima \"%1\" ne postoji", -NoActiveX : "Vaše postavke pretraživača mogle bi ograničiti neke od mogućnosti editora. Morate uključiti opciju \"Run ActiveX controls and plug-ins\" u postavkama. Ukoliko to ne učinite, moguće su razliite greške tijekom rada.", -BrowseServerBlocked : "Pretraivač nije moguće otvoriti. Provjerite da li je uključeno blokiranje pop-up prozora.", -DialogBlocked : "Nije moguće otvoriti novi prozor. Provjerite da li je uključeno blokiranje pop-up prozora.", -VisitLinkBlocked : "Nije moguće otvoriti novi prozor. Provjerite da li je uključeno blokiranje pop-up prozora.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Poništi", -DlgBtnClose : "Zatvori", -DlgBtnBrowseServer : "Pretraži server", -DlgAdvancedTag : "Napredno", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Molimo unesite URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Smjer jezika", -DlgGenLangDirLtr : "S lijeva na desno (LTR)", -DlgGenLangDirRtl : "S desna na lijevo (RTL)", -DlgGenLangCode : "Kôd jezika", -DlgGenAccessKey : "Pristupna tipka", -DlgGenName : "Naziv", -DlgGenTabIndex : "Tab Indeks", -DlgGenLongDescr : "Dugački opis URL", -DlgGenClass : "Stylesheet klase", -DlgGenTitle : "Advisory naslov", -DlgGenContType : "Advisory vrsta sadržaja", -DlgGenLinkCharset : "Kodna stranica povezanih resursa", -DlgGenStyle : "Stil", - -// Image Dialog -DlgImgTitle : "Svojstva slika", -DlgImgInfoTab : "Info slike", -DlgImgBtnUpload : "Pošalji na server", -DlgImgURL : "URL", -DlgImgUpload : "Pošalji", -DlgImgAlt : "Alternativni tekst", -DlgImgWidth : "Širina", -DlgImgHeight : "Visina", -DlgImgLockRatio : "Zaključaj odnos", -DlgBtnResetSize : "Obriši veličinu", -DlgImgBorder : "Okvir", -DlgImgHSpace : "HSpace", -DlgImgVSpace : "VSpace", -DlgImgAlign : "Poravnaj", -DlgImgAlignLeft : "Lijevo", -DlgImgAlignAbsBottom: "Abs dolje", -DlgImgAlignAbsMiddle: "Abs sredina", -DlgImgAlignBaseline : "Bazno", -DlgImgAlignBottom : "Dolje", -DlgImgAlignMiddle : "Sredina", -DlgImgAlignRight : "Desno", -DlgImgAlignTextTop : "Vrh teksta", -DlgImgAlignTop : "Vrh", -DlgImgPreview : "Pregledaj", -DlgImgAlertUrl : "Unesite URL slike", -DlgImgLinkTab : "Link", - -// Flash Dialog -DlgFlashTitle : "Flash svojstva", -DlgFlashChkPlay : "Auto Play", -DlgFlashChkLoop : "Ponavljaj", -DlgFlashChkMenu : "Omogući Flash izbornik", -DlgFlashScale : "Omjer", -DlgFlashScaleAll : "Prikaži sve", -DlgFlashScaleNoBorder : "Bez okvira", -DlgFlashScaleFit : "Točna veličina", - -// Link Dialog -DlgLnkWindowTitle : "Link", -DlgLnkInfoTab : "Link Info", -DlgLnkTargetTab : "Meta", - -DlgLnkType : "Link vrsta", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Sidro na ovoj stranici", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protokol", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Odaberi sidro", -DlgLnkAnchorByName : "Po nazivu sidra", -DlgLnkAnchorById : "Po Id elementa", -DlgLnkNoAnchors : "(Nema dostupnih sidra)", -DlgLnkEMail : "E-Mail adresa", -DlgLnkEMailSubject : "Naslov", -DlgLnkEMailBody : "Sadržaj poruke", -DlgLnkUpload : "Pošalji", -DlgLnkBtnUpload : "Pošalji na server", - -DlgLnkTarget : "Meta", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Novi prozor (_blank)", -DlgLnkTargetParent : "Roditeljski prozor (_parent)", -DlgLnkTargetSelf : "Isti prozor (_self)", -DlgLnkTargetTop : "Vršni prozor (_top)", -DlgLnkTargetFrameName : "Ime ciljnog okvira", -DlgLnkPopWinName : "Naziv popup prozora", -DlgLnkPopWinFeat : "Mogućnosti popup prozora", -DlgLnkPopResize : "Promjenljive veličine", -DlgLnkPopLocation : "Traka za lokaciju", -DlgLnkPopMenu : "Izborna traka", -DlgLnkPopScroll : "Scroll traka", -DlgLnkPopStatus : "Statusna traka", -DlgLnkPopToolbar : "Traka s alatima", -DlgLnkPopFullScrn : "Cijeli ekran (IE)", -DlgLnkPopDependent : "Ovisno (Netscape)", -DlgLnkPopWidth : "Širina", -DlgLnkPopHeight : "Visina", -DlgLnkPopLeft : "Lijeva pozicija", -DlgLnkPopTop : "Gornja pozicija", - -DlnLnkMsgNoUrl : "Molimo upišite URL link", -DlnLnkMsgNoEMail : "Molimo upišite e-mail adresu", -DlnLnkMsgNoAnchor : "Molimo odaberite sidro", -DlnLnkMsgInvPopName : "Ime popup prozora mora početi sa slovom i ne smije sadržavati razmake", - -// Color Dialog -DlgColorTitle : "Odaberite boju", -DlgColorBtnClear : "Obriši", -DlgColorHighlight : "Osvijetli", -DlgColorSelected : "Odaberi", - -// Smiley Dialog -DlgSmileyTitle : "Ubaci smješka", - -// Special Character Dialog -DlgSpecialCharTitle : "Odaberite posebni karakter", - -// Table Dialog -DlgTableTitle : "Svojstva tablice", -DlgTableRows : "Redova", -DlgTableColumns : "Kolona", -DlgTableBorder : "Veličina okvira", -DlgTableAlign : "Poravnanje", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Lijevo", -DlgTableAlignCenter : "Središnje", -DlgTableAlignRight : "Desno", -DlgTableWidth : "Širina", -DlgTableWidthPx : "piksela", -DlgTableWidthPc : "postotaka", -DlgTableHeight : "Visina", -DlgTableCellSpace : "Prostornost ćelija", -DlgTableCellPad : "Razmak ćelija", -DlgTableCaption : "Naslov", -DlgTableSummary : "Sažetak", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Svojstva ćelije", -DlgCellWidth : "Širina", -DlgCellWidthPx : "piksela", -DlgCellWidthPc : "postotaka", -DlgCellHeight : "Visina", -DlgCellWordWrap : "Word Wrap", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Da", -DlgCellWordWrapNo : "Ne", -DlgCellHorAlign : "Vodoravno poravnanje", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Lijevo", -DlgCellHorAlignCenter : "Središnje", -DlgCellHorAlignRight: "Desno", -DlgCellVerAlign : "Okomito poravnanje", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Gornje", -DlgCellVerAlignMiddle : "Srednišnje", -DlgCellVerAlignBottom : "Donje", -DlgCellVerAlignBaseline : "Bazno", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Spajanje redova", -DlgCellCollSpan : "Spajanje kolona", -DlgCellBackColor : "Boja pozadine", -DlgCellBorderColor : "Boja okvira", -DlgCellBtnSelect : "Odaberi...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Pronađi i zamijeni", - -// Find Dialog -DlgFindTitle : "Pronađi", -DlgFindFindBtn : "Pronađi", -DlgFindNotFoundMsg : "Traženi tekst nije pronađen.", - -// Replace Dialog -DlgReplaceTitle : "Zamijeni", -DlgReplaceFindLbl : "Pronađi:", -DlgReplaceReplaceLbl : "Zamijeni s:", -DlgReplaceCaseChk : "Usporedi mala/velika slova", -DlgReplaceReplaceBtn : "Zamijeni", -DlgReplaceReplAllBtn : "Zamijeni sve", -DlgReplaceWordChk : "Usporedi cijele riječi", - -// Paste Operations / Dialog -PasteErrorCut : "Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog izrezivanja. Molimo koristite kraticu na tipkovnici (Ctrl+X).", -PasteErrorCopy : "Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tipkovnici (Ctrl+C).", - -PasteAsText : "Zalijepi kao čisti tekst", -PasteFromWord : "Zalijepi iz Worda", - -DlgPasteMsg2 : "Molimo zaljepite unutar doljnjeg okvira koristeći tipkovnicu (Ctrl+V) i kliknite OK.", -DlgPasteSec : "Zbog sigurnosnih postavki Vašeg pretraživača, editor nema direktan pristup Vašem međuspremniku. Potrebno je ponovno zalijepiti tekst u ovaj prozor.", -DlgPasteIgnoreFont : "Zanemari definiciju vrste fonta", -DlgPasteRemoveStyles : "Ukloni definicije stilova", - -// Color Picker -ColorAutomatic : "Automatski", -ColorMoreColors : "Više boja...", - -// Document Properties -DocProps : "Svojstva dokumenta", - -// Anchor Dialog -DlgAnchorTitle : "Svojstva sidra", -DlgAnchorName : "Ime sidra", -DlgAnchorErrorName : "Molimo unesite ime sidra", - -// Speller Pages Dialog -DlgSpellNotInDic : "Nije u rječniku", -DlgSpellChangeTo : "Promijeni u", -DlgSpellBtnIgnore : "Zanemari", -DlgSpellBtnIgnoreAll : "Zanemari sve", -DlgSpellBtnReplace : "Zamijeni", -DlgSpellBtnReplaceAll : "Zamijeni sve", -DlgSpellBtnUndo : "Vrati", -DlgSpellNoSuggestions : "-Nema preporuke-", -DlgSpellProgress : "Provjera u tijeku...", -DlgSpellNoMispell : "Provjera završena: Nema grešaka", -DlgSpellNoChanges : "Provjera završena: Nije napravljena promjena", -DlgSpellOneChange : "Provjera završena: Jedna riječ promjenjena", -DlgSpellManyChanges : "Provjera završena: Promijenjeno %1 riječi", - -IeSpellDownload : "Provjera pravopisa nije instalirana. Želite li skinuti provjeru pravopisa?", - -// Button Dialog -DlgButtonText : "Tekst (vrijednost)", -DlgButtonType : "Vrsta", -DlgButtonTypeBtn : "Gumb", -DlgButtonTypeSbm : "Pošalji", -DlgButtonTypeRst : "Poništi", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Ime", -DlgCheckboxValue : "Vrijednost", -DlgCheckboxSelected : "Odabrano", - -// Form Dialog -DlgFormName : "Ime", -DlgFormAction : "Akcija", -DlgFormMethod : "Metoda", - -// Select Field Dialog -DlgSelectName : "Ime", -DlgSelectValue : "Vrijednost", -DlgSelectSize : "Veličina", -DlgSelectLines : "linija", -DlgSelectChkMulti : "Dozvoli višestruki odabir", -DlgSelectOpAvail : "Dostupne opcije", -DlgSelectOpText : "Tekst", -DlgSelectOpValue : "Vrijednost", -DlgSelectBtnAdd : "Dodaj", -DlgSelectBtnModify : "Promijeni", -DlgSelectBtnUp : "Gore", -DlgSelectBtnDown : "Dolje", -DlgSelectBtnSetValue : "Postavi kao odabranu vrijednost", -DlgSelectBtnDelete : "Obriši", - -// Textarea Dialog -DlgTextareaName : "Ime", -DlgTextareaCols : "Kolona", -DlgTextareaRows : "Redova", - -// Text Field Dialog -DlgTextName : "Ime", -DlgTextValue : "Vrijednost", -DlgTextCharWidth : "Širina", -DlgTextMaxChars : "Najviše karaktera", -DlgTextType : "Vrsta", -DlgTextTypeText : "Tekst", -DlgTextTypePass : "Šifra", - -// Hidden Field Dialog -DlgHiddenName : "Ime", -DlgHiddenValue : "Vrijednost", - -// Bulleted List Dialog -BulletedListProp : "Svojstva liste", -NumberedListProp : "Svojstva brojčane liste", -DlgLstStart : "Početak", -DlgLstType : "Vrsta", -DlgLstTypeCircle : "Krug", -DlgLstTypeDisc : "Disk", -DlgLstTypeSquare : "Kvadrat", -DlgLstTypeNumbers : "Brojevi (1, 2, 3)", -DlgLstTypeLCase : "Mala slova (a, b, c)", -DlgLstTypeUCase : "Velika slova (A, B, C)", -DlgLstTypeSRoman : "Male rimske brojke (i, ii, iii)", -DlgLstTypeLRoman : "Velike rimske brojke (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Općenito", -DlgDocBackTab : "Pozadina", -DlgDocColorsTab : "Boje i margine", -DlgDocMetaTab : "Meta Data", - -DlgDocPageTitle : "Naslov stranice", -DlgDocLangDir : "Smjer jezika", -DlgDocLangDirLTR : "S lijeva na desno", -DlgDocLangDirRTL : "S desna na lijevo", -DlgDocLangCode : "Kôd jezika", -DlgDocCharSet : "Enkodiranje znakova", -DlgDocCharSetCE : "Središnja Europa", -DlgDocCharSetCT : "Tradicionalna kineska (Big5)", -DlgDocCharSetCR : "Ćirilica", -DlgDocCharSetGR : "Grčka", -DlgDocCharSetJP : "Japanska", -DlgDocCharSetKR : "Koreanska", -DlgDocCharSetTR : "Turska", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Zapadna Europa", -DlgDocCharSetOther : "Ostalo enkodiranje znakova", - -DlgDocDocType : "Zaglavlje vrste dokumenta", -DlgDocDocTypeOther : "Ostalo zaglavlje vrste dokumenta", -DlgDocIncXHTML : "Ubaci XHTML deklaracije", -DlgDocBgColor : "Boja pozadine", -DlgDocBgImage : "URL slike pozadine", -DlgDocBgNoScroll : "Pozadine se ne pomiče", -DlgDocCText : "Tekst", -DlgDocCLink : "Link", -DlgDocCVisited : "Posjećeni link", -DlgDocCActive : "Aktivni link", -DlgDocMargins : "Margine stranice", -DlgDocMaTop : "Vrh", -DlgDocMaLeft : "Lijevo", -DlgDocMaRight : "Desno", -DlgDocMaBottom : "Dolje", -DlgDocMeIndex : "Ključne riječi dokumenta (odvojene zarezom)", -DlgDocMeDescr : "Opis dokumenta", -DlgDocMeAuthor : "Autor", -DlgDocMeCopy : "Autorska prava", -DlgDocPreview : "Pregledaj", - -// Templates Dialog -Templates : "Predlošci", -DlgTemplatesTitle : "Predlošci sadržaja", -DlgTemplatesSelMsg : "Molimo odaberite predložak koji želite otvoriti
    (stvarni sadržaj će biti izgubljen):", -DlgTemplatesLoading : "Učitavam listu predložaka. Molimo pričekajte...", -DlgTemplatesNoTpl : "(Nema definiranih predložaka)", -DlgTemplatesReplace : "Zamijeni trenutne sadržaje", - -// About Dialog -DlgAboutAboutTab : "O FCKEditoru", -DlgAboutBrowserInfoTab : "Podaci o pretraživaču", -DlgAboutLicenseTab : "Licenca", -DlgAboutVersion : "inačica", -DlgAboutInfo : "Za više informacija posjetite", - -// Div Dialog -DlgDivGeneralTab : "Općenito", -DlgDivAdvancedTab : "Napredno", -DlgDivStyle : "Stil", -DlgDivInlineStyle : "Stil u redu", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/hu.js b/httemplate/elements/fckeditor/editor/lang/hu.js deleted file mode 100644 index 0a72cac90..000000000 --- a/httemplate/elements/fckeditor/editor/lang/hu.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Hungarian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Eszköztár elrejtése", -ToolbarExpand : "Eszköztár megjelenítése", - -// Toolbar Items and Context Menu -Save : "Mentés", -NewPage : "Új oldal", -Preview : "Előnézet", -Cut : "Kivágás", -Copy : "Másolás", -Paste : "Beillesztés", -PasteText : "Beillesztés formázás nélkül", -PasteWord : "Beillesztés Word-ből", -Print : "Nyomtatás", -SelectAll : "Mindent kijelöl", -RemoveFormat : "Formázás eltávolítása", -InsertLinkLbl : "Hivatkozás", -InsertLink : "Hivatkozás beillesztése/módosítása", -RemoveLink : "Hivatkozás törlése", -VisitLink : "Open Link", //MISSING -Anchor : "Horgony beillesztése/szerkesztése", -AnchorDelete : "Horgony eltávolítása", -InsertImageLbl : "Kép", -InsertImage : "Kép beillesztése/módosítása", -InsertFlashLbl : "Flash", -InsertFlash : "Flash beillesztése, módosítása", -InsertTableLbl : "Táblázat", -InsertTable : "Táblázat beillesztése/módosítása", -InsertLineLbl : "Vonal", -InsertLine : "Elválasztóvonal beillesztése", -InsertSpecialCharLbl: "Speciális karakter", -InsertSpecialChar : "Speciális karakter beillesztése", -InsertSmileyLbl : "Hangulatjelek", -InsertSmiley : "Hangulatjelek beillesztése", -About : "FCKeditor névjegy", -Bold : "Félkövér", -Italic : "Dőlt", -Underline : "Aláhúzott", -StrikeThrough : "Áthúzott", -Subscript : "Alsó index", -Superscript : "Felső index", -LeftJustify : "Balra", -CenterJustify : "Középre", -RightJustify : "Jobbra", -BlockJustify : "Sorkizárt", -DecreaseIndent : "Behúzás csökkentése", -IncreaseIndent : "Behúzás növelése", -Blockquote : "Idézet blokk", -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Visszavonás", -Redo : "Ismétlés", -NumberedListLbl : "Számozás", -NumberedList : "Számozás beillesztése/törlése", -BulletedListLbl : "Felsorolás", -BulletedList : "Felsorolás beillesztése/törlése", -ShowTableBorders : "Táblázat szegély mutatása", -ShowDetails : "Részletek mutatása", -Style : "Stílus", -FontFormat : "Formátum", -Font : "Betűtípus", -FontSize : "Méret", -TextColor : "Betűszín", -BGColor : "Háttérszín", -Source : "Forráskód", -Find : "Keresés", -Replace : "Csere", -SpellCheck : "Helyesírás-ellenőrzés", -UniversalKeyboard : "Univerzális billentyűzet", -PageBreakLbl : "Oldaltörés", -PageBreak : "Oldaltörés beillesztése", - -Form : "Űrlap", -Checkbox : "Jelölőnégyzet", -RadioButton : "Választógomb", -TextField : "Szövegmező", -Textarea : "Szövegterület", -HiddenField : "Rejtettmező", -Button : "Gomb", -SelectionField : "Legördülő lista", -ImageButton : "Képgomb", - -FitWindow : "Maximalizálás", -ShowBlocks : "Blokkok megjelenítése", - -// Context Menu -EditLink : "Hivatkozás módosítása", -CellCM : "Cella", -RowCM : "Sor", -ColumnCM : "Oszlop", -InsertRowAfter : "Sor beillesztése az aktuális sor mögé", -InsertRowBefore : "Sor beillesztése az aktuális sor elé", -DeleteRows : "Sorok törlése", -InsertColumnAfter : "Oszlop beillesztése az aktuális oszlop mögé", -InsertColumnBefore : "Oszlop beillesztése az aktuális oszlop elé", -DeleteColumns : "Oszlopok törlése", -InsertCellAfter : "Cella beillesztése az aktuális cella mögé", -InsertCellBefore : "Cella beillesztése az aktuális cella elé", -DeleteCells : "Cellák törlése", -MergeCells : "Cellák egyesítése", -MergeRight : "Cellák egyesítése jobbra", -MergeDown : "Cellák egyesítése lefelé", -HorizontalSplitCell : "Cellák szétválasztása vízszintesen", -VerticalSplitCell : "Cellák szétválasztása függőlegesen", -TableDelete : "Táblázat törlése", -CellProperties : "Cella tulajdonságai", -TableProperties : "Táblázat tulajdonságai", -ImageProperties : "Kép tulajdonságai", -FlashProperties : "Flash tulajdonságai", - -AnchorProp : "Horgony tulajdonságai", -ButtonProp : "Gomb tulajdonságai", -CheckboxProp : "Jelölőnégyzet tulajdonságai", -HiddenFieldProp : "Rejtett mező tulajdonságai", -RadioButtonProp : "Választógomb tulajdonságai", -ImageButtonProp : "Képgomb tulajdonságai", -TextFieldProp : "Szövegmező tulajdonságai", -SelectionFieldProp : "Legördülő lista tulajdonságai", -TextareaProp : "Szövegterület tulajdonságai", -FormProp : "Űrlap tulajdonságai", - -FontFormats : "Normál;Formázott;Címsor;Fejléc 1;Fejléc 2;Fejléc 3;Fejléc 4;Fejléc 5;Fejléc 6;Bekezdés (DIV)", - -// Alerts and Messages -ProcessingXHTML : "XHTML feldolgozása. Kérem várjon...", -Done : "Kész", -PasteWordConfirm : "A beilleszteni kívánt szöveg Word-ből van másolva. El kívánja távolítani a formázást a beillesztés előtt?", -NotCompatiblePaste : "Ez a parancs csak Internet Explorer 5.5 verziótól használható. Megpróbálja beilleszteni a szöveget az eredeti formázással?", -UnknownToolbarItem : "Ismeretlen eszköztár elem \"%1\"", -UnknownCommand : "Ismeretlen parancs \"%1\"", -NotImplemented : "A parancs nem hajtható végre", -UnknownToolbarSet : "Az eszközkészlet \"%1\" nem létezik", -NoActiveX : "A böngésző biztonsági beállításai korlátozzák a szerkesztő lehetőségeit. Engedélyezni kell ezt az opciót: \"Run ActiveX controls and plug-ins\". Ettől függetlenül előfordulhatnak hibaüzenetek ill. bizonyos funkciók hiányozhatnak.", -BrowseServerBlocked : "Nem lehet megnyitni a fájlböngészőt. Bizonyosodjon meg róla, hogy a felbukkanó ablakok engedélyezve vannak.", -DialogBlocked : "Nem lehet megnyitni a párbeszédablakot. Bizonyosodjon meg róla, hogy a felbukkanó ablakok engedélyezve vannak.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "Rendben", -DlgBtnCancel : "Mégsem", -DlgBtnClose : "Bezárás", -DlgBtnBrowseServer : "Böngészés a szerveren", -DlgAdvancedTag : "További opciók", -DlgOpOther : "Egyéb", -DlgInfoTab : "Alaptulajdonságok", -DlgAlertUrl : "Illessze be a webcímet", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Azonosító", -DlgGenLangDir : "Írás iránya", -DlgGenLangDirLtr : "Balról jobbra", -DlgGenLangDirRtl : "Jobbról balra", -DlgGenLangCode : "Nyelv kódja", -DlgGenAccessKey : "Billentyűkombináció", -DlgGenName : "Név", -DlgGenTabIndex : "Tabulátor index", -DlgGenLongDescr : "Részletes leírás webcíme", -DlgGenClass : "Stíluskészlet", -DlgGenTitle : "Súgócimke", -DlgGenContType : "Súgó tartalomtípusa", -DlgGenLinkCharset : "Hivatkozott tartalom kódlapja", -DlgGenStyle : "Stílus", - -// Image Dialog -DlgImgTitle : "Kép tulajdonságai", -DlgImgInfoTab : "Alaptulajdonságok", -DlgImgBtnUpload : "Küldés a szerverre", -DlgImgURL : "Hivatkozás", -DlgImgUpload : "Feltöltés", -DlgImgAlt : "Buborék szöveg", -DlgImgWidth : "Szélesség", -DlgImgHeight : "Magasság", -DlgImgLockRatio : "Arány megtartása", -DlgBtnResetSize : "Eredeti méret", -DlgImgBorder : "Keret", -DlgImgHSpace : "Vízsz. táv", -DlgImgVSpace : "Függ. táv", -DlgImgAlign : "Igazítás", -DlgImgAlignLeft : "Bal", -DlgImgAlignAbsBottom: "Legaljára", -DlgImgAlignAbsMiddle: "Közepére", -DlgImgAlignBaseline : "Alapvonalhoz", -DlgImgAlignBottom : "Aljára", -DlgImgAlignMiddle : "Középre", -DlgImgAlignRight : "Jobbra", -DlgImgAlignTextTop : "Szöveg tetejére", -DlgImgAlignTop : "Tetejére", -DlgImgPreview : "Előnézet", -DlgImgAlertUrl : "Töltse ki a kép webcímét", -DlgImgLinkTab : "Hivatkozás", - -// Flash Dialog -DlgFlashTitle : "Flash tulajdonságai", -DlgFlashChkPlay : "Automata lejátszás", -DlgFlashChkLoop : "Folyamatosan", -DlgFlashChkMenu : "Flash menü engedélyezése", -DlgFlashScale : "Méretezés", -DlgFlashScaleAll : "Mindent mutat", -DlgFlashScaleNoBorder : "Keret nélkül", -DlgFlashScaleFit : "Teljes kitöltés", - -// Link Dialog -DlgLnkWindowTitle : "Hivatkozás tulajdonságai", -DlgLnkInfoTab : "Alaptulajdonságok", -DlgLnkTargetTab : "Megjelenítés", - -DlgLnkType : "Hivatkozás típusa", -DlgLnkTypeURL : "Webcím", -DlgLnkTypeAnchor : "Horgony az oldalon", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protokoll", -DlgLnkProtoOther : "", -DlgLnkURL : "Webcím", -DlgLnkAnchorSel : "Horgony választása", -DlgLnkAnchorByName : "Horgony név szerint", -DlgLnkAnchorById : "Azonosító szerint", -DlgLnkNoAnchors : "(Nincs horgony a dokumentumban)", -DlgLnkEMail : "E-Mail cím", -DlgLnkEMailSubject : "Üzenet tárgya", -DlgLnkEMailBody : "Üzenet", -DlgLnkUpload : "Feltöltés", -DlgLnkBtnUpload : "Küldés a szerverre", - -DlgLnkTarget : "Tartalom megjelenítése", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Új ablakban (_blank)", -DlgLnkTargetParent : "Szülő ablakban (_parent)", -DlgLnkTargetSelf : "Azonos ablakban (_self)", -DlgLnkTargetTop : "Legfelső ablakban (_top)", -DlgLnkTargetFrameName : "Keret neve", -DlgLnkPopWinName : "Felugró ablak neve", -DlgLnkPopWinFeat : "Felugró ablak jellemzői", -DlgLnkPopResize : "Méretezhető", -DlgLnkPopLocation : "Címsor", -DlgLnkPopMenu : "Menü sor", -DlgLnkPopScroll : "Gördítősáv", -DlgLnkPopStatus : "Állapotsor", -DlgLnkPopToolbar : "Eszköztár", -DlgLnkPopFullScrn : "Teljes képernyő (csak IE)", -DlgLnkPopDependent : "Szülőhöz kapcsolt (csak Netscape)", -DlgLnkPopWidth : "Szélesség", -DlgLnkPopHeight : "Magasság", -DlgLnkPopLeft : "Bal pozíció", -DlgLnkPopTop : "Felső pozíció", - -DlnLnkMsgNoUrl : "Adja meg a hivatkozás webcímét", -DlnLnkMsgNoEMail : "Adja meg az E-Mail címet", -DlnLnkMsgNoAnchor : "Válasszon egy horgonyt", -DlnLnkMsgInvPopName : "A felbukkanó ablak neve alfanumerikus karakterrel kezdôdjön, valamint ne tartalmazzon szóközt", - -// Color Dialog -DlgColorTitle : "Színválasztás", -DlgColorBtnClear : "Törlés", -DlgColorHighlight : "Előnézet", -DlgColorSelected : "Kiválasztott", - -// Smiley Dialog -DlgSmileyTitle : "Hangulatjel beszúrása", - -// Special Character Dialog -DlgSpecialCharTitle : "Speciális karakter választása", - -// Table Dialog -DlgTableTitle : "Táblázat tulajdonságai", -DlgTableRows : "Sorok", -DlgTableColumns : "Oszlopok", -DlgTableBorder : "Szegélyméret", -DlgTableAlign : "Igazítás", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Balra", -DlgTableAlignCenter : "Középre", -DlgTableAlignRight : "Jobbra", -DlgTableWidth : "Szélesség", -DlgTableWidthPx : "képpont", -DlgTableWidthPc : "százalék", -DlgTableHeight : "Magasság", -DlgTableCellSpace : "Cella térköz", -DlgTableCellPad : "Cella belső margó", -DlgTableCaption : "Felirat", -DlgTableSummary : "Leírás", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Cella tulajdonságai", -DlgCellWidth : "Szélesség", -DlgCellWidthPx : "képpont", -DlgCellWidthPc : "százalék", -DlgCellHeight : "Magasság", -DlgCellWordWrap : "Sortörés", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Igen", -DlgCellWordWrapNo : "Nem", -DlgCellHorAlign : "Vízsz. igazítás", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Balra", -DlgCellHorAlignCenter : "Középre", -DlgCellHorAlignRight: "Jobbra", -DlgCellVerAlign : "Függ. igazítás", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Tetejére", -DlgCellVerAlignMiddle : "Középre", -DlgCellVerAlignBottom : "Aljára", -DlgCellVerAlignBaseline : "Egyvonalba", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Sorok egyesítése", -DlgCellCollSpan : "Oszlopok egyesítése", -DlgCellBackColor : "Háttérszín", -DlgCellBorderColor : "Szegélyszín", -DlgCellBtnSelect : "Kiválasztás...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Keresés és csere", - -// Find Dialog -DlgFindTitle : "Keresés", -DlgFindFindBtn : "Keresés", -DlgFindNotFoundMsg : "A keresett szöveg nem található.", - -// Replace Dialog -DlgReplaceTitle : "Csere", -DlgReplaceFindLbl : "Keresett szöveg:", -DlgReplaceReplaceLbl : "Csere erre:", -DlgReplaceCaseChk : "kis- és nagybetű megkülönböztetése", -DlgReplaceReplaceBtn : "Csere", -DlgReplaceReplAllBtn : "Az összes cseréje", -DlgReplaceWordChk : "csak ha ez a teljes szó", - -// Paste Operations / Dialog -PasteErrorCut : "A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a kivágás műveletet. Használja az alábbi billentyűkombinációt (Ctrl+X).", -PasteErrorCopy : "A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a másolás műveletet. Használja az alábbi billentyűkombinációt (Ctrl+X).", - -PasteAsText : "Beillesztés formázatlan szövegként", -PasteFromWord : "Beillesztés Word-ből", - -DlgPasteMsg2 : "Másolja be az alábbi mezőbe a Ctrl+V billentyűk lenyomásával, majd nyomjon Rendben-t.", -DlgPasteSec : "A böngésző biztonsági beállításai miatt a szerkesztő nem képes hozzáférni a vágólap adataihoz. Illeszd be újra ebben az ablakban.", -DlgPasteIgnoreFont : "Betű formázások megszüntetése", -DlgPasteRemoveStyles : "Stílusok eltávolítása", - -// Color Picker -ColorAutomatic : "Automatikus", -ColorMoreColors : "További színek...", - -// Document Properties -DocProps : "Dokumentum tulajdonságai", - -// Anchor Dialog -DlgAnchorTitle : "Horgony tulajdonságai", -DlgAnchorName : "Horgony neve", -DlgAnchorErrorName : "Kérem adja meg a horgony nevét", - -// Speller Pages Dialog -DlgSpellNotInDic : "Nincs a szótárban", -DlgSpellChangeTo : "Módosítás", -DlgSpellBtnIgnore : "Kihagyja", -DlgSpellBtnIgnoreAll : "Mindet kihagyja", -DlgSpellBtnReplace : "Csere", -DlgSpellBtnReplaceAll : "Összes cseréje", -DlgSpellBtnUndo : "Visszavonás", -DlgSpellNoSuggestions : "Nincs javaslat", -DlgSpellProgress : "Helyesírás-ellenőrzés folyamatban...", -DlgSpellNoMispell : "Helyesírás-ellenőrzés kész: Nem találtam hibát", -DlgSpellNoChanges : "Helyesírás-ellenőrzés kész: Nincs változtatott szó", -DlgSpellOneChange : "Helyesírás-ellenőrzés kész: Egy szó cserélve", -DlgSpellManyChanges : "Helyesírás-ellenőrzés kész: %1 szó cserélve", - -IeSpellDownload : "A helyesírás-ellenőrző nincs telepítve. Szeretné letölteni most?", - -// Button Dialog -DlgButtonText : "Szöveg (Érték)", -DlgButtonType : "Típus", -DlgButtonTypeBtn : "Gomb", -DlgButtonTypeSbm : "Küldés", -DlgButtonTypeRst : "Alaphelyzet", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Név", -DlgCheckboxValue : "Érték", -DlgCheckboxSelected : "Kiválasztott", - -// Form Dialog -DlgFormName : "Név", -DlgFormAction : "Adatfeldolgozást végző hivatkozás", -DlgFormMethod : "Adatküldés módja", - -// Select Field Dialog -DlgSelectName : "Név", -DlgSelectValue : "Érték", -DlgSelectSize : "Méret", -DlgSelectLines : "sor", -DlgSelectChkMulti : "több sor is kiválasztható", -DlgSelectOpAvail : "Elérhető opciók", -DlgSelectOpText : "Szöveg", -DlgSelectOpValue : "Érték", -DlgSelectBtnAdd : "Hozzáad", -DlgSelectBtnModify : "Módosít", -DlgSelectBtnUp : "Fel", -DlgSelectBtnDown : "Le", -DlgSelectBtnSetValue : "Legyen az alapértelmezett érték", -DlgSelectBtnDelete : "Töröl", - -// Textarea Dialog -DlgTextareaName : "Név", -DlgTextareaCols : "Karakterek száma egy sorban", -DlgTextareaRows : "Sorok száma", - -// Text Field Dialog -DlgTextName : "Név", -DlgTextValue : "Érték", -DlgTextCharWidth : "Megjelenített karakterek száma", -DlgTextMaxChars : "Maximális karakterszám", -DlgTextType : "Típus", -DlgTextTypeText : "Szöveg", -DlgTextTypePass : "Jelszó", - -// Hidden Field Dialog -DlgHiddenName : "Név", -DlgHiddenValue : "Érték", - -// Bulleted List Dialog -BulletedListProp : "Felsorolás tulajdonságai", -NumberedListProp : "Számozás tulajdonságai", -DlgLstStart : "Start", -DlgLstType : "Formátum", -DlgLstTypeCircle : "Kör", -DlgLstTypeDisc : "Lemez", -DlgLstTypeSquare : "Négyzet", -DlgLstTypeNumbers : "Számok (1, 2, 3)", -DlgLstTypeLCase : "Kisbetűk (a, b, c)", -DlgLstTypeUCase : "Nagybetűk (A, B, C)", -DlgLstTypeSRoman : "Kis római számok (i, ii, iii)", -DlgLstTypeLRoman : "Nagy római számok (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Általános", -DlgDocBackTab : "Háttér", -DlgDocColorsTab : "Színek és margók", -DlgDocMetaTab : "Meta adatok", - -DlgDocPageTitle : "Oldalcím", -DlgDocLangDir : "Írás iránya", -DlgDocLangDirLTR : "Balról jobbra", -DlgDocLangDirRTL : "Jobbról balra", -DlgDocLangCode : "Nyelv kód", -DlgDocCharSet : "Karakterkódolás", -DlgDocCharSetCE : "Közép-Európai", -DlgDocCharSetCT : "Kínai Tradicionális (Big5)", -DlgDocCharSetCR : "Cyrill", -DlgDocCharSetGR : "Görög", -DlgDocCharSetJP : "Japán", -DlgDocCharSetKR : "Koreai", -DlgDocCharSetTR : "Török", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Nyugat-Európai", -DlgDocCharSetOther : "Más karakterkódolás", - -DlgDocDocType : "Dokumentum típus fejléc", -DlgDocDocTypeOther : "Más dokumentum típus fejléc", -DlgDocIncXHTML : "XHTML deklarációk beillesztése", -DlgDocBgColor : "Háttérszín", -DlgDocBgImage : "Háttérkép cím", -DlgDocBgNoScroll : "Nem gördíthető háttér", -DlgDocCText : "Szöveg", -DlgDocCLink : "Cím", -DlgDocCVisited : "Látogatott cím", -DlgDocCActive : "Aktív cím", -DlgDocMargins : "Oldal margók", -DlgDocMaTop : "Felső", -DlgDocMaLeft : "Bal", -DlgDocMaRight : "Jobb", -DlgDocMaBottom : "Alsó", -DlgDocMeIndex : "Dokumentum keresőszavak (vesszővel elválasztva)", -DlgDocMeDescr : "Dokumentum leírás", -DlgDocMeAuthor : "Szerző", -DlgDocMeCopy : "Szerzői jog", -DlgDocPreview : "Előnézet", - -// Templates Dialog -Templates : "Sablonok", -DlgTemplatesTitle : "Elérhető sablonok", -DlgTemplatesSelMsg : "Válassza ki melyik sablon nyíljon meg a szerkesztőben
    (a jelenlegi tartalom elveszik):", -DlgTemplatesLoading : "Sablon lista betöltése. Kis türelmet...", -DlgTemplatesNoTpl : "(Nincs sablon megadva)", -DlgTemplatesReplace : "Kicseréli a jelenlegi tartalmat", - -// About Dialog -DlgAboutAboutTab : "Névjegy", -DlgAboutBrowserInfoTab : "Böngésző információ", -DlgAboutLicenseTab : "Licensz", -DlgAboutVersion : "verzió", -DlgAboutInfo : "További információkért látogasson el ide:", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/is.js b/httemplate/elements/fckeditor/editor/lang/is.js deleted file mode 100644 index 3238f7d86..000000000 --- a/httemplate/elements/fckeditor/editor/lang/is.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Icelandic language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Fela verkstiku", -ToolbarExpand : "Sýna verkstiku", - -// Toolbar Items and Context Menu -Save : "Vista", -NewPage : "Ný síða", -Preview : "Forskoða", -Cut : "Klippa", -Copy : "Afrita", -Paste : "Líma", -PasteText : "Líma ósniðinn texta", -PasteWord : "Líma úr Word", -Print : "Prenta", -SelectAll : "Velja allt", -RemoveFormat : "Fjarlægja snið", -InsertLinkLbl : "Stikla", -InsertLink : "Stofna/breyta stiklu", -RemoveLink : "Fjarlægja stiklu", -VisitLink : "Opna stiklusíðu", -Anchor : "Stofna/breyta kaflamerki", -AnchorDelete : "Eyða kaflamerki", -InsertImageLbl : "Setja inn mynd", -InsertImage : "Setja inn/breyta mynd", -InsertFlashLbl : "Flash", -InsertFlash : "Setja inn/breyta Flash", -InsertTableLbl : "Tafla", -InsertTable : "Setja inn/breyta töflu", -InsertLineLbl : "Lína", -InsertLine : "Lóðrétt lína", -InsertSpecialCharLbl: "Merki", -InsertSpecialChar : "Setja inn merki", -InsertSmileyLbl : "Svipur", -InsertSmiley : "Setja upp svip", -About : "Um FCKeditor", -Bold : "Feitletrað", -Italic : "Skáletrað", -Underline : "Undirstrikað", -StrikeThrough : "Yfirstrikað", -Subscript : "Niðurskrifað", -Superscript : "Uppskrifað", -LeftJustify : "Vinstrijöfnun", -CenterJustify : "Miðja texta", -RightJustify : "Hægrijöfnun", -BlockJustify : "Jafna báðum megin", -DecreaseIndent : "Auka inndrátt", -IncreaseIndent : "Minnka inndrátt", -Blockquote : "Inndráttur", -CreateDiv : "Búa til DIV-hýsil", -EditDiv : "Breyta DIV-hýsli", -DeleteDiv : "Eyða DIV-hýsli", -Undo : "Afturkalla", -Redo : "Hætta við afturköllun", -NumberedListLbl : "Númeraður listi", -NumberedList : "Setja inn/fella númeraðan lista", -BulletedListLbl : "Punktalisti", -BulletedList : "Setja inn/fella punktalista", -ShowTableBorders : "Sýna töflugrind", -ShowDetails : "Sýna smáatriði", -Style : "Stílflokkur", -FontFormat : "Stílsnið", -Font : "Leturgerð ", -FontSize : "Leturstærð ", -TextColor : "Litur texta", -BGColor : "Bakgrunnslitur", -Source : "Kóði", -Find : "Leita", -Replace : "Skipta út", -SpellCheck : "Villuleit", -UniversalKeyboard : "Hnattrænt lyklaborð", -PageBreakLbl : "Síðuskil", -PageBreak : "Setja inn síðuskil", - -Form : "Setja inn innsláttarform", -Checkbox : "Setja inn hökunarreit", -RadioButton : "Setja inn valhnapp", -TextField : "Setja inn textareit", -Textarea : "Setja inn textasvæði", -HiddenField : "Setja inn falið svæði", -Button : "Setja inn hnapp", -SelectionField : "Setja inn lista", -ImageButton : "Setja inn myndahnapp", - -FitWindow : "Skoða ritil í fullri stærð", -ShowBlocks : "Sýna blokkir", - -// Context Menu -EditLink : "Breyta stiklu", -CellCM : "Reitur", -RowCM : "Röð", -ColumnCM : "Dálkur", -InsertRowAfter : "Skjóta inn röð fyrir neðan", -InsertRowBefore : "Skjóta inn röð fyrir ofan", -DeleteRows : "Eyða röð", -InsertColumnAfter : "Skjóta inn dálki hægra megin", -InsertColumnBefore : "Skjóta inn dálki vinstra megin", -DeleteColumns : "Fella dálk", -InsertCellAfter : "Skjóta inn reiti fyrir framan", -InsertCellBefore : "Skjóta inn reiti fyrir aftan", -DeleteCells : "Fella reit", -MergeCells : "Sameina reiti", -MergeRight : "Sameina til hægri", -MergeDown : "Sameina niður á við", -HorizontalSplitCell : "Kljúfa reit lárétt", -VerticalSplitCell : "Kljúfa reit lóðrétt", -TableDelete : "Fella töflu", -CellProperties : "Eigindi reits", -TableProperties : "Eigindi töflu", -ImageProperties : "Eigindi myndar", -FlashProperties : "Eigindi Flash", - -AnchorProp : "Eigindi kaflamerkis", -ButtonProp : "Eigindi hnapps", -CheckboxProp : "Eigindi markreits", -HiddenFieldProp : "Eigindi falins svæðis", -RadioButtonProp : "Eigindi valhnapps", -ImageButtonProp : "Eigindi myndahnapps", -TextFieldProp : "Eigindi textareits", -SelectionFieldProp : "Eigindi lista", -TextareaProp : "Eigindi textasvæðis", -FormProp : "Eigindi innsláttarforms", - -FontFormats : "Venjulegt letur;Forsniðið;Vistfang;Fyrirsögn 1;Fyrirsögn 2;Fyrirsögn 3;Fyrirsögn 4;Fyrirsögn 5;Fyrirsögn 6;Venjulegt (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Meðhöndla XHTML...", -Done : "Tilbúið", -PasteWordConfirm : "Textinn sem þú ætlar að líma virðist koma úr Word. Viltu hreinsa óþarfar Word-skipanir úr honum?", -NotCompatiblePaste : "Þessi aðgerð er bundin við Internet Explorer 5.5 og nýrri. Viltu líma textann án þess að hreinsa hann?", -UnknownToolbarItem : "Óþekktur hlutur í verkstiku \"%1\"!", -UnknownCommand : "Óþekkt skipanaheiti \"%1\"!", -NotImplemented : "Skipun ekki virkjuð!", -UnknownToolbarSet : "Verkstikan \"%1\" ekki til!", -NoActiveX : "Öryggisstillingarnar í vafranum þínum leyfa ekki alla möguleika ritilsins.
    Láttu vafrann leyfa Active-X og viðbætur til að komast hjá villum og takmörkunum.", -BrowseServerBlocked : "Ritillinn getur ekki opnað nauðsynlega hjálparglugga!
    Láttu hann leyfa þessari síðu að opna sprettiglugga.", -DialogBlocked : "Ekki var hægt að opna skipanaglugga!
    Nauðsynlegt er að leyfa síðunni að opna sprettiglugga.", -VisitLinkBlocked : "Ekki var hægt að opna nýjan glugga. Gangtu úr skugga um að engir sprettigluggabanar séu virkir.", - -// Dialogs -DlgBtnOK : "Í lagi", -DlgBtnCancel : "Hætta við", -DlgBtnClose : "Loka", -DlgBtnBrowseServer : "Fletta í skjalasafni", -DlgAdvancedTag : "Tæknilegt", -DlgOpOther : "", -DlgInfoTab : "Upplýsingar", -DlgAlertUrl : "Sláðu inn slóð", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Auðkenni", -DlgGenLangDir : "Lesstefna", -DlgGenLangDirLtr : "Frá vinstri til hægri (LTR)", -DlgGenLangDirRtl : "Frá hægri til vinstri (RTL)", -DlgGenLangCode : "Tungumálakóði", -DlgGenAccessKey : "Skammvalshnappur", -DlgGenName : "Nafn", -DlgGenTabIndex : "Raðnúmer innsláttarreits", -DlgGenLongDescr : "Nánari lýsing", -DlgGenClass : "Stílsniðsflokkur", -DlgGenTitle : "Titill", -DlgGenContType : "Tegund innihalds", -DlgGenLinkCharset : "Táknróf", -DlgGenStyle : "Stíll", - -// Image Dialog -DlgImgTitle : "Eigindi myndar", -DlgImgInfoTab : "Almennt", -DlgImgBtnUpload : "Hlaða upp", -DlgImgURL : "Vefslóð", -DlgImgUpload : "Hlaða upp", -DlgImgAlt : "Baklægur texti", -DlgImgWidth : "Breidd", -DlgImgHeight : "Hæð", -DlgImgLockRatio : "Festa stærðarhlutfall", -DlgBtnResetSize : "Reikna stærð", -DlgImgBorder : "Rammi", -DlgImgHSpace : "Vinstri bil", -DlgImgVSpace : "Hægri bil", -DlgImgAlign : "Jöfnun", -DlgImgAlignLeft : "Vinstri", -DlgImgAlignAbsBottom: "Abs neðst", -DlgImgAlignAbsMiddle: "Abs miðjuð", -DlgImgAlignBaseline : "Grunnlína", -DlgImgAlignBottom : "Neðst", -DlgImgAlignMiddle : "Miðjuð", -DlgImgAlignRight : "Hægri", -DlgImgAlignTextTop : "Efri brún texta", -DlgImgAlignTop : "Efst", -DlgImgPreview : "Sýna dæmi", -DlgImgAlertUrl : "Sláðu inn slóðina að myndinni", -DlgImgLinkTab : "Stikla", - -// Flash Dialog -DlgFlashTitle : "Eigindi Flash", -DlgFlashChkPlay : "Sjálfvirk spilun", -DlgFlashChkLoop : "Endurtekning", -DlgFlashChkMenu : "Sýna Flash-valmynd", -DlgFlashScale : "Skali", -DlgFlashScaleAll : "Sýna allt", -DlgFlashScaleNoBorder : "Án ramma", -DlgFlashScaleFit : "Fella skala að stærð", - -// Link Dialog -DlgLnkWindowTitle : "Stikla", -DlgLnkInfoTab : "Almennt", -DlgLnkTargetTab : "Mark", - -DlgLnkType : "Stikluflokkur", -DlgLnkTypeURL : "Vefslóð", -DlgLnkTypeAnchor : "Bókamerki á þessari síðu", -DlgLnkTypeEMail : "Netfang", -DlgLnkProto : "Samskiptastaðall", -DlgLnkProtoOther : "", -DlgLnkURL : "Vefslóð", -DlgLnkAnchorSel : "Veldu akkeri", -DlgLnkAnchorByName : "Eftir akkerisnafni", -DlgLnkAnchorById : "Eftir auðkenni einingar", -DlgLnkNoAnchors : "", -DlgLnkEMail : "Netfang", -DlgLnkEMailSubject : "Efni", -DlgLnkEMailBody : "Meginmál", -DlgLnkUpload : "Senda upp", -DlgLnkBtnUpload : "Senda upp", - -DlgLnkTarget : "Mark", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nýr gluggi (_blank)", -DlgLnkTargetParent : "Yfirsettur rammi (_parent)", -DlgLnkTargetSelf : "Sami gluggi (_self)", -DlgLnkTargetTop : "Allur glugginn (_top)", -DlgLnkTargetFrameName : "Nafn markglugga", -DlgLnkPopWinName : "Nafn sprettiglugga", -DlgLnkPopWinFeat : "Eigindi sprettiglugga", -DlgLnkPopResize : "Skölun", -DlgLnkPopLocation : "Fanglína", -DlgLnkPopMenu : "Vallína", -DlgLnkPopScroll : "Skrunstikur", -DlgLnkPopStatus : "Stöðustika", -DlgLnkPopToolbar : "Verkfærastika", -DlgLnkPopFullScrn : "Heilskjár (IE)", -DlgLnkPopDependent : "Háð venslum (Netscape)", -DlgLnkPopWidth : "Breidd", -DlgLnkPopHeight : "Hæð", -DlgLnkPopLeft : "Fjarlægð frá vinstri", -DlgLnkPopTop : "Fjarlægð frá efri brún", - -DlnLnkMsgNoUrl : "Sláðu inn veffang stiklunnar!", -DlnLnkMsgNoEMail : "Sláðu inn netfang!", -DlnLnkMsgNoAnchor : "Veldu fyrst eitthvert bókamerki!", -DlnLnkMsgInvPopName : "Sprettisíðan verður að byrja á bókstaf (a-z) og má ekki innihalda stafabil", - -// Color Dialog -DlgColorTitle : "Velja lit", -DlgColorBtnClear : "Núllstilla", -DlgColorHighlight : "Litmerkja", -DlgColorSelected : "Valið", - -// Smiley Dialog -DlgSmileyTitle : "Velja svip", - -// Special Character Dialog -DlgSpecialCharTitle : "Velja tákn", - -// Table Dialog -DlgTableTitle : "Eigindi töflu", -DlgTableRows : "Raðir", -DlgTableColumns : "Dálkar", -DlgTableBorder : "Breidd ramma", -DlgTableAlign : "Jöfnun", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Vinstrijafnað", -DlgTableAlignCenter : "Miðjað", -DlgTableAlignRight : "Hægrijafnað", -DlgTableWidth : "Breidd", -DlgTableWidthPx : "myndeindir", -DlgTableWidthPc : "prósent", -DlgTableHeight : "Hæð", -DlgTableCellSpace : "Bil milli reita", -DlgTableCellPad : "Reitaspássía", -DlgTableCaption : "Titill", -DlgTableSummary : "Áfram", -DlgTableHeaders : "Fyrirsagnir", -DlgTableHeadersNone : "Engar", -DlgTableHeadersColumn : "Fyrsti dálkur", -DlgTableHeadersRow : "Fyrsta röð", -DlgTableHeadersBoth : "Hvort tveggja", - -// Table Cell Dialog -DlgCellTitle : "Eigindi reits", -DlgCellWidth : "Breidd", -DlgCellWidthPx : "myndeindir", -DlgCellWidthPc : "prósent", -DlgCellHeight : "Hæð", -DlgCellWordWrap : "Línuskipting", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Já", -DlgCellWordWrapNo : "Nei", -DlgCellHorAlign : "Lárétt jöfnun", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Vinstrijafnað", -DlgCellHorAlignCenter : "Miðjað", -DlgCellHorAlignRight: "Hægrijafnað", -DlgCellVerAlign : "Lóðrétt jöfnun", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Efst", -DlgCellVerAlignMiddle : "Miðjað", -DlgCellVerAlignBottom : "Neðst", -DlgCellVerAlignBaseline : "Grunnlína", -DlgCellType : "Tegund reits", -DlgCellTypeData : "Gögn", -DlgCellTypeHeader : "Fyrirsögn", -DlgCellRowSpan : "Hæð í röðum talið", -DlgCellCollSpan : "Breidd í dálkum talið", -DlgCellBackColor : "Bakgrunnslitur", -DlgCellBorderColor : "Rammalitur", -DlgCellBtnSelect : "Veldu...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Finna og skipta", - -// Find Dialog -DlgFindTitle : "Finna", -DlgFindFindBtn : "Finna", -DlgFindNotFoundMsg : "Leitartexti fannst ekki!", - -// Replace Dialog -DlgReplaceTitle : "Skipta út", -DlgReplaceFindLbl : "Leita að:", -DlgReplaceReplaceLbl : "Skipta út fyrir:", -DlgReplaceCaseChk : "Gera greinarmun á¡ há¡- og lágstöfum", -DlgReplaceReplaceBtn : "Skipta út", -DlgReplaceReplAllBtn : "Skipta út allsstaðar", -DlgReplaceWordChk : "Aðeins heil orð", - -// Paste Operations / Dialog -PasteErrorCut : "Öryggisstillingar vafrans þíns leyfa ekki klippingu texta með músaraðgerð. Notaðu lyklaborðið í klippa (Ctrl+X).", -PasteErrorCopy : "Öryggisstillingar vafrans þíns leyfa ekki afritun texta með músaraðgerð. Notaðu lyklaborðið í afrita (Ctrl+C).", - -PasteAsText : "Líma sem ósniðinn texta", -PasteFromWord : "Líma úr Word", - -DlgPasteMsg2 : "Límdu í svæðið hér að neðan og (Ctrl+V) og smelltu á OK.", -DlgPasteSec : "Vegna öryggisstillinga í vafranum þínum fær ritillinn ekki beinan aðgang að klippuborðinu. Þú verður að líma innihaldið aftur inn í þennan glugga.", -DlgPasteIgnoreFont : "Hunsa leturskilgreiningar", -DlgPasteRemoveStyles : "Hunsa letureigindi", - -// Color Picker -ColorAutomatic : "Sjálfval", -ColorMoreColors : "Fleiri liti...", - -// Document Properties -DocProps : "Eigindi skjals", - -// Anchor Dialog -DlgAnchorTitle : "Eigindi bókamerkis", -DlgAnchorName : "Nafn bókamerkis", -DlgAnchorErrorName : "Sláðu inn nafn bókamerkis!", - -// Speller Pages Dialog -DlgSpellNotInDic : "Ekki í orðabókinni", -DlgSpellChangeTo : "Tillaga", -DlgSpellBtnIgnore : "Hunsa", -DlgSpellBtnIgnoreAll : "Hunsa allt", -DlgSpellBtnReplace : "Skipta", -DlgSpellBtnReplaceAll : "Skipta öllu", -DlgSpellBtnUndo : "Til baka", -DlgSpellNoSuggestions : "- engar tillögur -", -DlgSpellProgress : "Villuleit í gangi...", -DlgSpellNoMispell : "Villuleit lokið: Engin villa fannst", -DlgSpellNoChanges : "Villuleit lokið: Engu orði breytt", -DlgSpellOneChange : "Villuleit lokið: Einu orði breytt", -DlgSpellManyChanges : "Villuleit lokið: %1 orðum breytt", - -IeSpellDownload : "Villuleit ekki sett upp.
    Viltu setja hana upp?", - -// Button Dialog -DlgButtonText : "Texti", -DlgButtonType : "Gerð", -DlgButtonTypeBtn : "Hnappur", -DlgButtonTypeSbm : "Staðfesta", -DlgButtonTypeRst : "Hreinsa", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nafn", -DlgCheckboxValue : "Gildi", -DlgCheckboxSelected : "Valið", - -// Form Dialog -DlgFormName : "Nafn", -DlgFormAction : "Aðgerð", -DlgFormMethod : "Aðferð", - -// Select Field Dialog -DlgSelectName : "Nafn", -DlgSelectValue : "Gildi", -DlgSelectSize : "Stærð", -DlgSelectLines : "línur", -DlgSelectChkMulti : "Leyfa fleiri kosti", -DlgSelectOpAvail : "Kostir", -DlgSelectOpText : "Texti", -DlgSelectOpValue : "Gildi", -DlgSelectBtnAdd : "Bæta við", -DlgSelectBtnModify : "Breyta", -DlgSelectBtnUp : "Upp", -DlgSelectBtnDown : "Niður", -DlgSelectBtnSetValue : "Merkja sem valið", -DlgSelectBtnDelete : "Eyða", - -// Textarea Dialog -DlgTextareaName : "Nafn", -DlgTextareaCols : "Dálkar", -DlgTextareaRows : "Línur", - -// Text Field Dialog -DlgTextName : "Nafn", -DlgTextValue : "Gildi", -DlgTextCharWidth : "Breidd (leturtákn)", -DlgTextMaxChars : "Hámarksfjöldi leturtákna", -DlgTextType : "Gerð", -DlgTextTypeText : "Texti", -DlgTextTypePass : "Lykilorð", - -// Hidden Field Dialog -DlgHiddenName : "Nafn", -DlgHiddenValue : "Gildi", - -// Bulleted List Dialog -BulletedListProp : "Eigindi depillista", -NumberedListProp : "Eigindi tölusetts lista", -DlgLstStart : "Byrja", -DlgLstType : "Gerð", -DlgLstTypeCircle : "Hringur", -DlgLstTypeDisc : "Fylltur hringur", -DlgLstTypeSquare : "Ferningur", -DlgLstTypeNumbers : "Tölusett (1, 2, 3)", -DlgLstTypeLCase : "Lágstafir (a, b, c)", -DlgLstTypeUCase : "Hástafir (A, B, C)", -DlgLstTypeSRoman : "Rómverkar lágstafatölur (i, ii, iii)", -DlgLstTypeLRoman : "Rómverkar hástafatölur (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Almennt", -DlgDocBackTab : "Bakgrunnur", -DlgDocColorsTab : "Litir og rammar", -DlgDocMetaTab : "Lýsigögn", - -DlgDocPageTitle : "Titill síðu", -DlgDocLangDir : "Tungumál", -DlgDocLangDirLTR : "Vinstri til hægri (LTR)", -DlgDocLangDirRTL : "Hægri til vinstri (RTL)", -DlgDocLangCode : "Tungumálakóði", -DlgDocCharSet : "Letursett", -DlgDocCharSetCE : "Mið-evrópskt", -DlgDocCharSetCT : "Kínverskt, hefðbundið (Big5)", -DlgDocCharSetCR : "Kýrilskt", -DlgDocCharSetGR : "Grískt", -DlgDocCharSetJP : "Japanskt", -DlgDocCharSetKR : "Kóreskt", -DlgDocCharSetTR : "Tyrkneskt", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Vestur-evrópst", -DlgDocCharSetOther : "Annað letursett", - -DlgDocDocType : "Flokkur skjalategunda", -DlgDocDocTypeOther : "Annar flokkur skjalategunda", -DlgDocIncXHTML : "Fella inn XHTML lýsingu", -DlgDocBgColor : "Bakgrunnslitur", -DlgDocBgImage : "Slóð bakgrunnsmyndar", -DlgDocBgNoScroll : "Læstur bakgrunnur", -DlgDocCText : "Texti", -DlgDocCLink : "Stikla", -DlgDocCVisited : "Heimsótt stikla", -DlgDocCActive : "Virk stikla", -DlgDocMargins : "Hliðarspássía", -DlgDocMaTop : "Efst", -DlgDocMaLeft : "Vinstri", -DlgDocMaRight : "Hægri", -DlgDocMaBottom : "Neðst", -DlgDocMeIndex : "Lykilorð efnisorðaskrár (aðgreind með kommum)", -DlgDocMeDescr : "Lýsing skjals", -DlgDocMeAuthor : "Höfundur", -DlgDocMeCopy : "Höfundarréttur", -DlgDocPreview : "Sýna", - -// Templates Dialog -Templates : "Sniðmát", -DlgTemplatesTitle : "Innihaldssniðmát", -DlgTemplatesSelMsg : "Veldu sniðmát til að opna í ritlinum.
    (Núverandi innihald víkur fyrir því!):", -DlgTemplatesLoading : "Sæki lista yfir sniðmát...", -DlgTemplatesNoTpl : "(Ekkert sniðmát er skilgreint!)", -DlgTemplatesReplace : "Skipta út raunverulegu innihaldi", - -// About Dialog -DlgAboutAboutTab : "Um", -DlgAboutBrowserInfoTab : "Almennt", -DlgAboutLicenseTab : "Leyfi", -DlgAboutVersion : "útgáfa", -DlgAboutInfo : "Nánari upplýsinar, sjá:", - -// Div Dialog -DlgDivGeneralTab : "Almennt", -DlgDivAdvancedTab : "Sérhæft", -DlgDivStyle : "Stíll", -DlgDivInlineStyle : "Línulægur stíll", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/it.js b/httemplate/elements/fckeditor/editor/lang/it.js deleted file mode 100644 index 51b0d8510..000000000 --- a/httemplate/elements/fckeditor/editor/lang/it.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Italian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Nascondi la barra degli strumenti", -ToolbarExpand : "Mostra la barra degli strumenti", - -// Toolbar Items and Context Menu -Save : "Salva", -NewPage : "Nuova pagina vuota", -Preview : "Anteprima", -Cut : "Taglia", -Copy : "Copia", -Paste : "Incolla", -PasteText : "Incolla come testo semplice", -PasteWord : "Incolla da Word", -Print : "Stampa", -SelectAll : "Seleziona tutto", -RemoveFormat : "Elimina formattazione", -InsertLinkLbl : "Collegamento", -InsertLink : "Inserisci/Modifica collegamento", -RemoveLink : "Elimina collegamento", -VisitLink : "Open Link", //MISSING -Anchor : "Inserisci/Modifica Ancora", -AnchorDelete : "Rimuovi Ancora", -InsertImageLbl : "Immagine", -InsertImage : "Inserisci/Modifica immagine", -InsertFlashLbl : "Oggetto Flash", -InsertFlash : "Inserisci/Modifica Oggetto Flash", -InsertTableLbl : "Tabella", -InsertTable : "Inserisci/Modifica tabella", -InsertLineLbl : "Riga orizzontale", -InsertLine : "Inserisci riga orizzontale", -InsertSpecialCharLbl: "Caratteri speciali", -InsertSpecialChar : "Inserisci carattere speciale", -InsertSmileyLbl : "Emoticon", -InsertSmiley : "Inserisci emoticon", -About : "Informazioni su FCKeditor", -Bold : "Grassetto", -Italic : "Corsivo", -Underline : "Sottolineato", -StrikeThrough : "Barrato", -Subscript : "Pedice", -Superscript : "Apice", -LeftJustify : "Allinea a sinistra", -CenterJustify : "Centra", -RightJustify : "Allinea a destra", -BlockJustify : "Giustifica", -DecreaseIndent : "Riduci rientro", -IncreaseIndent : "Aumenta rientro", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Annulla", -Redo : "Ripristina", -NumberedListLbl : "Elenco numerato", -NumberedList : "Inserisci/Modifica elenco numerato", -BulletedListLbl : "Elenco puntato", -BulletedList : "Inserisci/Modifica elenco puntato", -ShowTableBorders : "Mostra bordi tabelle", -ShowDetails : "Mostra dettagli", -Style : "Stile", -FontFormat : "Formato", -Font : "Font", -FontSize : "Dimensione", -TextColor : "Colore testo", -BGColor : "Colore sfondo", -Source : "Codice Sorgente", -Find : "Trova", -Replace : "Sostituisci", -SpellCheck : "Correttore ortografico", -UniversalKeyboard : "Tastiera universale", -PageBreakLbl : "Interruzione di pagina", -PageBreak : "Inserisci interruzione di pagina", - -Form : "Modulo", -Checkbox : "Checkbox", -RadioButton : "Radio Button", -TextField : "Campo di testo", -Textarea : "Area di testo", -HiddenField : "Campo nascosto", -Button : "Bottone", -SelectionField : "Menu di selezione", -ImageButton : "Bottone immagine", - -FitWindow : "Massimizza l'area dell'editor", -ShowBlocks : "Visualizza Blocchi", - -// Context Menu -EditLink : "Modifica collegamento", -CellCM : "Cella", -RowCM : "Riga", -ColumnCM : "Colonna", -InsertRowAfter : "Inserisci Riga Dopo", -InsertRowBefore : "Inserisci Riga Prima", -DeleteRows : "Elimina righe", -InsertColumnAfter : "Inserisci Colonna Dopo", -InsertColumnBefore : "Inserisci Colonna Prima", -DeleteColumns : "Elimina colonne", -InsertCellAfter : "Inserisci Cella Dopo", -InsertCellBefore : "Inserisci Cella Prima", -DeleteCells : "Elimina celle", -MergeCells : "Unisce celle", -MergeRight : "Unisci a Destra", -MergeDown : "Unisci in Basso", -HorizontalSplitCell : "Dividi Cella Orizzontalmente", -VerticalSplitCell : "Dividi Cella Verticalmente", -TableDelete : "Cancella Tabella", -CellProperties : "Proprietà cella", -TableProperties : "Proprietà tabella", -ImageProperties : "Proprietà immagine", -FlashProperties : "Proprietà Oggetto Flash", - -AnchorProp : "Proprietà ancora", -ButtonProp : "Proprietà bottone", -CheckboxProp : "Proprietà checkbox", -HiddenFieldProp : "Proprietà campo nascosto", -RadioButtonProp : "Proprietà radio button", -ImageButtonProp : "Proprietà bottone immagine", -TextFieldProp : "Proprietà campo di testo", -SelectionFieldProp : "Proprietà menu di selezione", -TextareaProp : "Proprietà area di testo", -FormProp : "Proprietà modulo", - -FontFormats : "Normale;Formattato;Indirizzo;Titolo 1;Titolo 2;Titolo 3;Titolo 4;Titolo 5;Titolo 6;Paragrafo (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Elaborazione XHTML in corso. Attendere prego...", -Done : "Completato", -PasteWordConfirm : "Il testo da incollare sembra provenire da Word. Desideri pulirlo prima di incollare?", -NotCompatiblePaste : "Questa funzione è disponibile solo per Internet Explorer 5.5 o superiore. Desideri incollare il testo senza pulirlo?", -UnknownToolbarItem : "Elemento della barra strumenti sconosciuto \"%1\"", -UnknownCommand : "Comando sconosciuto \"%1\"", -NotImplemented : "Comando non implementato", -UnknownToolbarSet : "La barra di strumenti \"%1\" non esiste", -NoActiveX : "Le impostazioni di sicurezza del tuo browser potrebbero limitare alcune funzionalità dell'editor. Devi abilitare l'opzione \"Esegui controlli e plug-in ActiveX\". Potresti avere errori e notare funzionalità mancanti.", -BrowseServerBlocked : "Non è possibile aprire la finestra di espolorazione risorse. Verifica che tutti i blocca popup siano bloccati.", -DialogBlocked : "Non è possibile aprire la finestra di dialogo. Verifica che tutti i blocca popup siano bloccati.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Annulla", -DlgBtnClose : "Chiudi", -DlgBtnBrowseServer : "Cerca sul server", -DlgAdvancedTag : "Avanzate", -DlgOpOther : "", -DlgInfoTab : "Info", -DlgAlertUrl : "Devi inserire l'URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Direzione scrittura", -DlgGenLangDirLtr : "Da Sinistra a Destra (LTR)", -DlgGenLangDirRtl : "Da Destra a Sinistra (RTL)", -DlgGenLangCode : "Codice Lingua", -DlgGenAccessKey : "Scorciatoia
    da tastiera", -DlgGenName : "Nome", -DlgGenTabIndex : "Ordine di tabulazione", -DlgGenLongDescr : "URL descrizione estesa", -DlgGenClass : "Nome classe CSS", -DlgGenTitle : "Titolo", -DlgGenContType : "Tipo della risorsa collegata", -DlgGenLinkCharset : "Set di caretteri della risorsa collegata", -DlgGenStyle : "Stile", - -// Image Dialog -DlgImgTitle : "Proprietà immagine", -DlgImgInfoTab : "Informazioni immagine", -DlgImgBtnUpload : "Invia al server", -DlgImgURL : "URL", -DlgImgUpload : "Carica", -DlgImgAlt : "Testo alternativo", -DlgImgWidth : "Larghezza", -DlgImgHeight : "Altezza", -DlgImgLockRatio : "Blocca rapporto", -DlgBtnResetSize : "Reimposta dimensione", -DlgImgBorder : "Bordo", -DlgImgHSpace : "HSpace", -DlgImgVSpace : "VSpace", -DlgImgAlign : "Allineamento", -DlgImgAlignLeft : "Sinistra", -DlgImgAlignAbsBottom: "In basso assoluto", -DlgImgAlignAbsMiddle: "Centrato assoluto", -DlgImgAlignBaseline : "Linea base", -DlgImgAlignBottom : "In Basso", -DlgImgAlignMiddle : "Centrato", -DlgImgAlignRight : "Destra", -DlgImgAlignTextTop : "In alto al testo", -DlgImgAlignTop : "In Alto", -DlgImgPreview : "Anteprima", -DlgImgAlertUrl : "Devi inserire l'URL per l'immagine", -DlgImgLinkTab : "Collegamento", - -// Flash Dialog -DlgFlashTitle : "Proprietà Oggetto Flash", -DlgFlashChkPlay : "Avvio Automatico", -DlgFlashChkLoop : "Cicla", -DlgFlashChkMenu : "Abilita Menu di Flash", -DlgFlashScale : "Ridimensiona", -DlgFlashScaleAll : "Mostra Tutto", -DlgFlashScaleNoBorder : "Senza Bordo", -DlgFlashScaleFit : "Dimensione Esatta", - -// Link Dialog -DlgLnkWindowTitle : "Collegamento", -DlgLnkInfoTab : "Informazioni collegamento", -DlgLnkTargetTab : "Destinazione", - -DlgLnkType : "Tipo di Collegamento", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Ancora nella pagina", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "Protocollo", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Scegli Ancora", -DlgLnkAnchorByName : "Per Nome", -DlgLnkAnchorById : "Per id elemento", -DlgLnkNoAnchors : "(Nessuna ancora disponibile nel documento)", -DlgLnkEMail : "Indirizzo E-Mail", -DlgLnkEMailSubject : "Oggetto del messaggio", -DlgLnkEMailBody : "Corpo del messaggio", -DlgLnkUpload : "Carica", -DlgLnkBtnUpload : "Invia al Server", - -DlgLnkTarget : "Destinazione", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Nuova finestra (_blank)", -DlgLnkTargetParent : "Finestra padre (_parent)", -DlgLnkTargetSelf : "Stessa finestra (_self)", -DlgLnkTargetTop : "Finestra superiore (_top)", -DlgLnkTargetFrameName : "Nome del riquadro di destinazione", -DlgLnkPopWinName : "Nome finestra popup", -DlgLnkPopWinFeat : "Caratteristiche finestra popup", -DlgLnkPopResize : "Ridimensionabile", -DlgLnkPopLocation : "Barra degli indirizzi", -DlgLnkPopMenu : "Barra del menu", -DlgLnkPopScroll : "Barre di scorrimento", -DlgLnkPopStatus : "Barra di stato", -DlgLnkPopToolbar : "Barra degli strumenti", -DlgLnkPopFullScrn : "A tutto schermo (IE)", -DlgLnkPopDependent : "Dipendente (Netscape)", -DlgLnkPopWidth : "Larghezza", -DlgLnkPopHeight : "Altezza", -DlgLnkPopLeft : "Posizione da sinistra", -DlgLnkPopTop : "Posizione dall'alto", - -DlnLnkMsgNoUrl : "Devi inserire l'URL del collegamento", -DlnLnkMsgNoEMail : "Devi inserire un'indirizzo e-mail", -DlnLnkMsgNoAnchor : "Devi selezionare un'ancora", -DlnLnkMsgInvPopName : "Il nome del popup deve iniziare con una lettera, e non può contenere spazi", - -// Color Dialog -DlgColorTitle : "Seleziona colore", -DlgColorBtnClear : "Vuota", -DlgColorHighlight : "Evidenziato", -DlgColorSelected : "Selezionato", - -// Smiley Dialog -DlgSmileyTitle : "Inserisci emoticon", - -// Special Character Dialog -DlgSpecialCharTitle : "Seleziona carattere speciale", - -// Table Dialog -DlgTableTitle : "Proprietà tabella", -DlgTableRows : "Righe", -DlgTableColumns : "Colonne", -DlgTableBorder : "Dimensione bordo", -DlgTableAlign : "Allineamento", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Sinistra", -DlgTableAlignCenter : "Centrato", -DlgTableAlignRight : "Destra", -DlgTableWidth : "Larghezza", -DlgTableWidthPx : "pixel", -DlgTableWidthPc : "percento", -DlgTableHeight : "Altezza", -DlgTableCellSpace : "Spaziatura celle", -DlgTableCellPad : "Padding celle", -DlgTableCaption : "Intestazione", -DlgTableSummary : "Indice", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "Proprietà cella", -DlgCellWidth : "Larghezza", -DlgCellWidthPx : "pixel", -DlgCellWidthPc : "percento", -DlgCellHeight : "Altezza", -DlgCellWordWrap : "A capo automatico", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Si", -DlgCellWordWrapNo : "No", -DlgCellHorAlign : "Allineamento orizzontale", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Sinistra", -DlgCellHorAlignCenter : "Centrato", -DlgCellHorAlignRight: "Destra", -DlgCellVerAlign : "Allineamento verticale", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "In Alto", -DlgCellVerAlignMiddle : "Centrato", -DlgCellVerAlignBottom : "In Basso", -DlgCellVerAlignBaseline : "Linea base", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "Righe occupate", -DlgCellCollSpan : "Colonne occupate", -DlgCellBackColor : "Colore sfondo", -DlgCellBorderColor : "Colore bordo", -DlgCellBtnSelect : "Scegli...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Cerca e Sostituisci", - -// Find Dialog -DlgFindTitle : "Trova", -DlgFindFindBtn : "Trova", -DlgFindNotFoundMsg : "L'elemento cercato non è stato trovato.", - -// Replace Dialog -DlgReplaceTitle : "Sostituisci", -DlgReplaceFindLbl : "Trova:", -DlgReplaceReplaceLbl : "Sostituisci con:", -DlgReplaceCaseChk : "Maiuscole/minuscole", -DlgReplaceReplaceBtn : "Sostituisci", -DlgReplaceReplAllBtn : "Sostituisci tutto", -DlgReplaceWordChk : "Solo parole intere", - -// Paste Operations / Dialog -PasteErrorCut : "Le impostazioni di sicurezza del browser non permettono di tagliare automaticamente il testo. Usa la tastiera (Ctrl+X).", -PasteErrorCopy : "Le impostazioni di sicurezza del browser non permettono di copiare automaticamente il testo. Usa la tastiera (Ctrl+C).", - -PasteAsText : "Incolla come testo semplice", -PasteFromWord : "Incolla da Word", - -DlgPasteMsg2 : "Incolla il testo all'interno dell'area sottostante usando la scorciatoia di tastiere (Ctrl+V) e premi OK.", -DlgPasteSec : "A causa delle impostazioni di sicurezza del browser,l'editor non è in grado di accedere direttamente agli appunti. E' pertanto necessario incollarli di nuovo in questa finestra.", -DlgPasteIgnoreFont : "Ignora le definizioni di Font", -DlgPasteRemoveStyles : "Rimuovi le definizioni di Stile", - -// Color Picker -ColorAutomatic : "Automatico", -ColorMoreColors : "Altri colori...", - -// Document Properties -DocProps : "Proprietà del Documento", - -// Anchor Dialog -DlgAnchorTitle : "Proprietà ancora", -DlgAnchorName : "Nome ancora", -DlgAnchorErrorName : "Inserici il nome dell'ancora", - -// Speller Pages Dialog -DlgSpellNotInDic : "Non nel dizionario", -DlgSpellChangeTo : "Cambia in", -DlgSpellBtnIgnore : "Ignora", -DlgSpellBtnIgnoreAll : "Ignora tutto", -DlgSpellBtnReplace : "Cambia", -DlgSpellBtnReplaceAll : "Cambia tutto", -DlgSpellBtnUndo : "Annulla", -DlgSpellNoSuggestions : "- Nessun suggerimento -", -DlgSpellProgress : "Controllo ortografico in corso", -DlgSpellNoMispell : "Controllo ortografico completato: nessun errore trovato", -DlgSpellNoChanges : "Controllo ortografico completato: nessuna parola cambiata", -DlgSpellOneChange : "Controllo ortografico completato: 1 parola cambiata", -DlgSpellManyChanges : "Controllo ortografico completato: %1 parole cambiate", - -IeSpellDownload : "Contollo ortografico non installato. Lo vuoi scaricare ora?", - -// Button Dialog -DlgButtonText : "Testo (Value)", -DlgButtonType : "Tipo", -DlgButtonTypeBtn : "Bottone", -DlgButtonTypeSbm : "Invio", -DlgButtonTypeRst : "Annulla", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Nome", -DlgCheckboxValue : "Valore", -DlgCheckboxSelected : "Selezionato", - -// Form Dialog -DlgFormName : "Nome", -DlgFormAction : "Azione", -DlgFormMethod : "Metodo", - -// Select Field Dialog -DlgSelectName : "Nome", -DlgSelectValue : "Valore", -DlgSelectSize : "Dimensione", -DlgSelectLines : "righe", -DlgSelectChkMulti : "Permetti selezione multipla", -DlgSelectOpAvail : "Opzioni disponibili", -DlgSelectOpText : "Testo", -DlgSelectOpValue : "Valore", -DlgSelectBtnAdd : "Aggiungi", -DlgSelectBtnModify : "Modifica", -DlgSelectBtnUp : "Su", -DlgSelectBtnDown : "Gi", -DlgSelectBtnSetValue : "Imposta come predefinito", -DlgSelectBtnDelete : "Rimuovi", - -// Textarea Dialog -DlgTextareaName : "Nome", -DlgTextareaCols : "Colonne", -DlgTextareaRows : "Righe", - -// Text Field Dialog -DlgTextName : "Nome", -DlgTextValue : "Valore", -DlgTextCharWidth : "Larghezza", -DlgTextMaxChars : "Numero massimo di caratteri", -DlgTextType : "Tipo", -DlgTextTypeText : "Testo", -DlgTextTypePass : "Password", - -// Hidden Field Dialog -DlgHiddenName : "Nome", -DlgHiddenValue : "Valore", - -// Bulleted List Dialog -BulletedListProp : "Proprietà lista puntata", -NumberedListProp : "Proprietà lista numerata", -DlgLstStart : "Inizio", -DlgLstType : "Tipo", -DlgLstTypeCircle : "Tondo", -DlgLstTypeDisc : "Disco", -DlgLstTypeSquare : "Quadrato", -DlgLstTypeNumbers : "Numeri (1, 2, 3)", -DlgLstTypeLCase : "Caratteri minuscoli (a, b, c)", -DlgLstTypeUCase : "Caratteri maiuscoli (A, B, C)", -DlgLstTypeSRoman : "Numeri Romani minuscoli (i, ii, iii)", -DlgLstTypeLRoman : "Numeri Romani maiuscoli (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Genarale", -DlgDocBackTab : "Sfondo", -DlgDocColorsTab : "Colori e margini", -DlgDocMetaTab : "Meta Data", - -DlgDocPageTitle : "Titolo pagina", -DlgDocLangDir : "Direzione scrittura", -DlgDocLangDirLTR : "Da Sinistra a Destra (LTR)", -DlgDocLangDirRTL : "Da Destra a Sinistra (RTL)", -DlgDocLangCode : "Codice Lingua", -DlgDocCharSet : "Set di caretteri", -DlgDocCharSetCE : "Europa Centrale", -DlgDocCharSetCT : "Cinese Tradizionale (Big5)", -DlgDocCharSetCR : "Cirillico", -DlgDocCharSetGR : "Greco", -DlgDocCharSetJP : "Giapponese", -DlgDocCharSetKR : "Coreano", -DlgDocCharSetTR : "Turco", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Europa Occidentale", -DlgDocCharSetOther : "Altro set di caretteri", - -DlgDocDocType : "Intestazione DocType", -DlgDocDocTypeOther : "Altra intestazione DocType", -DlgDocIncXHTML : "Includi dichiarazione XHTML", -DlgDocBgColor : "Colore di sfondo", -DlgDocBgImage : "Immagine di sfondo", -DlgDocBgNoScroll : "Sfondo fissato", -DlgDocCText : "Testo", -DlgDocCLink : "Collegamento", -DlgDocCVisited : "Collegamento visitato", -DlgDocCActive : "Collegamento attivo", -DlgDocMargins : "Margini", -DlgDocMaTop : "In Alto", -DlgDocMaLeft : "A Sinistra", -DlgDocMaRight : "A Destra", -DlgDocMaBottom : "In Basso", -DlgDocMeIndex : "Chiavi di indicizzazione documento (separate da virgola)", -DlgDocMeDescr : "Descrizione documento", -DlgDocMeAuthor : "Autore", -DlgDocMeCopy : "Copyright", -DlgDocPreview : "Anteprima", - -// Templates Dialog -Templates : "Modelli", -DlgTemplatesTitle : "Contenuto dei modelli", -DlgTemplatesSelMsg : "Seleziona il modello da aprire nell'editor
    (il contenuto attuale verrà eliminato):", -DlgTemplatesLoading : "Caricamento modelli in corso. Attendere prego...", -DlgTemplatesNoTpl : "(Nessun modello definito)", -DlgTemplatesReplace : "Cancella il contenuto corrente", - -// About Dialog -DlgAboutAboutTab : "Informazioni", -DlgAboutBrowserInfoTab : "Informazioni Browser", -DlgAboutLicenseTab : "Licenza", -DlgAboutVersion : "versione", -DlgAboutInfo : "Per maggiori informazioni visitare", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/ja.js b/httemplate/elements/fckeditor/editor/lang/ja.js deleted file mode 100644 index b7dde042b..000000000 --- a/httemplate/elements/fckeditor/editor/lang/ja.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Japanese language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "ツールバーを隠す", -ToolbarExpand : "ツールバーを表示", - -// Toolbar Items and Context Menu -Save : "保存", -NewPage : "新しいページ", -Preview : "プレビュー", -Cut : "切り取り", -Copy : "コピー", -Paste : "貼り付け", -PasteText : "プレーンテキスト貼り付け", -PasteWord : "ワード文章から貼り付け", -Print : "印刷", -SelectAll : "すべて選択", -RemoveFormat : "フォーマット削除", -InsertLinkLbl : "リンク", -InsertLink : "リンク挿入/編集", -RemoveLink : "リンク削除", -VisitLink : "リンクを開く", -Anchor : "アンカー挿入/編集", -AnchorDelete : "アンカー削除", -InsertImageLbl : "イメージ", -InsertImage : "イメージ挿入/編集", -InsertFlashLbl : "Flash", -InsertFlash : "Flash挿入/編集", -InsertTableLbl : "テーブル", -InsertTable : "テーブル挿入/編集", -InsertLineLbl : "ライン", -InsertLine : "横罫線", -InsertSpecialCharLbl: "特殊文字", -InsertSpecialChar : "特殊文字挿入", -InsertSmileyLbl : "絵文字", -InsertSmiley : "絵文字挿入", -About : "FCKeditorヘルプ", -Bold : "太字", -Italic : "斜体", -Underline : "下線", -StrikeThrough : "打ち消し線", -Subscript : "添え字", -Superscript : "上付き文字", -LeftJustify : "左揃え", -CenterJustify : "中央揃え", -RightJustify : "右揃え", -BlockJustify : "両端揃え", -DecreaseIndent : "インデント解除", -IncreaseIndent : "インデント", -Blockquote : "ブロック引用", -CreateDiv : "Div 作成", -EditDiv : "Div 編集", -DeleteDiv : "Div 削除", -Undo : "元に戻す", -Redo : "やり直し", -NumberedListLbl : "段落番号", -NumberedList : "段落番号の追加/削除", -BulletedListLbl : "箇条書き", -BulletedList : "箇条書きの追加/削除", -ShowTableBorders : "テーブルボーダー表示", -ShowDetails : "詳細表示", -Style : "スタイル", -FontFormat : "フォーマット", -Font : "フォント", -FontSize : "サイズ", -TextColor : "テキスト色", -BGColor : "背景色", -Source : "ソース", -Find : "検索", -Replace : "置き換え", -SpellCheck : "スペルチェック", -UniversalKeyboard : "ユニバーサル・キーボード", -PageBreakLbl : "改ページ", -PageBreak : "改ページ挿入", - -Form : "フォーム", -Checkbox : "チェックボックス", -RadioButton : "ラジオボタン", -TextField : "1行テキスト", -Textarea : "テキストエリア", -HiddenField : "不可視フィールド", -Button : "ボタン", -SelectionField : "選択フィールド", -ImageButton : "画像ボタン", - -FitWindow : "エディタサイズを最大にします", -ShowBlocks : "ブロック表示", - -// Context Menu -EditLink : "リンク編集", -CellCM : "セル", -RowCM : "行", -ColumnCM : "カラム", -InsertRowAfter : "列の後に挿入", -InsertRowBefore : "列の前に挿入", -DeleteRows : "行削除", -InsertColumnAfter : "カラムの後に挿入", -InsertColumnBefore : "カラムの前に挿入", -DeleteColumns : "列削除", -InsertCellAfter : "セルの後に挿入", -InsertCellBefore : "セルの前に挿入", -DeleteCells : "セル削除", -MergeCells : "セル結合", -MergeRight : "右に結合", -MergeDown : "下に結合", -HorizontalSplitCell : "セルを水平方向分割", -VerticalSplitCell : "セルを垂直方向に分割", -TableDelete : "テーブル削除", -CellProperties : "セル プロパティ", -TableProperties : "テーブル プロパティ", -ImageProperties : "イメージ プロパティ", -FlashProperties : "Flash プロパティ", - -AnchorProp : "アンカー プロパティ", -ButtonProp : "ボタン プロパティ", -CheckboxProp : "チェックボックス プロパティ", -HiddenFieldProp : "不可視フィールド プロパティ", -RadioButtonProp : "ラジオボタン プロパティ", -ImageButtonProp : "画像ボタン プロパティ", -TextFieldProp : "1行テキスト プロパティ", -SelectionFieldProp : "選択フィールド プロパティ", -TextareaProp : "テキストエリア プロパティ", -FormProp : "フォーム プロパティ", - -FontFormats : "標準;書式付き;アドレス;見出し 1;見出し 2;見出し 3;見出し 4;見出し 5;見出し 6;標準 (DIV)", - -// Alerts and Messages -ProcessingXHTML : "XHTML処理中. しばらくお待ちください...", -Done : "完了", -PasteWordConfirm : "貼り付けを行うテキストは、ワード文章からコピーされようとしています。貼り付ける前にクリーニングを行いますか?", -NotCompatiblePaste : "このコマンドはインターネット・エクスプローラーバージョン5.5以上で利用可能です。クリーニングしないで貼り付けを行いますか?", -UnknownToolbarItem : "未知のツールバー項目 \"%1\"", -UnknownCommand : "未知のコマンド名 \"%1\"", -NotImplemented : "コマンドはインプリメントされませんでした。", -UnknownToolbarSet : "ツールバー設定 \"%1\" 存在しません。", -NoActiveX : "エラー、警告メッセージなどが発生した場合、ブラウザーのセキュリティ設定によりエディタのいくつかの機能が制限されている可能性があります。セキュリティ設定のオプションで\"ActiveXコントロールとプラグインの実行\"を有効にするにしてください。", -BrowseServerBlocked : "サーバーブラウザーを開くことができませんでした。ポップアップ・ブロック機能が無効になっているか確認してください。", -DialogBlocked : "ダイアログウィンドウを開くことができませんでした。ポップアップ・ブロック機能が無効になっているか確認してください。", -VisitLinkBlocked : "新しいウィンドウを開くことができませんでした。ポップアップ・ブロック機能が無効になっているか確認してください。", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "キャンセル", -DlgBtnClose : "閉じる", -DlgBtnBrowseServer : "サーバーブラウザー", -DlgAdvancedTag : "高度な設定", -DlgOpOther : "<その他>", -DlgInfoTab : "情報", -DlgAlertUrl : "URLを挿入してください", - -// General Dialogs Labels -DlgGenNotSet : "<なし>", -DlgGenId : "Id", -DlgGenLangDir : "文字表記の方向", -DlgGenLangDirLtr : "左から右 (LTR)", -DlgGenLangDirRtl : "右から左 (RTL)", -DlgGenLangCode : "言語コード", -DlgGenAccessKey : "アクセスキー", -DlgGenName : "Name属性", -DlgGenTabIndex : "タブインデックス", -DlgGenLongDescr : "longdesc属性(長文説明)", -DlgGenClass : "スタイルシートクラス", -DlgGenTitle : "Title属性", -DlgGenContType : "Content Type属性", -DlgGenLinkCharset : "リンクcharset属性", -DlgGenStyle : "スタイルシート", - -// Image Dialog -DlgImgTitle : "イメージ プロパティ", -DlgImgInfoTab : "イメージ 情報", -DlgImgBtnUpload : "サーバーに送信", -DlgImgURL : "URL", -DlgImgUpload : "アップロード", -DlgImgAlt : "代替テキスト", -DlgImgWidth : "幅", -DlgImgHeight : "高さ", -DlgImgLockRatio : "ロック比率", -DlgBtnResetSize : "サイズリセット", -DlgImgBorder : "ボーダー", -DlgImgHSpace : "横間隔", -DlgImgVSpace : "縦間隔", -DlgImgAlign : "行揃え", -DlgImgAlignLeft : "左", -DlgImgAlignAbsBottom: "下部(絶対的)", -DlgImgAlignAbsMiddle: "中央(絶対的)", -DlgImgAlignBaseline : "ベースライン", -DlgImgAlignBottom : "下", -DlgImgAlignMiddle : "中央", -DlgImgAlignRight : "右", -DlgImgAlignTextTop : "テキスト上部", -DlgImgAlignTop : "上", -DlgImgPreview : "プレビュー", -DlgImgAlertUrl : "イメージのURLを入力してください。", -DlgImgLinkTab : "リンク", - -// Flash Dialog -DlgFlashTitle : "Flash プロパティ", -DlgFlashChkPlay : "再生", -DlgFlashChkLoop : "ループ再生", -DlgFlashChkMenu : "Flashメニュー可能", -DlgFlashScale : "拡大縮小設定", -DlgFlashScaleAll : "すべて表示", -DlgFlashScaleNoBorder : "外が見えない様に拡大", -DlgFlashScaleFit : "上下左右にフィット", - -// Link Dialog -DlgLnkWindowTitle : "ハイパーリンク", -DlgLnkInfoTab : "ハイパーリンク 情報", -DlgLnkTargetTab : "ターゲット", - -DlgLnkType : "リンクタイプ", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "このページのアンカー", -DlgLnkTypeEMail : "E-Mail", -DlgLnkProto : "プロトコル", -DlgLnkProtoOther : "<その他>", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "アンカーを選択", -DlgLnkAnchorByName : "アンカー名", -DlgLnkAnchorById : "エレメントID", -DlgLnkNoAnchors : "(ドキュメントにおいて利用可能なアンカーはありません。)", -DlgLnkEMail : "E-Mail アドレス", -DlgLnkEMailSubject : "件名", -DlgLnkEMailBody : "本文", -DlgLnkUpload : "アップロード", -DlgLnkBtnUpload : "サーバーに送信", - -DlgLnkTarget : "ターゲット", -DlgLnkTargetFrame : "<フレーム>", -DlgLnkTargetPopup : "<ポップアップウィンドウ>", -DlgLnkTargetBlank : "新しいウィンドウ (_blank)", -DlgLnkTargetParent : "親ウィンドウ (_parent)", -DlgLnkTargetSelf : "同じウィンドウ (_self)", -DlgLnkTargetTop : "最上位ウィンドウ (_top)", -DlgLnkTargetFrameName : "目的のフレーム名", -DlgLnkPopWinName : "ポップアップウィンドウ名", -DlgLnkPopWinFeat : "ポップアップウィンドウ特徴", -DlgLnkPopResize : "リサイズ可能", -DlgLnkPopLocation : "ロケーションバー", -DlgLnkPopMenu : "メニューバー", -DlgLnkPopScroll : "スクロールバー", -DlgLnkPopStatus : "ステータスバー", -DlgLnkPopToolbar : "ツールバー", -DlgLnkPopFullScrn : "全画面モード(IE)", -DlgLnkPopDependent : "開いたウィンドウに連動して閉じる (Netscape)", -DlgLnkPopWidth : "幅", -DlgLnkPopHeight : "高さ", -DlgLnkPopLeft : "左端からの座標で指定", -DlgLnkPopTop : "上端からの座標で指定", - -DlnLnkMsgNoUrl : "リンクURLを入力してください。", -DlnLnkMsgNoEMail : "メールアドレスを入力してください。", -DlnLnkMsgNoAnchor : "アンカーを選択してください。", -DlnLnkMsgInvPopName : "ポップ・アップ名は英字で始まる文字で指定してくだい。ポップ・アップ名にスペースは含めません", - -// Color Dialog -DlgColorTitle : "色選択", -DlgColorBtnClear : "クリア", -DlgColorHighlight : "ハイライト", -DlgColorSelected : "選択色", - -// Smiley Dialog -DlgSmileyTitle : "顔文字挿入", - -// Special Character Dialog -DlgSpecialCharTitle : "特殊文字選択", - -// Table Dialog -DlgTableTitle : "テーブル プロパティ", -DlgTableRows : "行", -DlgTableColumns : "列", -DlgTableBorder : "ボーダーサイズ", -DlgTableAlign : "キャプションの整列", -DlgTableAlignNotSet : "<なし>", -DlgTableAlignLeft : "左", -DlgTableAlignCenter : "中央", -DlgTableAlignRight : "右", -DlgTableWidth : "テーブル幅", -DlgTableWidthPx : "ピクセル", -DlgTableWidthPc : "パーセント", -DlgTableHeight : "テーブル高さ", -DlgTableCellSpace : "セル内余白", -DlgTableCellPad : "セル内間隔", -DlgTableCaption : "キャプション", -DlgTableSummary : "テーブル目的/構造", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "セル プロパティ", -DlgCellWidth : "幅", -DlgCellWidthPx : "ピクセル", -DlgCellWidthPc : "パーセント", -DlgCellHeight : "高さ", -DlgCellWordWrap : "折り返し", -DlgCellWordWrapNotSet : "<なし>", -DlgCellWordWrapYes : "Yes", -DlgCellWordWrapNo : "No", -DlgCellHorAlign : "セル横の整列", -DlgCellHorAlignNotSet : "<なし>", -DlgCellHorAlignLeft : "左", -DlgCellHorAlignCenter : "中央", -DlgCellHorAlignRight: "右", -DlgCellVerAlign : "セル縦の整列", -DlgCellVerAlignNotSet : "<なし>", -DlgCellVerAlignTop : "上", -DlgCellVerAlignMiddle : "中央", -DlgCellVerAlignBottom : "下", -DlgCellVerAlignBaseline : "ベースライン", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "縦幅(行数)", -DlgCellCollSpan : "横幅(列数)", -DlgCellBackColor : "背景色", -DlgCellBorderColor : "ボーダーカラー", -DlgCellBtnSelect : "選択...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "検索して置換", - -// Find Dialog -DlgFindTitle : "検索", -DlgFindFindBtn : "検索", -DlgFindNotFoundMsg : "指定された文字列は見つかりませんでした。", - -// Replace Dialog -DlgReplaceTitle : "置き換え", -DlgReplaceFindLbl : "検索する文字列:", -DlgReplaceReplaceLbl : "置換えする文字列:", -DlgReplaceCaseChk : "部分一致", -DlgReplaceReplaceBtn : "置換え", -DlgReplaceReplAllBtn : "すべて置換え", -DlgReplaceWordChk : "単語単位で一致", - -// Paste Operations / Dialog -PasteErrorCut : "ブラウザーのセキュリティ設定によりエディタの切り取り操作が自動で実行することができません。実行するには手動でキーボードの(Ctrl+X)を使用してください。", -PasteErrorCopy : "ブラウザーのセキュリティ設定によりエディタのコピー操作が自動で実行することができません。実行するには手動でキーボードの(Ctrl+C)を使用してください。", - -PasteAsText : "プレーンテキスト貼り付け", -PasteFromWord : "ワード文章から貼り付け", - -DlgPasteMsg2 : "キーボード(Ctrl+V)を使用して、次の入力エリア内で貼って、OKを押してください。", -DlgPasteSec : "ブラウザのセキュリティ設定により、エディタはクリップボード・データに直接アクセスすることができません。このウィンドウは貼り付け操作を行う度に表示されます。", -DlgPasteIgnoreFont : "FontタグのFace属性を無視します。", -DlgPasteRemoveStyles : "スタイル定義を削除します。", - -// Color Picker -ColorAutomatic : "自動", -ColorMoreColors : "その他の色...", - -// Document Properties -DocProps : "文書 プロパティ", - -// Anchor Dialog -DlgAnchorTitle : "アンカー プロパティ", -DlgAnchorName : "アンカー名", -DlgAnchorErrorName : "アンカー名を必ず入力してください。", - -// Speller Pages Dialog -DlgSpellNotInDic : "辞書にありません", -DlgSpellChangeTo : "変更", -DlgSpellBtnIgnore : "無視", -DlgSpellBtnIgnoreAll : "すべて無視", -DlgSpellBtnReplace : "置換", -DlgSpellBtnReplaceAll : "すべて置換", -DlgSpellBtnUndo : "やり直し", -DlgSpellNoSuggestions : "- 該当なし -", -DlgSpellProgress : "スペルチェック処理中...", -DlgSpellNoMispell : "スペルチェック完了: スペルの誤りはありませんでした", -DlgSpellNoChanges : "スペルチェック完了: 語句は変更されませんでした", -DlgSpellOneChange : "スペルチェック完了: 1語句変更されました", -DlgSpellManyChanges : "スペルチェック完了: %1 語句変更されました", - -IeSpellDownload : "スペルチェッカーがインストールされていません。今すぐダウンロードしますか?", - -// Button Dialog -DlgButtonText : "テキスト (値)", -DlgButtonType : "タイプ", -DlgButtonTypeBtn : "ボタン", -DlgButtonTypeSbm : "送信", -DlgButtonTypeRst : "リセット", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "名前", -DlgCheckboxValue : "値", -DlgCheckboxSelected : "選択済み", - -// Form Dialog -DlgFormName : "フォーム名", -DlgFormAction : "アクション", -DlgFormMethod : "メソッド", - -// Select Field Dialog -DlgSelectName : "名前", -DlgSelectValue : "値", -DlgSelectSize : "サイズ", -DlgSelectLines : "行", -DlgSelectChkMulti : "複数項目選択を許可", -DlgSelectOpAvail : "利用可能なオプション", -DlgSelectOpText : "選択項目名", -DlgSelectOpValue : "選択項目値", -DlgSelectBtnAdd : "追加", -DlgSelectBtnModify : "編集", -DlgSelectBtnUp : "上へ", -DlgSelectBtnDown : "下へ", -DlgSelectBtnSetValue : "選択した値を設定", -DlgSelectBtnDelete : "削除", - -// Textarea Dialog -DlgTextareaName : "名前", -DlgTextareaCols : "列", -DlgTextareaRows : "行", - -// Text Field Dialog -DlgTextName : "名前", -DlgTextValue : "値", -DlgTextCharWidth : "サイズ", -DlgTextMaxChars : "最大長", -DlgTextType : "タイプ", -DlgTextTypeText : "テキスト", -DlgTextTypePass : "パスワード入力", - -// Hidden Field Dialog -DlgHiddenName : "名前", -DlgHiddenValue : "値", - -// Bulleted List Dialog -BulletedListProp : "箇条書き プロパティ", -NumberedListProp : "段落番号 プロパティ", -DlgLstStart : "開始文字", -DlgLstType : "タイプ", -DlgLstTypeCircle : "白丸", -DlgLstTypeDisc : "黒丸", -DlgLstTypeSquare : "四角", -DlgLstTypeNumbers : "アラビア数字 (1, 2, 3)", -DlgLstTypeLCase : "英字小文字 (a, b, c)", -DlgLstTypeUCase : "英字大文字 (A, B, C)", -DlgLstTypeSRoman : "ローマ数字小文字 (i, ii, iii)", -DlgLstTypeLRoman : "ローマ数字大文字 (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "全般", -DlgDocBackTab : "背景", -DlgDocColorsTab : "色とマージン", -DlgDocMetaTab : "メタデータ", - -DlgDocPageTitle : "ページタイトル", -DlgDocLangDir : "言語文字表記の方向", -DlgDocLangDirLTR : "左から右に表記(LTR)", -DlgDocLangDirRTL : "右から左に表記(RTL)", -DlgDocLangCode : "言語コード", -DlgDocCharSet : "文字セット符号化", -DlgDocCharSetCE : "Central European", -DlgDocCharSetCT : "Chinese Traditional (Big5)", -DlgDocCharSetCR : "Cyrillic", -DlgDocCharSetGR : "Greek", -DlgDocCharSetJP : "Japanese", -DlgDocCharSetKR : "Korean", -DlgDocCharSetTR : "Turkish", -DlgDocCharSetUN : "Unicode (UTF-8)", -DlgDocCharSetWE : "Western European", -DlgDocCharSetOther : "他の文字セット符号化", - -DlgDocDocType : "文書タイプヘッダー", -DlgDocDocTypeOther : "その他文書タイプヘッダー", -DlgDocIncXHTML : "XHTML宣言をインクルード", -DlgDocBgColor : "背景色", -DlgDocBgImage : "背景画像 URL", -DlgDocBgNoScroll : "スクロールしない背景", -DlgDocCText : "テキスト", -DlgDocCLink : "リンク", -DlgDocCVisited : "アクセス済みリンク", -DlgDocCActive : "アクセス中リンク", -DlgDocMargins : "ページ・マージン", -DlgDocMaTop : "上部", -DlgDocMaLeft : "左", -DlgDocMaRight : "右", -DlgDocMaBottom : "下部", -DlgDocMeIndex : "文書のキーワード(カンマ区切り)", -DlgDocMeDescr : "文書の概要", -DlgDocMeAuthor : "文書の作者", -DlgDocMeCopy : "文書の著作権", -DlgDocPreview : "プレビュー", - -// Templates Dialog -Templates : "テンプレート(雛形)", -DlgTemplatesTitle : "テンプレート内容", -DlgTemplatesSelMsg : "エディターで使用するテンプレートを選択してください。
    (現在のエディタの内容は失われます):", -DlgTemplatesLoading : "テンプレート一覧読み込み中. しばらくお待ちください...", -DlgTemplatesNoTpl : "(テンプレートが定義されていません)", -DlgTemplatesReplace : "現在のエディタの内容と置換えをします", - -// About Dialog -DlgAboutAboutTab : "バージョン情報", -DlgAboutBrowserInfoTab : "ブラウザ情報", -DlgAboutLicenseTab : "ライセンス", -DlgAboutVersion : "バージョン", -DlgAboutInfo : "より詳しい情報はこちらで", - -// Div Dialog -DlgDivGeneralTab : "全般", -DlgDivAdvancedTab : "高度な設定", -DlgDivStyle : "スタイル", -DlgDivInlineStyle : "インラインスタイル", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/km.js b/httemplate/elements/fckeditor/editor/lang/km.js deleted file mode 100644 index e0af4d02b..000000000 --- a/httemplate/elements/fckeditor/editor/lang/km.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Khmer language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "បង្រួមរបាឧបរកណ៍", -ToolbarExpand : "ពង្រីករបាឧបរណ៍", - -// Toolbar Items and Context Menu -Save : "រក្សាទុក", -NewPage : "ទំព័រថ្មី", -Preview : "មើលសាកល្បង", -Cut : "កាត់យក", -Copy : "ចំលងយក", -Paste : "ចំលងដាក់", -PasteText : "ចំលងដាក់ជាអត្ថបទធម្មតា", -PasteWord : "ចំលងដាក់ពី Word", -Print : "បោះពុម្ភ", -SelectAll : "ជ្រើសរើសទាំងអស់", -RemoveFormat : "លប់ចោល ការរចនា", -InsertLinkLbl : "ឈ្នាប់", -InsertLink : "បន្ថែម/កែប្រែ ឈ្នាប់", -RemoveLink : "លប់ឈ្នាប់", -VisitLink : "Open Link", //MISSING -Anchor : "បន្ថែម/កែប្រែ យុថ្កា", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "រូបភាព", -InsertImage : "បន្ថែម/កែប្រែ រូបភាព", -InsertFlashLbl : "Flash", -InsertFlash : "បន្ថែម/កែប្រែ Flash", -InsertTableLbl : "តារាង", -InsertTable : "បន្ថែម/កែប្រែ តារាង", -InsertLineLbl : "បន្ទាត់", -InsertLine : "បន្ថែមបន្ទាត់ផ្តេក", -InsertSpecialCharLbl: "អក្សរពិសេស", -InsertSpecialChar : "បន្ថែមអក្សរពិសេស", -InsertSmileyLbl : "រូបភាព", -InsertSmiley : "បន្ថែម រូបភាព", -About : "អំពី FCKeditor", -Bold : "អក្សរដិតធំ", -Italic : "អក្សរផ្តេក", -Underline : "ដិតបន្ទាត់ពីក្រោមអក្សរ", -StrikeThrough : "ដិតបន្ទាត់ពាក់កណ្តាលអក្សរ", -Subscript : "អក្សរតូចក្រោម", -Superscript : "អក្សរតូចលើ", -LeftJustify : "តំរឹមឆ្វេង", -CenterJustify : "តំរឹមកណ្តាល", -RightJustify : "តំរឹមស្តាំ", -BlockJustify : "តំរឹមសងខាង", -DecreaseIndent : "បន្ថយការចូលបន្ទាត់", -IncreaseIndent : "បន្ថែមការចូលបន្ទាត់", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "សារឡើងវិញ", -Redo : "ធ្វើឡើងវិញ", -NumberedListLbl : "បញ្ជីជាអក្សរ", -NumberedList : "បន្ថែម/លប់ បញ្ជីជាអក្សរ", -BulletedListLbl : "បញ្ជីជារង្វង់មូល", -BulletedList : "បន្ថែម/លប់ បញ្ជីជារង្វង់មូល", -ShowTableBorders : "បង្ហាញស៊ុមតារាង", -ShowDetails : "បង្ហាញពិស្តារ", -Style : "ម៉ូត", -FontFormat : "រចនា", -Font : "ហ្វុង", -FontSize : "ទំហំ", -TextColor : "ពណ៌អក្សរ", -BGColor : "ពណ៌ផ្ទៃខាងក្រោយ", -Source : "កូត", -Find : "ស្វែងរក", -Replace : "ជំនួស", -SpellCheck : "ពិនិត្យអក្ខរាវិរុទ្ធ", -UniversalKeyboard : "ក្តារពុម្ភអក្សរសកល", -PageBreakLbl : "ការផ្តាច់ទំព័រ", -PageBreak : "បន្ថែម ការផ្តាច់ទំព័រ", - -Form : "បែបបទ", -Checkbox : "ប្រអប់ជ្រើសរើស", -RadioButton : "ប៉ូតុនរង្វង់មូល", -TextField : "ជួរសរសេរអត្ថបទ", -Textarea : "តំបន់សរសេរអត្ថបទ", -HiddenField : "ជួរលាក់", -Button : "ប៉ូតុន", -SelectionField : "ជួរជ្រើសរើស", -ImageButton : "ប៉ូតុនរូបភាព", - -FitWindow : "Maximize the editor size", //MISSING -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "កែប្រែឈ្នាប់", -CellCM : "Cell", //MISSING -RowCM : "Row", //MISSING -ColumnCM : "Column", //MISSING -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "លប់ជួរផ្តេក", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "លប់ជួរឈរ", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "លប់សែល", -MergeCells : "បញ្ជូលសែល", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "លប់តារាង", -CellProperties : "ការកំណត់សែល", -TableProperties : "ការកំណត់តារាង", -ImageProperties : "ការកំណត់រូបភាព", -FlashProperties : "ការកំណត់ Flash", - -AnchorProp : "ការកំណត់យុថ្កា", -ButtonProp : "ការកំណត់ ប៉ូតុន", -CheckboxProp : "ការកំណត់ប្រអប់ជ្រើសរើស", -HiddenFieldProp : "ការកំណត់ជួរលាក់", -RadioButtonProp : "ការកំណត់ប៉ូតុនរង្វង់", -ImageButtonProp : "ការកំណត់ប៉ូតុនរូបភាព", -TextFieldProp : "ការកំណត់ជួរអត្ថបទ", -SelectionFieldProp : "ការកំណត់ជួរជ្រើសរើស", -TextareaProp : "ការកំណត់កន្លែងសរសេរអត្ថបទ", -FormProp : "ការកំណត់បែបបទ", - -FontFormats : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)", - -// Alerts and Messages -ProcessingXHTML : "កំពុងដំណើរការ XHTML ។ សូមរងចាំ...", -Done : "ចប់រួចរាល់", -PasteWordConfirm : "អត្ថបទដែលលោកអ្នកបំរុងចំលងដាក់ ហាក់បីដូចជាត្រូវចំលងមកពីកម្មវិធី​Word​។ តើលោកអ្នកចង់សំអាតមុនចំលងអត្ថបទដាក់ទេ?", -NotCompatiblePaste : "ពាក្យបញ្ជានេះប្រើបានតែជាមួយ Internet Explorer កំរិត 5.5 រឺ លើសនេះ ។ តើលោកអ្នកចង់ចំលងដាក់ដោយមិនចាំបាច់សំអាតទេ?", -UnknownToolbarItem : "វត្ថុលើរបាឧបរកណ៍ មិនស្គាល់ \"%1\"", -UnknownCommand : "ឈ្មោះពាក្យបញ្ជា មិនស្គាល់ \"%1\"", -NotImplemented : "ពាក្យបញ្ជា មិនបានអនុវត្ត", -UnknownToolbarSet : "របាឧបរកណ៍ \"%1\" ពុំមាន ។", -NoActiveX : "ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះ​អាចធ្វើអោយលោកអ្នកមិនអាចប្រើមុខងារខ្លះរបស់កម្មវិធីតាក់តែងអត្ថបទនេះ ។ លោកអ្នកត្រូវកំណត់អោយ \"ActiveX និង​កម្មវិធីជំនួយក្នុង (plug-ins)\" អោយដំណើរការ ។ លោកអ្នកអាចជួបប្រទះនឹង បញ្ហា ព្រមជាមួយនឹងការបាត់បង់មុខងារណាមួយរបស់កម្មវិធីតាក់តែងអត្ថបទនេះ ។", -BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.", //MISSING -DialogBlocked : "វីនដូវមិនអាចបើកបានទេ ។ សូមពិនិត្យចំពោះកម្មវិធីបិទ វីនដូវលោត (popup) ថាតើវាដំណើរការរឺទេ ។", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "យល់ព្រម", -DlgBtnCancel : "មិនយល់ព្រម", -DlgBtnClose : "បិទ", -DlgBtnBrowseServer : "មើល", -DlgAdvancedTag : "កំរិតខ្ពស់", -DlgOpOther : "<ផ្សេងទៅត>", -DlgInfoTab : "ពត៌មាន", -DlgAlertUrl : "សូមសរសេរ URL", - -// General Dialogs Labels -DlgGenNotSet : "<មិនមែន>", -DlgGenId : "Id", -DlgGenLangDir : "ទិសដៅភាសា", -DlgGenLangDirLtr : "ពីឆ្វេងទៅស្តាំ(LTR)", -DlgGenLangDirRtl : "ពីស្តាំទៅឆ្វេង(RTL)", -DlgGenLangCode : "លេខកូតភាសា", -DlgGenAccessKey : "ឃី សំរាប់ចូល", -DlgGenName : "ឈ្មោះ", -DlgGenTabIndex : "លេខ Tab", -DlgGenLongDescr : "អធិប្បាយ URL វែង", -DlgGenClass : "Stylesheet Classes", -DlgGenTitle : "ចំណងជើង ប្រឹក្សា", -DlgGenContType : "ប្រភេទអត្ថបទ ប្រឹក្សា", -DlgGenLinkCharset : "លេខកូតអក្សររបស់ឈ្នាប់", -DlgGenStyle : "ម៉ូត", - -// Image Dialog -DlgImgTitle : "ការកំណត់រូបភាព", -DlgImgInfoTab : "ពត៌មានអំពីរូបភាព", -DlgImgBtnUpload : "បញ្ជូនទៅកាន់ម៉ាស៊ីនផ្តល់សេវា", -DlgImgURL : "URL", -DlgImgUpload : "ទាញយក", -DlgImgAlt : "អត្ថបទជំនួស", -DlgImgWidth : "ទទឹង", -DlgImgHeight : "កំពស់", -DlgImgLockRatio : "អត្រាឡុក", -DlgBtnResetSize : "កំណត់ទំហំឡើងវិញ", -DlgImgBorder : "ស៊ុម", -DlgImgHSpace : "គំលាតទទឹង", -DlgImgVSpace : "គំលាតបណ្តោយ", -DlgImgAlign : "កំណត់ទីតាំង", -DlgImgAlignLeft : "ខាងឆ្វង", -DlgImgAlignAbsBottom: "Abs Bottom", //MISSING -DlgImgAlignAbsMiddle: "Abs Middle", //MISSING -DlgImgAlignBaseline : "បន្ទាត់ជាមូលដ្ឋាន", -DlgImgAlignBottom : "ខាងក្រោម", -DlgImgAlignMiddle : "កណ្តាល", -DlgImgAlignRight : "ខាងស្តាំ", -DlgImgAlignTextTop : "លើអត្ថបទ", -DlgImgAlignTop : "ខាងលើ", -DlgImgPreview : "មើលសាកល្បង", -DlgImgAlertUrl : "សូមសរសេរងាស័យដ្ឋានរបស់រូបភាព", -DlgImgLinkTab : "ឈ្នាប់", - -// Flash Dialog -DlgFlashTitle : "ការកំណត់ Flash", -DlgFlashChkPlay : "លេងដោយស្វ័យប្រវត្ត", -DlgFlashChkLoop : "ចំនួនដង", -DlgFlashChkMenu : "បង្ហាញ មឺនុយរបស់ Flash", -DlgFlashScale : "ទំហំ", -DlgFlashScaleAll : "បង្ហាញទាំងអស់", -DlgFlashScaleNoBorder : "មិនបង្ហាញស៊ុម", -DlgFlashScaleFit : "ត្រូវល្មម", - -// Link Dialog -DlgLnkWindowTitle : "ឈ្នាប់", -DlgLnkInfoTab : "ពត៌មានអំពីឈ្នាប់", -DlgLnkTargetTab : "គោលដៅ", - -DlgLnkType : "ប្រភេទឈ្នាប់", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "យុថ្កានៅក្នុងទំព័រនេះ", -DlgLnkTypeEMail : "អ៊ីមែល", -DlgLnkProto : "ប្រូតូកូល", -DlgLnkProtoOther : "<ផ្សេងទៀត>", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "ជ្រើសរើសយុថ្កា", -DlgLnkAnchorByName : "តាមឈ្មោះរបស់យុថ្កា", -DlgLnkAnchorById : "តាម Id", -DlgLnkNoAnchors : "(No anchors available in the document)", //MISSING -DlgLnkEMail : "អ៊ីមែល", -DlgLnkEMailSubject : "ចំណងជើងអត្ថបទ", -DlgLnkEMailBody : "អត្ថបទ", -DlgLnkUpload : "ទាញយក", -DlgLnkBtnUpload : "ទាញយក", - -DlgLnkTarget : "គោលដៅ", -DlgLnkTargetFrame : "<ហ្វ្រេម>", -DlgLnkTargetPopup : "<វីនដូវ លោត>", -DlgLnkTargetBlank : "វីនដូវថ្មី (_blank)", -DlgLnkTargetParent : "វីនដូវមេ (_parent)", -DlgLnkTargetSelf : "វីនដូវដដែល (_self)", -DlgLnkTargetTop : "វីនដូវនៅលើគេ(_top)", -DlgLnkTargetFrameName : "ឈ្មោះហ្រ្វេមដែលជាគោលដៅ", -DlgLnkPopWinName : "ឈ្មោះវីនដូវលោត", -DlgLnkPopWinFeat : "លក្ខណះរបស់វីនដូលលោត", -DlgLnkPopResize : "ទំហំអាចផ្លាស់ប្តូរ", -DlgLnkPopLocation : "របា ទីតាំង", -DlgLnkPopMenu : "របា មឺនុយ", -DlgLnkPopScroll : "របា ទាញ", -DlgLnkPopStatus : "របា ពត៌មាន", -DlgLnkPopToolbar : "របា ឩបករណ៍", -DlgLnkPopFullScrn : "អេក្រុងពេញ(IE)", -DlgLnkPopDependent : "អាស្រ័យលើ (Netscape)", -DlgLnkPopWidth : "ទទឹង", -DlgLnkPopHeight : "កំពស់", -DlgLnkPopLeft : "ទីតាំងខាងឆ្វេង", -DlgLnkPopTop : "ទីតាំងខាងលើ", - -DlnLnkMsgNoUrl : "សូមសរសេរ អាស័យដ្ឋាន URL", -DlnLnkMsgNoEMail : "សូមសរសេរ អាស័យដ្ឋាន អ៊ីមែល", -DlnLnkMsgNoAnchor : "សូមជ្រើសរើស យុថ្កា", -DlnLnkMsgInvPopName : "The popup name must begin with an alphabetic character and must not contain spaces", //MISSING - -// Color Dialog -DlgColorTitle : "ជ្រើសរើស ពណ៌", -DlgColorBtnClear : "លប់", -DlgColorHighlight : "ផាត់ពណ៌", -DlgColorSelected : "បានជ្រើសរើស", - -// Smiley Dialog -DlgSmileyTitle : "បញ្ជូលរូបភាព", - -// Special Character Dialog -DlgSpecialCharTitle : "តូអក្សរពិសេស", - -// Table Dialog -DlgTableTitle : "ការកំណត់ តារាង", -DlgTableRows : "ជួរផ្តេក", -DlgTableColumns : "ជួរឈរ", -DlgTableBorder : "ទំហំស៊ុម", -DlgTableAlign : "ការកំណត់ទីតាំង", -DlgTableAlignNotSet : "<មិនកំណត់>", -DlgTableAlignLeft : "ខាងឆ្វេង", -DlgTableAlignCenter : "កណ្តាល", -DlgTableAlignRight : "ខាងស្តាំ", -DlgTableWidth : "ទទឹង", -DlgTableWidthPx : "ភីកសែល", -DlgTableWidthPc : "ភាគរយ", -DlgTableHeight : "កំពស់", -DlgTableCellSpace : "គំលាតសែល", -DlgTableCellPad : "គែមសែល", -DlgTableCaption : "ចំណងជើង", -DlgTableSummary : "សេចក្តីសង្ខេប", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "ការកំណត់ សែល", -DlgCellWidth : "ទទឹង", -DlgCellWidthPx : "ភីកសែល", -DlgCellWidthPc : "ភាគរយ", -DlgCellHeight : "កំពស់", -DlgCellWordWrap : "បង្ហាញអត្ថបទទាំងអស់", -DlgCellWordWrapNotSet : "<មិនកំណត់>", -DlgCellWordWrapYes : "បាទ(ចា)", -DlgCellWordWrapNo : "ទេ", -DlgCellHorAlign : "តំរឹមផ្តេក", -DlgCellHorAlignNotSet : "<មិនកំណត់>", -DlgCellHorAlignLeft : "ខាងឆ្វេង", -DlgCellHorAlignCenter : "កណ្តាល", -DlgCellHorAlignRight: "Right", //MISSING -DlgCellVerAlign : "តំរឹមឈរ", -DlgCellVerAlignNotSet : "<មិនកណត់>", -DlgCellVerAlignTop : "ខាងលើ", -DlgCellVerAlignMiddle : "កណ្តាល", -DlgCellVerAlignBottom : "ខាងក្រោម", -DlgCellVerAlignBaseline : "បន្ទាត់ជាមូលដ្ឋាន", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "បញ្ជូលជួរផ្តេក", -DlgCellCollSpan : "បញ្ជូលជួរឈរ", -DlgCellBackColor : "ពណ៌ផ្នែកខាងក្រោម", -DlgCellBorderColor : "ពណ៌ស៊ុម", -DlgCellBtnSelect : "ជ្រើសរើស...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Find and Replace", //MISSING - -// Find Dialog -DlgFindTitle : "ស្វែងរក", -DlgFindFindBtn : "ស្វែងរក", -DlgFindNotFoundMsg : "ពាក្យនេះ រកមិនឃើញទេ ។", - -// Replace Dialog -DlgReplaceTitle : "ជំនួស", -DlgReplaceFindLbl : "ស្វែងរកអ្វី:", -DlgReplaceReplaceLbl : "ជំនួសជាមួយ:", -DlgReplaceCaseChk : "ករណ៉ត្រូវរក", -DlgReplaceReplaceBtn : "ជំនួស", -DlgReplaceReplAllBtn : "ជំនួសទាំងអស់", -DlgReplaceWordChk : "ត្រូវពាក្យទាំងអស់", - -// Paste Operations / Dialog -PasteErrorCut : "ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះ​មិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ កាត់អត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ (Ctrl+X) ។", -PasteErrorCopy : "ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះ​មិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ ចំលងអត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ (Ctrl+C)។", - -PasteAsText : "ចំលងដាក់អត្ថបទធម្មតា", -PasteFromWord : "ចំលងពាក្យពីកម្មវិធី Word", - -DlgPasteMsg2 : "សូមចំលងអត្ថបទទៅដាក់ក្នុងប្រអប់ដូចខាងក្រោមដោយប្រើប្រាស់ ឃី ​(Ctrl+V) ហើយចុច OK ។", -DlgPasteSec : "Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.", //MISSING -DlgPasteIgnoreFont : "មិនគិតអំពីប្រភេទពុម្ភអក្សរ", -DlgPasteRemoveStyles : "លប់ម៉ូត", - -// Color Picker -ColorAutomatic : "ស្វ័យប្រវត្ត", -ColorMoreColors : "ពណ៌ផ្សេងទៀត..", - -// Document Properties -DocProps : "ការកំណត់ ឯកសារ", - -// Anchor Dialog -DlgAnchorTitle : "ការកំណត់ចំណងជើងយុទ្ធថ្កា", -DlgAnchorName : "ឈ្មោះយុទ្ធថ្កា", -DlgAnchorErrorName : "សូមសរសេរ ឈ្មោះយុទ្ធថ្កា", - -// Speller Pages Dialog -DlgSpellNotInDic : "គ្មានក្នុងវចនានុក្រម", -DlgSpellChangeTo : "ផ្លាស់ប្តូរទៅ", -DlgSpellBtnIgnore : "មិនផ្លាស់ប្តូរ", -DlgSpellBtnIgnoreAll : "មិនផ្លាស់ប្តូរ ទាំងអស់", -DlgSpellBtnReplace : "ជំនួស", -DlgSpellBtnReplaceAll : "ជំនួសទាំងអស់", -DlgSpellBtnUndo : "សារឡើងវិញ", -DlgSpellNoSuggestions : "- គ្មានសំណើរ -", -DlgSpellProgress : "កំពុងពិនិត្យអក្ខរាវិរុទ្ធ...", -DlgSpellNoMispell : "ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: គ្មានកំហុស", -DlgSpellNoChanges : "ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: ពុំមានផ្លាស់ប្តូរ", -DlgSpellOneChange : "ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: ពាក្យមួយត្រូចបានផ្លាស់ប្តូរ", -DlgSpellManyChanges : "ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: %1 ពាក្យបានផ្លាស់ប្តូរ", - -IeSpellDownload : "ពុំមានកម្មវិធីពិនិត្យអក្ខរាវិរុទ្ធ ។ តើចង់ទាញយកពីណា?", - -// Button Dialog -DlgButtonText : "អត្ថបទ(តំលៃ)", -DlgButtonType : "ប្រភេទ", -DlgButtonTypeBtn : "Button", //MISSING -DlgButtonTypeSbm : "Submit", //MISSING -DlgButtonTypeRst : "Reset", //MISSING - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "ឈ្មោះ", -DlgCheckboxValue : "តំលៃ", -DlgCheckboxSelected : "បានជ្រើសរើស", - -// Form Dialog -DlgFormName : "ឈ្មោះ", -DlgFormAction : "សកម្មភាព", -DlgFormMethod : "វិធី", - -// Select Field Dialog -DlgSelectName : "ឈ្មោះ", -DlgSelectValue : "តំលៃ", -DlgSelectSize : "ទំហំ", -DlgSelectLines : "បន្ទាត់", -DlgSelectChkMulti : "អនុញ្ញាតអោយជ្រើសរើសច្រើន", -DlgSelectOpAvail : "ការកំណត់ជ្រើសរើស ដែលអាចកំណត់បាន", -DlgSelectOpText : "ពាក្យ", -DlgSelectOpValue : "តំលៃ", -DlgSelectBtnAdd : "បន្ថែម", -DlgSelectBtnModify : "ផ្លាស់ប្តូរ", -DlgSelectBtnUp : "លើ", -DlgSelectBtnDown : "ក្រោម", -DlgSelectBtnSetValue : "Set as selected value", //MISSING -DlgSelectBtnDelete : "លប់", - -// Textarea Dialog -DlgTextareaName : "ឈ្មោះ", -DlgTextareaCols : "ជូរឈរ", -DlgTextareaRows : "ជូរផ្តេក", - -// Text Field Dialog -DlgTextName : "ឈ្មោះ", -DlgTextValue : "តំលៃ", -DlgTextCharWidth : "ទទឹង អក្សរ", -DlgTextMaxChars : "អក្សរអតិបរិមា", -DlgTextType : "ប្រភេទ", -DlgTextTypeText : "ពាក្យ", -DlgTextTypePass : "ពាក្យសំងាត់", - -// Hidden Field Dialog -DlgHiddenName : "ឈ្មោះ", -DlgHiddenValue : "តំលៃ", - -// Bulleted List Dialog -BulletedListProp : "កំណត់បញ្ជីរង្វង់", -NumberedListProp : "កំណត់បញ្េជីលេខ", -DlgLstStart : "Start", //MISSING -DlgLstType : "ប្រភេទ", -DlgLstTypeCircle : "រង្វង់", -DlgLstTypeDisc : "Disc", -DlgLstTypeSquare : "ការេ", -DlgLstTypeNumbers : "លេខ(1, 2, 3)", -DlgLstTypeLCase : "អក្សរតូច(a, b, c)", -DlgLstTypeUCase : "អក្សរធំ(A, B, C)", -DlgLstTypeSRoman : "អក្សរឡាតាំងតូច(i, ii, iii)", -DlgLstTypeLRoman : "អក្សរឡាតាំងធំ(I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "ទូទៅ", -DlgDocBackTab : "ផ្នែកខាងក្រោយ", -DlgDocColorsTab : "ទំព័រ​និង ស៊ុម", -DlgDocMetaTab : "ទិន្នន័យមេ", - -DlgDocPageTitle : "ចំណងជើងទំព័រ", -DlgDocLangDir : "ទិសដៅសរសេរភាសា", -DlgDocLangDirLTR : "ពីឆ្វេងទៅស្ដាំ(LTR)", -DlgDocLangDirRTL : "ពីស្ដាំទៅឆ្វេង(RTL)", -DlgDocLangCode : "លេខកូតភាសា", -DlgDocCharSet : "កំណត់លេខកូតភាសា", -DlgDocCharSetCE : "Central European", //MISSING -DlgDocCharSetCT : "Chinese Traditional (Big5)", //MISSING -DlgDocCharSetCR : "Cyrillic", //MISSING -DlgDocCharSetGR : "Greek", //MISSING -DlgDocCharSetJP : "Japanese", //MISSING -DlgDocCharSetKR : "Korean", //MISSING -DlgDocCharSetTR : "Turkish", //MISSING -DlgDocCharSetUN : "Unicode (UTF-8)", //MISSING -DlgDocCharSetWE : "Western European", //MISSING -DlgDocCharSetOther : "កំណត់លេខកូតភាសាផ្សេងទៀត", - -DlgDocDocType : "ប្រភេទក្បាលទំព័រ", -DlgDocDocTypeOther : "ប្រភេទក្បាលទំព័រផ្សេងទៀត", -DlgDocIncXHTML : "បញ្ជូល XHTML", -DlgDocBgColor : "ពណ៌ខាងក្រោម", -DlgDocBgImage : "URL របស់រូបភាពខាងក្រោម", -DlgDocBgNoScroll : "ទំព័រក្រោមមិនប្តូរ", -DlgDocCText : "អត្តបទ", -DlgDocCLink : "ឈ្នាប់", -DlgDocCVisited : "ឈ្នាប់មើលហើយ", -DlgDocCActive : "ឈ្នាប់កំពុងមើល", -DlgDocMargins : "ស៊ុមទំព័រ", -DlgDocMaTop : "លើ", -DlgDocMaLeft : "ឆ្វេង", -DlgDocMaRight : "ស្ដាំ", -DlgDocMaBottom : "ក្រោម", -DlgDocMeIndex : "ពាក្យនៅក្នុងឯកសារ (ផ្តាច់ពីគ្នាដោយក្បៀស)", -DlgDocMeDescr : "សេចក្តីអត្ថាធិប្បាយអំពីឯកសារ", -DlgDocMeAuthor : "អ្នកនិពន្ធ", -DlgDocMeCopy : "រក្សាសិទ្ធិ៏", -DlgDocPreview : "មើលសាកល្បង", - -// Templates Dialog -Templates : "ឯកសារគំរូ", -DlgTemplatesTitle : "ឯកសារគំរូ របស់អត្ថន័យ", -DlgTemplatesSelMsg : "សូមជ្រើសរើសឯកសារគំរូ ដើម្បីបើកនៅក្នុងកម្មវិធីតាក់តែងអត្ថបទ
    (អត្ថបទនឹងបាត់បង់):", -DlgTemplatesLoading : "កំពុងអានបញ្ជីឯកសារគំរូ ។ សូមរងចាំ...", -DlgTemplatesNoTpl : "(ពុំមានឯកសារគំរូត្រូវបានកំណត់)", -DlgTemplatesReplace : "Replace actual contents", //MISSING - -// About Dialog -DlgAboutAboutTab : "អំពី", -DlgAboutBrowserInfoTab : "ព៌តមានកម្មវិធីរុករក", -DlgAboutLicenseTab : "License", //MISSING -DlgAboutVersion : "ជំនាន់", -DlgAboutInfo : "សំរាប់ព៌តមានផ្សេងទៀត សូមទាក់ទង", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/ko.js b/httemplate/elements/fckeditor/editor/lang/ko.js deleted file mode 100644 index 91df044ff..000000000 --- a/httemplate/elements/fckeditor/editor/lang/ko.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Korean language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "툴바 감추기", -ToolbarExpand : "툴바 보이기", - -// Toolbar Items and Context Menu -Save : "저장하기", -NewPage : "새 문서", -Preview : "미리보기", -Cut : "잘라내기", -Copy : "복사하기", -Paste : "붙여넣기", -PasteText : "텍스트로 붙여넣기", -PasteWord : "MS Word 형식에서 붙여넣기", -Print : "인쇄하기", -SelectAll : "전체선택", -RemoveFormat : "포맷 지우기", -InsertLinkLbl : "링크", -InsertLink : "링크 삽입/변경", -RemoveLink : "링크 삭제", -VisitLink : "Open Link", //MISSING -Anchor : "책갈피 삽입/변경", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "이미지", -InsertImage : "이미지 삽입/변경", -InsertFlashLbl : "플래쉬", -InsertFlash : "플래쉬 삽입/변경", -InsertTableLbl : "표", -InsertTable : "표 삽입/변경", -InsertLineLbl : "수평선", -InsertLine : "수평선 삽입", -InsertSpecialCharLbl: "특수문자 삽입", -InsertSpecialChar : "특수문자 삽입", -InsertSmileyLbl : "아이콘", -InsertSmiley : "아이콘 삽입", -About : "FCKeditor에 대하여", -Bold : "진하게", -Italic : "이텔릭", -Underline : "밑줄", -StrikeThrough : "취소선", -Subscript : "아래 첨자", -Superscript : "위 첨자", -LeftJustify : "왼쪽 정렬", -CenterJustify : "가운데 정렬", -RightJustify : "오른쪽 정렬", -BlockJustify : "양쪽 맞춤", -DecreaseIndent : "내어쓰기", -IncreaseIndent : "들여쓰기", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "취소", -Redo : "재실행", -NumberedListLbl : "순서있는 목록", -NumberedList : "순서있는 목록", -BulletedListLbl : "순서없는 목록", -BulletedList : "순서없는 목록", -ShowTableBorders : "표 테두리 보기", -ShowDetails : "문서기호 보기", -Style : "스타일", -FontFormat : "포맷", -Font : "폰트", -FontSize : "글자 크기", -TextColor : "글자 색상", -BGColor : "배경 색상", -Source : "소스", -Find : "찾기", -Replace : "바꾸기", -SpellCheck : "철자검사", -UniversalKeyboard : "다국어 입력기", -PageBreakLbl : "Page Break", //MISSING -PageBreak : "Insert Page Break", //MISSING - -Form : "폼", -Checkbox : "체크박스", -RadioButton : "라디오버튼", -TextField : "입력필드", -Textarea : "입력영역", -HiddenField : "숨김필드", -Button : "버튼", -SelectionField : "펼침목록", -ImageButton : "이미지버튼", - -FitWindow : "에디터 최대화", -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "링크 수정", -CellCM : "셀/칸(Cell)", -RowCM : "행(Row)", -ColumnCM : "열(Column)", -InsertRowAfter : "뒤에 행 삽입", -InsertRowBefore : "앞에 행 삽입", -DeleteRows : "가로줄 삭제", -InsertColumnAfter : "뒤에 열 삽입", -InsertColumnBefore : "앞에 열 삽입", -DeleteColumns : "세로줄 삭제", -InsertCellAfter : "뒤에 셀/칸 삽입", -InsertCellBefore : "앞에 셀/칸 삽입", -DeleteCells : "셀 삭제", -MergeCells : "셀 합치기", -MergeRight : "오른쪽 뭉치기", -MergeDown : "왼쪽 뭉치기", -HorizontalSplitCell : "수평 나누기", -VerticalSplitCell : "수직 나누기", -TableDelete : "표 삭제", -CellProperties : "셀 속성", -TableProperties : "표 속성", -ImageProperties : "이미지 속성", -FlashProperties : "플래쉬 속성", - -AnchorProp : "책갈피 속성", -ButtonProp : "버튼 속성", -CheckboxProp : "체크박스 속성", -HiddenFieldProp : "숨김필드 속성", -RadioButtonProp : "라디오버튼 속성", -ImageButtonProp : "이미지버튼 속성", -TextFieldProp : "입력필드 속성", -SelectionFieldProp : "펼침목록 속성", -TextareaProp : "입력영역 속성", -FormProp : "폼 속성", - -FontFormats : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6", - -// Alerts and Messages -ProcessingXHTML : "XHTML 처리중. 잠시만 기다려주십시요.", -Done : "완료", -PasteWordConfirm : "붙여넣기 할 텍스트는 MS Word에서 복사한 것입니다. 붙여넣기 전에 MS Word 포멧을 삭제하시겠습니까?", -NotCompatiblePaste : "이 명령은 인터넷익스플로러 5.5 버전 이상에서만 작동합니다. 포멧을 삭제하지 않고 붙여넣기 하시겠습니까?", -UnknownToolbarItem : "알수없는 툴바입니다. : \"%1\"", -UnknownCommand : "알수없는 기능입니다. : \"%1\"", -NotImplemented : "기능이 실행되지 않았습니다.", -UnknownToolbarSet : "툴바 설정이 없습니다. : \"%1\"", -NoActiveX : "브러우저의 보안 설정으로 인해 몇몇 기능의 작동에 장애가 있을 수 있습니다. \"액티브-액스 기능과 플러그 인\" 옵션을 허용하여 주시지 않으면 오류가 발생할 수 있습니다.", -BrowseServerBlocked : "브러우저 요소가 열리지 않습니다. 팝업차단 설정이 꺼져있는지 확인하여 주십시오.", -DialogBlocked : "윈도우 대화창을 열 수 없습니다. 팝업차단 설정이 꺼져있는지 확인하여 주십시오.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "예", -DlgBtnCancel : "아니오", -DlgBtnClose : "닫기", -DlgBtnBrowseServer : "서버 보기", -DlgAdvancedTag : "자세히", -DlgOpOther : "<기타>", -DlgInfoTab : "정보", -DlgAlertUrl : "URL을 입력하십시요", - -// General Dialogs Labels -DlgGenNotSet : "<설정되지 않음>", -DlgGenId : "ID", -DlgGenLangDir : "쓰기 방향", -DlgGenLangDirLtr : "왼쪽에서 오른쪽 (LTR)", -DlgGenLangDirRtl : "오른쪽에서 왼쪽 (RTL)", -DlgGenLangCode : "언어 코드", -DlgGenAccessKey : "엑세스 키", -DlgGenName : "Name", -DlgGenTabIndex : "탭 순서", -DlgGenLongDescr : "URL 설명", -DlgGenClass : "Stylesheet Classes", -DlgGenTitle : "Advisory Title", -DlgGenContType : "Advisory Content Type", -DlgGenLinkCharset : "Linked Resource Charset", -DlgGenStyle : "Style", - -// Image Dialog -DlgImgTitle : "이미지 설정", -DlgImgInfoTab : "이미지 정보", -DlgImgBtnUpload : "서버로 전송", -DlgImgURL : "URL", -DlgImgUpload : "업로드", -DlgImgAlt : "이미지 설명", -DlgImgWidth : "너비", -DlgImgHeight : "높이", -DlgImgLockRatio : "비율 유지", -DlgBtnResetSize : "원래 크기로", -DlgImgBorder : "테두리", -DlgImgHSpace : "수평여백", -DlgImgVSpace : "수직여백", -DlgImgAlign : "정렬", -DlgImgAlignLeft : "왼쪽", -DlgImgAlignAbsBottom: "줄아래(Abs Bottom)", -DlgImgAlignAbsMiddle: "줄중간(Abs Middle)", -DlgImgAlignBaseline : "기준선", -DlgImgAlignBottom : "아래", -DlgImgAlignMiddle : "중간", -DlgImgAlignRight : "오른쪽", -DlgImgAlignTextTop : "글자상단", -DlgImgAlignTop : "위", -DlgImgPreview : "미리보기", -DlgImgAlertUrl : "이미지 URL을 입력하십시요", -DlgImgLinkTab : "링크", - -// Flash Dialog -DlgFlashTitle : "플래쉬 등록정보", -DlgFlashChkPlay : "자동재생", -DlgFlashChkLoop : "반복", -DlgFlashChkMenu : "플래쉬메뉴 가능", -DlgFlashScale : "영역", -DlgFlashScaleAll : "모두보기", -DlgFlashScaleNoBorder : "경계선없음", -DlgFlashScaleFit : "영역자동조절", - -// Link Dialog -DlgLnkWindowTitle : "링크", -DlgLnkInfoTab : "링크 정보", -DlgLnkTargetTab : "타겟", - -DlgLnkType : "링크 종류", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "책갈피", -DlgLnkTypeEMail : "이메일", -DlgLnkProto : "프로토콜", -DlgLnkProtoOther : "<기타>", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "책갈피 선택", -DlgLnkAnchorByName : "책갈피 이름", -DlgLnkAnchorById : "책갈피 ID", -DlgLnkNoAnchors : "(문서에 책갈피가 없습니다.)", -DlgLnkEMail : "이메일 주소", -DlgLnkEMailSubject : "제목", -DlgLnkEMailBody : "내용", -DlgLnkUpload : "업로드", -DlgLnkBtnUpload : "서버로 전송", - -DlgLnkTarget : "타겟", -DlgLnkTargetFrame : "<프레임>", -DlgLnkTargetPopup : "<팝업창>", -DlgLnkTargetBlank : "새 창 (_blank)", -DlgLnkTargetParent : "부모 창 (_parent)", -DlgLnkTargetSelf : "현재 창 (_self)", -DlgLnkTargetTop : "최 상위 창 (_top)", -DlgLnkTargetFrameName : "타겟 프레임 이름", -DlgLnkPopWinName : "팝업창 이름", -DlgLnkPopWinFeat : "팝업창 설정", -DlgLnkPopResize : "크기조정", -DlgLnkPopLocation : "주소표시줄", -DlgLnkPopMenu : "메뉴바", -DlgLnkPopScroll : "스크롤바", -DlgLnkPopStatus : "상태바", -DlgLnkPopToolbar : "툴바", -DlgLnkPopFullScrn : "전체화면 (IE)", -DlgLnkPopDependent : "Dependent (Netscape)", -DlgLnkPopWidth : "너비", -DlgLnkPopHeight : "높이", -DlgLnkPopLeft : "왼쪽 위치", -DlgLnkPopTop : "윗쪽 위치", - -DlnLnkMsgNoUrl : "링크 URL을 입력하십시요.", -DlnLnkMsgNoEMail : "이메일주소를 입력하십시요.", -DlnLnkMsgNoAnchor : "책갈피명을 입력하십시요.", -DlnLnkMsgInvPopName : "팝업창의 타이틀은 공백을 허용하지 않습니다.", - -// Color Dialog -DlgColorTitle : "색상 선택", -DlgColorBtnClear : "지우기", -DlgColorHighlight : "현재", -DlgColorSelected : "선택됨", - -// Smiley Dialog -DlgSmileyTitle : "아이콘 삽입", - -// Special Character Dialog -DlgSpecialCharTitle : "특수문자 선택", - -// Table Dialog -DlgTableTitle : "표 설정", -DlgTableRows : "가로줄", -DlgTableColumns : "세로줄", -DlgTableBorder : "테두리 크기", -DlgTableAlign : "정렬", -DlgTableAlignNotSet : "<설정되지 않음>", -DlgTableAlignLeft : "왼쪽", -DlgTableAlignCenter : "가운데", -DlgTableAlignRight : "오른쪽", -DlgTableWidth : "너비", -DlgTableWidthPx : "픽셀", -DlgTableWidthPc : "퍼센트", -DlgTableHeight : "높이", -DlgTableCellSpace : "셀 간격", -DlgTableCellPad : "셀 여백", -DlgTableCaption : "캡션", -DlgTableSummary : "요약", -DlgTableHeaders : "Headers", //MISSING -DlgTableHeadersNone : "None", //MISSING -DlgTableHeadersColumn : "First column", //MISSING -DlgTableHeadersRow : "First Row", //MISSING -DlgTableHeadersBoth : "Both", //MISSING - -// Table Cell Dialog -DlgCellTitle : "셀 설정", -DlgCellWidth : "너비", -DlgCellWidthPx : "픽셀", -DlgCellWidthPc : "퍼센트", -DlgCellHeight : "높이", -DlgCellWordWrap : "워드랩", -DlgCellWordWrapNotSet : "<설정되지 않음>", -DlgCellWordWrapYes : "예", -DlgCellWordWrapNo : "아니오", -DlgCellHorAlign : "수평 정렬", -DlgCellHorAlignNotSet : "<설정되지 않음>", -DlgCellHorAlignLeft : "왼쪽", -DlgCellHorAlignCenter : "가운데", -DlgCellHorAlignRight: "오른쪽", -DlgCellVerAlign : "수직 정렬", -DlgCellVerAlignNotSet : "<설정되지 않음>", -DlgCellVerAlignTop : "위", -DlgCellVerAlignMiddle : "중간", -DlgCellVerAlignBottom : "아래", -DlgCellVerAlignBaseline : "기준선", -DlgCellType : "Cell Type", //MISSING -DlgCellTypeData : "Data", //MISSING -DlgCellTypeHeader : "Header", //MISSING -DlgCellRowSpan : "세로 합치기", -DlgCellCollSpan : "가로 합치기", -DlgCellBackColor : "배경 색상", -DlgCellBorderColor : "테두리 색상", -DlgCellBtnSelect : "선택", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "찾기 & 바꾸기", - -// Find Dialog -DlgFindTitle : "찾기", -DlgFindFindBtn : "찾기", -DlgFindNotFoundMsg : "문자열을 찾을 수 없습니다.", - -// Replace Dialog -DlgReplaceTitle : "바꾸기", -DlgReplaceFindLbl : "찾을 문자열:", -DlgReplaceReplaceLbl : "바꿀 문자열:", -DlgReplaceCaseChk : "대소문자 구분", -DlgReplaceReplaceBtn : "바꾸기", -DlgReplaceReplAllBtn : "모두 바꾸기", -DlgReplaceWordChk : "온전한 단어", - -// Paste Operations / Dialog -PasteErrorCut : "브라우저의 보안설정때문에 잘라내기 기능을 실행할 수 없습니다. 키보드 명령을 사용하십시요. (Ctrl+X).", -PasteErrorCopy : "브라우저의 보안설정때문에 복사하기 기능을 실행할 수 없습니다. 키보드 명령을 사용하십시요. (Ctrl+C).", - -PasteAsText : "텍스트로 붙여넣기", -PasteFromWord : "MS Word 형식에서 붙여넣기", - -DlgPasteMsg2 : "키보드의 (Ctrl+V) 를 이용해서 상자안에 붙여넣고 OK 를 누르세요.", -DlgPasteSec : "브러우저 보안 설정으로 인해, 클립보드의 자료를 직접 접근할 수 없습니다. 이 창에 다시 붙여넣기 하십시오.", -DlgPasteIgnoreFont : "폰트 설정 무시", -DlgPasteRemoveStyles : "스타일 정의 제거", - -// Color Picker -ColorAutomatic : "기본색상", -ColorMoreColors : "색상선택...", - -// Document Properties -DocProps : "문서 속성", - -// Anchor Dialog -DlgAnchorTitle : "책갈피 속성", -DlgAnchorName : "책갈피 이름", -DlgAnchorErrorName : "책갈피 이름을 입력하십시요.", - -// Speller Pages Dialog -DlgSpellNotInDic : "사전에 없는 단어", -DlgSpellChangeTo : "변경할 단어", -DlgSpellBtnIgnore : "건너뜀", -DlgSpellBtnIgnoreAll : "모두 건너뜀", -DlgSpellBtnReplace : "변경", -DlgSpellBtnReplaceAll : "모두 변경", -DlgSpellBtnUndo : "취소", -DlgSpellNoSuggestions : "- 추천단어 없음 -", -DlgSpellProgress : "철자검사를 진행중입니다...", -DlgSpellNoMispell : "철자검사 완료: 잘못된 철자가 없습니다.", -DlgSpellNoChanges : "철자검사 완료: 변경된 단어가 없습니다.", -DlgSpellOneChange : "철자검사 완료: 단어가 변경되었습니다.", -DlgSpellManyChanges : "철자검사 완료: %1 단어가 변경되었습니다.", - -IeSpellDownload : "철자 검사기가 철치되지 않았습니다. 지금 다운로드하시겠습니까?", - -// Button Dialog -DlgButtonText : "버튼글자(값)", -DlgButtonType : "버튼종류", -DlgButtonTypeBtn : "Button", //MISSING -DlgButtonTypeSbm : "Submit", //MISSING -DlgButtonTypeRst : "Reset", //MISSING - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "이름", -DlgCheckboxValue : "값", -DlgCheckboxSelected : "선택됨", - -// Form Dialog -DlgFormName : "폼이름", -DlgFormAction : "실행경로(Action)", -DlgFormMethod : "방법(Method)", - -// Select Field Dialog -DlgSelectName : "이름", -DlgSelectValue : "값", -DlgSelectSize : "세로크기", -DlgSelectLines : "줄", -DlgSelectChkMulti : "여러항목 선택 허용", -DlgSelectOpAvail : "선택옵션", -DlgSelectOpText : "이름", -DlgSelectOpValue : "값", -DlgSelectBtnAdd : "추가", -DlgSelectBtnModify : "변경", -DlgSelectBtnUp : "위로", -DlgSelectBtnDown : "아래로", -DlgSelectBtnSetValue : "선택된것으로 설정", -DlgSelectBtnDelete : "삭제", - -// Textarea Dialog -DlgTextareaName : "이름", -DlgTextareaCols : "칸수", -DlgTextareaRows : "줄수", - -// Text Field Dialog -DlgTextName : "이름", -DlgTextValue : "값", -DlgTextCharWidth : "글자 너비", -DlgTextMaxChars : "최대 글자수", -DlgTextType : "종류", -DlgTextTypeText : "문자열", -DlgTextTypePass : "비밀번호", - -// Hidden Field Dialog -DlgHiddenName : "이름", -DlgHiddenValue : "값", - -// Bulleted List Dialog -BulletedListProp : "순서없는 목록 속성", -NumberedListProp : "순서있는 목록 속성", -DlgLstStart : "Start", //MISSING -DlgLstType : "종류", -DlgLstTypeCircle : "원(Circle)", -DlgLstTypeDisc : "Disc", //MISSING -DlgLstTypeSquare : "네모점(Square)", -DlgLstTypeNumbers : "번호 (1, 2, 3)", -DlgLstTypeLCase : "소문자 (a, b, c)", -DlgLstTypeUCase : "대문자 (A, B, C)", -DlgLstTypeSRoman : "로마자 수문자 (i, ii, iii)", -DlgLstTypeLRoman : "로마자 대문자 (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "일반", -DlgDocBackTab : "배경", -DlgDocColorsTab : "색상 및 여백", -DlgDocMetaTab : "메타데이터", - -DlgDocPageTitle : "페이지명", -DlgDocLangDir : "문자 쓰기방향", -DlgDocLangDirLTR : "왼쪽에서 오른쪽 (LTR)", -DlgDocLangDirRTL : "오른쪽에서 왼쪽 (RTL)", -DlgDocLangCode : "언어코드", -DlgDocCharSet : "캐릭터셋 인코딩", -DlgDocCharSetCE : "Central European", //MISSING -DlgDocCharSetCT : "Chinese Traditional (Big5)", //MISSING -DlgDocCharSetCR : "Cyrillic", //MISSING -DlgDocCharSetGR : "Greek", //MISSING -DlgDocCharSetJP : "Japanese", //MISSING -DlgDocCharSetKR : "Korean", //MISSING -DlgDocCharSetTR : "Turkish", //MISSING -DlgDocCharSetUN : "Unicode (UTF-8)", //MISSING -DlgDocCharSetWE : "Western European", //MISSING -DlgDocCharSetOther : "다른 캐릭터셋 인코딩", - -DlgDocDocType : "문서 헤드", -DlgDocDocTypeOther : "다른 문서헤드", -DlgDocIncXHTML : "XHTML 문서정의 포함", -DlgDocBgColor : "배경색상", -DlgDocBgImage : "배경이미지 URL", -DlgDocBgNoScroll : "스크롤되지않는 배경", -DlgDocCText : "텍스트", -DlgDocCLink : "링크", -DlgDocCVisited : "방문한 링크(Visited)", -DlgDocCActive : "활성화된 링크(Active)", -DlgDocMargins : "페이지 여백", -DlgDocMaTop : "위", -DlgDocMaLeft : "왼쪽", -DlgDocMaRight : "오른쪽", -DlgDocMaBottom : "아래", -DlgDocMeIndex : "문서 키워드 (콤마로 구분)", -DlgDocMeDescr : "문서 설명", -DlgDocMeAuthor : "작성자", -DlgDocMeCopy : "저작권", -DlgDocPreview : "미리보기", - -// Templates Dialog -Templates : "템플릿", -DlgTemplatesTitle : "내용 템플릿", -DlgTemplatesSelMsg : "에디터에서 사용할 템플릿을 선택하십시요.
    (지금까지 작성된 내용은 사라집니다.):", -DlgTemplatesLoading : "템플릿 목록을 불러오는중입니다. 잠시만 기다려주십시요.", -DlgTemplatesNoTpl : "(템플릿이 없습니다.)", -DlgTemplatesReplace : "현재 내용 바꾸기", - -// About Dialog -DlgAboutAboutTab : "About", -DlgAboutBrowserInfoTab : "브라우저 정보", -DlgAboutLicenseTab : "License", //MISSING -DlgAboutVersion : "버전", -DlgAboutInfo : "더 많은 정보를 보시려면 다음 사이트로 가십시오.", - -// Div Dialog -DlgDivGeneralTab : "General", //MISSING -DlgDivAdvancedTab : "Advanced", //MISSING -DlgDivStyle : "Style", //MISSING -DlgDivInlineStyle : "Inline Style", //MISSING - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/lt.js b/httemplate/elements/fckeditor/editor/lang/lt.js deleted file mode 100644 index 44f5da64e..000000000 --- a/httemplate/elements/fckeditor/editor/lang/lt.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Lithuanian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Sutraukti mygtukų juostą", -ToolbarExpand : "Išplėsti mygtukų juostą", - -// Toolbar Items and Context Menu -Save : "Išsaugoti", -NewPage : "Naujas puslapis", -Preview : "Peržiūra", -Cut : "Iškirpti", -Copy : "Kopijuoti", -Paste : "Įdėti", -PasteText : "Įdėti kaip gryną tekstą", -PasteWord : "Įdėti iš Word", -Print : "Spausdinti", -SelectAll : "Pažymėti viską", -RemoveFormat : "Panaikinti formatą", -InsertLinkLbl : "Nuoroda", -InsertLink : "Įterpti/taisyti nuorodą", -RemoveLink : "Panaikinti nuorodą", -VisitLink : "Atidaryti nuorodą", -Anchor : "Įterpti/modifikuoti žymę", -AnchorDelete : "Naikinti žymę", -InsertImageLbl : "Vaizdas", -InsertImage : "Įterpti/taisyti vaizdą", -InsertFlashLbl : "Flash", -InsertFlash : "Įterpti/taisyti Flash", -InsertTableLbl : "Lentelė", -InsertTable : "Įterpti/taisyti lentelę", -InsertLineLbl : "Linija", -InsertLine : "Įterpti horizontalią liniją", -InsertSpecialCharLbl: "Spec. simbolis", -InsertSpecialChar : "Įterpti specialų simbolį", -InsertSmileyLbl : "Veideliai", -InsertSmiley : "Įterpti veidelį", -About : "Apie FCKeditor", -Bold : "Pusjuodis", -Italic : "Kursyvas", -Underline : "Pabrauktas", -StrikeThrough : "Perbrauktas", -Subscript : "Apatinis indeksas", -Superscript : "Viršutinis indeksas", -LeftJustify : "Lygiuoti kairę", -CenterJustify : "Centruoti", -RightJustify : "Lygiuoti dešinę", -BlockJustify : "Lygiuoti abi puses", -DecreaseIndent : "Sumažinti įtrauką", -IncreaseIndent : "Padidinti įtrauką", -Blockquote : "Citata", -CreateDiv : "Sukurti Div elementą", -EditDiv : "Reaguoti Div elementą", -DeleteDiv : "Šalinti Div elementą", -Undo : "Atšaukti", -Redo : "Atstatyti", -NumberedListLbl : "Numeruotas sąrašas", -NumberedList : "Įterpti/Panaikinti numeruotą sąrašą", -BulletedListLbl : "Suženklintas sąrašas", -BulletedList : "Įterpti/Panaikinti suženklintą sąrašą", -ShowTableBorders : "Rodyti lentelės rėmus", -ShowDetails : "Rodyti detales", -Style : "Stilius", -FontFormat : "Šrifto formatas", -Font : "Šriftas", -FontSize : "Šrifto dydis", -TextColor : "Teksto spalva", -BGColor : "Fono spalva", -Source : "Šaltinis", -Find : "Rasti", -Replace : "Pakeisti", -SpellCheck : "Rašybos tikrinimas", -UniversalKeyboard : "Universali klaviatūra", -PageBreakLbl : "Puslapių skirtukas", -PageBreak : "Įterpti puslapių skirtuką", - -Form : "Forma", -Checkbox : "Žymimasis langelis", -RadioButton : "Žymimoji akutė", -TextField : "Teksto laukas", -Textarea : "Teksto sritis", -HiddenField : "Nerodomas laukas", -Button : "Mygtukas", -SelectionField : "Atrankos laukas", -ImageButton : "Vaizdinis mygtukas", - -FitWindow : "Padidinti redaktorių", -ShowBlocks : "Rodyti blokus", - -// Context Menu -EditLink : "Taisyti nuorodą", -CellCM : "Langelis", -RowCM : "Eilutė", -ColumnCM : "Stulpelis", -InsertRowAfter : "Įterpti eilutę po", -InsertRowBefore : "Įterpti eilutę prieš", -DeleteRows : "Šalinti eilutes", -InsertColumnAfter : "Įterpti stulpelį po", -InsertColumnBefore : "Įterpti stulpelį prieš", -DeleteColumns : "Šalinti stulpelius", -InsertCellAfter : "Įterpti langelį po", -InsertCellBefore : "Įterpti langelį prieš", -DeleteCells : "Šalinti langelius", -MergeCells : "Sujungti langelius", -MergeRight : "Sujungti su dešine", -MergeDown : "Sujungti su apačia", -HorizontalSplitCell : "Skaidyti langelį horizontaliai", -VerticalSplitCell : "Skaidyti langelį vertikaliai", -TableDelete : "Šalinti lentelę", -CellProperties : "Langelio savybės", -TableProperties : "Lentelės savybės", -ImageProperties : "Vaizdo savybės", -FlashProperties : "Flash savybės", - -AnchorProp : "Žymės savybės", -ButtonProp : "Mygtuko savybės", -CheckboxProp : "Žymimojo langelio savybės", -HiddenFieldProp : "Nerodomo lauko savybės", -RadioButtonProp : "Žymimosios akutės savybės", -ImageButtonProp : "Vaizdinio mygtuko savybės", -TextFieldProp : "Teksto lauko savybės", -SelectionFieldProp : "Atrankos lauko savybės", -TextareaProp : "Teksto srities savybės", -FormProp : "Formos savybės", - -FontFormats : "Normalus;Formuotas;Kreipinio;Antraštinis 1;Antraštinis 2;Antraštinis 3;Antraštinis 4;Antraštinis 5;Antraštinis 6", - -// Alerts and Messages -ProcessingXHTML : "Apdorojamas XHTML. Prašome palaukti...", -Done : "Baigta", -PasteWordConfirm : "Įdedamas tekstas yra panašus į kopiją iš Word. Ar Jūs norite prieš įdėjimą išvalyti jį?", -NotCompatiblePaste : "Ši komanda yra prieinama tik per Internet Explorer 5.5 ar aukštesnę versiją. Ar Jūs norite įterpti be valymo?", -UnknownToolbarItem : "Nežinomas mygtukų juosta elementas \"%1\"", -UnknownCommand : "Nežinomas komandos vardas \"%1\"", -NotImplemented : "Komanda nėra įgyvendinta", -UnknownToolbarSet : "Mygtukų juostos rinkinys \"%1\" neegzistuoja", -NoActiveX : "Jūsų naršyklės saugumo nuostatos gali riboti kai kurias redaktoriaus savybes. Jūs turite aktyvuoti opciją \"Run ActiveX controls and plug-ins\". Kitu atveju Jums bus pranešama apie klaidas ir trūkstamas savybes.", -BrowseServerBlocked : "Neįmanoma atidaryti naujo naršyklės lango. Įsitikinkite, kad iškylančių langų blokavimo programos neveiksnios.", -DialogBlocked : "Neįmanoma atidaryti dialogo lango. Įsitikinkite, kad iškylančių langų blokavimo programos neveiksnios.", -VisitLinkBlocked : "Neįmanoma atidaryti naujo lango. Įsitikinkite, kad iškylančių langų blokavimo programos neveiksnios.", - -// Dialogs -DlgBtnOK : "OK", -DlgBtnCancel : "Nutraukti", -DlgBtnClose : "Uždaryti", -DlgBtnBrowseServer : "Naršyti po serverį", -DlgAdvancedTag : "Papildomas", -DlgOpOther : "", -DlgInfoTab : "Informacija", -DlgAlertUrl : "Prašome įrašyti URL", - -// General Dialogs Labels -DlgGenNotSet : "", -DlgGenId : "Id", -DlgGenLangDir : "Teksto kryptis", -DlgGenLangDirLtr : "Iš kairės į dešinę (LTR)", -DlgGenLangDirRtl : "Iš dešinės į kairę (RTL)", -DlgGenLangCode : "Kalbos kodas", -DlgGenAccessKey : "Prieigos raktas", -DlgGenName : "Vardas", -DlgGenTabIndex : "Tabuliavimo indeksas", -DlgGenLongDescr : "Ilgas aprašymas URL", -DlgGenClass : "Stilių lentelės klasės", -DlgGenTitle : "Konsultacinė antraštė", -DlgGenContType : "Konsultacinio turinio tipas", -DlgGenLinkCharset : "Susietų išteklių simbolių lentelė", -DlgGenStyle : "Stilius", - -// Image Dialog -DlgImgTitle : "Vaizdo savybės", -DlgImgInfoTab : "Vaizdo informacija", -DlgImgBtnUpload : "Siųsti į serverį", -DlgImgURL : "URL", -DlgImgUpload : "Nusiųsti", -DlgImgAlt : "Alternatyvus Tekstas", -DlgImgWidth : "Plotis", -DlgImgHeight : "Aukštis", -DlgImgLockRatio : "Išlaikyti proporciją", -DlgBtnResetSize : "Atstatyti dydį", -DlgImgBorder : "Rėmelis", -DlgImgHSpace : "Hor.Erdvė", -DlgImgVSpace : "Vert.Erdvė", -DlgImgAlign : "Lygiuoti", -DlgImgAlignLeft : "Kairę", -DlgImgAlignAbsBottom: "Absoliučią apačią", -DlgImgAlignAbsMiddle: "Absoliutų vidurį", -DlgImgAlignBaseline : "Apatinę liniją", -DlgImgAlignBottom : "Apačią", -DlgImgAlignMiddle : "Vidurį", -DlgImgAlignRight : "Dešinę", -DlgImgAlignTextTop : "Teksto viršūnę", -DlgImgAlignTop : "Viršūnę", -DlgImgPreview : "Peržiūra", -DlgImgAlertUrl : "Prašome įvesti vaizdo URL", -DlgImgLinkTab : "Nuoroda", - -// Flash Dialog -DlgFlashTitle : "Flash savybės", -DlgFlashChkPlay : "Automatinis paleidimas", -DlgFlashChkLoop : "Ciklas", -DlgFlashChkMenu : "Leisti Flash meniu", -DlgFlashScale : "Mastelis", -DlgFlashScaleAll : "Rodyti visą", -DlgFlashScaleNoBorder : "Be rėmelio", -DlgFlashScaleFit : "Tikslus atitikimas", - -// Link Dialog -DlgLnkWindowTitle : "Nuoroda", -DlgLnkInfoTab : "Nuorodos informacija", -DlgLnkTargetTab : "Paskirtis", - -DlgLnkType : "Nuorodos tipas", -DlgLnkTypeURL : "URL", -DlgLnkTypeAnchor : "Žymė šiame puslapyje", -DlgLnkTypeEMail : "El.paštas", -DlgLnkProto : "Protokolas", -DlgLnkProtoOther : "", -DlgLnkURL : "URL", -DlgLnkAnchorSel : "Pasirinkite žymę", -DlgLnkAnchorByName : "Pagal žymės vardą", -DlgLnkAnchorById : "Pagal žymės Id", -DlgLnkNoAnchors : "(Šiame dokumente žymių nėra)", -DlgLnkEMail : "El.pašto adresas", -DlgLnkEMailSubject : "Žinutės tema", -DlgLnkEMailBody : "Žinutės turinys", -DlgLnkUpload : "Siųsti", -DlgLnkBtnUpload : "Siųsti į serverį", - -DlgLnkTarget : "Paskirties vieta", -DlgLnkTargetFrame : "", -DlgLnkTargetPopup : "", -DlgLnkTargetBlank : "Naujas langas (_blank)", -DlgLnkTargetParent : "Pirminis langas (_parent)", -DlgLnkTargetSelf : "Tas pats langas (_self)", -DlgLnkTargetTop : "Svarbiausias langas (_top)", -DlgLnkTargetFrameName : "Paskirties kadro vardas", -DlgLnkPopWinName : "Paskirties lango vardas", -DlgLnkPopWinFeat : "Išskleidžiamo lango savybės", -DlgLnkPopResize : "Keičiamas dydis", -DlgLnkPopLocation : "Adreso juosta", -DlgLnkPopMenu : "Meniu juosta", -DlgLnkPopScroll : "Slinkties juostos", -DlgLnkPopStatus : "Būsenos juosta", -DlgLnkPopToolbar : "Mygtukų juosta", -DlgLnkPopFullScrn : "Visas ekranas (IE)", -DlgLnkPopDependent : "Priklausomas (Netscape)", -DlgLnkPopWidth : "Plotis", -DlgLnkPopHeight : "Aukštis", -DlgLnkPopLeft : "Kairė pozicija", -DlgLnkPopTop : "Viršutinė pozicija", - -DlnLnkMsgNoUrl : "Prašome įvesti nuorodos URL", -DlnLnkMsgNoEMail : "Prašome įvesti el.pašto adresą", -DlnLnkMsgNoAnchor : "Prašome pasirinkti žymę", -DlnLnkMsgInvPopName : "Iššokančio lango pavadinimas privalo prasidėti lotyniška raide ir negali turėti tarpų", - -// Color Dialog -DlgColorTitle : "Pasirinkite spalvą", -DlgColorBtnClear : "Trinti", -DlgColorHighlight : "Paryškinta", -DlgColorSelected : "Pažymėta", - -// Smiley Dialog -DlgSmileyTitle : "Įterpti veidelį", - -// Special Character Dialog -DlgSpecialCharTitle : "Pasirinkite specialų simbolį", - -// Table Dialog -DlgTableTitle : "Lentelės savybės", -DlgTableRows : "Eilutės", -DlgTableColumns : "Stulpeliai", -DlgTableBorder : "Rėmelio dydis", -DlgTableAlign : "Lygiuoti", -DlgTableAlignNotSet : "", -DlgTableAlignLeft : "Kairę", -DlgTableAlignCenter : "Centrą", -DlgTableAlignRight : "Dešinę", -DlgTableWidth : "Plotis", -DlgTableWidthPx : "taškais", -DlgTableWidthPc : "procentais", -DlgTableHeight : "Aukštis", -DlgTableCellSpace : "Tarpas tarp langelių", -DlgTableCellPad : "Trapas nuo langelio rėmo iki teksto", -DlgTableCaption : "Antraštė", -DlgTableSummary : "Santrauka", -DlgTableHeaders : "Antraštės", -DlgTableHeadersNone : "Nėra", -DlgTableHeadersColumn : "Pirmas stulpelis", -DlgTableHeadersRow : "Pirma eilutė", -DlgTableHeadersBoth : "Abu", - -// Table Cell Dialog -DlgCellTitle : "Langelio savybės", -DlgCellWidth : "Plotis", -DlgCellWidthPx : "taškais", -DlgCellWidthPc : "procentais", -DlgCellHeight : "Aukštis", -DlgCellWordWrap : "Teksto laužymas", -DlgCellWordWrapNotSet : "", -DlgCellWordWrapYes : "Taip", -DlgCellWordWrapNo : "Ne", -DlgCellHorAlign : "Horizontaliai lygiuoti", -DlgCellHorAlignNotSet : "", -DlgCellHorAlignLeft : "Kairę", -DlgCellHorAlignCenter : "Centrą", -DlgCellHorAlignRight: "Dešinę", -DlgCellVerAlign : "Vertikaliai lygiuoti", -DlgCellVerAlignNotSet : "", -DlgCellVerAlignTop : "Viršų", -DlgCellVerAlignMiddle : "Vidurį", -DlgCellVerAlignBottom : "Apačią", -DlgCellVerAlignBaseline : "Apatinę liniją", -DlgCellType : "Langelio tipas", -DlgCellTypeData : "Duomenys", -DlgCellTypeHeader : "Antraštė", -DlgCellRowSpan : "Eilučių apjungimas", -DlgCellCollSpan : "Stulpelių apjungimas", -DlgCellBackColor : "Fono spalva", -DlgCellBorderColor : "Rėmelio spalva", -DlgCellBtnSelect : "Pažymėti...", - -// Find and Replace Dialog -DlgFindAndReplaceTitle : "Surasti ir pakeisti", - -// Find Dialog -DlgFindTitle : "Paieška", -DlgFindFindBtn : "Surasti", -DlgFindNotFoundMsg : "Nurodytas tekstas nerastas.", - -// Replace Dialog -DlgReplaceTitle : "Pakeisti", -DlgReplaceFindLbl : "Surasti tekstą:", -DlgReplaceReplaceLbl : "Pakeisti tekstu:", -DlgReplaceCaseChk : "Skirti didžiąsias ir mažąsias raides", -DlgReplaceReplaceBtn : "Pakeisti", -DlgReplaceReplAllBtn : "Pakeisti viską", -DlgReplaceWordChk : "Atitikti pilną žodį", - -// Paste Operations / Dialog -PasteErrorCut : "Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti iškirpimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl+X).", -PasteErrorCopy : "Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti kopijavimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl+C).", - -PasteAsText : "Įdėti kaip gryną tekstą", -PasteFromWord : "Įdėti iš Word", - -DlgPasteMsg2 : "Žemiau esančiame įvedimo lauke įdėkite tekstą, naudodami klaviatūrą (Ctrl+V) ir paspauskite mygtuką OK.", -DlgPasteSec : "Dėl jūsų naršyklės saugumo nustatymų, redaktorius negali tiesiogiai pasiekti laikinosios atminties. Jums reikia nukopijuoti dar kartą į šį langą.", -DlgPasteIgnoreFont : "Ignoruoti šriftų nustatymus", -DlgPasteRemoveStyles : "Pašalinti stilių nustatymus", - -// Color Picker -ColorAutomatic : "Automatinis", -ColorMoreColors : "Daugiau spalvų...", - -// Document Properties -DocProps : "Dokumento savybės", - -// Anchor Dialog -DlgAnchorTitle : "Žymės savybės", -DlgAnchorName : "Žymės vardas", -DlgAnchorErrorName : "Prašome įvesti žymės vardą", - -// Speller Pages Dialog -DlgSpellNotInDic : "Žodyne nerastas", -DlgSpellChangeTo : "Pakeisti į", -DlgSpellBtnIgnore : "Ignoruoti", -DlgSpellBtnIgnoreAll : "Ignoruoti visus", -DlgSpellBtnReplace : "Pakeisti", -DlgSpellBtnReplaceAll : "Pakeisti visus", -DlgSpellBtnUndo : "Atšaukti", -DlgSpellNoSuggestions : "- Nėra pasiūlymų -", -DlgSpellProgress : "Vyksta rašybos tikrinimas...", -DlgSpellNoMispell : "Rašybos tikrinimas baigtas: Nerasta rašybos klaidų", -DlgSpellNoChanges : "Rašybos tikrinimas baigtas: Nėra pakeistų žodžių", -DlgSpellOneChange : "Rašybos tikrinimas baigtas: Vienas žodis pakeistas", -DlgSpellManyChanges : "Rašybos tikrinimas baigtas: Pakeista %1 žodžių", - -IeSpellDownload : "Rašybos tikrinimas neinstaliuotas. Ar Jūs norite jį dabar atsisiųsti?", - -// Button Dialog -DlgButtonText : "Tekstas (Reikšmė)", -DlgButtonType : "Tipas", -DlgButtonTypeBtn : "Mygtukas", -DlgButtonTypeSbm : "Siųsti", -DlgButtonTypeRst : "Išvalyti", - -// Checkbox and Radio Button Dialogs -DlgCheckboxName : "Vardas", -DlgCheckboxValue : "Reikšmė", -DlgCheckboxSelected : "Pažymėtas", - -// Form Dialog -DlgFormName : "Vardas", -DlgFormAction : "Veiksmas", -DlgFormMethod : "Metodas", - -// Select Field Dialog -DlgSelectName : "Vardas", -DlgSelectValue : "Reikšmė", -DlgSelectSize : "Dydis", -DlgSelectLines : "eilučių", -DlgSelectChkMulti : "Leisti daugeriopą atranką", -DlgSelectOpAvail : "Galimos parinktys", -DlgSelectOpText : "Tekstas", -DlgSelectOpValue : "Reikšmė", -DlgSelectBtnAdd : "Įtraukti", -DlgSelectBtnModify : "Modifikuoti", -DlgSelectBtnUp : "Aukštyn", -DlgSelectBtnDown : "Žemyn", -DlgSelectBtnSetValue : "Laikyti pažymėta reikšme", -DlgSelectBtnDelete : "Trinti", - -// Textarea Dialog -DlgTextareaName : "Vardas", -DlgTextareaCols : "Ilgis", -DlgTextareaRows : "Plotis", - -// Text Field Dialog -DlgTextName : "Vardas", -DlgTextValue : "Reikšmė", -DlgTextCharWidth : "Ilgis simboliais", -DlgTextMaxChars : "Maksimalus simbolių skaičius", -DlgTextType : "Tipas", -DlgTextTypeText : "Tekstas", -DlgTextTypePass : "Slaptažodis", - -// Hidden Field Dialog -DlgHiddenName : "Vardas", -DlgHiddenValue : "Reikšmė", - -// Bulleted List Dialog -BulletedListProp : "Suženklinto sąrašo savybės", -NumberedListProp : "Numeruoto sąrašo savybės", -DlgLstStart : "Pradėti nuo", -DlgLstType : "Tipas", -DlgLstTypeCircle : "Apskritimas", -DlgLstTypeDisc : "Diskas", -DlgLstTypeSquare : "Kvadratas", -DlgLstTypeNumbers : "Skaičiai (1, 2, 3)", -DlgLstTypeLCase : "Mažosios raidės (a, b, c)", -DlgLstTypeUCase : "Didžiosios raidės (A, B, C)", -DlgLstTypeSRoman : "Romėnų mažieji skaičiai (i, ii, iii)", -DlgLstTypeLRoman : "Romėnų didieji skaičiai (I, II, III)", - -// Document Properties Dialog -DlgDocGeneralTab : "Bendros savybės", -DlgDocBackTab : "Fonas", -DlgDocColorsTab : "Spalvos ir kraštinės", -DlgDocMetaTab : "Meta duomenys", - -DlgDocPageTitle : "Puslapio antraštė", -DlgDocLangDir : "Kalbos kryptis", -DlgDocLangDirLTR : "Iš kairės į dešinę (LTR)", -DlgDocLangDirRTL : "Iš dešinės į kairę (RTL)", -DlgDocLangCode : "Kalbos kodas", -DlgDocCharSet : "Simbolių kodavimo lentelė", -DlgDocCharSetCE : "Centrinės Europos", -DlgDocCharSetCT : "Tradicinės kinų (Big5)", -DlgDocCharSetCR : "Kirilica", -DlgDocCharSetGR : "Graikų", -DlgDocCharSetJP : "Japonų", -DlgDocCharSetKR : "Korėjiečių", -DlgDocCharSetTR : "Turkų", -DlgDocCharSetUN : "Unikodas (UTF-8)", -DlgDocCharSetWE : "Vakarų Europos", -DlgDocCharSetOther : "Kita simbolių kodavimo lentelė", - -DlgDocDocType : "Dokumento tipo antraštė", -DlgDocDocTypeOther : "Kita dokumento tipo antraštė", -DlgDocIncXHTML : "Įtraukti XHTML deklaracijas", -DlgDocBgColor : "Fono spalva", -DlgDocBgImage : "Fono paveikslėlio nuoroda (URL)", -DlgDocBgNoScroll : "Neslenkantis fonas", -DlgDocCText : "Tekstas", -DlgDocCLink : "Nuoroda", -DlgDocCVisited : "Aplankyta nuoroda", -DlgDocCActive : "Aktyvi nuoroda", -DlgDocMargins : "Puslapio kraštinės", -DlgDocMaTop : "Viršuje", -DlgDocMaLeft : "Kairėje", -DlgDocMaRight : "Dešinėje", -DlgDocMaBottom : "Apačioje", -DlgDocMeIndex : "Dokumento indeksavimo raktiniai žodžiai (atskirti kableliais)", -DlgDocMeDescr : "Dokumento apibūdinimas", -DlgDocMeAuthor : "Autorius", -DlgDocMeCopy : "Autorinės teisės", -DlgDocPreview : "Peržiūra", - -// Templates Dialog -Templates : "Šablonai", -DlgTemplatesTitle : "Turinio šablonai", -DlgTemplatesSelMsg : "Pasirinkite norimą šabloną
    (Dėmesio! esamas turinys bus prarastas):", -DlgTemplatesLoading : "Įkeliamas šablonų sąrašas. Prašome palaukti...", -DlgTemplatesNoTpl : "(Šablonų sąrašas tuščias)", -DlgTemplatesReplace : "Pakeisti dabartinį turinį pasirinktu šablonu", - -// About Dialog -DlgAboutAboutTab : "Apie", -DlgAboutBrowserInfoTab : "Naršyklės informacija", -DlgAboutLicenseTab : "Licenzija", -DlgAboutVersion : "versija", -DlgAboutInfo : "Papildomą informaciją galima gauti", - -// Div Dialog -DlgDivGeneralTab : "Bendros savybės", -DlgDivAdvancedTab : "Papildomos savybės", -DlgDivStyle : "Stilius", -DlgDivInlineStyle : "Stilius kode", - -ScaytTitle : "SCAYT", //MISSING -ScaytTitleOptions : "Options", //MISSING -ScaytTitleLangs : "Languages", //MISSING -ScaytTitleAbout : "About" //MISSING -}; diff --git a/httemplate/elements/fckeditor/editor/lang/lv.js b/httemplate/elements/fckeditor/editor/lang/lv.js deleted file mode 100644 index 666dca79a..000000000 --- a/httemplate/elements/fckeditor/editor/lang/lv.js +++ /dev/null @@ -1,539 +0,0 @@ -/* - * FCKeditor - The text editor for Internet - http://www.fckeditor.net - * Copyright (C) 2003-2010 Frederico Caldeira Knabben - * - * == BEGIN LICENSE == - * - * Licensed under the terms of any of the following licenses at your - * choice: - * - * - GNU General Public License Version 2 or later (the "GPL") - * http://www.gnu.org/licenses/gpl.html - * - * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") - * http://www.gnu.org/licenses/lgpl.html - * - * - Mozilla Public License Version 1.1 or later (the "MPL") - * http://www.mozilla.org/MPL/MPL-1.1.html - * - * == END LICENSE == - * - * Latvian language file. - */ - -var FCKLang = -{ -// Language direction : "ltr" (left to right) or "rtl" (right to left). -Dir : "ltr", - -ToolbarCollapse : "Samazināt rīku joslu", -ToolbarExpand : "Paplašināt rīku joslu", - -// Toolbar Items and Context Menu -Save : "Saglabāt", -NewPage : "Jauna lapa", -Preview : "Pārskatīt", -Cut : "Izgriezt", -Copy : "Kopēt", -Paste : "Ievietot", -PasteText : "Ievietot kā vienkāršu tekstu", -PasteWord : "Ievietot no Worda", -Print : "Drukāt", -SelectAll : "Iezīmēt visu", -RemoveFormat : "Noņemt stilus", -InsertLinkLbl : "Hipersaite", -InsertLink : "Ievietot/Labot hipersaiti", -RemoveLink : "Noņemt hipersaiti", -VisitLink : "Open Link", //MISSING -Anchor : "Ievietot/Labot iezīmi", -AnchorDelete : "Remove Anchor", //MISSING -InsertImageLbl : "Attēls", -InsertImage : "Ievietot/Labot Attēlu", -InsertFlashLbl : "Flash", -InsertFlash : "Ievietot/Labot Flash", -InsertTableLbl : "Tabula", -InsertTable : "Ievietot/Labot Tabulu", -InsertLineLbl : "Atdalītājsvītra", -InsertLine : "Ievietot horizontālu Atdalītājsvītru", -InsertSpecialCharLbl: "Īpašs simbols", -InsertSpecialChar : "Ievietot speciālo simbolu", -InsertSmileyLbl : "Smaidiņi", -InsertSmiley : "Ievietot smaidiņu", -About : "Īsumā par FCKeditor", -Bold : "Treknu šriftu", -Italic : "Slīprakstā", -Underline : "Apakšsvītra", -StrikeThrough : "Pārsvītrots", -Subscript : "Zemrakstā", -Superscript : "Augšrakstā", -LeftJustify : "Izlīdzināt pa kreisi", -CenterJustify : "Izlīdzināt pret centru", -RightJustify : "Izlīdzināt pa labi", -BlockJustify : "Izlīdzināt malas", -DecreaseIndent : "Samazināt atkāpi", -IncreaseIndent : "Palielināt atkāpi", -Blockquote : "Blockquote", //MISSING -CreateDiv : "Create Div Container", //MISSING -EditDiv : "Edit Div Container", //MISSING -DeleteDiv : "Remove Div Container", //MISSING -Undo : "Atcelt", -Redo : "Atkārtot", -NumberedListLbl : "Numurēts saraksts", -NumberedList : "Ievietot/Noņemt numerēto sarakstu", -BulletedListLbl : "Izcelts saraksts", -BulletedList : "Ievietot/Noņemt izceltu sarakstu", -ShowTableBorders : "Parādīt tabulas robežas", -ShowDetails : "Parādīt sīkāku informāciju", -Style : "Stils", -FontFormat : "Formāts", -Font : "Šrifts", -FontSize : "Izmērs", -TextColor : "Teksta krāsa", -BGColor : "Fona krāsa", -Source : "HTML kods", -Find : "Meklēt", -Replace : "Nomainīt", -SpellCheck : "Pareizrakstības pārbaude", -UniversalKeyboard : "Universāla klaviatūra", -PageBreakLbl : "Lapas pārtraukums", -PageBreak : "Ievietot lapas pārtraukumu", - -Form : "Forma", -Checkbox : "Atzīmēšanas kastīte", -RadioButton : "Izvēles poga", -TextField : "Teksta rinda", -Textarea : "Teksta laukums", -HiddenField : "Paslēpta teksta rinda", -Button : "Poga", -SelectionField : "Iezīmēšanas lauks", -ImageButton : "Attēlpoga", - -FitWindow : "Maksimizēt redaktora izmēru", -ShowBlocks : "Show Blocks", //MISSING - -// Context Menu -EditLink : "Labot hipersaiti", -CellCM : "Šūna", -RowCM : "Rinda", -ColumnCM : "Kolonna", -InsertRowAfter : "Insert Row After", //MISSING -InsertRowBefore : "Insert Row Before", //MISSING -DeleteRows : "Dzēst rindas", -InsertColumnAfter : "Insert Column After", //MISSING -InsertColumnBefore : "Insert Column Before", //MISSING -DeleteColumns : "Dzēst kolonnas", -InsertCellAfter : "Insert Cell After", //MISSING -InsertCellBefore : "Insert Cell Before", //MISSING -DeleteCells : "Dzēst rūtiņas", -MergeCells : "Apvienot rūtiņas", -MergeRight : "Merge Right", //MISSING -MergeDown : "Merge Down", //MISSING -HorizontalSplitCell : "Split Cell Horizontally", //MISSING -VerticalSplitCell : "Split Cell Vertically", //MISSING -TableDelete : "Dzēst tabulu", -CellProperties : "Rūtiņas īpašības", -TableProperties : "Tabulas īpašības", -ImageProperties : "Attēla īpašības", -FlashProperties : "Flash īpašības", - -AnchorProp : "Iezīmes īpašības", -ButtonProp : "Pogas īpašības", -CheckboxProp : "Atzīmēšanas kastītes īpašības", -HiddenFieldProp : "Paslēptās teksta rindas īpašības", -RadioButtonProp : "Izvēles poga īpašības", -ImageButtonProp : "Attēlpogas īpašības", -TextFieldProp : "Teksta rindas īpašības", -SelectionFieldProp : "Iezīmēšanas lauka īpašības", -TextareaProp : "Teksta laukuma īpašības", -FormProp : "Formas īpašības", - -FontFormats : "Normāls teksts;Formatēts teksts;Adrese;Virsraksts 1;Virsraksts 2;Virsraksts 3;Virsraksts 4;Virsraksts 5;Virsraksts 6;Rindkopa (DIV)", - -// Alerts and Messages -ProcessingXHTML : "Tiek apstrādāts XHTML. Lūdzu uzgaidiet...", -Done : "Darīts", -PasteWordConfirm : "Teksta fragments, kas tiek ievietots, izskatās, ka būtu sagatavots Word'ā. Vai vēlaties to apstrādāt pirms ievietošanas?", -NotCompatiblePaste : "Šī darbība ir pieejama Internet Explorer'ī, kas jaunāks par 5.5 versiju. Vai vēlaties ievietot bez apstrādes?", -UnknownToolbarItem : "Nezināms rīku joslas objekts \"%1\"", -UnknownCommand : "Nezināmas darbības nosaukums \"%1\"", -NotImplemented : "Darbība netika paveikta", -UnknownToolbarSet : "Rīku joslas komplekts \"%1\" neeksistē", -NoActiveX : "Interneta pārlūkprogrammas drošības uzstādījumi varētu ietekmēt dažas no redaktora īpašībām. Jābūt aktivizētai sadaļai \"Run ActiveX controls and plug-ins\". Savādāk ir iespējamas kļūdas darbībā un kļūdu paziņojumu parādīšanās.", -BrowseServerBlocked : "Resursu pārlūks nevar tikt atvērts. Pārliecinieties, ka uznirstošo logu bloķētāji ir atslēgti.", -DialogBlocked : "Nav iespējams atvērt dialoglogu. Pārliecinieties, ka uznirstošo logu bloķētāji ir atslēgti.", -VisitLinkBlocked : "It was not possible to open a new window. Make sure all popup blockers are disabled.", //MISSING - -// Dialogs -DlgBtnOK : "Darīts!", -DlgBtnCancel : "Atcelt", -DlgBtnClose : "Aizvērt", -DlgBtnBrowseServer : "Skatīt servera saturu", -DlgAdvancedTag : "Izvērstais", -DlgOpOther : "", -DlgInfoTab : "Informācija", -DlgAlertUrl : "Lūdzu, ievietojiet hipersaiti", - -// General Dialogs Labels -DlgGenNotSet : "